![]() |
|
Handling MessagesExample: window_click ![]() Alright, we've got a window, but it doesn't do anything except what In the next section I am going to show you how to modify what you already have to do somehting new. This way I can just tell you "Handle this message, and do this in it..." and you will know what I mean and be able to do so without seeing an entire example. That's the hope anyway, so pay attention. OK for starters take the example code for the last window we worked on and make sure it compiles and runs as expected. Then you can either keep working on it for the next little bit or copy it to a new project to modify.
We're going to add the capability to show the user what the name of our program is
when they click on our window. Not very exciting, it's basically to get the
hang of handling messages. Lets look at what we have in our PROCEDURE WndProc(hwnd : HWND; msg : UINT; wParam : WPARAM; lParam : LPARAM): LRESULT [EXPORT, OSCall]; VAR FileName : ARRAY [0..MAX_PATH] OF CHAR; BEGIN CASE msg OF | WM_CLOSE : FUNC DestroyWindow(hwnd); | WM_DESTROY : PostQuitMessage(0); ELSE RETURN DefWindowProc(hwnd, msg, wParam, lParam); END; RETURN 0; END WndProc; If we want to handle mouse clicks, we need to add a
If I or someone else refers to handling a message they mean to add it into the PROCEDURE WndProc(hwnd : HWND; msg : UINT; wParam : WPARAM; lParam : LPARAM): LRESULT [EXPORT, OSCall]; VAR FileName : ARRAY [0..MAX_PATH] OF CHAR; BEGIN CASE msg OF | WM_CLOSE : FUNC DestroyWindow(hwnd); | WM_DESTROY : PostQuitMessage(0); | WM_LBUTTONDOWN : (* <- we just added this *) ELSE RETURN DefWindowProc(hwnd, msg, wParam, lParam); END; RETURN 0; END WndProc; The order in which you handle your messages rarely matters.
As you can see we added another case into our First I will present the code we want to add (that will show the user the filename of our program) and then I will integrate it into our program. Later on I will probably just show you the code and let you integrate it into your program. This is of course better for me as I don't have to type as much and it's better for you because you will be able to add the code into ANY program and not just the ones I present. If you aren't sure how to do it, look at the example zip file included with the section. FUNC GetModuleFileName(Instance, FileName, MAX_PATH); FUNC MessageBox(hwnd, FileName, "This program is:", MB_OK BOR MB_ICONINFORMATION); Now this code does not stand on it's own, it can't just be slapped into our code any old place. We specifically want it to run when the user clicks the mouse button so this is how I would merge this small bit of code into our skeleton program: PROCEDURE WndProc(hwnd : HWND; msg : UINT; wParam : WPARAM; lParam : LPARAM): LRESULT [EXPORT, OSCall]; VAR FileName : ARRAY [0..MAX_PATH] OF CHAR; BEGIN CASE msg OF | WM_CLOSE : FUNC DestroyWindow(hwnd); | WM_DESTROY : PostQuitMessage(0); (* BEGIN NEW CODE *) | WM_LBUTTONDOWN : FUNC GetModuleFileName(Instance, FileName, MAX_PATH); FUNC MessageBox(hwnd, FileName, "This program is:", MB_OK BOR MB_ICONINFORMATION); (* END NEW CODE *) ELSE RETURN DefWindowProc(hwnd, msg, wParam, lParam); END; RETURN 0; END WndProc; So if you've added in that code, compile it now. If it works, click on the window and you should see a box with the name of the .exe pop up. VAR FileName : ARRAY [0..MAX_PATH] OF CHAR;
Look up
After So if you've added in that code, compile it now. If it works, click on the window and you should see a box with the name of the .exe pop up. If it doesn't work, here's the full code to the program. Compare it to what you have and see what, if any, mistakes you made. MODULE window_click; FROM WIN32 IMPORT HWND,UINT,WPARAM,LPARAM,LRESULT,HBRUSH,MAX_PATH, GetModuleFileName ; FROM WINUSER IMPORT WM_CLOSE,WM_DESTROY,WM_LBUTTONDOWN, IDI_APPLICATION,IDC_ARROW,COLOR_WINDOW, WS_EX_CLIENTEDGE,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, WNDCLASS,MSG, DestroyWindow,PostQuitMessage,DefWindowProc, RegisterClass,CreateWindowEx, ShowWindow,UpdateWindow, GetMessage,TranslateMessage,DispatchMessage, LoadCursor,LoadIcon, MessageBox,MB_ICONEXCLAMATION,MB_OK,MB_ICONINFORMATION; FROM WINX IMPORT Instance,CmdShow; FROM SYSTEM IMPORT CAST,ADR,FUNC; CONST g_szClassName = "myWindowClass"; (* Exported procedure *) PROCEDURE WndProc(hwnd : HWND; msg : UINT; wParam : WPARAM; lParam : LPARAM): LRESULT [EXPORT, OSCall]; VAR FileName : ARRAY [0..MAX_PATH] OF CHAR; BEGIN CASE msg OF | WM_CLOSE : FUNC DestroyWindow(hwnd); | WM_DESTROY : PostQuitMessage(0); | WM_LBUTTONDOWN : FUNC GetModuleFileName(Instance, FileName, MAX_PATH); FUNC MessageBox(hwnd, FileName, "This program is:", MB_OK BOR MB_ICONINFORMATION); ELSE RETURN DefWindowProc(hwnd, msg, wParam, lParam); END; RETURN 0; END WndProc; VAR wc : WNDCLASS; hwnd : HWND; Msg : MSG; BEGIN wc.style := 0; wc.lpfnWndProc := WndProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := Instance; wc.hIcon := LoadIcon(NIL, IDI_APPLICATION^); wc.hCursor := LoadCursor(NIL, IDC_ARROW^); wc.hbrBackground := CAST(HBRUSH, COLOR_WINDOW+1); wc.lpszMenuName := NIL; wc.lpszClassName := ADR(g_szClassName); IF RegisterClass(wc)=0 THEN FUNC MessageBox(NIL, "Window Class registration failed!", "Error!", MB_ICONEXCLAMATION BOR MB_OK); RETURN ; END; hwnd := CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "The title of my window",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NIL, NIL, Instance, NIL); IF hwnd = NIL THEN FUNC MessageBox(NIL, "Window Creation failed!", "Error!", MB_ICONEXCLAMATION BOR MB_OK); RETURN ; END; FUNC ShowWindow(hwnd, CmdShow); FUNC UpdateWindow(hwnd); WHILE GetMessage( Msg, NIL, 0, 0) DO FUNC TranslateMessage(Msg); FUNC DispatchMessage(Msg); END; END window_click. Copyright © 1998-2011, Brook Miles. All rights reserved. Adapted for Modula-2 by Frank Schoonjans, with permission. |