如果我使用这样的预定义类emptyPanel
:
WNDCLASSW emptyPanel;
emptyPanel.style = CS_HREDRAW | CS_VREDRAW;
emptyPanel.lpszClassName = L"Empty Panel";
emptyPanel.hInstance = hInstance;
emptyPanel.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
emptyPanel.lpfnWndProc = WndProc;
emptyPanel.hCursor = LoadCursor(NULL, IDC_ARROW);
emptyPanel.hIcon = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassW(&emptyPanel);
用这样的类调用创建子窗口是多么昂贵:
CreateWindowW(L"Empty Panel", L"", WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hwnd, NULL, NULL, NULL);
对CreateWindowW的调用是在WndProc函数中生成的,如下所示:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
...
case WM_USER_ADD_COMPONENT:
callFunctionThatCreatesWindow();
break;
...
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
callFunctionThatCreatesWindow
根据环境调用不同的函数(例如要添加的组件类型),以创建窗口。但是,在这个问题的情况下,只创建了一种类型的窗口。
然后要触发WM_USER_ADD_COMPONENT事件,我为我想要创建的每个子窗口调用SendMessage(hwnd, WM_USER_ADD_COMPONENT, 0, 0);
。
像这样创建100多个子窗口会冻结窗口。有没有更好的方法来创建具有自己的绘图功能/事件处理程序的子窗口?
答案 0 :(得分:1)
像这样创建100多个子窗口会冻结窗口。
在Windows的循环中执行任何将冻结窗口。 Windows是事件驱动的,必须允许message pump 运行,否则系统将“冻结”。您应该将代码更改为事件驱动,例如。发布事件(消息),然后创建子窗口作为对此事件的响应。然后发布第二个事件,依此类推。有些人可能会建议使用message loops PeekMessage
使用PostMessage
加密代码(例如,在您的100 +循环中),但我不赞成这种做法。
我调用SendMessage(hwnd,WM_USER_ADD_COMPONENT,0,0)