Order of winapi functions at compile time and runtime, and message loop

Started by
4 comments, last by SteveHatcher 9 years, 4 months ago

Hello,

I have been studying this 4 part series to get familiar with winapi concepts such as creating windows and message events.

http://msdn.microsoft.com/en-us/library/windows/desktop/ff381399%28v=vs.85%29.aspx

I am struggling to get my head around what is called when, such as at compile time and at run time, when the 'events' are taking place. I have some questions if those more knowledgeable can assist me:

In the simplest of demos, the "hello world" of windows gui programming (located here http://msdn.microsoft.com/en-us/library/windows/desktop/ff381409%28v=vs.85%29.aspx), I just want to ensure I understand what happens at compile time and run time.

Upon first program run, after HWND hwnd = CreateWindowEx() the program jumps to LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam). With a breakpoint at switch(uMsg) which lies in the WindowProc, I see the program do this:

uMsg = 36

program goes to return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 129

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 131

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 1

return DefWindowProc(hwnd, uMsg, wParam, lParam);

program then goes to ShowWindow(hwnd, nCmdShow); Are we at run-time now?

Continuing the step through...

uMsg = 24

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 70

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 70

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 28

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 134

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 127

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 127

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 127

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 6

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 641

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 642

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 7

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 133

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 20

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 71

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 5

return DefWindowProc(hwnd, uMsg, wParam, lParam);

uMsg = 3

return DefWindowProc(hwnd, uMsg, wParam, lParam);

After all of this we FINALLY hit

MSG msg = { };

then

while (GetMessage(&msg, NULL, 0, 0))

it then jumps back to switch(uMsg)

uMsg = 127

return DefWindowProc(hwnd, uMsg, wParam, lParam);

3 times, then

uMsg = 136

return DefWindowProc(hwnd, uMsg, wParam, lParam);

then off to

TranslateMessage(&msg);

DispatchMessage(&msg);

Then If i keep spamming Continue it seems to keep jumping between the message loop and the WindowProc. This is without me, the user, interacting with the window in any way. (In fact there is no way for me to intact with it except a close, minimise, or resize)

Basically I really want to know what is going on. What do these numbers mean? When I don't use the debugger the window just pops up. So what are all these messages being generated when I'm not touching the window? And what is the distinction between run-time and compile time with win32 programs?

Thanks. Apologizes for the long post, I just really have to set breakpoints and step through code to understand what is going on, and when its doing all of these mysterious commands I must know why.

Advertisement

Basically everything you described is run-time behavior, either initialization or normal program execution. If you want to know more about the difference between 'compile time' and 'run time' this stack overflow discussion might be informative.

(In fact there is no way for me to intact with it except a close, minimise, or resize)

You can also move your mouse around the window as well as in-and-out of the window. You can gain or lose focus of the window. And more that I'm not even thinking of. Of course what is really happening is Windows is interacting with your application, not you the user. The user interacts with Windows and Windows decides what to send to the program to handle and most of the time the program just says "ok Windows, I heard you. Now you take care of this message for me." That's what DefWindowProc is for. Of course, being the OS, Windows cares about more than the user so there were more messages than you thought. particularly during initialization. This link purports to list Windows messages and what the messages map to; it seems pretty accurate. So, based on your list of message numbers I found the corresponding message name and linked to MSDN so you can quickly reference the documentation on what the message is for:

uMsg = 36 -> WM_GETMINMAXINFO (addendum)

uMsg = 129 -> WM_NCCREATE

uMsg = 131 -> WM_NCCALCSIZE

uMsg = 1 -> WM_CREATE

uMsg = 24 -> WM_SHOWWINDOW

uMsg = 70 -> WM_WINDOWPOSCHANGING

uMsg = 70 -> WM_WINDOWPOSCHANGING

uMsg = 28 -> WM_ACTIVATEAPP

uMsg = 134 -> WM_NCACTIVATE

uMsg = 127 -> WM_GETICON

uMsg = 127 -> WM_GETICON

uMsg = 127 -> WM_GETICON

uMsg = 6 -> WM_ACTIVATE

uMsg = 641 -> WM_IME_SETCONTEXT

uMsg = 642 -> WM_IME_NOTIFY

uMsg = 7 -> WM_SETFOCUS

uMsg = 133 -> WM_NCPAINT

uMsg = 20 -> WM_ERASEBKGND

uMsg = 71 -> WM_WINDOWPOSCHANGED

uMsg = 5 -> WM_SIZE

uMsg = 3 -> WM_MOVE

As I said, most of the time you just want Windows to handle these for you.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

At winmain () you were already at runtime. In fact you were already a notch before in CRTmain() which calls winmain()
...

Great, thanks for your very informative response. That table lookup was interesting too. I guess when I was learning console based C++ I was in control of absolutely everything which made me feel more comfortable with whats going on. But now delving into winapi there are all these functions firing off at random times, calling and doing things which I have NFI about. Like I resize the window... it fires of a WM_SIZE.. I had no idea about that until I found it was making text disappear. It probably fires off some other things too which I wont know unless I step through a debugger. So it seems just going through the msdn code examples is the best way to learn this winapi stuff.

uMsg = 36 -> WM_GETMINMAXINFO (addendum)

