繁体   English   中英

如何使用Win32 API创建多个窗口

[英]How to make multiple windows using Win32 API

我看到很多教程和文章向我展示如何制作一个简单的Windows程序,这很棒,但没有一个向我展示如何制作多个窗口。

现在我有创建和绘制分层窗口的工作代码,我可以使用GDI来绘制任何我想要的东西,拖动它,甚至使它透明等等。

但我想要第二个矩形区域,我可以绘制,拖动等等。换句话说,第二个窗口。 可能希望它成为一个儿童窗口。 问题是,我该怎么做?

此外,如果有人知道任何好的资源(在线优选),如Windows API中的窗口管理文章或教程,请分享。

要创建多个窗口,请重复创建第一个窗口时创建第二个窗口时执行的所有步骤。 执行此操作的一种好方法是复制并粘贴第一个窗口中的所有代码。 然后执行搜索和替换,将第一个窗口的所有名称替换为第二个窗口的唯一名称。 我正在做的代码如下。

最重要的是要注意第二个窗口的windows类应该在代码行“windowclassforwindow2.lpszClassName =”window class2“中具有唯一的名称。如果它没有唯一的名称,则Windows注册将失败。

    #include <windows.h>

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT message,WPARAM wParam,LPARAM lParam);

bool window1closed=false;
bool window2closed=false;

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
    bool endprogram=false;

    //create window 1

    WNDCLASSEX windowclassforwindow1;
    ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX));
    windowclassforwindow1.cbClsExtra=NULL;
    windowclassforwindow1.cbSize=sizeof(WNDCLASSEX);
    windowclassforwindow1.cbWndExtra=NULL;
    windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW;
    windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW);
    windowclassforwindow1.hIcon=NULL;
    windowclassforwindow1.hIconSm=NULL;
    windowclassforwindow1.hInstance=hInst;
    windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1;
    windowclassforwindow1.lpszClassName=L"windowclass 1";
    windowclassforwindow1.lpszMenuName=NULL;
    windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&windowclassforwindow1))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow1=CreateWindowEx(NULL,
        windowclassforwindow1.lpszClassName,
            L"Parent Window",
            WS_OVERLAPPEDWINDOW,
            200,
            150,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL                /* No Window Creation data */
);

    if(!handleforwindow1)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow1,nShowCmd);

    // create window 2

    WNDCLASSEX windowclassforwindow2;
    ZeroMemory(&windowclassforwindow2,sizeof(WNDCLASSEX));
    windowclassforwindow2.cbClsExtra=NULL;
    windowclassforwindow2.cbSize=sizeof(WNDCLASSEX);
    windowclassforwindow2.cbWndExtra=NULL;
    windowclassforwindow2.hbrBackground=(HBRUSH)COLOR_WINDOW;
    windowclassforwindow2.hCursor=LoadCursor(NULL,IDC_ARROW);
    windowclassforwindow2.hIcon=NULL;
    windowclassforwindow2.hIconSm=NULL;
    windowclassforwindow2.hInstance=hInst;
    windowclassforwindow2.lpfnWndProc=(WNDPROC)windowprocessforwindow2;
    windowclassforwindow2.lpszClassName=L"window class2";
    windowclassforwindow2.lpszMenuName=NULL;
    windowclassforwindow2.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&windowclassforwindow2))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed for window 2",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow2=CreateWindowEx(NULL,
        windowclassforwindow2.lpszClassName,
            L"Child Window",
            WS_OVERLAPPEDWINDOW,
            200,
            150,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL);

    if(!handleforwindow2)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow2,nShowCmd);
    SetParent(handleforwindow2,handleforwindow1);
    MSG msg;
    ZeroMemory(&msg,sizeof(MSG));
    while (endprogram==false) {
        if (GetMessage(&msg,NULL,0,0));
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        if (window1closed==true && window2closed==true) {
            endprogram=true;
        }
    }
    MessageBox(NULL,
    L"Both Windows are closed.  Program will now close.",
    L"",
    MB_ICONINFORMATION);
    return 0;
}

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY: {
            MessageBox(NULL,
            L"Window 1 closed",
            L"Message",
            MB_ICONINFORMATION);

            window1closed=true;
            return 0;
        }
        break;
    }

    return DefWindowProc(handleforwindow,msg,wParam,lParam);
}

LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam)
{
    switch(msg)
    {
        case WM_DESTROY: {
            MessageBox(NULL,
            L"Window 2 closed",
            L"Message",
            MB_ICONINFORMATION);

            window2closed=true;
            return 0;
        }
        break;
    }

    return DefWindowProc(handleforwindow,msg,wParam,lParam);
}

一个更复杂的示例 - 使用函数来创建窗口。

在没有函数的情况下创建每个窗口可能会使代码变得混乱 - 特别是如果它在if语句中。 下面的代码使用单独的函数来创建每个窗口。 前三个窗口有一个创建窗口按钮来创建下一个窗口。

    #include <Windows.h>

LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow3(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow4(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);

#define createwindowbuttoninwindow1 101
#define createwindowbuttoninwindow2 201
#define createwindowbuttoninwindow3 301

bool window1open,window2open,window3open,window4open=false;
bool windowclass1registeredbefore,windowclass2registeredbefore,
    windowclass3registeredbefore,windowclass4registeredbefore=false;

enum windowtoopenenumt {none,window2,window3,window4};

windowtoopenenumt windowtoopenenum=none;

void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);
void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);
void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
    bool endprogram=false;
    WNDCLASSEX windowclassforwindow2;   
    WNDCLASSEX windowclassforwindow3;
    WNDCLASSEX windowclassforwindow4;
    HWND handleforwindow2;
    HWND handleforwindow3;
    HWND handleforwindow4;

    //create window 1
    MSG msg;
    WNDCLASSEX windowclassforwindow1;
    ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX));
    windowclassforwindow1.cbClsExtra=NULL;
    windowclassforwindow1.cbSize=sizeof(WNDCLASSEX);
    windowclassforwindow1.cbWndExtra=NULL;
    windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW;
    windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW);
    windowclassforwindow1.hIcon=NULL;
    windowclassforwindow1.hIconSm=NULL;
    windowclassforwindow1.hInstance=hInst;
    windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1;
    windowclassforwindow1.lpszClassName=L"window class 1";
    windowclassforwindow1.lpszMenuName=NULL;
    windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&windowclassforwindow1))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    HWND handleforwindow1=CreateWindowEx(NULL,
            windowclassforwindow1.lpszClassName,
            L"Window 1",
            WS_OVERLAPPEDWINDOW,
            200,
            150,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL                /* No Window Creation data */
);

    if(!handleforwindow1)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(handleforwindow1,nShowCmd);
    bool endloop=false;
    while (endloop==false) {
        if (GetMessage(&msg,NULL,0,0));
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if (windowtoopenenum !=none) {
            switch (windowtoopenenum) {
                case window2:
                    if (window2open==false) {                                                       
                        createwindow2(windowclassforwindow2,handleforwindow2,hInst,nShowCmd);
                    }
                    break;
                case window3:
                    if (window3open==false) {           
                        createwindow3(windowclassforwindow3,handleforwindow3,hInst,nShowCmd);
                    }
                    break;
                case window4:               
                    if (window4open==false) {               
                        createwindow4(windowclassforwindow4,handleforwindow4,hInst,nShowCmd);
                    }
                    break;
            }
        windowtoopenenum=none;
    }
    if (window1open==false && window2open==false && window3open==false && window4open==false)
        endloop=true;

    }
    MessageBox(NULL,
            L"All Windows are closed.  Program will now close.",
            L"Message",
            MB_ICONINFORMATION);

}

void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
    if (windowclass2registeredbefore==false) {
    ZeroMemory(&wc,sizeof(WNDCLASSEX));
    wc.cbClsExtra=NULL;
    wc.cbSize=sizeof(WNDCLASSEX);
    wc.cbWndExtra=NULL;
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hIcon=NULL;
    wc.hIconSm=NULL;
    wc.hInstance=hInst;
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow2;
    wc.lpszClassName=L"wc2";
    wc.lpszMenuName=NULL;
    wc.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&wc))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }
    else
        windowclass2registeredbefore=true;
    } 
    hwnd=CreateWindowEx(NULL,
            wc.lpszClassName,
            L"Window 2",
            WS_OVERLAPPEDWINDOW,
            200,
            170,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL                /* No Window Creation data */
);

    if(!hwnd)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(hwnd,nShowCmd);
}

