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 |