使用winapi创建子窗口是否昂贵?

使用winapi创建子窗口是否昂贵?,winapi,Winapi,如果我像这样使用预定义类emptyPanel: WNDCLASSW emptyPanel; emptyPanel.style = CS_HREDRAW | CS_VREDRAW; emptyPanel.lpszClassName = L"Empty Panel"; emptyPanel.hInstance = hInstance; emptyPanel.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); emptyPanel.lpf

如果我像这样使用预定义类
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);
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);
}
使用该类调用create child windows的成本有多高,如下所示:

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);
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);
}

对CreateWindowW的调用是从WndProc函数中生成的,如下所示:

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);
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多个子窗口会冻结窗口。有没有更好的方法来创建具有自己的绘图功能/事件处理程序的子窗口

像这样创建100多个子窗口会冻结窗口

在Windows中循环执行任何操作都会冻结窗口。Windows是事件驱动的,必须允许运行,否则系统将“冻结”。您应该将代码更改为事件驱动,例如发布事件(消息),然后创建子窗口作为对此事件的响应。然后发布第二个事件,依此类推。有些人可能会建议在代码中添加使用(例如,在100+循环中),但我不赞成这种方法

我调用SendMessage(hwnd,WM\u USER\u ADD\u组件,0,0)


请尝试改用。

没有其他方法可以创建调用
[NtUser]CreateWindowExW的窗口-当然操作“昂贵”。如何-但是与什么相比?你使用的是什么语言?我使用c来解决这个问题这是一个100%纯winapi的问题。语言是不相关的。我已相应地重新标记。创建100个子窗口应该没什么大不了的。如果你需要这样做,你需要这样做。还有什么其他方法可以创建这些窗口。我可以在大约100毫秒内创建200个按钮。我想答案可以在你没有显示的代码中找到。就我的一生而言,我无法理解为什么您不生成一个,这实际上是对这样一个问题最基本的调试。对CreateWindowW的调用是从WndProc内部生成的,通过发送带有SendMessage的用户定义消息WM_user_ADD_组件来触发。创建100个窗口应该不会花费太多时间。在创建这些窗口的同时发送消息可能会导致各种各样的重新进入者的怪异行为。在提出解决方案之前,最好先找到真正的问题。