그래서 미리 정의 된 클래스 (예 : 단추 클래스에 대한 사용자 지정 WndProc 만들기)에 대한 내 자신의 사용자 지정 메시지 proc을 정의 할 수 있도록 Win32에서 미리 정의 된 창 클래스를 서브 클래 싱하는 연습을하고 있습니다. 대부분은 그렇지만 WM_COMMAND 메시지를 새 메시지 proc에 자동으로 보내지는 못합니다. WM_COMMAND에 대한 부모 창에서 사례를 설정하고 wParam을 확인한 다음 WM_COMMAND 메시지를 보낸 하위 창에 대해 각각의 새 메시지 proc를 호출하지만 다른 모든 명령과 마찬가지로 자동으로 수행하는 것이 좋습니다. 지금까지 내가 정의한 사용자 정의 메시지 proc에서 시도한 다른 모든 WM_에 대해 부모님의 메시지 프로 시저에서 자동으로 전달 된 것을 알 수 있지만 WM_COMMAND 메시지는 명시 적으로 리디렉션하지 않는 한 표시되지 않습니다. 나는 WM_COMMAND 메시지를 부모 윈도우에 보낼 것이다. 서브 클래 싱 방식은 내가 설정 한 방법과 같지만 누군가가 왜 그런지 설명 할 수 있거나, 내가 속한 모든 메시지를 지시하기 위해해야 할 일이 무엇인지를 설명 할 수있다. 단추 창을 내가 정의한 커스텀 WndProc에 추가하면 매우 만족 스러울 것이다.Win32 서브 클래 싱 - 메시지 정보
코드 : 디자인으로
#include <Windows.h>
#include <windowsx.h>
#define IDC_BUTTON 0
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK WndProcButton (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND g_hwndButton = NULL;
WNDPROC g_wndProcButtonOrigianl = NULL;
BOOL g_bSeeingMouse = FALSE;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCmdLine, int iCmdShow)
{
static TCHAR szClassName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szClassName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szClassName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szClassName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProcButton (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_COMMAND:
MessageBox(hwnd, TEXT("Test box"), TEXT("Test box"), MB_OK);
SetFocus(g_hwndButton);
break;
default:
if(!g_bSeeingMouse && GetCapture() == hwnd)
{
g_bSeeingMouse = TRUE;
SetWindowText(hwnd, L"Ok +mouse");
}
else if(g_bSeeingMouse && GetCapture() != hwnd)
{
g_bSeeingMouse = FALSE;
SetWindowText(hwnd, L"Ok");
}
break;
}
return CallWindowProc(g_wndProcButtonOrigianl, hwnd, message, wParam, lParam);
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
g_hwndButton = CreateWindow(L"Button", // predefined class
L"Ok", // button text
(WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON), // styles
// Size and poition values are given explicitly, because
// the CW_USEDEFAULT constant gives zero values for buttons.
10, // starting x position
10, // starting y position
100, // button width
30, // button height
hwnd, // parent window
(HMENU)IDC_BUTTON, // no menu
(HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
NULL); // pointer not needed
SetFocus(g_hwndButton);
g_wndProcButtonOrigianl = (WNDPROC)SetWindowLongPtr(g_hwndButton, GWLP_WNDPROC, (LONG_PTR)WndProcButton);
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}