window에서의 시작 포인트: WIN MAIN
#define WINAPI __stdcall #define WINAPIV __cdecl #define APIENTRY WINAPI int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
__cdecl : c/c++의 디폴트 호출규약. 오른쪽부터 전달되는 인자가 먼저 스택에 쌓이고 반환시 함수를 호출하는 쪽이 stack frame을 반환한다.
__fastcall : 함수 호출을 빠르게 처리하기 위한 규약. 레지스터 ecx, edx, 사용. 2개를 넘어선 인자는 stack을 활용한다.
64비트 기반 윈도우 : 8개 레지스터중 4개를 인자전달에 쓴다.
HINSTANCE hInst;
운영체제는 각각 프로세스를 인식할 방법이 필요하다. 인스턴스는 프로세스의 고유한 식별 번호이다(프로그램당 하나의 인스턴스) 운영체제가 식별 번호를 만들고 wWinMain에 식별 번호를 전달해 준다.
{ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 여기에 코드를 입력합니다. // 전역 문자열을 초기화합니다. LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 응용 프로그램 초기화를 수행합니다. if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT1)); MSG msg; // 기본 메시지 루프입니다. while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; }
LoadStringW(멀티바이트기반은 LoadStringA)
szTitle, szWindowClass 같은 것들은 전부 프로젝트 .rc string table에 있다.
<MyRegisterClass : 창클래스 등록>
MyRegisterClass(hInstance); ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; //귀찮으면 WNDCLASSEX 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_WIN32PROJECT1)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WIN32PROJECT1); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex); }
-윈도우 프로시저 등록
-아이콘 등록
-커서 등록
-윈도우 기본 백그라운드 창 색깔 결정
-메뉴창 알려주고(툴같은거 만들 때)
-RegisterClassEx : 지금 이 구성한 윈도우를 레지스터에 등록한다.
#ifdef UNICODE typedef WNDCLASSEXW WNDCLASSEX; typedef PWNDCLASSEXW PWNDCLASSEX; typedef NPWNDCLASSEXW NPWNDCLASSEX; typedef LPWNDCLASSEXW LPWNDCLASSEX; #else typedef WNDCLASSEXA WNDCLASSEX; typedef PWNDCLASSEXA PWNDCLASSEX; typedef NPWNDCLASSEXA NPWNDCLASSEX; typedef LPWNDCLASSEXA LPWNDCLASSEX; #endif // UNICODE#ifdef~#else~#endif 유니코드 설정에 따라서 달라짐
<WndProc : main 창의 메세지를 처리한다. >
//메세지 처리 루프에서 메세지가 들어오면 WndProc로 진입한다. 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; }윈도우는 메세지 기반의 운영체제.
이벤트가 발생하면 윈도우OS는 이를 Message로 변환하여 Message큐에 넣는다.
메세지 루프는 무한 루프를 돌면서 메세지 큐에 있는 메세지를 가져온다. 이 때 가져온 메세지를 Window Procedure가 처리한다.
사용자 정의 WndProc을 사용하기 위해 함수 포인터를 사용하며 윈도우 프로시저 함수포인터는 레지스터 등록 때 같이 등록한다.
MyRegisterClass에 WndProc 등록 부분이 있다.
<InitInstance : 실제 윈도우 창을 생성한다>
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다. HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); // nCmdShow : 처음 실행했을때 처음 보이게될 창의 방식 UpdateWindow(hWnd); // return TRUE; }WS_OVERLAPPEDWINDOW : 윈도우 레이아웃 (단축키 최소화키 등등)
'2020 이전 > Win API' 카테고리의 다른 글
WinAPI 5일차 오브젝트 구조, 점과 점 거리, 플레이어 이동 (0) | 2018.11.23 |
---|---|
Win API 4일차 Scene & Layer 구조 설계 (0) | 2018.10.31 |
Win API 3일차 Core 로직 & 타이머 작성 (0) | 2018.10.31 |
Win API 2일차 게임 프레임워크 작성 (0) | 2018.10.30 |
test (0) | 2018.10.26 |