So I have beginners knowledge of C++ (4 months daily study, so maybe slightly more than beginner but definitely very new) and I have started looking at some win API stuff and have a few blanks in my head.
I am sure there are many things wrong with the below, or better ways to do it, and that will come in time but I'd like to know why when I step through this code does it for instance loop a few times through the first WndProc definition before passing the control elsewhere, and seemingly cease to ever come into contact with other parts of the program.
Is windows looping through the code to check for events at high speed then moving control else where?
I am sure with your knowledge you may want to even correct my question, so all information that you find related to what I think I'm asking here is appreciated.
Forgive the comments, they're to future self ;)
#include <Windows.h>
#include <string>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch (msg)
{
case WM_CLOSE:
PostQuitMessage(69);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
const auto CLASSNAME = "hwWindow";
//register window class
WNDCLASSEX wc = {};
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = nullptr;
wc.hIcon = nullptr;
wc.hCursor =nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = CLASSNAME;
wc.hIconSm = nullptr;
RegisterClassEx(&wc);
//create window instance
HWND RyanWin = CreateWindowEx(
0,
CLASSNAME,
"Hacker",
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
1200, 1200, 640, 480,
nullptr,
nullptr,
hInstance,
nullptr);
HWND hWnd = CreateWindowEx(
0,
CLASSNAME,
"Happy HW Windows",
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
200, 200, 640, 480,
nullptr,
nullptr,
hInstance,
nullptr);
ShowWindow(hWnd, SW_SHOW);
ShowWindow(RyanWin , SW_SHOW);
MSG msg;
BOOL gResult;
while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
{
TranslateMessage(&msg);
UINT m = msg.message;
DispatchMessage(&msg);
}
if (gResult == -1) { return -1; }
else { return msg.wParam; }
return 0;
}
Related
I'm trying to make a window for DirectX, but for some reason, when the window is created, it can't be closed after pressing X and it becomes a zombie process. I found that the GetMessage loop did not call WndProc at all after pressing X. I tried to find a solution, but unsuccessfully, so I want to ask the community. Please advise me.
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
nCmdShow)
{
//register windows class
const wchar_t* pClassName = L"Senko Interaction";
WNDCLASSEX wc = { 0 };
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = pClassName;
wc.hIconSm = nullptr;
RegisterClassEx(&wc);
//create window instance
HWND hWnd = CreateWindowEx(
0,
pClassName,
L"Senko Interaction",
WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
0, 0, 1280, 720,
nullptr, nullptr, hInstance, nullptr
);
ShowWindow(hWnd, SW_SHOW);
//create message loop
MSG msg;
BOOL gResult;
while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (gResult == -1)
{
return -1; //return -1
}
else
{
return msg.wParam; //return 0
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
PostQuitMessage(1);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam); //return 1
}
You set your window class to use DefWindowProc() instead of WndProc() for the lpfnWndProc, so it makes sense why WndProc() is never called:
wc.lpfnWndProc = DefWindowProc; // WRONG
That should be:
wc.lpfnWndProc = WndProc; // CORRECT
I am trying to learn the basics of graphical programming (IN GENERAL, not specifically windows), and would like to use the simplest, most encapsulated methods. I have the following code and would simply like to draw an image to the screen.
Note: The game->update is a call to my own class meant as the main game. I want to handle everything pertaining to my game there. That is why it is in the game loop.
#include <Windows.h>
#include "Asteroid_Game.h"
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_DESTROY) { PostQuitMessage(0); return 0; }
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmd, int nCmdShow)
{
WNDCLASSEX windowClass;
ZeroMemory(&windowClass, sizeof(WNDCLASSEX));
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
windowClass.hInstance = hInstance;
windowClass.lpfnWndProc = WindowProc;
windowClass.lpszClassName = "MainWindow";
windowClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&windowClass);
RECT rect = { 0, 0, 1000, 1000 };
AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, WS_EX_OVERLAPPEDWINDOW);
HWND windowHandle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MainWindow", "Asteroids - Pre-Alpha 0.1", WS_OVERLAPPEDWINDOW, 100, 100,
rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, 0);
if (!windowHandle)return -1;
ShowWindow(windowHandle, nCmdShow);
MSG message;
message.message = WM_NULL;
Asteroids* game = new Asteroids();
while (message.message != WM_QUIT)
{
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&message);
else
{
// Game Loop:
game->update();
}
delete game;
return 0;
}
I want to draw an image, say with the name "image.png".
I need to know the syntax.
Remember, I want to stay as encapsulated as possible. In other words, the less Windows API, the better.
Thanks for reading.
I created in C++ a window with the Win API.
If I set the target platform to x86 in Visual Studio (2015) all works fine.
But if I set the target platform to x64 all works fine too except that I get a busy cursor for the first 4-5 seconds when the window popped up.
This isn't that bad but I am just wondering what is causing this.
I saw this behavior when using GLFW too so it seems to be not a programming error.
Maybe someone know what is causing this?
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = "MainWindowClass";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
RECT wr = { 0, 0, 800, 800 };
AdjustWindowRectEx(&wr, WS_OVERLAPPEDWINDOW, FALSE, 0);
hWnd = CreateWindowEx(0, "MainWindowClass", "DirectX Lab", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
I was working through a book which shows me how to create a windows application. I have written the code, however when I compile and run it, it says that it was successfuly built but it doesn't show a window where it should write "Hello World". I am using Visual Studio 2010 with C++, what might be the problem?
Thanks
Here is the code;
//Header Files
#include <windows.h>
#include <stdlib.h>
#include <time.h>
//Application Title
#define APPTITLE L"Hello World"
//function prototypes (forward declarations)
BOOL InitInstance( HINSTANCE, int);
ATOM MyRegisterClass( HINSTANCE);
LRESULT CALLBACK WinProc( HWND, UINT, WPARAM, LPARAM);
//The window event callback function
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
//char *szHello = "Hello World!";
RECT rt;
int x, y, n;
COLORREF c;
switch(message)
{
case WM_PAINT:
//get the dimensions of the window
GetClientRect( hWnd, &rt);
//Start drawing on device context
hdc = BeginPaint( hWnd, &ps);
//Draw some text
DrawText( hdc, L"Hello World!", strlen( "Hello World!"), &rt, DT_CENTER);
//Draw 1000 random pixels
for( n=0; n < 3000; n++)
{
x = rand() % (rt.right - rt.left);
y = rand() % (rt.bottom - rt.top);
c = RGB( rand()%256, rand()%256, rand()%256);
SetPixel( hdc, x, y, c);
}
//Stop drawing
EndPaint( hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof( WNDCLASSEX);
//FILL THE STRUCT WITH INGO
wc.cbSize = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
//set up the window with the class info
return RegisterClassEx(&wc);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
//create a new window
hWnd = CreateWindow(
APPTITLE, //Window class
APPTITLE, //title bar
WS_OVERLAPPEDWINDOW, //window Style
CW_USEDEFAULT, //x position of window
CW_USEDEFAULT, //y postion of window
500, //width of the window
400, //height of the window
NULL, //parent window
NULL, //menu
hInstance, //application instance
NULL); //window parameters
//was there an error creating the window?
if( !hWnd)
return FALSE;
//Display the window
ShowWindow( hWnd, nCmdShow);
UpdateWindow( hWnd);
return TRUE;
}
//Entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//declare varuables
MSG msg;
//register the class
MyRegisterClass( hInstance);
//Initialize application
if( !InitInstance(hInstance, nCmdShow))
return FALSE;
//set random number seed
srand(time(NULL));
//Main message loop
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage( &msg);
DispatchMessage( &msg);
}
return msg.wParam;
}
This line is wrong:
wc.cbSize = CS_HREDRAW | CS_VREDRAW;
You mean
wc.style = CS_HREDRAW | CS_VREDRAW;
In fact I would change the window class initialisation code so that you make it very clear in the code that the entire struct is initialised.
WNDCLASSEX wc = { 0 };//initialise struct to 0
wc.cbSize = sizeof( WNDCLASSEX);
//FILL THE STRUCT WITH INGO
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = APPTITLE;
And you were missing some error checking:
if (!MyRegisterClass( hInstance))
return FALSE;
Stepping through under the debugger will allow you to see where in the process things are going wrong.
I want to create a simple project (the language doesn't really matter/but I prefer C++) which simply takes a window title as it's input and duplicate it's visual part, bit by bit, to a new window. just like a mirror better I'd say.
As far as I remember there was a win32 API for this but I can't remember, so would you please tell me how can I achieve this?
And please tell me, will your answers work with DirectX/Open-GL applications as well or not?
You can get DC of first window, and get DC of second window. And after this do BitBlt or StretchBlt. It has to work... But I don't know what about DirectX/Open-Gl... I think it has to work too. But anyway. It won't take much time to check it.
Here is the source code for a program that will mirror other apps, you can use StretchBlt() instead of BitBlt(), this will not copy Menubars or popups.
Some apps like chrome, calculator, and camera use child windows for the visual part, and FindWindow() only scans through top-level windows for the title, so you can use FindWindowEx() with it to make that work!
#include <windows.h>
HWND sourceWindow;
void Mirror(HWND hwndSource, HWND hwndDst)
{
HDC source = GetDC(hwndSource);
HDC dst = GetDC(hwndDst);
RECT srcSiz;
GetClientRect(hwndSource, &srcSiz);
SetWindowPos(hwndDst, NULL, 0, 0, srcSiz.right, srcSiz.bottom, SWP_NOMOVE | SWP_NOZORDER);
BitBlt(dst, 0, 0, srcSiz.right, srcSiz.bottom, source, 0, 0, SRCCOPY);
ReleaseDC(hwndSource, source);
ReleaseDC(hwndDst, dst);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_CREATE:
SetTimer(hwnd, 1, 500, (TIMERPROC) NULL);//This will refresh after every 500 ms
break;
case WM_TIMER:
Mirror(sourceWindow, hwnd);
break;
case WM_DESTROY:
KillTimer(hwnd, 1);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(0, 0, 0)));
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyWindow";
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindow", "MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
sourceWindow = FindWindowA(NULL, "<WindowTitle>");//or you can use class name
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}