uMsg = 129 -> WM_NCCREATE

uMsg = 131 -> WM_NCCALCSIZE

uMsg = 1 -> WM_CREATE

uMsg = 24 -> WM_SHOWWINDOW

uMsg = 70 -> WM_WINDOWPOSCHANGING

uMsg = 70 -> WM_WINDOWPOSCHANGING

uMsg = 28 -> WM_ACTIVATEAPP

uMsg = 134 -> WM_NCACTIVATE

uMsg = 127 -> WM_GETICON

uMsg = 127 -> WM_GETICON

uMsg = 127 -> WM_GETICON

uMsg = 6 -> WM_ACTIVATE

uMsg = 641 -> WM_IME_SETCONTEXT

uMsg = 642 -> WM_IME_NOTIFY

uMsg = 7 -> WM_SETFOCUS

uMsg = 133 -> WM_NCPAINT

uMsg = 20 -> WM_ERASEBKGND

uMsg = 71 -> WM_WINDOWPOSCHANGED

uMsg = 5 -> WM_SIZE

uMsg = 3 -> WM_MOVE

As I said, most of the time you just want Windows to handle these for you.

I guess most of this is windows 'initializing' the window? Since it runs the same time every time I run the program, which is a minimum win32 example, I guess this is the barebones code which windows does to create the window. I had no idea it was messages which actually create the window.

Thanks again


I guess most of this is windows 'initializing' the window? Since it runs the same time every time I run the program, which is a minimum win32 example, I guess this is the barebones code which windows does to create the window. I had no idea it was messages which actually create the window.

Understanding the concept of a message-driven application can be a bit confusing at first, and being a bit more precise in the semantics may help.

"this is the barebones code" - what you're looking at is not code (which you likely well understand) - it's data being sent by the Windows operating system to a window procedure. The window procedure, most commonly through a simple switch statement, evaluates each message, and determines what other procedures and code (if any) to execute based on individual messages. The majority of the messages received are simply passed onto the default window procedure (conveniently supplied by the Windows operating system) for processing.

Just for the sake of semantic clarity, and you likely understand, the messages do not "create the window." Messages being sent by the Windows OS are, for the most part, sent right back to the OS, which allocates memory, sets parameters, etc., and draws various parts of the window in a particular position on the desktop, and of a particular size, based on initial user input to the CreateWindow function call.

I would suggest a concept comprised of the following: "The Windows operating system can create and display windows in the desktop window in a defined way, with a consistent appearance, and respond to user input in a consistent manner. Through the window procedure, an application can customize the appearance and behavior of the window."

I.e., the window procedure allows the application to override any messages it chooses, and to either execute application specific code, or to even ignore processing of the message, depending on the desired behavior.

EDIT: If you want to spend a bit more effort (and $$$, ~70USD ohmy.png ) learning about the Win32 API beyond the series of articles you reference, you might look into Charles Petzold's "Programming Windows," various editions. One of the things that Microsoft has done well is, over a period of years, to remain consistent in the Win32 API. I have the 5th edition (1998) and the information and examples provided therein still work like a champ.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.


I guess most of this is windows 'initializing' the window? Since it runs the same time every time I run the program, which is a minimum win32 example, I guess this is the barebones code which windows does to create the window. I had no idea it was messages which actually create the window.

Understanding the concept of a message-driven application can be a bit confusing at first, and being a bit more precise in the semantics may help.

"this is the barebones code" - what you're looking at is not code (which you likely well understand) - it's data being sent by the Windows operating system to a window procedure. The window procedure, most commonly through a simple switch statement, evaluates each message, and determines what other procedures and code (if any) to execute based on individual messages. The majority of the messages received are simply passed onto the default window procedure (conveniently supplied by the Windows operating system) for processing.

Just for the sake of semantic clarity, and you likely understand, the messages do not "create the window." Messages being sent by the Windows OS are, for the most part, sent right back to the OS, which allocates memory, sets parameters, etc., and draws various parts of the window in a particular position on the desktop, and of a particular size, based on initial user input to the CreateWindow function call.

I would suggest a concept comprised of the following: "The Windows operating system can create and display windows in the desktop window in a defined way, with a consistent appearance, and respond to user input in a consistent manner. Through the window procedure, an application can customize the appearance and behavior of the window."

I.e., the window procedure allows the application to override any messages it chooses, and to either execute application specific code, or to even ignore processing of the message, depending on the desired behavior.

EDIT: If you want to spend a bit more effort (and $$$, ~70USD ohmy.png ) learning about the Win32 API beyond the series of articles you reference, you might look into Charles Petzold's "Programming Windows," various editions. One of the things that Microsoft has done well is, over a period of years, to remain consistent in the Win32 API. I have the 5th edition (1998) and the information and examples provided therein still work like a champ.

Thanks for your reply. I am still getting my head around this "windows sends it to the program which sends it back etc..." I may pick up a copy of that book as I have constantly heard it is great for winAPI programming, and I really want to get my head around this stuff.

It is still a very big difference jumping into this from console c++. Thanks again for the assistance.

Jumping back to my original question, most win 32 demos I have seem to execute the same msg codes in that order, so it must be a standard windows initialization routine or something to get a blank window open.

This topic is closed to new replies.

Advertisement