창 클래스 정보

각 창 클래스에는 동일한 클래스의 모든 창에서 공유하는 연결된 창 프로시저가 있습니다. 창 프로시저는 해당 클래스의 모든 창에 대한 메시지를 처리하므로 해당 동작과 모양을 제어합니다. 자세한 내용은 창 프로시저를 참조하세요.

프로세스는 해당 클래스의 창을 만들려면 먼저 창 클래스를 등록해야 합니다. 창 클래스를 등록하면 창 프로시저, 클래스 스타일 및 기타 클래스 특성이 클래스 이름과 연결됩니다. 프로세스가 CreateWindow 또는 CreateWindowEx 함수에서 클래스 이름을 지정하는 경우 시스템은 창 프로시저, 스타일 및 해당 클래스 이름과 연결된 기타 특성이 있는 창을 만듭니다.

이 섹션에서는 다음 항목을 설명합니다.

창 클래스의 형식

다음과 같은 세 가지 유형의 창 클래스가 있습니다.

이러한 형식은 scope 및 등록 및 제거 시기 및 방법에서 다릅니다.

시스템 클래스

시스템 클래스는 시스템에서 등록한 창 클래스입니다. 대부분의 시스템 클래스는 모든 프로세스에서 사용할 수 있지만 다른 클래스는 시스템에서 내부적으로만 사용됩니다. 시스템에서 이러한 클래스를 등록하기 때문에 프로세스에서 클래스를 삭제할 수 없습니다.

시스템은 스레드 중 하나가 사용자 또는 GDI(Windows Graphics Device Interface) 함수를 처음 호출할 때 프로세스에 대한 시스템 클래스를 등록합니다.

각 애플리케이션은 시스템 클래스의 자체 복사본을 받습니다. 동일한 VDM의 모든 16비트 Windows 기반 애플리케이션은 16비트 Windows에서와 마찬가지로 시스템 클래스를 공유합니다.

다음 표에서는 모든 프로세스에서 사용할 수 있는 시스템 클래스에 대해 설명합니다.

클래스 설명
단추 단추의 클래스입니다.
ComboBox 콤보 상자의 클래스입니다.
편집 편집 컨트롤의 클래스입니다.
ListBox 목록 상자의 클래스입니다.
MDIClient MDI 클라이언트 창에 대한 클래스입니다.
ScrollBar 스크롤 막대의 클래스입니다.
정적 정적 컨트롤에 대한 클래스입니다.

 

다음 표에서는 시스템에서만 사용할 수 있는 시스템 클래스에 대해 설명합니다. 완전성을 위해 여기에 나열됩니다.

클래스 Description
ComboLBox 콤보 상자에 포함된 목록 상자의 클래스입니다.
DDEMLEvent DDEML(동적 데이터 교환 관리 라이브러리) 이벤트에 대한 클래스입니다.
메시지 메시지 전용 창의 클래스입니다.
#32768 메뉴의 클래스입니다.
#32769 바탕 화면 창의 클래스입니다.
#32770 대화 상자의 클래스입니다.
#32771 작업 전환 창의 클래스입니다.
#32772 아이콘 제목에 대한 클래스입니다.

 

애플리케이션 전역 클래스

애플리케이션 전역 클래스는 프로세스의 다른 모든 모듈에서 사용할 수 있는 실행 파일 또는 DLL에 의해 등록된 창 클래스입니다. 예를 들어 .dll RegisterClassEx 함수를 호출하여 사용자 지정 컨트롤을 애플리케이션 전역 클래스로 정의하는 창 클래스를 등록하여 .dll 로드하는 프로세스가 사용자 지정 컨트롤의 인스턴스를 만들 수 있도록 할 수 있습니다.

모든 프로세스에서 사용할 수 있는 클래스를 만들려면 .dll 창 클래스를 만들고 모든 프로세스에서 .dll 로드합니다. 모든 프로세스에서 .dll 로드하려면 다음 레지스트리 키의 AppInit_DLLs 값에 해당 이름을 추가합니다.

Hkey_local_machine\소프트웨어\Microsoft\\ Windows NT CurrentVersion\Windows

프로세스가 시작될 때마다 시스템은 진입점 함수를 호출하기 전에 새로 시작된 프로세스의 컨텍스트에서 지정된 .dll 로드합니다. .dll 초기화 프로시저 중에 클래스를 등록해야 하며 CS_GLOBALCLASS 스타일을 지정해야 합니다. 자세한 내용은 클래스 스타일을 참조하세요.

