1

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?

5
  • Simply define additional window classes (RegisterClass(), etc) like you do for your main window, and then create (CreateWindow/Ex()) and show/hide instances of each class as a child window within the right-hand area as needed. Commented Mar 4, 2021 at 3:18
  • Will each child window not act like a real window. And also should each child window get its own WNDPROC? Commented Mar 4, 2021 at 3:20
  • "Will each child window not act like a real window" - not when used as a child (it has the WS_CHILD style applied), no. "should each child window get its own WNDPROC?" - that is up to you. You are defining the classes, you can use whatever WndProc you want. Just make sure your message handlers pay attention to which HWND they are operating on. Commented Mar 4, 2021 at 3:21
  • It's my understanding that WPF (Windows Presentation Foundation) and UWP (Univeral Windows Platform) are better for creating Windows Desktop applications. Have you thought about using either of those instead of using WinAPI? Commented Mar 4, 2021 at 3:22
  • @rsa UWP is a platform, not a UI stack. The UI stack you are thinking of is WinUI. And WPF is inherently .NET-only, so not at all useful to a C++ developer. Commented Mar 4, 2021 at 6:25

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.