void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
    if (windowclass3registeredbefore==false) {
    ZeroMemory(&wc,sizeof(WNDCLASSEX));
    wc.cbClsExtra=NULL;
    wc.cbSize=sizeof(WNDCLASSEX);
    wc.cbWndExtra=NULL;
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hIcon=NULL;
    wc.hIconSm=NULL;
    wc.hInstance=hInst;
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow3;
    wc.lpszClassName=L"window class 3";
    wc.lpszMenuName=NULL;
    wc.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&wc))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }
    else
        windowclass3registeredbefore=true;
    }
    hwnd=CreateWindowEx(NULL,
            wc.lpszClassName,
            L"Window 3",
            WS_OVERLAPPEDWINDOW,
            200,
            190,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL                /* No Window Creation data */
);

    if(!hwnd)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(hwnd,nShowCmd);
}

void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
    if (windowclass4registeredbefore==false) {
        ZeroMemory(&wc,sizeof(WNDCLASSEX));
    wc.cbClsExtra=NULL;
    wc.cbSize=sizeof(WNDCLASSEX);
    wc.cbWndExtra=NULL;
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hIcon=NULL;
    wc.hIconSm=NULL;
    wc.hInstance=hInst;
    wc.lpfnWndProc=(WNDPROC)windowprocessforwindow4;
    wc.lpszClassName=L"window class 4";
    wc.lpszMenuName=NULL;
    wc.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClassEx(&wc))
    {
        int nResult=GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }
    else
        windowclass4registeredbefore=true;
    }
    hwnd=CreateWindowEx(NULL,
            wc.lpszClassName,
            L"Window 4",
            WS_OVERLAPPEDWINDOW,
            200,
            210,
            640,
            480,
            NULL,
            NULL,
            hInst,
            NULL                /* No Window Creation data */
);

    if(!hwnd)
    {
        int nResult=GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

    ShowWindow(hwnd,nShowCmd);
}

// windows process functions

LRESULT CALLBACK windowprocessforwindow1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
    switch(message) {
        case WM_CREATE:
                window1open=true;
                CreateWindowEx(NULL,
                L"BUTTON",
                L"Open Window 2",
                WS_TABSTOP|WS_VISIBLE|
                WS_CHILD|BS_DEFPUSHBUTTON,
                50,
                220,
                150,
                24,
                hwnd,
                (HMENU)createwindowbuttoninwindow1,
                GetModuleHandle(NULL),
                NULL);
            break;
            case WM_DESTROY:
                window1open=false;
                break;
        case WM_COMMAND:
            switch LOWORD(wParam) {
                case createwindowbuttoninwindow1:
                    windowtoopenenum=window2;
                    break;
            }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);

}

