ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [1] - Creating a window
    Graphics 2021. 7. 2. 21:36

    Creating a window

     

    간단한 DirectX11을 이용한 창을 만듭니다.

    console이 아닌 window로 출력하기 위해서는 Visual Studio Community 2019의 Solution Property의 Linker->System tab에서 subsystem을 console이 아닌 Windows로 설정해줍니다. header file로 <Windows.h>가 반드시 필요합니다.

    Console프로그램의 진입점이 int main(void) 인 것 처럼 Window로 출력하는 프로그램의 경우엔 CALLBACK WinMain이 Entry point가 됩니다. 가장 먼저 해야할 일은 Window Class를 하나 Register하고 Window Instance를 만드는 것입니다.

    Window Class and Associated Window Procedure

    조금 찾아보니 우리가 흔히 생각하는 OS가 아닌 Window는 상위에 Window Class라고 부르는 카테고리가 있습니다. 즉, 하나의 Window Class에 속한 Window는 Associated Window Procedure이라는 것을 공유하는데 이 Window Procedure은 Window Class에 속한 모든 Window에 배포되는 입력이나 메시지를 관리 또는 관장한다고 합니다. 이 Window Procedure은 일종의 함수입니다. 이 함수가 Window Class로 보내지는 메시지나 입력들을 처리하기 때문에 Window내의 행동이나 외형은 이 Window Procedure에 영향을 받습니다. 

    Window가 Window Class에 종속이 되어 있기 때문에 우리는 반드시 Window을 만들기 전에 Window Class을 정의해줄 필요가 있습니다. 특히, 하단의 예시를 보면 Class Name을 정의하는 모습을 볼 수 있는데 이 class name은 시스템은 바로 이 이름으로 Window의 Style, Procedure나 각종 Attributes을 정의하게 됩니다. 따라서 이 이름은 후에 다시 사용하게 될 때, 반드시 일치해야 합니다. 

    Types of Window Classes

    아직 청사진이 그려지지 않아서 조금 더 문서를 읽어보았습니다. Window Class는 언제, 어떻게 만들어지고[Registered] 파괴되는지[Destroyed]에 따라서 크게 세 가지의 종류가 있습니다. 

    1. System Classes

    2. Application Global Classes

    3. Application Local Classes

     첫 번째 System Classes는 말 그대로 시스템에 의해서 등록되고 파괴되는 클라스입니다. 이 class는 시스템에 의해서만 등록 또는 파괴가 가능하지만 대부분의 프로세스들이 이 class을 사용할 수 있습니다. 이 System class는 우리가 만든 프로세스의 스레드가 한 번이라도 UserWindows Graphics Device Inteface(GDI)의 함수를 사용할 때 등록이 됩니다. 우리가 만든 프로세스들이 접근할 수 있는 System Class의 종류가 MSDN의 공식 문서에 나와 있습니다. 보면 익숙한 이름들이 많습니다. 운영체제 시간에 배웠던 그 프로세스가 맞기는 하지만 다음 문서를 꼭 읽어 보는 것이 좋습니다. (Process Information - Win32 apps | Microsoft Docs)

    figure 1a

    반대로 시스템만이 접근할 수 있는 System Class도 존재합니다. 

     두 번째 Application Global Classes는 조금 내용이 어렵습니다. MSDN의 문서를 추려보면 프로세스가 접근하고 사용이 가능한 DLL이나 Excecutable files들에 의해서 등록된 Window Class들을 말합니다. 그런데 이건 현재 제 지식을 아득히 뛰어 넘는 내용이며 당장 급한 건 아닌 것 같아서 읽어만 두었습니다. 프로세스들이 이 class에 접근하려면 레지스터 키를 등록해야 한다는데 잘 모르겠습니다. 헤헤.

     세 번째 Application Local Classes은 Procedure가 메인 윈도우를 위한 메시지나 입력을 처리할 때 사용합니다. 이건 우리가 윈도우를 닫아버리면 함께 해제된다고 하는데 UnregisterClass을 사용해서 메모리를 반환 하는 것이 좋다고 명시되어 있습니다. 이 세 가지의 Window Class를 각각 관리하기 위해서 시스템은 이 세 가지의 Window Class 구조체가 격납된 이루어진 리스트를 갖고 있습니다. 만약 다음과 같이 Window class을 만들어서 등록한다면, 시스템은 Window Class의 종류에 따라 알맞은 위치에 Window Class Name을 격납을 할 것입니다. 

    만약, 우리가 아래와 같이 Window Class을 등록을 하고 CreateWindow을 호출을 한다면 시스템은 어떤 과정을 거치는데 솔직히 이 부분은 너무 어려웠습니다.

    (Module Information - Win32 apps | Microsoft Docs)

    figure 1b

    지금 이해된 바로는 CreateWindow 함수에 이 함수를 호출하는 Class Name에 대한 handle을 Argument로 전달합니다. 그러면 Local Classes가 격납된 리스트에서 이 Class Name과 일치하는 Window Class을 찾는다는 것입니다. 그러면 어떤 어플리케이션이나 DLL이 CreateWindow을 호출했는지 알게 되고 해당 Window Class에 Window을 하나 만들어 줄 것입니다. 여기까지가 나름 해석하고 이해한 내용입니다.

    '모듈의 핸들과 매치되는 인스턴스 핸들을 갖고 있는 name이 명시된 class를 위해서 local classes의 리스트를 탐색한다.'

    틀린 것 같지만 그냥 기록만 해두겠습니다. 무슨 말인지 잘 이해가 되지 않습니다. 제발 미래의 내가 이 글을 다시 읽기를 바랍니다. 아무튼 이 부분이 중요한 이유는 모든 Window가 이 절차를 밟기 때문입니다. 

    다음은 Window Class을 Register하고 Window를 하나 만드는 예시입니다. Window Class을 등록하는 첫 번째 단계는 WNDCLASS 또는 WNDCLASSEX 구조체를 채우는 일입니다. 둘은 거의 똑같지만 Extension버전이 아무래도 최신 버전일 것입니다. 위에서 Window Class가 크게 세 가지로 분류된다고 했는데 아래에 보면 Style이 CS_OWNDC로 설정된 것을 확인할 수 있습니다. 만약 Application Local Class로 만들어야 한다면 이 부분을 CS_GLOBALCLASS로 설정해서는 안됩니다. 제 경우에는 가장 기본이 되는 값으로 채웠습니다.

    figure.a

    상단의 pClassName이 이 Window Class의 호출 명이 된다고 생각하면 편합니다. 이는 후에 Instance를 생성할 때도 반드시 일치해야 합니다.

    두 개의 HINSTANCE와 Long Pointer String, integer의 parameter가 존재합니다.

    1. _hInstance 

    현재 실행 중인 응용프로그램의 instance의 정보들을 다루는 handle입니다. 

    2. _hPrevInstance

    이건 이제 딱히 쓸일이 없습니다. 이전 응용프로그램의 Handle인데 늘 NULL로 유지합니다. 

    3. _lpCmdLine

    이건 중요합니다. 프로그램을 실행할 때, 외부에서 입력한 Command line이 이 Argument를 통해서 하나의 String의 형태로 전달합니다.

    4. _nCmdShow

    후에 Window의 형태를 결정하는 인자인데 처음에는 크게 관심을 가질 일이 없습니다. 자세한 건 언제나 MSDN

    WinMain function (winbase.h) - Win32 apps | Microsoft Docs

    준비가 끝나면 WNDCLASSEX structure를 만들어 해당 포인터를 RegisterClassEX에 전달합니다. 각 Parameter의 정보들이 MSDN의 홈페이지에서 기다립니다.

    Register Window -> Create Instance -> Show Window 순입니다. 가장 기초.

    'Graphics' 카테고리의 다른 글

    [5] - Window Framework  (0) 2021.07.10
    [4] - Mouse and Char  (0) 2021.07.03
    [3] - Window Messages  (0) 2021.07.03
    [2] - Message Pump  (0) 2021.07.03
    [ Anything ] C++ - 1  (0) 2021.06.21
Designed by Tistory.