Win32 API
창 다루기
수색…
창 만들기
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tchar.h>
const TCHAR CLSNAME[] = TEXT("helloworldWClass");
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PTSTR cmdline,
int cmdshow)
{
WNDCLASSEX wc = { };
MSG msg;
HWND hwnd;
wc.cbSize = sizeof (wc);
wc.style = 0;
wc.lpfnWndProc = winproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = CLSNAME;
wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, TEXT("Could not register window class"),
NULL, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx(WS_EX_LEFT,
CLSNAME,
NULL,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInst,
NULL);
if (!hwnd) {
MessageBox(NULL, TEXT("Could not create window"), NULL, MB_ICONERROR);
return 0;
}
ShowWindow(hwnd, cmdshow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
return DefWindowProc(hwnd, wm, wp, lp);
}
가장 먼저 UNICODE
와 _UNICODE
의 두 매크로 정의가 있습니다. 이러한 매크로는 우리 프로그램이 일반 좁은 문자열 ( char[n]
)이 아닌 와이드 문자열 ( wchar_t[n]
)을 이해하도록합니다. 결과적으로 모든 문자열 리터럴은 TEXT(
매크로 : Win32 문자열의 일반 문자 유형은 TCHAR
입니다.이 문자의 정의는 UNICODE
가 정의되었는지 여부에 달려 있습니다.) 새 헤더가 포함됩니다. <tchar.h>
에는 TCHAR
선언.
창은 창 클래스라고 합니다. 아이콘, 커서 및 다른 것과 같이 인스턴스간에 공유 될 창에 대한 정보를 설명합니다. 창 클래스는이 예에서 CLSNAME
글로 z 변수에 제공된 창 클래스 이름으로 식별됩니다. WinMain
의 첫 번째 행위는 WNDCLASSEX wc
라는 창 클래스 구조를 채우는 것입니다. 회원들은 :
- cbSize : 구조의 크기 (바이트)
- style : 윈도우 클래스 스타일. 지금은 0입니다.
- lpfnWndProc : 이것은 더 중요한 필드 중 하나입니다. 윈도우 프로 시저 의 주소를 저장합니다. 윈도우 프로시 저는이 윈도우 클래스의 인스턴스 인 모든 윈도우에 대한 이벤트를 처리하는 함수입니다.
- cbClsExtra : 창 클래스에 할당 할 여분의 바이트 수입니다. 대부분의 경우이 멤버는 0입니다.
- cbWndExtra : 각 개별 창에 할당 할 여분의 바이트 수입니다. 모든 인스턴스에 공통적 인
cbClsExtra
와 혼동하지 마십시오. 이것은 종종 0입니다. - hInstance : 인스턴스 핸들.
WinMain
의hInst
인수를이 필드에 할당하면됩니다. - hIcon : 윈도우 클래스의 아이콘 핸들.
LoadIcon(NULL, IDI_APPLICATION)
은 기본 응용 프로그램 아이콘을로드합니다. - hCursor : 윈도우 클래스의 커서 핸들.
LoadCursor(NULL, IDC_ARROW)
는 기본 커서를로드합니다. - hbrBackground : 배경 브러시 핸들.
GetStockObject (WHITE_BRUSH)
는 흰색 브러시 핸들을 제공합니다.GetStockObject
가 제네릭 개체를 반환하기 때문에 반환 값을 캐스팅해야합니다. - lpszMenuName : 사용할 메뉴 막대의 자원 이름. 메뉴 막대가 필요하지 않으면이 필드는 NULL이 될 수 있습니다.
- lpszClassName :이 창 클래스 구조를 식별하는 클래스 이름. 이 예에서
CLSNAME
글로 z 변수는 창 클래스 이름을 저장합니다. - hIconSm : 작은 클래스 아이콘 핸들.
이 구조체가 초기화 된 후 RegisterClassEx
함수가 호출됩니다. 이로 인해 창 클래스가 Windows에 등록되어 응용 프로그램에 알립니다. 실패하면 0을 반환합니다.
이제 창 클래스가 등록되었으므로 CreateWindowEx
사용하여 창을 표시 할 수 있습니다. 인수는 다음과 같습니다.
- stylesex : 확장 된 창 스타일. 기본값은 WS_EX_LEFT입니다.
- clsname : 클래스 이름
- cap : 창 제목 또는 캡션. 이 경우 창 제목 표시 줄에 표시되는 캡션입니다.
- styles : 창 스타일. 이와 같이 최상위 (상위) 창을 만들려면 전달할 플래그가 WS_OVERLAPPEDWINDOW입니다.
- x : 윈도우의 왼쪽 위 모퉁이의 x 좌표입니다.
- y : 윈도우의 왼쪽 위 모퉁이의 y 좌표입니다.
- cx : 창 너비
- cy : 창 높이
- hwndParent : 부모 창 핸들. 이 창 자체는 부모 창이므로이 인수는 NULL입니다.
- hMenuOrID : 생성되는 윈도우가 부모 윈도우 인 경우이 인수는 윈도우 메뉴의 핸들입니다. 이것을
WNDCLASSEX::lpszClassName
클래스 메뉴와 혼동하지 마십시오. 클래스 메뉴는 동일한 클래스 이름을 가진 모든 창 인스턴스에 공통입니다. 그러나이 인수는이 인스턴스에만 해당됩니다. 생성되는 윈도우가 자식 윈도우 인 경우, 이는 자식 윈도우의 ID입니다. 이 경우 메뉴가없는 부모 창을 작성하므로 NULL이 전달됩니다. - hInst : 응용 프로그램의 인스턴스에 대한 핸들입니다.
- etc : 윈도우의 윈도우 프로 시저에 전달되는 추가 정보. 추가 정보가 전송되지 않으면 NULL을 전달하십시오.
x
또는 y
또는 cx
또는 cy
가 CW_USEDEFAULT
이면 해당 인수의 값은 Windows에 의해 결정됩니다. 이것이 바로이 예제에서 수행 된 것입니다.
CreateWindowEx
는 새로 생성 된 윈도우에 대한 핸들을 반환합니다. 창을 만들지 못하면 NULL
을 반환 NULL
.
그런 다음 ShowWindow
를 호출하여 창을 표시합니다. 이 함수의 첫 번째 인수는 윈도우 핸들입니다. 두 번째 인수는 창 표시 방법을 나타내는 표시 스타일입니다. 대부분의 응용 프로그램은 WinMain
에서 전달 된 cmdshow
인수를 전달합니다. 창이 표시되면 UpdateWindow
호출하여 창을 업데이트해야합니다. 그러면 창에 업데이트 메시지가 전송됩니다. 다른 튜토리얼에서 이것이 무엇을 의미하는지 배우게 될 것입니다.
이제 응용 프로그램의 핵심은 메시지 펌프입니다. 운영 체제에서이 응용 프로그램으로 보낸 메시지를 펌프하고 창 프로 시저에 메시지를 디스패치합니다. GetMessage
호출은 응용 프로그램이 메시지를 수신하여 종료되도록 할 때까지 0이 아닌 값을 반환합니다.이 경우 0을 반환합니다. 우리에 관한 유일한 인수는 메시지에 대한 정보로 채워지는 MSG
구조에 대한 포인터입니다. 다른 인수는 모두 0입니다.
메시지 루프 내에서 TranslateMessage
는 가상 키 메시지를 문자 메시지로 변환합니다. 이것의 의미는 다시 우리에게 중요하지 않습니다. MSG
구조체에 대한 포인터를 사용합니다. 바로 뒤에 오는 호출 인 DispatchMessage
는 인수에 의해 가리키는 메시지를 창의 윈도우 프로 시저에 전달합니다. WinMain
야 할 마지막 일은 상태 코드를 반환하는 것입니다. MSG
구조체의 wParam
멤버는이 반환 값을 포함하므로 반환됩니다.
그러나 이것은 WinMain
기능을위한 것입니다. 다른 함수는 윈도우 프로 시저 인 winproc
입니다. Windows에서 보낸 메시지의 메시지를 처리합니다. winproc
의 서명은 다음과 같습니다.
- hwnd : 메시지가 처리되고있는 창의 핸들.
- wm : 윈도우 메시지 식별자
- wp : 메시지 정보 인수 중 하나. 이것은
wm
인수에 의존합니다. - lp : 메시지 정보 인수 중 하나입니다. 이것은
wm
인수에 따라 다릅니다. 이 인수는 일반적으로 포인터 또는 핸들을 전송하는 데 사용됩니다
이 간단한 프로그램에서 우리는 스스로 메시지를 처리하지 않습니다. 하지만 그렇다고해서 윈도우도 그렇지 않다는 것을 의미하지는 않는다. 이것이 DefWindowProc
호출해야하는 이유입니다. DefWindowProc
은 기본 윈도우 처리 코드를 포함합니다. 이 함수는 모든 윈도우 프로 시저의 끝에서 호출되어야합니다.
핸들이란 무엇입니까?
핸들 은 고유 한 객체를 나타내는 데이터 유형입니다. 그것들은 포인터이지만 운영 체제에 의해 유지되는 비밀 데이터 구조입니다. 이러한 구조의 세부 사항은 우리를 염려 할 필요가 없습니다. 사용자가해야 할 일은 단순히 API 호출을 사용하여 핸들을 작성 / 검색하고 해당 핸들 유형을 사용하는 다른 API 호출로 전달하는 것입니다. 우리가 사용한 유일한 핸들 유형은CreateWindowEx
의해 반환 된 HWND
뿐입니다. 상수
이 예제에서는 몇 개의 상수가 있습니다. 모든 상수는 2 ~ 3 자의 접두사로 시작합니다. (Windows 유형도 모두 대문자입니다)- IDI_APPLICATION : 기본 응용 프로그램 아이콘이 들어있는 자원 이름입니다.
LoadIcon
또는LoadImage
(이 예제에서는LoadIcon
와 함께 사용됩니다. - IDC_ARROW : 기본 응용 프로그램 커서를 나타내는 리소스 이름입니다.
LoadIcon
또는LoadImage
(이 예제에서는LoadIcon
와 함께 사용됩니다. - WHITE_BRUSH : 주식 개체의 이름입니다. 이 주식 개체는 흰색 브러시입니다.
- MB_ICONERROR :
MessageBox
와 함께 오류 아이콘을 표시하는 데 사용되는 플래그입니다. - WS_EX_LEFT : 기본 확장 창 스타일입니다. 이로 인해 창에 왼쪽 맞춤 속성이 생깁니다.
- WS_OVERLAPPEDWINDOW : 창은 제목 표시 줄, 크기 상자 및 최상위 창에 일반적으로 나타나는 다른 요소가있는 부모 창이어야 함을 나타내는 창 스타일입니다.
- CW_USEDEFAULT :
CreateWindowEx
의x
,y
,cx
또는cy
인수와 함께 사용됩니다. Windows가CW_USEDEFAULT
가 전달 된 인수에 유효한 값을 선택하도록합니다.
Windows 유형
Windows 용으로 프로그래밍 할 때는 내장 유형의 별명 인 Win32 유형에 익숙해 져야합니다. 이 유형은 모두 대문자입니다. 이 프로그램에서 사용되는 별명 유형은 다음과 같습니다.- TCHAR : 일반 문자 유형입니다.
UNICODE
가 정의되면, 이것은wchar_t
입니다. 그 외에도 그것은char
입니다. - UINT : 부호없는 정수입니다. 창 프로 시저 및 기타 목적에서 메시지 식별자를 나타내는 데 사용됩니다.
- WPARAM : Win16에서 이것은 WORD 인수 (따라서
W
접두어)입니다. 그러나 Win32가 도입되면서 이제는UINT_PTR
. 이것은 Windows 별칭의 요점을 보여줍니다. 그들은 변화로부터 프로그램을 보호하기 위해 존재합니다. - LPARAM : 이것은
LONG
인수입니다 (Win64에서는LONG_PTR
). - PTSTR :
P
는 포인터를 의미합니다.T
는 일반 문자를 의미하고STR
은 문자열을 의미합니다. 따라서 이것은TCHAR
문자열에 대한 포인터입니다. 다른 문자열 유형은 다음과 같습니다.- LPTSTR :
PTSTR
과 동일 - LPCTSTR :
const TCHAR *
의미합니다. - PCTSTR :
LPCTSTR
과 동일합니다. - LPWSTR : 넓은 문자열 (
wchar_t *
) - LPCWSTR : 의미
const wchar_t *
- PWSTR :
LPWSTR
과 동일합니다. - 그리고 훨씬 더 많이 볼 수 있듯이, Win32 유형은 Win16의 유물 인 많은 동의어 유형과 함께 이해하기가 번거 롭습니다.
- LPTSTR :
- LRESULT :이 형식은 창 프로 시저의 반환 값을 나타내는 데 사용됩니다. 보통 LONG (따라서
L
)입니다.