1. Visual Studio 프로젝트 생성
앞으로 진행할 모든 Win32 프로그래밍은 Visual Studio에서 진행하게 된다.
먼저 Windows Desktop 응용 프로그램 프로젝트를 생성하는것을 알아보자.
파일 > 새로 만들기 > 프로젝트를 클릭하면 다음과 같은 메뉴가 나오게 된다.
윈도우즈 데스크톱 응용 프로그램 만들기를 선택하고 확인을 누르면 다음과 같은 화면이 나타날 것이다.
2. Win32 프로그래밍의 기초
1번 섹션을 올바르게 따라했다면 3번쨰 그림과 같은 소스가 나타났을 것이다. 자동으로 생성된 소스는 실습 과정에서 불필요한 부분이 많이 포함되어 있어 다음과 같은 소스로 대체한다.
#include "stdafx.h"
#include "MyFirstWin32.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_DESTROY) PostQuitMessage(0);
else if (uMsg == WM_CLOSE) {
if (IDCANCEL == MessageBox(hWnd, L"마지막으로 아르토리아 최고인거 인정하고 가자", L"어 인정", MB_OKCANCEL));
return 1;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
wchar_t my_class_name[] = L"HelloWin32";
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = my_class_name;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
HWND hWnd = CreateWindow(my_class_name, L"Artoria First",
WS_OVERLAPPEDWINDOW, 100, 90, 400, 350, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
위의 소스는 크게 4가지의 부분으로 구성된다.
- 윈도우 클래스 등록
- 윈도우 생성
- 메시지 루프
- 메시지 처리기
2.1 윈도우 클래스 등록
WNDCLASS wc; wchar_t my_class_name[] = L"HelloWin32"; wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.lpfnWndProc = WndProc; wc.lpszClassName = my_class_name; wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc);
윈도우 클래스 구조체의 변수를 만들고 멤버를 설정하여 윈도우 클래스 등록을 위한 준비를 마치고 RegisterClass()를 사용하여 윈도우 클래스를 운영체제에 등록한다.
2.2 윈도우 생성
HWND hWnd = CreateWindow(my_class_name, L"Artoria First",WS_OVERLAPPEDWINDOW, 100, 90, 400, 350, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
2.3 메시지 루프
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
읽어온 메시지를 저장할 구조체를 만든 후 반복문을 사용해 프로그램이 종료될 때까지(GetMessage가 0 반환) 메시지 큐에서 메시지를 읽어와 ASCII 값으로 해독하고(Translate)하고 처리(Dispatch)한다.
2.4 메시지 처리기
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hWnd, uMsg, wParam, lParam); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_DESTROY) { PostQuitMessage(0); } return DefWindowProc(hWnd, uMsg, wParam, lParam); }
다음은 WM_CLOSE 메시지를 받으면 종료 전에 확인 메시지를 띄우는 코드이다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_DESTROY) { PostQuitMessage(0); } else if (uMsg == WM_CLOSE) { if (IDCANCEL == MessageBox(hWnd, L"마지막으로 아르토리아 최고인거 인정하고 가자", L"어 인정", MB_OKCANCEL)); return 1; return DefWindowProc(hWnd, uMsg, wParam, lParam); }
결과적으로 우리가 Windows 프로그래밍을 한다는 것은 메시지 처리기에서 메시지를 받아 이벤트를 처리하는 작업이다.
3. 자주 사용되는 메시지들
메시지 | 해설 |
WM_LBUTTONUP/DOWN | 마우스 왼쪽 버튼을 누를 때와 땔 때 |
WM_MOUSEMOVE | 마우스를 움직일 때 |
WM_CREATE | 윈도우가 생성될 때 |
WM_DESTROY | 윈도우가 파괴되기 직전에 발생 |
WM_CLOSE | 윈도우가 파괴되기 직전에 발생, 종료 여부 질문 |
WM_KEYDOWN / UP | 키보드 입력할 때 |
WM_PAINT | 창을 다시 그리게 하기 위한 메시지 |
WM_QUIT | 프로그램 종료하기 위해 |
'프로그래밍 > C, C++' 카테고리의 다른 글
[TIPS 18기]Windows 프로그래밍 - 2 (0) | 2018.02.26 |
---|---|
[Tips 18기] C언어 여덟번째 강좌 (0) | 2018.02.01 |
[Tips 18기] C언어 일곱번째 강좌 (0) | 2018.01.29 |