int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
, _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
// ... 생략
while (GetMessage(&Message, 0, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
// ... 생략
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage) {
case WM_LBUTTONDOWN:
{
HDC hdc = GetDC(hWnd); // DC 얻기
SetMapMode(hdc, MM_LOMETRIC); // 0.1mm 단위로 맵핑 모드 변경
RECT r;
GetClientRect(hWnd, &r); // 클라이언트 영역의 좌표를 얻는다.
// SetViewportOrgEx(hdc, r.right / 2, r.bottom / 2, NULL);
SetWindowOrgEx(hdc, 100, -50, NULL);
// 중심이 (0, 0)이고 반지름이 2cm인 원을 그린다.
Ellipse(hdc, 200, -200, 300, -300);
ReleaseDC(hWnd, hdc); // DC 반납
return 0;
}
// ... 생략.
}
// ...생략
}
Message
로 변환합니다.Window Procedure
에서 WM_LBUTTONDOWN Message
를 감지하고 이에 대한 처리를 수행합니다. 특정 동작이나 함수 호출이 발생할 수 있습니다. 위의 예시에서는 WndProc
함수에서 이를 처리합니다.Windows 프로그램에서 Message를 처리하는 부분을 Message Loop라고 지칭합니다.
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
BOOL GetMessage(
[out] LPMSG lpMsg,
[in, optional] HWND hWnd,
[in] UINT wMsgFilterMin,
[in] UINT wMsgFilterMax
);
System이 유지하는 Message Queue에서 Messag를 읽어들입니다. Message는 첫번째 인자가 지정하는 MSG 구조체에 저장됩니다.
함수는 읽어들인 Message가 프로그램을 종료하는 WM_QUIT일경우 False를 return하고, 그 외의 경우는 모두 True를 return합니다.
즉 Message Loop는 WM_QUIT Message가 읽혀질 때(프로그램이 종료될 때)까지 전체 while Loop가 실행됩니다.
BOOL TranslateMessage(
[in] const MSG *lpMsg
);
키보드의 입력 Message를 가공하여 프로그램에서 쉽게 사용할 수 있도록 도와줍니다.
Windows는 키보드의 어떤 키가 눌러졌다거나 떨어졌을 때 키보드의 Message를 발생시킵니다
해당 함수는 키보드의 눌림(WM_KEYDOWN)과 떨어짐(WM_KEYUP)이 연속적으로 발생할 때 문자가 입력되었다는 메시지(WM_CHAR)를 만드는 역할을 수행합니다.
LRESULT DispatchMessage(
[in] const MSG *lpMsg
);
System의 MessageQueue에서 꺼낸 Message를 프로그램의 Message 처리 함수인 (WndProc)로 전달합니다.
해당 함수를 사용하여 Message가 프로그램으로 전달되며 프로그램에서는 전달된 Message를 점검하여 다음 동작을 결정합니다.
Message Loop의 작업은 Message Queue에서 Message를 꺼낸 뒤 Message 처리 함수로 보내주는 역할입니다.
WNDPROC Wndproc;
LRESULT Wndproc(
HWND unnamedParam1,
UINT unnamedParam2,
WPARAM unnamedParam3,
LPARAM unnamedParam4
)
{...}
switch(iMessage)
{
case Msg1:
// process1
return 0;
case Msg2:
// process2
return 0;
case Msg3:
// process3
return 0;
default:
return DefWindowProc(...);
}