参考GPT和自己的思路:实现窗口嵌套需要在窗口过程函数中处理WM_CREATE消息,以创建子窗口,并在父窗口的WM_SIZE消息中调整子窗口的大小和位置。以下是一个简单的示例代码,可以创建两个嵌套的窗口。
#include <windows.h>
LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
WNDCLASS wc;
HWND hwndParent, hwndChild;
MSG msg;
// 注册父窗口类
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = ParentWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("ParentWndClass");
RegisterClass(&wc);
// 注册子窗口类
wc.lpfnWndProc = ChildWndProc;
wc.lpszClassName = TEXT("ChildWndClass");
RegisterClass(&wc);
// 创建父窗口
hwndParent = CreateWindow(TEXT("ParentWndClass"), TEXT("Parent Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL);
// 创建子窗口
hwndChild = CreateWindow(TEXT("ChildWndClass"), TEXT("Child Window"), WS_CHILD | WS_VISIBLE, 50, 50, 200, 150, hwndParent, NULL, hInstance, NULL);
ShowWindow(hwndParent, iCmdShow);
UpdateWindow(hwndParent);
// 消息循环
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
// 创建子窗口
CreateWindow(TEXT("ChildWndClass"), TEXT("Child Window"), WS_CHILD | WS_VISIBLE, 50, 50, 200, 150, hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
break;
case WM_SIZE:
// 调整子窗口的大小和位置
MoveWindow(GetDlgItem(hwnd, 1), 50, 50, LOWORD(lParam) - 100, HIWORD(lParam) - 100, TRUE);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE:
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 10, TEXT("Hello from child window!"), 25);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static HWND child_hwnd = NULL;
switch (msg) {
case WM_CREATE:
{
WNDCLASS wc = { 0 };
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = ChildWndProc;
wc.hInstance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
wc.lpszClassName = TEXT("Child");
RegisterClass(&wc);
child_hwnd = CreateWindow(TEXT("Child"), TEXT("Child Window"),
WS_CHILD | WS_VISIBLE, 50, 50, 200, 200,
hwnd, NULL, wc.hInstance, NULL);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 10, TEXT("Hello from parent window!"), 27);
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
static TCHAR szAppName[] = TEXT("Parent");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = ParentWndProc;
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 = szAppName;
if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("The Hello Program"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}