#include "windows.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
WNDCLASS wc_1;
WNDCLASS wc_2;
static TCHAR* NAME_1 = TEXT("one");
static TCHAR* NAME_2 = TEXT("two");
HWND hwnd_1 = NULL;
HWND hwnd_2 = NULL;
MSG msg_1;
MSG mag_2;
wc_1.style = CS_HREDRAW | CS_VREDRAW; //窗口样式
wc_1.lpfnWndProc = WndProc; //过程函数
wc_1.cbClsExtra = 0; //扩展字段
wc_1.cbWndExtra = 0; //扩展字段
wc_1.hInstance = hInstance; //当前实例句柄
wc_1.hIcon = LoadIcon(hInstance, IDI_APPLICATION); //设置程序图标
wc_1.hCursor = LoadCursor(NULL, IDC_ARROW); //设置鼠标
wc_1.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc_1.lpszMenuName = NULL;
wc_1.lpszClassName = NAME_1;
RegisterClass(&wc_1);
RegisterClass(&wc_2);
hwnd_1 = CreateWindow(NAME_1, //要注册的窗口类名
TEXT("The first window"),//窗口标题
WS_OVERLAPPEDWINDOW, //窗口样式
CW_USEDEFAULT, //窗口距离屏幕左上角都横坐标
CW_USEDEFAULT, //窗口距离屏幕左上角都纵坐标
400, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //当前实例句柄
NULL); //指向一个值的指针,该值传递给窗口 WM_CREATE消息。一般为NULL
ShowWindow(hwnd_1, iCmdShow);
UpdateWindow(hwnd_1);
while (GetMessage(&msg_1, NULL, 0, 0)) {
TranslateMessage(&msg_1);
DispatchMessage(&msg_1);
}
return msg_1.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
参考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;
}
依次调用 setparent 就可以相互嵌套了。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
在Win32 API中,可以使用CreateWindowEx函数创建一个子窗口,然后将其作为父窗口的一个子窗口。您可以使用窗口样式WS_CHILD将其设置为子窗口,然后使用SetParent函数将其添加为父窗口的子窗口。
下面是一个简单的示例,它创建了两个窗口,其中一个窗口包含两个子窗口:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASS wc = {0};
HWND hwnd, hwndButton, hwndEdit;
MSG msg;
// 注册窗口类
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = L"MyClass";
RegisterClass(&wc);
// 创建父窗口
hwnd = CreateWindow(wc.lpszClassName, L"MyWindow", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// 创建一个按钮控件
hwndButton = CreateWindow(L"BUTTON", L"Click me!", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
50, 50, 100, 30, hwnd, (HMENU)1, hInstance, NULL);
// 创建一个文本框控件
hwndEdit = CreateWindow(L"EDIT", L"", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_MULTILINE,
50, 100, 200, 150, hwnd, (HMENU)2, hInstance, NULL);
// 消息循环
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_COMMAND:
switch(LOWORD(wParam)) {
case 1:
MessageBox(hwnd, L"Button clicked!", L"Hello", MB_OK);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
在这个示例中,我们创建了一个父窗口 hwnd,然后在父窗口中创建了一个按钮控件 hwndButton 和一个文本框控件 hwndEdit,它们的父窗口都是 hwnd。注意到,在创建子窗口时,我们使用了 hwnd 作为最后一个参数,这就是指定
子窗口的父窗口句柄,也就是将子窗口作为父窗口的一个子控件来创建。
-
具体来说,hwndButton 是一个按钮控件,我们在创建时指定了它的风格为 WS_CHILD,这表示它是一个子窗口,并且它的父窗口是 hwnd。hwndEdit 是一个文本框控件,我们同样指定了它的风格为 WS_CHILD,这样它就成为了 hwnd 的一个子控件。
-
在消息处理函数中,我们处理了 WM_CREATE 和 WM_COMMAND 两个消息。在 WM_CREATE 消息中,我们创建了 hwndButton 和 hwndEdit,设置了它们的初始位置和大小,并将 hwnd 保存到它们的用户数据中。在 WM_COMMAND 消息中,我们判断是哪个控件发送了消息,如果是 hwndButton,则弹出一个对话框,如果是 hwndEdit,则获取编辑框中的文本并显示在对话框中。
-
这样,我们就实现了在一个父窗口中创建多个子控件的功能。在实际的应用中,可以根据需要创建更多的子控件,并根据消息处理函数中的逻辑实现各种功能。
参考GPT和自己的思路,要在一个窗口内嵌套其他窗口,你需要创建一个父窗口,然后在父窗口内创建多个子窗口。每个子窗口都有自己的窗口句柄和窗口过程函数。可以使用CreateWindow函数来创建窗口,并指定父窗口句柄作为其中一个参数,将它们嵌套在父窗口中。
下面是一个简单的示例程序,展示了如何创建一个具有多个子窗口的父窗口:
#include <windows.h>
// 父窗口的窗口过程函数
LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
// 子窗口1的窗口过程函数
LRESULT CALLBACK ChildWndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// 处理子窗口消息
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
// 子窗口2的窗口过程函数
LRESULT CALLBACK ChildWndProc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
// 处理子窗口消息
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
WNDCLASS wc;
HWND hwnd;
HWND child1, child2;
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) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("ParentClass");
RegisterClass(&wc);
// 创建父窗口
hwnd = CreateWindow(TEXT("ParentClass"), TEXT("Parent Window"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
// 注册子窗口1类
wc.style = 0;
wc.lpfnWndProc = ChildWndProc1;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("ChildClass1");
RegisterClass(&wc);
// 创建子窗口1
child1 = CreateWindow(TEXT("ChildClass1"), TEXT("Child Window 1"), WS_CHILD | WS_VISIBLE,
10, 10, 200, 200, hwnd, (HMENU)1, hInstance, NULL);
// 创建子窗口2
child2 = CreateWindow(TEXT("ChildClass2"), TEXT("Child Window 2"), WS_CHILD | WS_VISIBLE,
220, 10, 200, 200, hwnd, (HMENU)2, hInstance, NULL);
// 创建子窗口3
child3 = CreateWindow(TEXT("ChildClass1"), TEXT("Child Window 3"), WS_CHILD | WS_VISIBLE,
10, 220, 200, 200, hwnd, (HMENU)3, hInstance, NULL);
// 创建子窗口4
child4 = CreateWindow(TEXT("ChildClass2"), TEXT("Child Window 4"), WS_CHILD | WS_VISIBLE,
220, 220, 200, 200, hwnd, (HMENU)4, hInstance, NULL);
// 窗口显示
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
typedef struct {
int length; // 窗口长度
int width; // 窗口宽度
int x; // 窗口横坐标
int y; // 窗口纵坐标
} Window;
typedef struct {
int num_of_windows; // 窗口个数
Window window[]; // 包含多个子窗口
} Main_window;
int main() {
Main_window mainWindow;
mainWindow.num_of_windows = 2;
mainWindow.window[0].length = 20;
mainWindow.window[0].width = 10;
mainWindow.window[0].x = 0;
mainWindow.window[0].y = 0;
mainWindow.window[1].length = 30;
mainWindow.window[1].width = 15;
mainWindow.window[1].x = 10;
mainWindow.window[1].y = 10;
return 0;
}
注意:这只是实现多窗口的一种方式,具体还可以根据需要进行修改。同时,不同的平台上,窗口的实现方式可能也不同,需要根据实际情况进行处理。