성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>Win32 C/C++ - CS_GLOBALCLASS 설명</h1> <p> 보통은 윈도우 응용 프로그램을 만들 때 <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerclassa'>RegisterClass</a>는 기본 코드 그대로 사용하기 마련입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > BOOL InitApp(HINSTANCE hInstance) { WNDCLASS wc; wc.style = <span style='color: blue; font-weight: bold'>CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW</span>; wc.lpfnWndProc = WLWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA + sizeof(WLDLGPROC); wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; <span style='color: blue; font-weight: bold'>wc.lpszClassName = TEXT("WLDialog");</span> if (!<span style='color: blue; font-weight: bold'>RegisterClass</span>(&wc)) return FALSE; return TRUE; } </pre> <br /> oldnewthing 글에서는,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > When should I use CS_GLOBALCLASS? ; <a target='tab' href='https://devblogs.microsoft.com/oldnewthing/20230310-00/?p=107926'>https://devblogs.microsoft.com/oldnewthing/20230310-00/?p=107926</a> About Window Classes ; <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/winmsg/about-window-classes'>https://learn.microsoft.com/en-us/windows/win32/winmsg/about-window-classes</a> </pre> <br /> 위의 코드 중 style 필드에 설정할 수 있는 CS_GLOBALCLASS에 대해 자세하게 설명하고 있습니다.<br /> <br /> RegisterClass 호출 시 "lpszClassName" 필드에 클래스를 식별할 수 있는 이름을 전달하는데요, 실제로는 또 다른 식별자가 하나 더 있습니다. 바로 "hInstance" 필드입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > wc.hInstance = hInstance; wc.lpszClassName = TEXT("WLDialog"); </pre> <br /> 즉, 해당 클래스를 HINSTANCE+CLASSNAME 쌍으로 식별하게 되는 것입니다. 그래서 <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindoww'>CreateWindow</a> 호출 시,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > HWND hWnd = CreateWindowW(<span style='color: blue; font-weight: bold'>szWindowClass</span>, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, <span style='color: blue; font-weight: bold'>hInstance</span>, nullptr); </pre> <br /> 클래스 이름뿐만 아니라 HINSTANCE 값도 함께 넘기는 것입니다. 실제로 (기본 생성된 C/C++ Window 프로젝트에서) CreateWindow를 호출하는 코드를 다음과 같이 바꿔보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // Store instance handle in our global variable <span style='color: blue; font-weight: bold'>HINSTANCE hInst2 = (HINSTANCE)::GetModuleHandle(L"kernel32.dll");</span> HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, <span style='color: blue; font-weight: bold'>hInst2</span>, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } </pre> <br /> hWnd 값은 0이 나오고, 이때의 오류 코드는 "0x0000057F (Cannot find window class.)"가 됩니다. 그런데, 일반적으로 윈도우가 미리 제공하는 Button과 같은 경우에는 HINSTANCE를 그 Button을 구현한 모듈이 아닌 현재의 모듈을 전달해도 잘 동작합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > HWND hwndChild = CreateWindow( <span style='color: blue; font-weight: bold'>TEXT("button")</span>, /* Class Name */ TEXT("Button &1"), /* Title */ WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON | BS_TEXT, /* Style */ 0, 0, 100, 100, /* Position and size */ hWnd, /* Parent */ (HMENU)100, /* Child ID */ <span style='color: blue; font-weight: bold'>hInst</span>, /* Instance */ 0); /* No special parameters */ </pre> <br /> 왜냐하면, 바로 저 Button 클래스는 RegisterClass를 호출했을 때 style에 CS_GLOBALCLASS 옵션을 줬기 때문입니다. 즉, 이 옵션으로 설정된 클래스 이름은 그것을 식별하기 위한 조건에서 HINSTANCE가 무시되는 것입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 사실, 대부분의 경우에 CS_GLOBALCLASS 옵션을 쓸 필요는 없습니다. 혹시나 자신만의 윈도우 클래스를 만들어 DLL로 분리했을 때에도 그 DLL의 HINSTANCE(Module Handle) 값을 구해 넘겨주면 그만입니다.<br /> <br /> 하지만, 유일하게 신경 써야 할 때가 있는데요, 바로 대화창의 Template으로 특정 윈도우를 등록하는 경우입니다.<br /> <br /> 이전에 설명했던,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 자식 윈도우를 생성하는 방법 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/13289'>https://www.sysnet.pe.kr/2/0/13289</a> </pre> <br /> 글에서 아래와 같은 형식의 리소스 템플릿을 읽어들여 윈도우를 직접 생성하고 있는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > BEGIN ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20 LTEXT "Project1, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX LTEXT "Copyright (c) 2023",IDC_STATIC,42,26,114,8 DEFPUSHBUTTON "OK",IDOK,113,41,50,14,WS_GROUP END </pre> <br /> 보시면 저 정보에 HINSTANCE에 대한 필드가 없습니다. 어쩌면 기본 컨트롤에 대해서는 고정적으로 user32.dll의 모듈 핸들을 넘겨주도록 처리했어도 되었을 것입니다, 하지만 그런 경우 저런 식으로 기본 컨트롤만으로 구성된 예제는 상관없지만 이후 나온 <a target='tab' href='https://learn.microsoft.com/en-us/windows/win32/controls/common-controls-intro'>(Comctl32.dll에 구현된) Common Controls</a>나, 한때 유행했던 Internet Explorer ActiveX의 경우에는 CS_GLOBALCLASS 옵션이 없었다면 대화창의 template으로 처리할 수 없어, 아마도 불편하게 WM_INITDIALOG에서 코드로 생성해야만 했을 것입니다.<br /> <br /> 이런 거 보면... 정말 Win32 시스템을 설계한 사람들이 공을 참 많이 들였구나... 하는 생각이 듭니다. ^^<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1919
(왼쪽의 숫자를 입력해야 합니다.)