수색…


창 만들기

#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 : 인스턴스 핸들. WinMainhInst 인수를이 필드에 할당하면됩니다.
  • 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 또는 cyCW_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 : CreateWindowExx , 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의 유물 인 많은 동의어 유형과 함께 이해하기가 번거 롭습니다.
  • LRESULT :이 형식은 창 프로 시저의 반환 값을 나타내는 데 사용됩니다. 보통 LONG (따라서 L )입니다.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow