18 Haziran 2007 Pazartesi

win32 api programming...

IDM_ABOUT should be in your resource.h file as well, WM_COMMAND and WM_CREATE are windows messages, and are defined in winuser.h which you include automatically by including windows.h. You shouldn't change these, because the values they represent are used internally in Windows for message handling. If you change these your Window won't do much.

With Windows programming, there has to be a way for the coder to determine what should happen when a user clicks a button, types text in a text box, moves a window, minimizes the window, slides a scroll bar, closes the window, etc. While you might not use all of these at the same time (or any of them if you want), you will probably use them at least once in the course of Windows programming in general. To cope with this, Windows uses a message loop. This is typically in your WinMain function and consists of something like

MSG msg;

bool bFinish = false;

while(!bFinish)

{

if(PeekMessage(&msg, hWnd, 0, 0, PM_NOREMOVE) )

{

GetMessage(&msg, hWnd, 0, 0);

TranslateMessage(&msg);

DispatchMessage(&msg);

}

DoOtherStuff();

DoMoreOtherStuff();

}

When the program hits PeekMessage it checks the message queue (each button press and radio button change, or window movement, or window minimize adds a message to the message queue) to see if there's any messages there (PM_NOREMOVE means it just checks and returns true if there is a message waiting, but does not remove the message). We then hit GetMessage which retrieves the message and removes it from the queue (the difference between GetMessage and PeekMessage is basically that Peek gives you the option of not removing messages, and if there are no messages in the queue it will just return false, with GetMessage if there's no messages in the queue it will wait until there is a message. For a simple Windows program that doesn't matter and you can just use something like while(GetMessage(&msg, hWnd, 0, 0)) but if you want to do extra processing in between, eg in a game where something is constantly updating, you need to be able to access the main loop every time it runs, and dont' want to be sitting around waiting for Windows messages). Once it has retrieved a message, it puts it in TranslateMessage which changes certain aspects of it, basically making it more user friendly. Although not essential, I use it every time. DispatchMessage then does the next important thing, sends the translated message to your WndProc function.

This is the function that was named in the WNDCLASS or WNDCLASSEX structure when the window was first created. It passes in a handle to the window that called it (more than one window can share the same wndproc if they name it when they register the class), a UINT which is the Windows message that has been sent (more on that in a sec), a WPARAM which is mostly used for passing in extra data as values, and an LPARAM which tends to be used as a pointer to various structs that are used.

Inside your WndProc you will have something like switch(msg) and then lots of cases. This is where WM_COMMAND comes in. When you press a button or a radio control or in fact use any control on a dialogue, if it sends a message it will send it via the WM_COMMAND message. In the WPARAM it stores the value of the control (the unique identifier such as IDC_TEXT) but it stores it in the loword. Don't worry about this too much, all you need to know is that once you have a case WM_COMMAND: you have to have below it a switch(LOWORD(wParam)) or whatever your WPARAM is called, then you can use the switch statement to switch between cases and find the right control. Eg. You have a button called IDC_PRESSME and you want to check when it's pressed. That's easy, first you need a switch to find if a WM_COMMAND message has been sent, then you check which specific control it is, like so..

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

switch(msg)
{

case WM_COMMAND:

switch(LOWORD(wParam))
{

case IDC_PRESSME:

DoSomething();

break;
}

break;

default:

return DefWindowProc(hWnd, msg, wParam, lParam);

break;
}

return 0;
}

I hope that helps to give you an idea how it works, basically everything in windows has a UID, and you use that in message loops and in creating windows and controls from resources.

If I've done anything stupid don't laugh at me, it's early.

Hiç yorum yok: