If you made it this far and you are still having issues with the window, I'm going to guess that the default setting is on and the program expects to be encountering TCHAR type character strings instead of regular char, or maybe wchar_t depending on what it's set to. If none of that just made sense then I really suggest you read Petzold's Programing Windows API from chapter 1, or look up how to set your program to use ANSI instead of unicode... I think I phrased that right. Personally I tend to just use wchar_t format on everything.
I do have some info you might like though;
NT3 and TDSGoldenSun are both right in that their codes put together will work fine. The default template provided by Visual C++ is one of the most convoluted/confusing ways of going about setting up a window, so I would say that NT3 and GoldenSun have given the best starter's setup.
I'm going to try to go a bit further and explain what was wrong with your previous WndProc() having a loop around it's inner working like that, because when you're just starting out it might seem weird that winMain() doesn't seem to call the WndProc function, so how does it get into your program and keep running, right?
Look at the loop in TDSGoldenSun's WinMain() that goes:
1 2 3 4 5 6
|
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
//by the way, don't use peekmessage(), it is taking a "peek" at the next message on the que after the one that should be getting attention,
//this might be advantageous when you deal in multiple windows, but not to be used to run the main program itself
}
|
GetMessage() is getting the first message the operating system has in it's que for your window, TranslateMessage() is changing the information in the message so that it can be read by C++ Win API and sent off to the right window (because you can have multiple windows open at once, called child windows, your loop needs to know which window to send it to).
Finally DispatchMessage() is calling your WndProc that was pointed to in the WNDCLASS and it is supplying it with the message information. (so that last function is when the WndProc() gets called - also take note how I phrased that, your WNDCLASS has a
pointer to the WndProc function, not important now but may become so in the future)
In essence the WinMain() is doing nothing but initial set-up of the main window and then running that loop to catch messages from the OS and send it to your WndProc() until the window is closed with a PostQuitMessage(0) from the WndProc. The brains of the operation is not the WinMain() but actually in your WndProc, so having that internal while(PeekMessage(etc) actually prevents your window from getting the next message like it should.
This also means that since the WndProc is a function being called by the loop in WinMain(), it loses scope after each loop (meaning all regular variables lose their values between each message retrieved). If you want to keep information from the last time that the function looped (like if WM_KEYDOWN was called and you need to keep the char that was pressed) then you need to declare your variable as
static.
In the code below we are taking into account the chance that the user might resize the window screen, so we need to get the new rectangle that represents the new size.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
//declare variables that you use a lot in this scope
static RECT crect; //declare the crect rectangle to be static, we want to keep changes made from loop to loop
//these are given new values each time they are needed so they don't need to be static
HDC hdc;
PAINTSTRUCT ps;
switch(message)
{
case WM_CREATE:
//if there is any info that you need to set right when the window opens, set it in here.
//WM_CREATE will be called once and only once when the window is being created.
//actually it gives you a heads up that the window is about to be created
break;
case WM_SIZE://the screen is getting resized by the user
GetClientRect(hwnd, &crect);//load crect with the new size of the screen
InvalidateRect(hwnd, &crect, 1);//the screen is a new size so we want to redraw it.
break;
case WM_PAINT: //A message called whenever the screen needs redrawing
hdc = BeginPaint(hwnd, &ps);
//Do any drawing functions between Beginpaint and EndPaint
Rectangle(hdc, 10, 10, crect.right-10, crect.bottom-10); // draw a simple rectangle onscreen
EndPaint(hwnd, &ps);
break;
case WM_CLOSE: //The user has clicked on the red X to close the screen
//If there is any last minute thing you want to happen before closing, do it here
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);//sends a message to the OS to end the loop in WinMain()
break;
case WM_LBUTTONDOWN:
break;
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
|
I'm hoping we didn't throw too much at you, My best suggestion is to get Petzold's
Programing Windows fifth edition, whether you are lost or not right now, it is the holy-grail of beginning to moderate level Windows API. I am sorry for everything I threw at you, and I didn't even get into the use of LPARAM and WPARAM, I just wanted to give you a wide range of things that you can now look up on
http://msdn.microsoft.com/en-us/library/windows/desktop/ff818516%28v=vs.85%29.aspx