애플리케이션 전역 클래스를 제거하고 연결된 스토리지를 해제하려면 UnregisterClass 함수를 사용합니다.

애플리케이션 로컬 클래스

애플리케이션 로컬 클래스는 실행 파일 또는 .dll 전용으로 등록하는 모든 창 클래스입니다. 많은 수의 로컬 클래스를 등록할 수 있지만 일반적으로 하나만 등록하는 것이 일반적입니다. 이 창 클래스는 애플리케이션의 기본 창의 창 프로시저를 지원합니다.

등록한 모듈이 닫히면 시스템이 로컬 클래스를 삭제합니다. 애플리케이션은 UnregisterClass 함수를 사용하여 로컬 클래스를 제거하고 연결된 스토리지를 해제할 수도 있습니다.

시스템에서 창 클래스를 찾는 방법

시스템은 세 가지 유형의 창 클래스 각각에 대한 구조 목록을 유지 관리합니다. 애플리케이션이 CreateWindow 또는 CreateWindowEx 함수를 호출하여 지정된 클래스가 있는 창을 만들 때 시스템은 다음 절차를 사용하여 클래스를 찾습니다.

  1. instance 핸들이 모듈의 instance 핸들과 일치하는 지정된 이름의 클래스에 대한 애플리케이션 로컬 클래스 목록을 검색합니다. (여러 모듈은 동일한 이름을 사용하여 동일한 프로세스에서 로컬 클래스를 등록할 수 있습니다.)
  2. 이름이 애플리케이션 로컬 클래스 목록에 없으면 애플리케이션 전역 클래스 목록을 검색합니다.
  3. 이름이 애플리케이션 전역 클래스 목록에 없으면 시스템 클래스 목록을 검색합니다.

애플리케이션에서 만든 모든 창은 대화 상자와 같이 애플리케이션을 대신하여 시스템에서 만든 창을 포함하여 이 절차를 사용합니다. 다른 애플리케이션에 영향을 주지 않고 시스템 클래스를 재정의할 수 있습니다. 즉, 애플리케이션은 시스템 클래스와 이름이 같은 애플리케이션 로컬 클래스를 등록할 수 있습니다. 이렇게 하면 애플리케이션의 컨텍스트에서 시스템 클래스가 대체되지만 다른 애플리케이션에서 시스템 클래스를 사용하는 것을 방지하지는 않습니다.

창 클래스 등록

창 클래스는 창의 스타일, 아이콘, 커서, 메뉴 및 창 프로시저와 같은 창의 특성을 정의합니다. 창 클래스를 등록하는 첫 번째 단계는 WNDCLASSEX 구조를 창 클래스 정보로 채우는 것입니다. 자세한 내용은 창 클래스의 요소를 참조하세요. 다음으로, RegisterClassEx 함수에 구조를 전달합니다. 자세한 내용은 창 클래스 사용을 참조하세요.

애플리케이션 전역 클래스를 등록하려면 WNDCLASSEX 구조체의 스타일 멤버에 CS_GLOBALCLASS 스타일을 지정합니다. 애플리케이션 로컬 클래스를 등록할 때 CS_GLOBALCLASS 스타일을 지정하지 마세요.

RegisterClassEx, RegisterClassExA의 ANSI 버전을 사용하여 창 클래스를 등록하는 경우 애플리케이션은 시스템에서 ANSI 문자 집합을 사용하여 생성된 클래스의 창에 메시지의 텍스트 매개 변수를 전달하도록 요청합니다. RegisterClassEx, RegisterClassExW의 유니코드 버전을 사용하여 클래스를 등록하는 경우 애플리케이션은 시스템에서 유니코드 문자 집합을 사용하여 생성된 클래스의 창에 메시지의 텍스트 매개 변수를 전달하도록 요청합니다. IsWindowUnicode 함수를 사용하면 애플리케이션이 각 창의 특성을 쿼리할 수 있습니다. ANSI 및 유니코드 함수에 대한 자세한 내용은 함수 프로토타입에 대한 규칙을 참조하세요.

클래스를 등록한 실행 파일 또는 DLL은 클래스의 소유자입니다. 시스템은 클래스가 등록될 때 RegisterClassEx 함수에 전달된 WNDCLASSEX 구조체의 hInstance 멤버로부터 클래스 소유권을 결정합니다. DLL의 경우 hInstance 멤버는 .dll instance 대한 핸들이어야 합니다.

클래스를 소유하는 .dll 언로드되면 클래스가 제거되지 않습니다. 따라서 시스템에서 해당 클래스의 창에 대한 창 프로시저를 호출하는 경우 창 프로시저가 포함된 .dll 더 이상 메모리에 없기 때문에 액세스 위반이 발생합니다. 프로세스는 .dll 언로드되고 UnregisterClass 함수를 호출하기 전에 클래스를 사용하여 모든 창을 삭제해야 합니다.

Window 클래스의 요소

창 클래스의 요소는 클래스에 속하는 창의 기본 동작을 정의합니다. 창 클래스를 등록하는 애플리케이션은 WNDCLASSEX 구조체에서 적절한 멤버를 설정하고 구조를 RegisterClassEx 함수에 전달하여 클래스에 요소를 할당합니다. GetClassInfoExGetClassLong 함수는 지정된 창 클래스에 대한 정보를 검색합니다. SetClassLong 함수는 애플리케이션이 이미 등록한 로컬 또는 전역 클래스의 요소를 변경합니다.

전체 창 클래스는 여러 요소로 구성되지만 시스템에서는 애플리케이션이 클래스 이름, 창 프로시저 주소 및 instance 핸들을 제공해야 합니다. 다른 요소를 사용하여 커서 모양 및 창 메뉴 내용과 같은 클래스의 창에 대한 기본 특성을 정의합니다. WNDCLASSEX 구조체의 사용되지 않는 멤버를 0 또는 NULL로 초기화해야 합니다. 창 클래스 요소는 다음 표와 같습니다.

요소 목적
클래스 이름 클래스를 등록된 다른 클래스와 구분합니다.
창 프로시저 주소 클래스의 창에 전송된 모든 메시지를 처리하고 창의 동작을 정의하는 함수에 대한 포인터입니다.
인스턴스 핸들 클래스를 등록한 애플리케이션 또는 .dll 식별합니다.
클래스 커서 시스템에서 클래스의 창에 대해 표시하는 마우스 커서를 정의합니다.
클래스 아이콘 큰 아이콘과 작은 아이콘을 정의합니다.
클래스 배경 브러시 창을 열거나 칠할 때 클라이언트 영역을 채우는 색과 패턴을 정의합니다.
클래스 메뉴 메뉴를 명시적으로 정의하지 않는 창의 기본 메뉴를 지정합니다.
클래스 스타일 이동 또는 크기 조정 후 창을 업데이트하는 방법, 마우스의 두 번 클릭을 처리하는 방법, 디바이스 컨텍스트에 공간을 할당하는 방법 및 창의 다른 측면을 정의합니다.
추가 클래스 메모리 시스템에서 클래스에 대해 예약해야 하는 추가 메모리 양(바이트)을 지정합니다. 클래스의 모든 창은 추가 메모리를 공유하며 애플리케이션 정의 용도로 사용할 수 있습니다. 시스템은 이 메모리를 0으로 초기화합니다.
추가 창 메모리 시스템에서 클래스에 속하는 각 창에 대해 예약해야 하는 추가 메모리 양(바이트)을 지정합니다. 추가 메모리는 애플리케이션 정의 용도로 사용할 수 있습니다. 시스템은 이 메모리를 0으로 초기화합니다.

 

클래스 이름

한 클래스를 다른 클래스와 구분하려면 모든 창 클래스에 클래스 이름이 필요합니다. WNDCLASSEX 구조체의 lpszClassName 멤버를 이름을 지정하는 null로 끝나는 문자열의 주소로 설정하여 클래스 이름을 할당합니다. 창 클래스는 프로세스에 따라 달라지므로 창 클래스 이름은 동일한 프로세스 내에서만 고유해야 합니다. 또한 클래스 이름은 시스템의 프라이빗 원자 테이블의 공간을 차지하므로 클래스 이름 문자열을 가능한 한 짧게 유지해야 합니다.

GetClassName 함수는 지정된 창이 속한 클래스의 이름을 검색합니다.

창 프로시저 주소