LRESULT CALLBACK windowprocessforwindow2(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
    switch(message) {
        case WM_CREATE:
                window2open=true;
                CreateWindowEx(NULL,
                L"BUTTON",
                L"Open Window 3",
                WS_TABSTOP|WS_VISIBLE|
                WS_CHILD|BS_DEFPUSHBUTTON,
                50,
                220,
                150,
                24,
                hwnd,
                (HMENU)createwindowbuttoninwindow2,
                GetModuleHandle(NULL),
                NULL);
            break;
            case WM_DESTROY:
                window2open=false;
                break;
        case WM_COMMAND:
            switch LOWORD(wParam) {
                case createwindowbuttoninwindow2:
                    windowtoopenenum=window3;
                    break;
            }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK windowprocessforwindow3(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
    switch(message) {
        case WM_CREATE:
                window3open=true;
                CreateWindowEx(NULL,
                L"BUTTON",
                L"Open Window 4",
                WS_TABSTOP|WS_VISIBLE|
                WS_CHILD|BS_DEFPUSHBUTTON,
                50,
                220,
                150,
                24,
                hwnd,
                (HMENU)createwindowbuttoninwindow3,
                GetModuleHandle(NULL),
                NULL);
                break;
                case WM_DESTROY:
                window3open=false;
                break;
        case WM_COMMAND:
            switch LOWORD(wParam) {
                case createwindowbuttoninwindow3:
                    windowtoopenenum=window4;
                    break;
            }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK windowprocessforwindow4(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
    switch(message) {
        case WM_DESTROY:
            window4open=false;
            break;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

如果您关闭并重新打开窗户怎么办?

如果单击关闭按钮并重新打开同一窗口,请注意以下事项。 关闭按钮关闭后窗口关闭时,它将被销毁。 但是破坏窗口并不会破坏windows类。 它只会从createwindow函数中销毁窗口。 这使得上述程序中的if语句必须仅在窗口第一次显示时才创建Windows类。

一些旁注

您可以只使用一个Windows类创建多个窗口。 但问题是你有一个Windows进程函数来处理多个窗口。 在这个简单的例子中,这可行。 但是窗口越异构,就越需要为每个窗口创建一个单独的窗口类。

此外,多个createwindow函数可以组合成一个函数。 请注意,它们之间的唯一区别是wc.lpszClassName代码行。 但是Windows可能彼此不同,因此将功能合并为一个并不是必需的 - 更多的是不要让代码重复。

进一步阅读

网站上的链接与域功能x有关于Windows设计中的概念的更多细节。 链接在这里

functionx.com的主页具有良好的编程学习资源。 特别重要的是这个页面有一些编程参考资料,例如更改windows类,创建列表框和其他窗口控件。 它也是win32编程学习的一个很好的资源。 functionx.com win32编程

functionx.com win32编程

如果需要,可以多次点击CreateWindow()。 WinMain中的消息循环将事件传递给WinMain创建的所有窗口。 如果需要,您甚至可以创建两个重叠的窗口并将第二个窗口的父窗口设置为第一个窗口的句柄。

听起来你想要一个多文档界面 这是一个例子:

http://www.codeproject.com/KB/winsdk/Sigma.aspx

您可以使用CreateWindow / CreateWindowEx创建任意数量的窗口,并根据需要创建它们之间的关系(所有者/子项)。

您可以通过以下方式将窗口“拥有”:

SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR) hwndParent);

要将窗口转换为子窗口,请使用SetParent

请注意,使用GWLP_HWNDPARENTSetWindowLongPtr调用不会像SetParent一样(我认为MSDN错误)。 GWLP_HWNDPARENT不会将窗口转换为“子”,而是转换为“拥有”。

我知道这已经得到了解答,但我只是编写了一个程序,通过for循环打开任意数量的窗口。

这是我的版本。 基本上,它重用相同的类生成器来构建多个窗口。 您可以根据需要创建任意数量的内容。 只需确保相应地调整HWND []和WNDCLASSEX wc []数组。

注1:这段代码使用全局ApplicationInstance,它派生自WinMain函数。 在WinMain中,将收到的hInstance分配给ApplicationInstance,在此示例中假定全局可用。 这是您的主要应用程序窗口实例。

注意2:当然,您必须预先编写WinProc例程,并将其包含在另一个头文件中,或者仅在上面(在此示例中未显示)。在此代码中,它被引用为WinProc,当它通过时到PopulateClass(WNDPROC进程)

注3:SpawnWindow支持“居中”和“最大化”标志。 他们所做的是不言自明的。

此外,窗口类名称是自动生成的,因此您不必担心命名它,只需为其指定一个好的基本名称。

int WindowCounter = 0;
WNDCLASSEX wc[1000];
HWND hwnd[1000];
char class_name[256]; // for auto class name generation

void PopulateClass(WNDPROC process) {
    ZeroMemory(&wc[WindowCounter], sizeof(WNDCLASSEX));
    wc[WindowCounter].cbSize = sizeof(WNDCLASSEX);
    wc[WindowCounter].style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
    wc[WindowCounter].lpfnWndProc = process;
    wc[WindowCounter].cbClsExtra = 0;
    wc[WindowCounter].cbWndExtra = 0;
    wc[WindowCounter].hInstance = ApplicationInstance;
    wc[WindowCounter].hIcon = LoadIcon(nullptr, IDI_APPLICATION);
    wc[WindowCounter].hCursor = LoadCursor(nullptr, IDC_ARROW);
    wc[WindowCounter].hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wc[WindowCounter].lpszMenuName = nullptr;
    sprintf(class_name, "WindowClass%d", WindowCounter);
    wc[WindowCounter].lpszClassName = class_name;
    wc[WindowCounter].hIconSm = nullptr;
}

现在,让我们通过提供SpawnWindow函数将它们放在一起!

HWND SpawnWindow(int x,
                 int y,
                 int width,
                 int height,
                 bool centered = false,
                 bool maximized = false) {
    PopulateClass(WinProc);
    RegisterClassEx(&wc[ WindowCounter ]);
    int config_style = WS_OVERLAPPEDWINDOW;
    if (maximized) { width = GetSystemMetrics(SM_CXFULLSCREEN); height =     GetSystemMetrics(SM_CYFULLSCREEN); config_style = WS_OVERLAPPEDWINDOW |     WS_MAXIMIZE;  }
    if (centered) { x = (GetSystemMetrics(SM_CXFULLSCREEN) / 2) - (width /     2); y = (GetSystemMetrics(SM_CYFULLSCREEN) / 2) - (height / 2); }
    hwnd[WindowCounter] = CreateWindowEx(NULL,
        wc[WindowCounter].lpszClassName,
        config.namever(),
        WS_OVERLAPPEDWINDOW,
        x,
        y,
        width,
        height,
        nullptr,
        nullptr,
        ApplicationInstance,
        nullptr);
    HWND returnID = hwnd[WindowCounter];
    ShowWindow(hwnd[WindowCounter++], SW_SHOW);
    return returnID;
}

最后,只需一行代码就可以创建任意数量的窗口:

void CreateWindows() {
    HWND PrimaryWindow1 = SpawnWindow(500, 500, 250, 250);
    HWND PrimaryWindow2 = SpawnWindow(500, 500, 250, 250, true);
    HWND PrimaryWindow3 = SpawnWindow(500, 500, 250, 250, true, true);
    HWND PrimaryWindow4 = SpawnWindow(100, 100, 150, 150);
    HWND PrimaryWindow5 = SpawnWindow(450, 500, 350, 150);
}

在进入主循环之前,从WinMain调用CreateWindows()。

希望这有助于那里的人。

对所有窗口使用单个WinProc

注意,这将需要对上述代码进行额外修改。 特别是,将自定义类名传递给SpawnWindow函数,表示每个窗口。 例如:“WindowClass_App”,其中“WindowClass_”可以是名称的静态部分,实际标识符只是:“App”,“Toolbox”,“Sidebar”,“AnotherCustomWindow”等。首先定义它们:

#define WindowClass_App                    0
#define WindowClass_Layers                 2
#define WindowClass_OpenGL                 3
/* ...etc... */

我编写了一个将字符串转换为int ID的函数。 此ID将用于在单个WinProc函数中分支,具体取决于已接收消息的窗口类:

int IdentifyWindowClassID(const char *lpClassName) {
    int WindowClassID = -1;
    // Convert string names to integers, because C++ switch does not support strings
    if (strcmp(lpClassName, "WindowClass_App") == 0) WindowClassID = WindowClass_App;
    if (strcmp(lpClassName, "WindowClass_Layers") == 0) WindowClassID = WindowClass_Layers;
    if (strcmp(lpClassName, "WindowClass_OpenGL") == 0) WindowClassID = WindowClass_OpenGL;
    /* etc */
    return WindowClassID;
}

最后,WinProc本身:

long __stdcall WinProc(HWND hwnd, unsigned int msg, WPARAM wparam, LPARAM lparam)
{
    char lpClassName[128];
    GetClassName(hwnd, lpClassName, 128);

    int WindowClassID = IdentifyWindowClassID( lpClassName );

    switch (WindowClassID)
    {
        /* 1.) Main application window */
        case WindowClass_App: { 
            switch (msg) {    
                case WM_CREATE: {
                    /* ...code... */
                }
            /* ...code... */
        }

        /* 2.) Layers window */
        case WindowClass_Layers: {
            switch (msg) {    
                case WM_CREATE: {
                    /* ...code... */
                }
            /* ...code... */
        }

        /* 3.) OpenGL view window... */

       ...

这是基本模式。 当然,你可以用你想要的任何方式制作它,这就是我做的方式,它很简单,对我有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM