League Of Legends - Link Select [winAPI 01] Handle, DC, Window Event & ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค“ Study/winAPI

[winAPI 01] Handle, DC, Window Event & ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ

by GAMEMING 2024. 4. 3.
728x90

 

 

 

VS - Windows desktop application → ๋นˆํ”„๋กœ์ ํŠธ

 

 

 

- ๊ธฐ๋ณธ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์„ค๋ช…

 ๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ์ง„ํ–‰๋จ์— ๋”ฐ๋ผ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ๋ฉ”์„ธ์ง€ ํ๋กœ ์ด๋™๋˜์–ด ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌ๋œ๋‹ค.

  1. ์œˆ๋„์šฐ ์ƒ์„ฑ: ์œˆ๋„์šฐ๋ฅผ ์ƒ์„ฑ ์‹œ ํ™”๋ฉด์— ํ‘œ์‹œ(์œˆ๋„์šฐ์˜ ์†์„ฑ(ํฌ๊ธฐ, ์œ„์น˜...๋“ฑ์„ ์ง€์ •)
  2. ๋ฉ”์‹œ์ง€ ๋ฃจํ”„: ์œˆ๋„์šฐ๊ฐ€ ์ƒ์„ฑ ํ›„ ํ•ด๋‹น ์œˆ๋„์šฐ์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€ ๋ฃจํ”„ ์‹œ์ž‘ (์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด๋‚˜ ์‹œ์Šคํ…œ ์ด๋ฒคํŠธ ๋“ฑ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋Œ€๊ธฐํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• )
  3. ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ: ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ(๋งˆ์šฐ์Šค, ํ‚ค๋ณด๋“œ ๋“ฑ)์ด๋‚˜ ์‹œ์Šคํ…œ ์ด๋ฒคํŠธ(์œˆ๋„์šฐ ํฌ๊ธฐ ๋ณ€๊ฒฝ, ์ตœ์†Œํ™” ๋“ฑ)๋Š” ๋ฉ”์‹œ์ง€์˜ ํ˜•ํƒœ๋กœ ์œˆ๋„์šฐ์— ์ „๋‹ฌ (๋ฉ”์‹œ์ง€ ๋ฃจํ”„๋Š” ์ด ๋ฉ”์‹œ์ง€๋ฅผ ํ์—์„œ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์–ด ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜(์œˆ๋„์šฐ ํ”„๋กœ์‹œ์ €)๋กœ ์ „๋‹ฌ)
  4. ์œˆ๋„์šฐ ํ”„๋กœ์‹œ์ €:  ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์•„์„œ ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•จ
// ์ „์—ญ ๋ณ€์ˆ˜:
HINSTANCE hInst;                                // ํ˜„์žฌ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค.
WCHAR szTitle[MAX_LOADSTRING];                  // ์ œ๋ชฉ ํ‘œ์‹œ์ค„ ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค.
WCHAR szWindowClass[MAX_LOADSTRING];            // ๊ธฐ๋ณธ ์ฐฝ ํด๋ž˜์Šค ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // ์ „์—ญ ๋ฌธ์ž์—ด ์ดˆ๊ธฐํ™”
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT, szWindowClass, MAX_LOADSTRING);
   
    // ์œˆ๋„์šฐ ์ •๋ณด ๋“ฑ๋ก
    MyRegisterClass(hInstance);

    // ์œ„์˜ ์ •๋ณด ํ† ๋Œ€๋กœ ์œˆ๋„์šฐ(์ฐฝ) ์ƒ์„ฑ
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    // ๋‹จ์ถ•ํ‚ค ํ…Œ์ด๋ธ” ์ •๋ณด ๋กœ๋”ฉ
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT));

    MSG msg;

    // GetMessage
    // ๋ฉ”์„ธ์ง€ ํ์—์„œ ๋ฉ”์„ธ์ง€ ํ™•์ธ ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ
    // msg.message == WM_QUIT ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜ -> ํ”„๋กœ๊ทธ๋žจ ์ข…๋ฃŒ
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