모든 클래스에는 클래스의 창에 대한 모든 메시지를 처리하는 데 사용되는 창 프로시저의 진입점을 정의하는 창 프로시저 주소가 필요합니다. 시스템은 창이 클라이언트 영역을 그리거나 사용자의 입력에 응답하는 등의 작업을 수행해야 하는 경우 프로시저에 메시지를 전달합니다. 프로세스는 WNDCLASSEX 구조체의 lpfnWndProc 멤버에 주소를 복사하여 클래스에 창 프로시저를 할당합니다. 자세한 내용은 창 프로시저를 참조하세요.

인스턴스 핸들

모든 창 클래스에는 클래스를 등록한 애플리케이션 또는 .dll 식별하는 instance 핸들이 필요합니다. 시스템에는 모든 모듈을 추적하기 위해 instance 핸들이 필요합니다. 시스템은 실행 중인 실행 파일 또는 .dll 각 복사본에 핸들을 할당합니다.

시스템은 각 실행 파일의 진입점 함수에 instance 핸들을 전달합니다(WinMain 참조) 및 .dll(DllMain 참조). 실행 파일 또는 .dll WNDCLASSEX 구조체의 hInstance 멤버에 복사하여 이 instance 핸들을 클래스에 할당합니다.

클래스 커서

클래스 커서는 클래스 창의 클라이언트 영역에 있을 때 커서의 모양을 정의합니다. 시스템은 커서가 창의 클라이언트 영역에 들어갈 때 커서를 지정된 셰이프로 자동으로 설정하고 클라이언트 영역에 남아 있는 동안 해당 셰이프를 유지하도록 합니다. 창 클래스에 커서 셰이프를 할당하려면 LoadCursor 함수를 사용하여 미리 정의된 커서 셰이프를 로드한 다음 반환된 커서 핸들을 WNDCLASSEX 구조체의 hCursor 멤버에 할당합니다. 또는 사용자 지정 커서 리소스를 제공하고 LoadCursor 함수를 사용하여 애플리케이션의 리소스에서 로드합니다.

시스템에는 클래스 커서가 필요하지 않습니다. 애플리케이션이 WNDCLASSEX 구조체의 hCursor 멤버를 NULL로 설정하는 경우 클래스 커서가 정의되지 않습니다. 시스템에서는 커서가 창으로 이동할 때마다 창이 커서 셰이프를 설정한다고 가정합니다. 창이 WM_MOUSEMOVE 메시지를 받을 때마다 SetCursor 함수를 호출하여 창에서 커서 셰이프를 설정할 수 있습니다. 커서에 대한 자세한 내용은 커서를 참조하세요.

클래스 아이콘

클래스 아이콘은 시스템에서 특정 클래스의 창을 나타내는 데 사용하는 그림입니다. 애플리케이션에는 두 개의 클래스 아이콘(큰 아이콘과 작은 아이콘 1개)이 있을 수 있습니다. 시스템은 사용자가 ALT+TAB을 누를 때 표시되는 작업 전환 창과 작업 표시줄 및 탐색기의 큰 아이콘 보기에 창의 큰 클래스 아이콘을 표시합니다. 창의 제목 표시줄과 작업 표시줄 및 탐색기의 작은 아이콘 보기에 작은 클래스 아이콘이 나타납니다.

창 클래스에 크고 작은 아이콘을 할당하려면 WNDCLASSEX 구조체의 hIcon 및 hIconSm 멤버 에 있는 아이콘의 핸들을 지정합니다. 아이콘 차원은 크고 작은 클래스 아이콘에 필요한 차원을 따라야 합니다. 큰 클래스 아이콘의 경우 GetSystemMetrics 함수 호출에서 SM_CXICONSM_CYICON 값을 지정하여 필요한 차원을 확인할 수 있습니다. 작은 클래스 아이콘의 경우 SM_CXSMICONSM_CYSMICON 값을 지정합니다. 자세한 내용은 아이콘을 참조하세요.

애플리케이션이 WNDCLASSEX 구조의 hIconhIconSm 멤버를 NULL로 설정하는 경우 시스템은 기본 애플리케이션 아이콘을 창 클래스의 크고 작은 클래스 아이콘으로 사용합니다. 큰 클래스 아이콘을 지정하지만 작은 아이콘은 지정하지 않으면 시스템에서 큰 클래스 아이콘을 기반으로 작은 클래스 아이콘을 만듭니다. 그러나 작은 클래스 아이콘을 지정하지만 큰 클래스 아이콘을 지정하지 않으면 시스템은 기본 애플리케이션 아이콘을 큰 클래스 아이콘으로 사용하고 지정된 아이콘을 작은 클래스 아이콘으로 사용합니다.

WM_SETICON 메시지를 사용하여 특정 창에 대한 크거나 작은 클래스 아이콘을 재정의할 수 있습니다. WM_GETICON 메시지를 사용하여 현재 큰 클래스 또는 작은 클래스 아이콘을 검색할 수 있습니다.

클래스 배경 브러시

클래스 배경 브러시는 애플리케이션에서 후속 그리기를 위해 창의 클라이언트 영역을 준비합니다. 시스템은 브러시를 사용하여 클라이언트 영역을 단색 또는 패턴으로 채우므로 창에 속하는지 여부에 관계없이 해당 위치에서 모든 이전 이미지를 제거합니다. 시스템은 창에 WM_ERASEBKGND 메시지를 보내 배경을 그려야 한다는 것을 창에 알립니다. 자세한 내용은 브러시를 참조하세요.

클래스에 배경 브러시를 할당하려면 적절한 GDI 함수를 사용하여 브러시를 만들고 반환된 브러시 핸들을 WNDCLASSEX 구조의 hbrBackground 멤버에 할당합니다.

애플리케이션은 브러시를 만드는 대신 hbrBackground 멤버를 표준 시스템 색 값 중 하나로 설정할 수 있습니다. 표준 시스템 색 값 목록은 SetSysColors를 참조하세요.

표준 시스템 색을 사용하려면 애플리케이션에서 배경색 값을 하나씩 늘려야 합니다. 예를 들어 COLOR_BACKGROUND + 1은 시스템 배경색입니다. 또는 GetSysColorBrush 함수를 사용하여 표준 시스템 색에 해당하는 브러시에 대한 핸들을 검색한 다음 WNDCLASSEX 구조체의 hbrBackground 멤버에서 핸들을 지정할 수 있습니다.

시스템에서는 창 클래스에 클래스 배경 브러시가 필요하지 않습니다. 이 매개 변수가 NULL로 설정된 경우 창은 WM_ERASEBKGND 메시지를 받을 때마다 고유한 배경을 그려야 합니다.

클래스 메뉴

클래스 메뉴는 창을 만들 때 명시적 메뉴가 제공되지 않는 경우 클래스의 창에서 사용할 기본 메뉴를 정의합니다. 메뉴는 사용자가 애플리케이션이 수행할 작업을 선택할 수 있는 명령 목록입니다.

WNDCLASSEX 구조체의 lpszMenuName 멤버를 메뉴의 리소스 이름을 지정하는 null로 끝나는 문자열의 주소로 설정하여 클래스에 메뉴를 할당할 수 있습니다. 메뉴는 지정된 애플리케이션의 리소스로 간주됩니다. 필요한 경우 시스템이 메뉴를 자동으로 로드합니다. 메뉴 리소스가 이름이 아닌 정수로 식별되는 경우 애플리케이션은 값을 할당하기 전에 MAKEINTRESOURCE 매크로를 적용하여 lpszMenuName 멤버를 해당 정수로 설정할 수 있습니다.

시스템에는 클래스 메뉴가 필요하지 않습니다. 애플리케이션이 WNDCLASSEX 구조체의 lpszMenuName 멤버를 NULL로 설정하는 경우 클래스의 창에는 메뉴 모음이 없습니다. 클래스 메뉴가 제공되지 않더라도 애플리케이션은 창을 만들 때 창에 대한 메뉴 모음을 정의할 수 있습니다.

클래스에 대한 메뉴가 지정되고 해당 클래스의 자식 창이 만들어지면 메뉴가 무시됩니다. 자세한 내용은 메뉴를 참조하세요.

클래스 스타일

클래스 스타일은 창 클래스의 추가 요소를 정의합니다. 비트 OR(|) 연산자를 사용하여 둘 이상의 스타일을 결합할 수 있습니다. 창 클래스에 스타일을 할당하려면 WNDCLASSEX 구조체의 스타일 멤버에 스타일을 할당합니다. 클래스 스타일 목록은 창 클래스 스타일을 참조하세요.

