3-4
จัดการและตอบสนองต่อ message
หลังจากที่ได้
updated window แล้วก็พร้อมที่จะรับคำสั่งจาก user โดย window จะทำการเตรียมคิวสำหรับ
input
ที่เข้ามา โดยจะทำการแปล (Translates) เหตุการณ์(คำสั่งจาก user) เป็น
message สู่program message queue
จากนั้น program จะนำ message จากคิวมาประมวลผลโดยเราเรียกกระบวนการนี้ว่า
"Message Loop"
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage
(&msg) ;
DispatchMessage
(&msg) ;
}
ตอนนี้เราก็ได้ window ที่พร้อมแล้วสำหรับตอบเสนอความต้องการของ
user และก็จะเป็นหน้าที่ของwindow procedure (WndProc) ซึ่งจะเป็นตัวตัดสินใจที่ทำอย่างไรกับ
message ที่เกิดขึ้น แล้วจะแสดงอะไรบน control window ซึ่งwindow procedure
นั้นจะมีได้มากกว่า 1 ซึ่งอยู่ยนพื้นฐานของ window class เดียวกันโดยจะมีรูปแบบดังนี้
LRESULT CALLBACK WndProc (HWND hwnd,
UINT message, WPARAM wParam, LPARAM lParam)
โดย parameter ตัวแรกจะเป็น handle ของ window (หากมีหลาย window ก็จะเป็น
handle ของwindow ที่แสดงในปัจจุบัน)
ตัวที่2 จะเป็นmessage indentifier สำหรับตัวที่ 3 4 ก็จะเป็นข้อมูลของ
Message เช่นเดียวกับตัวที่ 2 เมื่อได้ message มาแล้วต่อไปก็ขึ้นอบู่กับว่าเราจะทำอย่างไรกับ
message เหล่านั้น โดยทั่วไปจะใช้ Switch-Case ในการจัดการกับ Message
ที่เกิดขึ้น
switch (iMsg)
{
case WM_CREATE :
........ต้องการให้ทำอะไร.........
return 0 ;
case WM_........ :
........ต้องการให้ทำอะไร.........
return 0 ;
case WM_DESTROY :
.....เมื่อมีการปิด window........
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
ในส่วนของ
Message WM_PAINT จะสำคัญมาก โดยที่เมื่อเราจะแสดง window เมื่อใช้
ฟังก์ชั่นUpdatedWindow แล้ว window procedure จะต้องตัดสินใจว่าจะเอาอะไรขึ้นมาแสดงหรือจะแสดงยังงัย
บน client area เช่นเมื่อมีการ resize ,minimize ,maximize...โดยปกติแล้วโปรแกรมจะเป็นฝ่ายรับ
Message แต่มีบางกรณีที่โปรแกรมของเราจะต้องส่ง messageไปยัง window
เช่นในกรณีที่ผู้ใช้ปิดปรแกรม เราจะส่ง message PostQuitMessage (0)
; เข้าmessage queue และเมื่อเกิด Message WM_DESTROY จะทำให้โปรแกรมออกจาก
message loopและออกจากโปรแกรม
//---------basicwnd.cpp--------------
#include <windows.h>
static
TCHAR szMyClass[] = "myWndClass" ;
LRESULT CALLBACK
WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch
(message)
{
case
WM_CREATE:
MessageBox(hwnd,"Now
I'm ready to respond any message","Just caption",MB_OK);
return
0 ;
case
WM_CLOSE:
DestroyWindow(hwnd);
return
0;
case
WM_DESTROY:
PostQuitMessage
(0) ;
return
0 ;
}
return
DefWindowProc (hwnd, message, wParam, lParam) ;
}
BOOL RegisterWndClass
(HINSTANCE hInstance)
{
WNDCLASSEX
wndclass;
wndclass.cbSize
= sizeof(WNDCLASSEX);
wndclass.style
= CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc
= WndProc;
wndclass.cbClsExtra
= 0;
wndclass.cbWndExtra
= 0;
wndclass.hInstance
= hInstance;
wndclass.hIcon
= LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor
= LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground
= (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName
= NULL;
wndclass.lpszClassName
= szMyClass;
wndclass.hIconSm
= LoadIcon(NULL, IDI_APPLICATION);
if
(!RegisterClassEx(&wndclass))
{
MessageBox(NULL,"Window
Registration Failed!", "Resgister Error",
MB_ICONEXCLAMATION
| MB_OK);
return
0 ;
}
return
true;
}
int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine,
int iCmdShow)
{
HWND
hwnd ;
MSG
msg ;
if
(!RegisterWndClass(hInstance))
{
return
false;
}
hwnd
= CreateWindowEx (NULL,
szMyClass,
"This
is caption",
WS_OVERLAPPEDWINDOW
| WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
)
;
ShowWindow
(hwnd, iCmdShow) ;
UpdateWindow
(hwnd) ;
while
(GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage
(&msg) ;
DispatchMessage
(&msg) ;
}
return
msg.wParam ;
}
Credit Note :
บทความใน series ของ WIN32 API Programming เรียบเรียง จาก
Programming Windows 5 th Edittion : Charles Petzold
|