Win32는 32비트 버전의 마이크로소프트 윈도에서 사용하는 윈도우 OS API
cf) 자료형 형 재선언
1) typedef
2) #define
Win32에서 선언된 대부분의 형들은 재선언된 것이다.
-> 'F12' 키를 눌러 선언된 형을 확인하면 된다.
기존의 C언어에서의 엔트리 포인트는 main() 함수이다.
윈도우로 넘어가면 엔트리 포인트가 WinMain()이 된다.
WinMain의 구조는 간략히 다음과 같다.
WinMain() {
1) 초기화 코드
- 윈도우 등록
- 윈도우 생성
2) Main Message Loop 코드
3) 해제 코드
}
아래 코드는 Win32 프로젝트의 메인함수이다.
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 여기에 코드를 입력합니다.
// 전역 문자열을 초기화합니다.
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WIN32PROJ, szWindowClass, MAX_LOADSTRING);
// WndProc을 등록하는 부분이 있다.
// 윈도우를 WndProc과 매칭시켜 이벤트 처리를 담당하도록 함.
MyRegisterClass(hInstance);
// 애플리케이션 초기화를 수행합니다:
// 윈도우를 생성하고 초기화한다.
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJ));
MSG msg;
/*
* Message structure
typedef struct tagMSG {
HWND hwnd; // 어떤 윈도우에게
UINT message; // 어떤 메시지를
WPARAM wParam; // 메시지 관련 정보1
LPARAM lParam; // 메시지 관련 정보1
DWORD time;
POINT pt; // 윈도우의 (x, y)좌표
// 마우스 클릭 위치 등에 필요
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, * PMSG, NEAR* NPMSG, FAR* LPMSG;
*/
// 기본 메시지 루프입니다:
// 메시지 큐에서 메시지를 루프를 돌며 가져와 처리(WndProc 호출)한다.
while (GetMessage(&msg, nullptr, 0, 0))
{
// 키보드 입력, 마우스 클릭과 같은 이벤트가 발생하면,
// 이벤트에 따라 메시지가 발생하고,
// 해당 메시지는 큐 형태의 자료구조에 추가됨
// 루프를 돌면서 큐에서 메시지를 하나씩 가져와
// 각 메시지에 대한 처리를 한다. 처리는 '윈도우 프로시저(WndProc)'에서 진행
// == callback (WndProc 호출)
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
윈도우 메시지 큐
source: https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kater102&logNo=122545087
WndProc 함수의 구조는 아래와 같다.
// 윈도우 핸들: 윈도우 식별자(값 또는 포인터)
// HWND, 윈도우 핸들(값)
// 윈도우 식별을 위해 필요한 값이다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 메뉴 선택을 구문 분석합니다:
switch (wmId)
{
// 각 케이스가 '이벤트 핸들러'이다.
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}