https://docs.microsoft.com/ko-kr/windows/win32/learnwin32/your-first-windows-program
μ λ΄μ©μ μ°Έκ³ νμ¬ μ 리ν λ΄μ©μ λλ€.
λͺ¨λ1. 첫 λ²μ§Έ Windows νλ‘κ·Έλ¨
1) μ°½ λ§λ€κΈ°
2) μ°½ λ©μΈμ§
3) μ°½ νλ‘μμ μμ±
μ°½ ν΄λμ€(Window Class)λ μ¬λ¬ μ°½μμ 곡ν΅μ μΌλ‘ μ¬μ©ν μ μλ λμμ μ§ν©μ λ§νλ€. μλ₯Ό λ€μ΄ λ²νΌ κ·Έλ£Ήμμ κ° λ²νΌμ λ²νΌμ ν΄λ¦ν λ μ μ¬ν λμμ ν¬ν¨νλ€. λ¬Όλ‘ λ²νΌμ΄ μμ ν λμΌνμ§λ μκ³ , κ° μ°½μ λν΄ κ³ μ ν λ°μ΄ν°λ₯Ό μΈμ€ν΄μ€ λ°μ΄ν°(instance data)λΌκ³ νλ€.
μ°½ ν΄λμ€λ C++μ "class"κ° μλμ μ΄ν΄νλ κ²μ΄ μ€μνλ€.
μ°½ ν΄λμ€λ μ΄μ 체μ μμ λ΄λΆμ μΌλ‘ μ¬μ©νλ λ°μ΄ν° κ΅¬μ‘°λ‘ λ°νμμ μμ€ν
μ λ±λ‘λλ€. μ μ°½ ν΄λμ€λ‘ λ±λ‘ νλ €λ©΄ λ¨Όμ ꡬ쑰체λ₯Ό μ
λ ₯νλ©΄λλ€.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
π ꡬ쑰체 λ©€λ² μ€μ
lpfnWndProc : μλμ° νλ‘μμ (Window procedure)λΌλ μμ© νλ‘κ·Έλ¨ μ μ ν¨μμ λν ν¬μΈν°μ΄λ€. μ°½μ λμ λλΆλΆμ μ μνλ€.
Hinstance : μμ© νλ‘κ·Έλ¨ μΈμ€ν΄μ€μ λν νΈλ€λ‘, Wwinmainμ hinstance λ§€κ° λ³μμμ μ΄ κ°μ κ°μ Έμ¨λ€.
lpszClassName : μ°½ ν΄λμ€λ₯Ό μλ³νλ λ¬Έμμ΄μ΄λ€.
κ·Έλ° λ€μ ꡬ쑰체μ μ£Όμλ₯Ό RegisterClass ν¨μμ μ λ¬νλ€. μ΄ ν¨μλ windows ν΄λμ€λ₯Ό μ΄μ 체μ μ λ±λ‘νλ€.
RegisterClass(&wc);
μ°½μ μ μΈμ€ν΄μ€λ₯Ό λ§λ€λ €λ©΄ CreateWindowEx ν¨μλ₯Ό νΈμΆνλ©΄ λλ€.
HWND hwnd = CreateWindowEx(0, // Optional window styles
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and Position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd = NULL)
{
return 0;
}
CreateWindowExλ μ μ°½μ λν νΈλ€μ λ°ννκ±°λ, μ€ν¨ν κ²½μ° 0μ λ°ννλ€. μ°½μ νμνλ €λ©΄ μ°½ νΈλ€μ ShowWindow ν¨μμ μ λ¬νλ©΄ λλ€.
ShowWindow(hwnd, nCmdShow);
hwndλ CreateWindowExμμ λ°νλλ μ°½ νΈλ€μ΄λ©° nCmdShowλ μ°½μ μ΅μννκ±°λ μ΅λν νλλ° μ¬μ©ν μ μλ€. μ΄μ체μ μμλ Wwinmain ν¨μλ₯Ό ν΅ν΄ μ΄ κ°μ νλ‘κ·Έλ¨μ μ λ¬νλ€.
π μ°½ λ§λ€κΈ°(μ 체 μ½λ)
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASS wc = { };
wc.lpfnWndPRoc = windowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window
HWND hwnd = CreateWindowEx(0, // Optional window styles
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and Position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd = NULL)
{
return 0;
}
μ μ½λλ₯Ό μ€ννλ©΄ μλμ κ°μ΄
Learn to Program Windows λΌλ μ΄λ¦μ μ°½μ΄ λ§λ€μ΄μ§λ€.
GUI μ΄ν리μΌμ΄μ μ μ¬μ©μ λ° μ΄μ체μ μ μ΄λ²€νΈμ μλ΅ν΄μΌ νλ€.
μ΄λ¬ν μ΄λ²€νΈλ€μ 미리 μμΈ‘ν μ μκΈ°μ Windows λ©μΈμ§ μ λ¬ λͺ¨λΈ(message-passing model)μ μ΄μ©νλ€. μ΄μ 체μ λ λ©μΈμ§λ₯Ό μ λ¬νμ¬ μ΄ν리μΌμ΄μ μ°½κ³Ό ν΅μ νλ€.
μλ₯Ό λ€μ΄ μ¬μ©μκ° λ§μ°μ€ μΌμͺ½ λ²νΌμ λλ₯΄λ©΄ μ°½μ λ€μκ³Ό κ°μ λ©μΈμ§κ° κ°λ€.
#define WM_LBUTTONDOWN 0x0201
μ°½μ λ©μΈμ§λ₯Ό μ λ¬νκΈ° μν΄ μ΄μ체μ λ ν΄λΉ μ°½μ λ±λ‘λ μλμ° νλ‘μμ λ₯Ό νΈμΆνλ€.
μ΄ν리μΌμ΄μ μλ μλ§μ λ©μΈμ§κ° μ€κ³ κ°κΈ° λλ¬Έμ λ©μΈμ§λ₯Ό κ²μνκ³ μ¬λ°λ₯Έ μ°½μΌλ‘ μ λ¬νλ 루νκ° νμνλ€.
μ΄μ체μ λ μ°½ λ§λλ κ° μ€λ λμ λν΄ μ°½ λ©μΈμ§μ λν νλ₯Ό λ§λλλ°, μ΄ νλ ν΄λΉ μ€λ λμμ λ§λ λͺ¨λ μ°½μ λν λ©μΈμ§λ₯Ό ν¬ν¨νλ€.
νλ₯Ό μ§μ μ‘°μν μλ μμΌλ GetMessage ν¨μλ₯Ό νΈμΆνμ¬ λ©μΈμ§λ₯Ό λμ΄μ¬ μ μλ€.
MSG msg;
GetMessage(&msg, NULL, 0, 0);
μ΄ ν¨μλ νμ ν€λμμ 첫λ²μ§Έ λ©μΈμ§λ₯Ό μ κ±°νλ€. νκ° λΉμ΄ μμΌλ©΄ λ€λ₯Έ λ©μΈμ§κ° νμ λκΈ°λ λκΉμ§ ν¨μκ° μ°¨λ¨λλ€. GetMessageκ° λ€λ₯Έ λ©μΈμ§λ₯Ό κΈ°λ€λ¦¬λ λμ κ³μ μ€νλλ μΆκ° μ€λ λλ₯Ό λ§λ€ μ μλ€.
GetMessageμ 첫λ²μ§Έ 맀κ°λ³μλ MSG ꡬ쑰체μ μ£Όμλ‘ ν¨μκ° μ±κ³΅νλ©΄ λ©μΈμ§μ λν μ λ³΄λ‘ MSG ꡬ쑰체λ₯Ό μ§μ΄λ€.
MSGλ₯Ό μ§μ κ²μ¬νμ§λ μκ³ , λ€λ₯Έ λ ν¨μμ μ λ¬νλ€.
TranslateMessage(&msg);
DispatchMessage(&msg);
TranlateMessgae : ν€λ³΄λ μ λ ₯μ λ¬Έμλ‘ λ³ν, DispatchMessageμ μ νΈμΆν΄μΌ νλ€.
DispatchMessage : λ©μΈμ§μ λμμΈ μλμ° νλ‘μμ λ₯Ό νΈμΆνλλ‘ μ΄μ체μ μκ² μ§μνλ€. μ¦ μ΄μ체μ λ μ°½ ν μ΄λΈμμ μ°½ νΈλ€μ μ°Ύκ³ μ°½κ³Ό μ°κ²°λ ν¨μ ν¬μΈν°λ₯Ό μ°Ύμ ν¨μλ₯Ό νΈμΆνλ€.
μλ₯Ό λ€μ΄ μ¬μ©μκ° λ§μ°μ€ μΌμͺ½ λ²νΌμ λλ₯Ό κ²½μ° μλμ μμλ‘ μλνλ€.
1) μ΄μ체μ λ WM_LBUTTONDOWN λ©μΈμ§λ₯Ό λ©μΈμ§ νμ λ£λλ€.
2) νλ‘κ·Έλ¨μμ GetMessage ν¨μλ₯Ό νΈμΆνλ€.
3) GetMessageλ νμμ WM_LBUTTONDOWN λ©μΈμ§λ₯Ό λμ΄μ MSG ꡬ쑰λ₯Ό μ±μ΄λ€.
4) νλ‘κ·Έλ¨μμ TranslateMessage λ° DispatchMessage ν¨μλ₯Ό νΈμΆνλ€.
5) DispatchMessage λ΄μμ μ΄μ체μ λ μλμ° νλ‘μμ λ₯Ό νΈμΆνλ€.
6) μλμ° νλ‘μμ λ λ©μΈμ§μ μλ΅νκ±°λ 무μν μ μλ€.
νλ‘κ·Έλ¨μ΄ μ€νλλ λμ λ©μΈμ§λ κ³μ νμ λμ°©νλ―λ‘ μ§μμ μΌλ‘ λ©μΈμ§λ₯Ό λ°μμ Dispatch νλ 루νκ° μμ΄μΌ νλ€.
λ°λΌμ λ€μκ³Ό κ°μ 루νκ° νμνλ€.
π μ§μμ μΌλ‘ λ©μΈμ§λ₯Ό λ°μμ Dispatch νλ 루ν
// Correct.
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
μ΄ν리μΌμ΄μ μ μ’ λ£νκ³ λ©μΈμ§ 루νλ₯Ό μ€λ¨νλ €λ©΄ PostQuitMessage ν¨μλ₯Ό νΈμΆνλ€.
π PostQuitMessage ν¨μ
PostQuitMessage(0);
μ¬κΈ°μ μ£ΌμκΉκ² λ³Ό μ μ μλμ° ν리μμ κ° WM_QUIT λ©μΈμ§λ₯Ό λ°μ§ μμ μ΄ λ©μΈμ§μ λν case λ¬Έμ΄ νμ μλ€λ κ²μ΄λ€.
π μλμ° νλ‘μμ
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
hwnd : μ°½μ λν νΈλ€
Umsg : λ©μΈμ§ μ½λ (ex. WM_SIZE : μ°½μ ν¬κΈ°κ° μ‘°μ λμμ)
wParam & lParam : μΆκ° λ°μ΄ν°
LRESULT : νλ‘κ·Έλ¨μμ Windows μκ² λ°ννλ μ μ κ°. μ΄ κ°μ μλ―Έλ λ©μΈμ§ μ½λμ λ°λΌ λ¬λΌμ§λ€.
CALLBACK : ν¨μμ λν νΈμΆ κ·μΉ
π μΌλ°μ μΈ μ½λ
switch (uMsg)
{
case WM_SIZE: // Handle window resizing
// etc
}
μΌλ°μ μΈ μλμ° νλ‘μμ λ μμ κ°μ λ©μΈμ§λ₯Ό μ²λ¦¬νλ―λ‘ μκ°μ΄ κΈΈμ΄μ§ μ μμ΄, μ½λλ₯Ό λͺ¨λμμΌλ‘ λ§λ€κ³ μ κ°λ³ ν¨μμμ κ° λ©μΈμ§λ₯Ό μ²λ¦¬νλλ‘ νλ€.
μ΄ λ μλμ° νλ‘μμ μμ wParam, lParamμ μΊμ€ν
νκ³ ν¨μμ μ λ¬νλ€.
π WM_SIZE λ©μΈμ§
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
int width = LOWORD(lParam); // Macro to get the low-order word
int height = HIWORD(lParam); // Macro to get the high-order word
// Respond to the message :
OnSize(hwnd, (UINT)wParam, width, height);
}
break;
}
}
void OnSize(HWND hwnd, UINT flag, int width, int height)
{
// Handle resizing
}
μλμ° νλ‘μμ μμ νΉμ λ©μΈμ§λ₯Ό μ²λ¦¬νμ§ μλ κ²½μ°μλ λ©μΈμ§ λ§€κ° λ³μλ₯Ό DefWindowProc ν¨μμ μ§μ μ λ¬νλ€.
π λ§€κ° λ³μλ₯Ό DefWindowProc ν¨μμ μ λ¬
return DefWindowProc(hwnd, uMsg, wParam, lParam);
μλμ° νλ‘μμ λ μ€νλλ λμ λμΌν μ€λ λ(thread)μ μμ±λ windowsμ λν λ€λ₯Έ λ©μΈμ§λ₯Ό μ°¨λ¨νλ€. μ΄λ° μ μΌλ‘ λ¬Έμ κ° λ°μνμ λλ Windowsμ κΈ°λ³Έ μ 곡λλ λ©ν°νμ€νΉ κΈ°λ₯ μ€ νλλ₯Ό μ¬μ©νμ¬ μμ μ λ€λ₯Έ μ€λ λλ‘ μ΄λν΄μΌ νλ€.