Search code examples
c++windowswinapiwindowmdi

Adding Multiple Windows to WinAPI Application


I am building an app with WinAPI that consists of basically two main parts: a panel on the left hand that is always shown and an area on the right that changes based on which screen is shown. Currently the left-hand, static area is just being drawn onto the main window; however, for I don't believe that I can simply draw the right area onto the main window as it needs to change. Therefore, I believe that I need to create windows there and just control what is shown by controlling its visibility. I read a lot about the Multiple Document Interface in the MSDN, but I'm not sure if that is what I am looking for. Specifically, I don't want the child windows to act like real windows, meaning I don't want them to have a title or icon or be able to be minimized, closed, resized, or moved. Basically, I want them to just be frames that hold controls/D2D geometry. What would be the best way to go about implementing this?


Solution

  • As Remy said, you only need to re-register a new window and then create it as a subclass in the main window. You don't need to set the title and maximize and minimize buttons in setting the style, and you can also decide by yourself whether you need to deal with the WNDPROC function of the subclass.

    Here is a sample(In order to display the child window, I set its background to black.):

    #include <Windows.h>
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK cldWndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(_In_  HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_  LPSTR szCmdLine, _In_  int iCmdShow)
    {
        static TCHAR szAppName[] = TEXT("hello windows");
        static TCHAR cldwndName[] = TEXT("test app");
        HWND hwnd;
        MSG msg;
        WNDCLASS wndclass;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = WndProc;
        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);
        }
    
        hwnd = CreateWindow(szAppName,
            TEXT("the hello program"),
            WS_OVERLAPPEDWINDOW,
            100,
            100,
            800,
            600,
            NULL,
            NULL,
            hInstance,
            NULL);
        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);
    
        WNDCLASS cldclass;
        cldclass.style = CS_HREDRAW | CS_VREDRAW;
        cldclass.lpfnWndProc = cldWndProc;
        cldclass.cbClsExtra = 0;
        cldclass.cbWndExtra = 0;
        cldclass.hInstance = hInstance;
        cldclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        cldclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        cldclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        cldclass.lpszMenuName = NULL;
        cldclass.lpszClassName = cldwndName;
        if (!RegisterClass(&cldclass))
        {
            MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
        }
    
        HWND hwnd1 = CreateWindow(cldwndName,
            NULL,
            WS_CHILD|WS_VISIBLE,
            400,
            200,
            200,
            300,
            hwnd,
            NULL,
            hInstance,
            NULL);
        ShowWindow(hwnd1, iCmdShow);
        UpdateWindow(hwnd1);
    
    
        while (GetMessageW(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
        }
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    LRESULT CALLBACK cldWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    

    It works for me:

    enter image description here