// ์ฐฝ์— ๋Œ€ํ•œ ์ •๋ณด
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance;

   // ์œˆ๋„์šฐ ์ฐฝ ๋งŒ๋“ค๊ธฐ(OS๊ด€ํ• ) -> ์—ฌ๋Ÿฌ ํ•จ์ˆ˜์™€ ID์คŒ -> ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ์ด์šฉํ•ด ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ
   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}
// ์ฃผ๋กœ ์ž‘์—…ํ•˜๋Š” ๋ถ€๋ถ„ -> ํ”„๋กœ์‹œ์ €
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;
            EndPaint(hWnd, &ps);  
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

 

 

 

- ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ & WM_PAINT

 : ์šฐ๋ฆฌ๋Š” ์šด์˜์ฒด์ œ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ(์ปค๋„ ์˜ค๋ธŒ์ ํŠธ)๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ์“ธ ์ˆ˜ ์—†๋‹ค

   → OS๋Š” ์œˆ๋„์šฐ ์•„์ด๋””๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์“ด๋‹ค

   (์—ฌ๊ธฐ์„œ ๊ฐ์ฒด๋ž€ HPEN, HDC, HWND ๋“ฑ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋“ค์ด๋ผ ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค)

 

   ์‚ฌ๊ฐํ˜• ํ•˜๋‚˜๋ฅผ ๊ทธ๋ ค๋ณด์ž. ์œ„์˜ ์ฝ”๋“œ์—์„œ WM_PAINT ๋ถ€๋ถ„๋งŒ์„ ๊ฑด๋“ค์ด๋ฉด ๋œ๋‹ค.

   WM_PAINT → ์œˆ๋„์šฐ์— ๊ทธ๋ ค์•ผ ํ•  ์ƒํ™ฉ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”์„ธ์ง€

 

 * ์—ฌ๊ธฐ์„œ ๊ทธ๋ ค์•ผ ํ•  ์ƒํ™ฉ์ด๋ž€? ๋ฌดํšจํ™”(invalidate) ์˜์—ญ์ด ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ๋กœ ์ •์˜

 * ๋ฌดํšจํ™” : ํ™” ๋ฉด์„ ๊ฐฑ์‹ ํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ๊ทธ๋ฆด ๋•Œ๋ฅผ ์˜๋ฏธ. ์œˆ๋„์šฐ์˜ ์ผ๋ถ€๋ถ„์ด๋‚˜ ์ „์ฒด๊ฐ€ ๋‹ค์‹œ ๊ทธ๋ ค์ ธ์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋จ

 * ๋ฌดํšจํ™” ์˜์—ญ์ผ ๊ฒฝ์šฐ : ๋‹ค๋ฅธ ์œˆ๋„์šฐ ์ฐฝ์— ๊ฐ€๋ ค์กŒ๋‹ค๊ฐ€ ๋‹ค์‹œ ๋ˆ„๋ฅผ ๋•Œ ๊ฒน์ณ์กŒ๋˜ ๋ถ€๋ถ„(์•„๋ž˜ ์‚ฌ์ง„์˜ ๊ฒ€์ • ์ƒ‰ ๋ถ€๋ถ„)์ด ๋ฌดํšจํ™” ์˜์—ญ์ด๋ผ๋Š” ๊ฒƒ์€ ์˜ˆ์ „์— ํ•ด๋‹น๋˜๋Š” ๋ง  → ํ˜„์žฌ๋Š” ๋‹ค์‹œ ๊ทธ๋ฆด ํ•„์š” ์—†์–ด์„œ WM_PAINT ๋ฉ”์„ธ์ง€ ๋ฐœ์ƒ X

 

 

 

 

 

 ๊ทธ๋Ÿฌ๋ฉด ์–ธ์ œ ๋ฌดํšจํ™” ์˜์—ญ์ด ๋ฐœ์ƒํ•˜๊ณ  WM_PAINT๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€ ?? ์ฐฝ์„ ์•„์— ๋‚ด๋ ธ๋‹ค๊ฐ€ ๋‹ค์‹œ ํ‚ค๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ

 ์•„๋ฌดํŠผ ์‚ฌ๊ฐํ˜• ํ•˜๋‚˜๋ฅผ ๊ทธ๋ ค๋ณด์ž

 