클래스 및 디바이스 컨텍스트

디바이스 컨텍스트는 애플리케이션이 창의 클라이언트 영역에서 그리는 데 사용하는 특별한 값 집합입니다. 시스템은 디스플레이의 각 창에 대한 디바이스 컨텍스트가 필요하지만 시스템이 해당 디바이스 컨텍스트를 저장하고 처리하는 방법에 약간의 유연성을 허용합니다.

디바이스 컨텍스트 스타일이 명시적으로 지정되지 않은 경우 시스템은 각 창이 시스템에서 유지 관리하는 컨텍스트 풀에서 검색된 디바이스 컨텍스트를 사용한다고 가정합니다. 이러한 경우 각 창은 그리기 전에 디바이스 컨텍스트를 검색하고 초기화하고 그리기 후에 해제해야 합니다.

창 내부에 페인트해야 할 때마다 디바이스 컨텍스트를 검색하지 않도록 애플리케이션은 창 클래스에 대한 CS_OWNDC 스타일을 지정할 수 있습니다. 이 클래스 스타일은 시스템에서 프라이빗 디바이스 컨텍스트를 만들도록 지시합니다. 즉, 클래스의 각 창에 고유한 디바이스 컨텍스트를 할당합니다. 애플리케이션은 컨텍스트를 한 번만 검색한 다음 모든 후속 그리기용으로 사용해야 합니다.

추가 클래스 메모리

시스템은 시스템의 각 창 클래스에 대해 내부적으로 WNDCLASSEX 구조를 유지 관리합니다. 애플리케이션이 창 클래스를 등록할 때 시스템에 WNDCLASSEX 구조의 끝에 여러 개의 추가 바이트 메모리를 할당하고 추가하도록 지시할 수 있습니다. 이 메모리를 추가 클래스 메모리 라고 하며 클래스에 속한 모든 창에서 공유됩니다. 추가 클래스 메모리를 사용하여 클래스와 관련된 정보를 저장합니다.

시스템의 로컬 힙에서 추가 메모리가 할당되므로 애플리케이션은 추가 클래스 메모리를 드물게 사용해야 합니다. 요청된 추가 클래스 메모리의 양이 40바이트보다 크면 RegisterClassEx 함수가 실패합니다. 애플리케이션에 40바이트 이상이 필요한 경우 자체 메모리를 할당하고 추가 클래스 메모리에 메모리에 대한 포인터를 저장해야 합니다.

SetClassWordSetClassLong 함수는 값을 추가 클래스 메모리에 복사합니다. 추가 클래스 메모리에서 값을 검색하려면 GetClassWordGetClassLong 함수를 사용합니다. WNDCLASSEX 구조체의 cbClsExtra 멤버는 할당할 추가 클래스 메모리의 양을 지정합니다. 추가 클래스 메모리를 사용하지 않는 애플리케이션은 cbClsExtra 멤버를 0으로 초기화해야 합니다.

추가 창 메모리

시스템은 각 창에 대한 내부 데이터 구조를 유지 관리합니다. 창 클래스를 등록할 때 애플리케이션은 추가 창 메모리라는 추가 바이트 수의 메모리를 지정할 수 있습니다. 클래스의 창을 만들 때 시스템은 지정된 양의 추가 창 메모리를 할당하고 창 구조의 끝에 추가합니다. 애플리케이션은 이 메모리를 사용하여 창별 데이터를 저장할 수 있습니다.

시스템의 로컬 힙에서 추가 메모리가 할당되므로 애플리케이션은 추가 창 메모리를 드물게 사용해야 합니다. 요청된 추가 창 메모리의 양이 40바이트보다 크면 RegisterClassEx 함수가 실패합니다. 애플리케이션에 40바이트 이상이 필요한 경우 자체 메모리를 할당하고 추가 창 메모리에 메모리에 대한 포인터를 저장해야 합니다.

SetWindowLong 함수는 값을 추가 메모리에 복사합니다. GetWindowLong 함수는 추가 메모리에서 값을 검색합니다. WNDCLASSEX 구조체의 cbWndExtra 멤버는 할당할 추가 창 메모리의 양을 지정합니다. 메모리를 사용하지 않는 애플리케이션은 cbWndExtra 를 0으로 초기화해야 합니다.