windows 使用 C++ 编程时如何在 win32 中创建子窗口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/838511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How should I create a child window in win32 while programming with C++?
提问by Goodies
i'm new to C++ as well as for windows programming..
我是 C++ 以及 Windows 编程的新手。
i have created a window using msdn CreateWindow()
function
我使用 msdnCreateWindow()
函数创建了一个窗口
which works correctly..now i would like to create a child window...the parent window should control the child window...
哪个工作正常......现在我想创建一个子窗口......父窗口应该控制子窗口......
Any helps sample code regarding this .
任何有关此的帮助示例代码。
Thanks in advance
提前致谢
回答by 1800 INFORMATION
Roughly speaking, in the handler for the parent, where you wish to create the child, you call CreateWindow
, passing in the window for the parent as the hwndParent
- probably, you also want to set certain styles on the child such as WS_CHILD
. Your interaction with the child window then depends on the type of the window you created. Some windows (such as buttons) are designed to work as child windows, so they send a lot of notification messages, so you would set up your parent to listen for those notification messages.
粗略地说,在父级的处理程序中,您希望在其中创建子级,您调用CreateWindow
,将父级的窗口作为 the 传递hwndParent
- 可能,您还想在子级上设置某些样式,例如WS_CHILD
. 您与子窗口的交互取决于您创建的窗口的类型。某些窗口(例如按钮)被设计为子窗口,因此它们会发送大量通知消息,因此您需要设置父窗口来侦听这些通知消息。
回答by RobS
I'd highly recommend having a read through Charles Petzold's"Programming Windows" if you can obtain a copy.
如果您可以获得一份副本,我强烈建议您通读Charles Petzold 的“Programming Windows”。
Otherwise, to answer your question, pass the parent window's handle as the parent when you create the child window (using either CreateWindow or CreateWindowEx):
否则,要回答您的问题,请在创建子窗口时将父窗口的句柄作为父窗口传递(使用 CreateWindow 或CreateWindowEx):
HWND CreateWindowEx
(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent, /// pass the parent window handle here
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
..As 1800 Info has also stated, perhaps also set the WS_CHILD style (more oon Window Styles here). This is just the rudimentary plumbing, really..
..正如 1800 Info 也指出的,也许还设置了 WS_CHILD 样式(更多关于Window Styles here)。这只是基本的管道,真的..
Can you be a bit more specific when you say "control the child window..."?
当你说“控制子窗口......”时,你能更具体一点吗?
回答by Goodies
It Is 2018 by now.. doing some retro work on this I found SetParent()to come out handy, to assure a child window remains inside the client region of the parent.. Before SetParent() the child need not be registered as a child. In CreateWindowEx the parent handle can be NULL at first. Style WS_CHILD is not needed, but WS_CLIPSIBLINGScomes out handy, it avoids flickering.
现在是 2018 年 .. 对此做一些复古工作我发现SetParent()派上用场,以确保子窗口保留在父窗口的客户区域内.. 在 SetParent() 之前,子窗口不需要注册为孩子。在 CreateWindowEx 中,父句柄起初可以为 NULL。样式 WS_CHILD 不是必需的,但是WS_CLIPSIBLINGS派上用场,它避免了闪烁。
This is my code for creating a child window:
这是我创建子窗口的代码:
HWND hwnd = CreateWindowExA(0, "WindowOfDLL", ctitle, WS_SIZEBOX | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, hMenu, inj_hModule, NULL);
SetParent(hwnd, hwndparent);
ShowWindow(hwnd, SW_SHOWNORMAL);
I've seen no problems (yet) with threading in Win10. Each of below child windows is created in a DLL which manages the assembly. When a child window is created, the DLL adds a new member to the assembly and launches a thread, which will serve the child window and performs above code in its initialisation.
我在 Win10 中看到线程没有问题(还)。下面的每个子窗口都是在管理程序集的 DLL 中创建的。创建子窗口时,DLL 向程序集添加一个新成员并启动一个线程,该线程将为子窗口提供服务并在其初始化时执行上述代码。
回答by Goodies
"could you post more of your code "
@BradB you're right.. our answers are all not very specific, this is old stuff it is difficult to put a complete frame in one post. Read the book RobS suggested I would say... and... take a look at Visual studio and more modern methods to design"child windows", like Winforms, WPF and Universal !
@BradB 你是对的……我们的答案都不是很具体,这是旧的东西,很难在一个帖子中放置一个完整的框架。阅读 RobS 建议我会说的书……然后……看看 Visual Studio 和更现代的方法来设计“子窗口”,如 Winforms、WPF 和 Universal!
Here is some more of my legacy code, just the preparations, to let it be a CHILD window. The events etc you will have to fill in yourself..
这是我的一些遗留代码,只是准备工作,让它成为一个子窗口。事件等你必须自己填写..
BOOL RegisterDLLWindowClass(LPCWSTR s)
{
WNDCLASSEX wc;
wc.hInstance = NULL; // inj_hModule;
wc.lpszClassName = s;
wc.lpfnWndProc = DLLWindowProc;
wc.style = CS_DBLCLKS;
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
if (!RegisterClassEx(&wc))
return 0;
}
HMENU CreateDLLWindowMenu()
{
WriteLine("Create menu");
HMENU hMenu;
hMenu = CreateMenu();
HMENU hMenuPopup;
if (hMenu == NULL)
return FALSE;
hMenuPopup = CreatePopupMenu();
AppendMenu(hMenuPopup, MF_STRING, MYMENU_FILTERSOFF, TEXT("Off"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_CANNY, TEXT("Canny"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_SOBEL, TEXT("Sobel"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_THRESHOLD, TEXT("Threshold"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_DILATE, TEXT("Dilate"));
AppendMenu(hMenuPopup, MF_STRING, MYMENU_HARRIS, TEXT("Harris"));
CheckMenuItem(hMenuPopup, 0, MF_BYPOSITION | MF_CHECKED);
AppendMenuW(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup, TEXT("Filter"));
HMENU hMenuPopup2 = CreatePopupMenu();
AppendMenu(hMenuPopup2, MF_STRING, MYMENU_SAMPLE1, TEXT("Change parameter"));
AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hMenuPopup2, TEXT("Test"));
return hMenu;
}
void WINAPI CreateAWindow(PassedToDLL *lpParam, DWORD dwStyle)
{
if (nInstances == 0) RegisterDLLWindowClass((LPCWSTR)L"WindowOfDLL");
HMENU hMenu = CreateDLLWindowMenu();
nInstances++;
CommonInfo[nInstances - 1] = lpParam;
int i = 20 + 4 * (rand() % 10);
lpParam->p = NewPanningStruct();
lpParam->hWndChild = CreateWindowEx(0, L"WindowOfDLL", lpParam->title,
dwStyle,
i, i, 800, 550, lpParam->hWndParent, hMenu, NULL, NULL);
if (wcslen(lpParam->filename) > 0)
{
LoadBitmapFromBMPFileW(lpParam->hWndChild, lpParam->filename, &(lpParam->hBmp),
&(lpParam->hPalette));
}
}