// WndProc

 case WM_PAINT:
 {
 	PAINTSTRUCT ps;              
        HDC hdc = BeginPaint(hWnd, &ps);    // Device Context ๋งŒ๋“ค์–ด์„œ ID ๋ฐ˜ํ™˜ (๊ทธ๋ฆฌ๊ธฐ)
 
 	Rectangle(hdc, 10, 10, 110, 110);   // ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
 	EndPaint(hWnd, &ps);		    // ๊ทธ๋ฆฌ๊ธฐ ์ข…๋ฃŒ
 }
 break;

๊ฒฐ๊ณผํ™”๋ฉด - ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ

 

 

 

* Device Context ๋ฌด์—‡์ธ๊ฐ€?

 : ๊ทธ๋ฆฌ๊ธฐ ์ž‘์—… ์ˆ˜ํ–‰์‹œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์ด๋ผ ํ•˜๊ณ  HDC๋ผ๋Š” ์• ์˜ ๊ด€ํ• ์ด๋‹ค

 : DC์˜ ๋ชฉ์ ์ง€๋Š” ํ˜„์žฌ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ์ฐฝ (hWnd) ์ด๊ณ  ๊ธฐ๋ณธ ์„ค์ • ํŽœ ์ƒ‰์€ ๊ฒ€์ •, ๋ธŒ๋Ÿฌ์‰ฌ๋Š” ํ•˜์–€์ƒ‰์ด๋‹ค

  → ๊ทธ๋ž˜์„œ ์œ„์˜ ์‚ฌ์ง„์ด ํฐ ๋ฐฐ๊ฒฝ์— ํˆฌ๋ช… ์‚ฌ๊ฐํ˜•์ด ์•„๋‹ˆ๋ผ ํ•˜์–€์ƒ‰ ๋ธŒ๋Ÿฌ์‰ฌ๋กœ ์ƒ‰์„ ์น ํ•ด์„œ ๋‚˜์˜จ ๊ฒƒ์ด๋‹ค

 : ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋ ค๊ณ  ํ•  ๋•Œ ๋„ํ™”์ง€์™€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋“ฏ, ์ฐฝ์ด ๋„ํ™”์ง€๋ฉฐ ๋„๊ตฌ๋Š” ํŽœ๊ณผ ๋ธŒ๋Ÿฌ์‰ฌ ๋“ฑ ๋‹ค์–‘ํ•˜๊ฒŒ ์žˆ๋‹ค

 

 

< Rectangle ํ•จ์ˆ˜ >

 

 

- hdc : ๋””๋ฐ”์ด์Šค ์ปจํ…์ŠคํŠธ์— ๋Œ€ํ•œ ํ•ธ๋“ค (HDC)

- left : ์‚ฌ๊ฐํ˜•์˜ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ์— ์žˆ๋Š” ๋…ผ๋ฆฌ ์ขŒํ‘œ์˜ x ์ขŒํ‘œ

- top : ์‚ฌ๊ฐํ˜•์˜ ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ์— ์žˆ๋Š” ๋…ผ๋ฆฌ ์ขŒํ‘œ์˜ y ์ขŒํ‘œ

- right : ์‚ฌ๊ฐํ˜•์˜ ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ๋ชจ์„œ๋ฆฌ์— ์žˆ๋Š” ๋…ผ๋ฆฌ ์ขŒํ‘œ์˜ x ์ขŒํ‘œ

- bottom : ์‚ฌ๊ฐํ˜•์˜ ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ๋ชจ์„œ๋ฆฌ์— ์žˆ๋Š” ๋…ผ๋ฆฌ ์ขŒํ‘œ์˜ y ์ขŒํ‘œ

 

 

 

๊ทธ๋Ÿฌ๋ฉด ์ง์ ‘ ํŽœ๊ณผ ๋ธŒ๋Ÿฌ์‰ฌ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์ง€ ์•Š๋Š”๊ฐ€? → OK

 

// WndProc

case WM_PAINT:    
    {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps); 
            
            HPEN hRedPen = CreatePen(BS_SOLID, 1, RGB(255, 0, 0));  
            HBRUSH hBlackBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
            
            HPEN hDefaultPen = (HPEN)SelectObject(hdc, hRedPen);    
            HBRUSH hDefaultBrush = (HBRUSH)SelectObject(hdc, hBlackBrush);
            Rectangle(hdc, 10, 10, 110, 110);

            SelectObject(hdc, hDefaultPen); 
            SelectObject(hdc, hDefaultBrush);  
            DeleteObject(hRedPen);             
            DeleteObject(hDefaultBrush)

            EndPaint(hWnd, &ps); 
        }
        break;

 

์•„ ๊ทธ๋ฆฌ๊ณ  ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ฝค ํ—ท๊ฐˆ๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ

switch-case๋ฌธ์—์„œ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ค‘๊ด„ํ˜ธ { ... } ๊ฐ€ ํ•„์š”ํ•˜๋‹ค

 

 

< CreatePen ํ•จ์ˆ˜ >

 : ์ง์ ‘ ํŽœ์„ ๋งŒ๋“ค์–ด์„œ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ํ•ธ๋“ค์€ HPEN(ํŽœ(์„ ) ๊ฐ์ฒด)

 

 

 - iStyle : ์•„๋ž˜์˜ ๊ฐ’์„ ๋„ฃ์–ด์„œ ๋‹ค์–‘ํ•˜๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅํ•˜๋‹ค. ํ˜„์žฌ ์‚ฌ์šฉํ•œ ๊ฒƒ์€ PS_SOLID๋กœ ์‹ค์„ ์„ ์˜๋ฏธ

 

- cWidth : ํŽœ์˜ ๊ตต๊ธฐ (ํ”ฝ์…€ ๋‹จ์œ„). ํ˜„์žฌ 1ํ”ฝ์…€

- color : RGB ๋งคํฌ๋กœ ์ด์šฉํ•ด์„œ ์ƒ‰์„ ์ง€์ •ํ•จ. ํ˜„์žฌ RGB(255, 0, 0)์œผ๋กœ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ์ง€์ •๋จ

 

 

 

1) HPEN ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ƒˆ๋กœ์šด ํŽœ์„ ๋งŒ๋“  ๊ฒƒ์„ ๋„ฃ๋Š”๋‹ค(IDํ• ๋‹น).

2) HBRUSH ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ƒˆ๋กœ์šด ๋ธŒ๋Ÿฌ์‰ฌ๋ฅผ ๋งŒ๋“  ๊ฒƒ์„ ๋„ฃ๋Š”๋‹ค(IDํ• ๋‹น).

3) HPEN, HBRUSH ๊ฐ์ฒด(hDefaultPen, hDefaultBrush)์— ์ด์ „์— ์„ ํƒ๋˜์—ˆ๋˜ ๊ฐ์ฒด์˜ ํ•ธ๋“ค์„ ์ €์žฅํ•œ๋‹ค.

 

 

4) ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฐ ํ›„, ๋‹ค์‹œ ์˜ˆ์ „ ๊ฒ€์ • ํŽœ๊ณผ ํ•˜์–€ ๋ธŒ๋Ÿฌ์‰ฌ๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋งŒ๋“ค์—ˆ๋˜ ๊ฐ์ฒด๋ฅผ ์ง€์šด๋‹ค.

 

 

< GetStockObject ํ•จ์ˆ˜ >

 : ์Šคํ†ก ํŽœ, ๋ธŒ๋Ÿฌ์‹œ, ๊ธ€๊ผด ๋˜๋Š” ํŒ”๋ ˆํŠธ ์ค‘ ํ•˜๋‚˜์— ๋Œ€ํ•œ ํ•ธ๋“ค์„ ๊ฒ€์ƒ‰ (= ํ•ด๋‹น ๊ฐ์ฒด์— ๋Œ€ํ•ด ๋ฏธ๋ฆฌ ์ •ํ•ด๋†“์€ ๊ฐ’์„ ์ด์šฉํ•˜๊ฒ ๋‹ค)

 

 

 

- i : ์ž์ฃผ ์“ฐ๋Š” ์ƒ‰์€ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋†“์€ ๊ฒƒ์ด๋‹ค. ํ˜„์žฌ BLACK_BRUSH๋ฅผ ํ†ตํ•ด ๊ฒ€์ •์ƒ‰ ๋ธŒ๋Ÿฌ์‰ฌ๋ฅผ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

  ๋งŒ์•ฝ ๋ฏธ๋ฆฌ ์ •ํ•ด๋†“์€๊ฒŒ ์—†๋‹ค๋ฉด PEN๊ณผ ๋งˆ์ฐฌ ๊ฐ€์ง€๋กœ CreateSolidBrushํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด RGB๊ฐ’์„ ๋„ฃ์–ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

 

 

 

- ์‚ฌ๊ฐํ˜• ์ด๋™ 

 ์ด ์‚ฌ๊ฐํ˜•์„ ํ‚ค๋ณด๋“œ๋กœ ์ด๋™ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

 ์šฐ์„  ๊ธฐ์กด ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆด ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ ์ค˜์„œ ๊ทธ๋ ธ๋‹ค๋ฉด, ์šฐ๋ฆฌ๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์— ๋”ฐ๋ผ ๋ฐ”๋€Œ์–ด์•ผ ํ•จ์œผ๋กœ ๋ณ€์ˆ˜๊ฐ€ ์™€์•ผ ํ•œ๋‹ค.

 POINT ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ์ขŒํ‘œ๊ฐ’๊ณผ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•œ ํ›„ ๊ทธ ์ขŒํ‘œ๊ฐ’๊ณผ ํฌ๊ธฐ๋ฅผ ์ด์šฉํ•ด์„œ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฌ์ž

 

 

objPos๊ฐ€ ์‚ฌ๊ฐํ˜• ์ค‘๊ฐ„์ , ๋ชจ์„œ๋ฆฌ ์ขŒํ‘œ๋ฅผ ๊ตฌํ•˜๋Š” ์‹

 

 

 ํ‚ค๋ณด๋“œ ์ด๋™์€ ์–ด๋–ป๊ฒŒ ๋ฐ›๋Š”๊ฐ€? → ์šฐ๋ฆฌ๊ฐ€ ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅผ ๋•Œ WM_KEYDOWN ๋ฉ”์„ธ์ง€๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

 ์œˆ๋„์šฐ ํ”„๋กœ์‹œ์ €์—์„œ wParam์€ ํ‚ค๋ณด๋“œ id๊ฐ’์„  lParam์€ ๋งˆ์šฐ์Šค ์ขŒํ‘œ (ํด๋ผ์ด์–ธํŠธ ๊ธฐ์ค€ (x, y))์„ ๋ฐ›๋Š”๋‹ค

 ๋”ฐ๋ผ์„œ WM_KEYDOWN ์•ˆ์—์„œ wParam์„ ์ด์šฉํ•ด ์ฒ˜๋ฆฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๋‹จ ๋ฌธ์ž ์ž…๋ ฅ์€ 'W'์™€ ๊ฐ™์ด ๋Œ€๋ฌธ์ž๋กœ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

 

 ์ƒํ•˜์ขŒ์šฐ ํ‚ค์ธ VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ ์ขŒํ‘œ ๊ฐ’์„ ์˜ฎ๊ฒจ๋ณด์ž

 // ์ „์—ญ๋ณ€์ˆ˜ 
POINT objPos{ 500, 300 };
POINT objScale{ 100, 100 };

 // WndProc
    case WM_PAINT:  
    {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);   /

            HPEN hRedPen = CreatePen(BS_SOLID, 1, RGB(255, 0, 0));
            HBRUSH hBlackBrush = (HBRUSH)GetStockObject(BLACK_BRUSH);          
            
            HPEN hDefaultPen = (HPEN)SelectObject(hdc, hRedPen);                
            HBRUSH hDefaultBrush = (HBRUSH)SelectObject(hdc, hBlackBrush);

            Rectangle(hdc, objPos.x - objScale.x / 2,
                objPos.y - objScale.y / 2,
                objPos.x + objScale.x / 2,
                objPos.y + objScale.y / 2);

            SelectObject(hdc, hDefaultPen);   
            SelectObject(hdc, hDefaultBrush);  
            DeleteObject(hRedPen);            
            DeleteObject(hDefaultBrush);

            EndPaint(hWnd, &ps);            
        }
 case WM_KEYDOWN:  
    {
        switch (wParam)
        {
        case VK_UP:
            objPos.y -= 10;            
            break;

        case VK_DOWN:
            objPos.y += 10;
            break;
            
        case VK_LEFT:
            objPos.x -= 10;
            break;

        case VK_RIGHT:
            objPos.x += 10;
            break;

        case 'W':  // ๋ฌธ์ž๋Š” ๋Œ€๋ฌธ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ˆŒ๋ฆฐ๋‹ค 
        {

        }
        break;
        }
    }
    break;

 

 

