김성엽님의 블로그를 따라하고 있습니다.
새 프로젝트를 생성할 때 Win32프로젝트
또는 Windows 데스크톱 어플리케이션
을 선택해서 진행하면 됨(VS2019에서는 Windows 데스크톱 어플리케이션 마법사)
기본 프로그램 틀을 제공해준다. 빌드 또한 가능하다.
기본 코드들이 굉장히 긴데, 사실 이거 다 안씀
실제로는 이렇게 사용함.
#include "framework.h"
#include "MyWin32.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_DESTROY) PostQuitMessage(0);
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"tipssoft";
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"Sihwan_Window",
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;
}
매개변수 | 설명 |
---|---|
hInstance | 이프로그램의 instance 핸들값이 전달됨 |
hPrevInstance | 현재 이 매개변수는 사용하지않음(NULL) |
lpCmdLine | main함수의 argc,argv 인자처럼 실행인자가 전달됨. 근데 각 인자가 문자열로 나눠져서 가는게 아니라, 실행파일 문자열 없이 하나의 인자로 전달됨. ex) Sihwan.exe Hello! -> Hello! 만 전달 |
nCmdShow | 응용 프로그램 초기시작 형식. 보통 SW_SHOWDEFAULT값이 전달됨. 아이콘이나 특정값을 지정하면 해당값이 여기 매개변수로 전달됨 |
크게 4가지 기능으로 구분됨
/*프로그램에 전달된 메시지를 번역하고 실행하는 작업*/
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) { // 메시지를 큐에서 읽는 함수
TranslateMessage(&msg); // 가상 키 메시지이면 ASCII 형태의 메시지를 추가로 생성
DispatchMessage(&msg); // 변환 된 메시지를 처리하는 함수
}
MSG 구조체
/*
* Message structure
*/
typedef struct tagMSG {
HWND hwnd; // 메시지가 발생한 윈도우 핸들
UINT message; // 발생한 메시지 아이디
WPARAM wParam; // 메시지와 함께 전달된 32비트 데이터
LPARAM lParam; // 메시지와 함께 전돨된 32비트 데이터
DWORD time; // 메시지가 전달된 시간(초단위)
POINT pt; // 메시지가 전달되었을 때 화면 마우스 기존 커서 좌표값
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
GetMessage()
PostQuitMessage(0)
TranslageMessage()
DispatchMessage()
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// 자신이 처리하지않은 메시지들의 기본 작업을 대신 처리해주는 함수
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
WndProc에서 발생하는 문제점
문제 발생시 해결법
이런 문제가 발생하지 않도록 하는 법
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// 메인 윈도우가 파괴될 때 메시지 큐에 WM_QUIT 메시지를 추가한다.
if (uMsg == WM_DESTROY) PostQuitMessage(0);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
위의 WndProc을 가지고 마우스 좌클릭 하는 작업을 만들게 된다면 이렇게 된다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if(uMsg == WM__LBUTTONDOWN){
// 좌클릭 시 무언가 일어난다.
}
else if (uMsg == WM_DESTROY) PostQuitMessage(0);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}