→ ์•ˆ์›€์ง์ธ๋‹ค

 

์™œ์ผ๊นŒ? ๊ทผ๋ฐ ์ด๊ฑฐ ์ด๋Ÿฌ๋ฉด ์›€์ง์ด๊ณ  ์ฐฝ๋‚ด๋ ธ๋‹ค๊ฐ€ ์˜ฌ๋ฆฌ๋ฉด ๋ฐ”๋€Œ์–ด์ ธ ์žˆ์Œ

ํ‚ค๋Š” ๋จน๋Š”๋ฐ WM_PAINT์—์„œ ๋‹ค์‹œ ์•ˆ๊ทธ๋ ค์„œ ๊ทธ๋Ÿผ

 

์ด๊ฑฐ๋ฅผ ํ‚ค๋งˆ๋‹ค ๋„ฃ์–ด์ฃผ๋ฉด ์›€์ง์ผ ๊ฒƒ์ด๋‹ค.

 

 

 

๊ทผ๋ฐ ์•„๋งˆ ์ด๋ ‡๊ฒŒ ๋‚˜์˜ฌํ…๋ฐ, ์ด์ „์— ๊ทธ๋ ธ๋˜ ๊ฒƒ์ด ๋‚จ์•„์žˆ์–ด์„œ ๊ทธ๋ ‡๋‹ค.

InvalidateRect(hWnd, nullptr, false)์—์„œ ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ false๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•œ ์ง€์ •๋œ ์œˆ๋„์šฐ์˜ ์ „์ฒด ์˜์—ญ์„ ๋ฌดํšจํ™”ํ•˜๋˜ ๋ฐฐ๊ฒฝ์ƒ‰์œผ๋กœ ์ฑ„์šฐ์ง€ ์•Š๋Š”๋‹ค

 

๋งˆ์ง€๋ง‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ true๋กœ ๋ฐ”๊พธ๋ฉด ์ „์ฒด ์˜์—ญ์„ ๋ฐฐ๊ฒฝ์ƒ‰์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.

 

    case WM_KEYDOWN:   
    {
        switch (wParam)
        {
        case VK_UP:
            objPos.y -= 10;             
            InvalidateRect(hWnd, nullptr, true);
            break;

        case VK_DOWN:
            objPos.y += 10;
            InvalidateRect(hWnd, nullptr, true);
            break;
            
        case VK_LEFT:
            objPos.x -= 10;
            InvalidateRect(hWnd, nullptr, true);
            break;

        case VK_RIGHT:
            objPos.x += 10;
            InvalidateRect(hWnd, nullptr, true);
            break;

        case 'W':
        {

        }
        break;
        }
    }

 

 

 ๊ทผ๋ฐ ํ•˜๋‚˜์˜ ํ‚ค๋ฅผ ๊ณ„์† ๋ˆ„๋ฅด๋ฉด ๋ฉˆ์ท„๋‹ค๊ฐ€ 1์ดˆ ์ง€๋‚œ ํ›„์—์•ผ ๊ณ„์† ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋Š” ๊ฒƒ์œผ๋กœ ์ธ์‹๋œ๋‹ค.

 ๊ฒŒ์ž„ ๋งŒ๋“ค ๋•Œ ๋‚ด๊ฐ€ ํ”Œ๋ ˆ์ดํ•˜๋Š” ์บ๋ฆญํ„ฐ๊ฐ€ ์ด๋Ÿฐ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž. ์–ด์ƒ‰ํ•˜๋‹ค.

 ๋‹ค์Œ ์‹œ๊ฐ„์— ๋” ์•Œ์•„๋ณด๋„๋ก ํ•œ๋‹ค