简体   繁体   English

c++ winapi - 按下按钮时在同一 window 中的 2 组不同按钮/控件布局之间切换的最佳实践

[英]c++ winapi - best practice for switching between 2 different sets of buttons/control layouts in the same window on button press

I'm a hobbyist programmer coming back to C++ after many years away from programming and new to winapi so sorry for the "basic" GUI question.我是一名业余程序员,在离开编程多年后回到 C++,并且是 winapi 的新手,对于“基本”GUI 问题,我深表歉意。 I'm trying to find the best practice for implementing the following, very common, behaviour.我试图找到实施以下非常常见的行为的最佳实践。

From a users perspective this is the behaviour I want to create.从用户的角度来看,这是我想要创建的行为。 I have 1 window with some buttons in it.我有 1 window,里面有一些按钮。 The user clicks on 1 of the buttons and the window contents appears to change to show different buttons/text fields etc. The user interacts with these controls then finally clicks a "back" button and they are returned to the first screen.用户单击其中一个按钮,window 内容似乎发生变化以显示不同的按钮/文本字段等。用户与这些控件交互,然后最后单击“后退”按钮,它们返回到第一个屏幕。

This behaviour is so common I thought it would be easy to find examples and best practices for implementing it but clearly I'm not asking the right questions in google.这种行为非常普遍,我认为很容易找到实施它的示例和最佳实践,但显然我没有在谷歌中提出正确的问题。 Not sure if the right way forward is a new window, a child window and how to set up winproc to capture the events in these 2 options, ie a winproc for each window or child or 1 massive winproc for everything.不确定正确的前进方式是新的 window、子 window 以及如何设置 winproc 以捕获这两个选项中的事件,即每个 window 或子 winproc 或 1 个大型 winproc 用于所有内容。 Hence the best practice question.因此,最佳实践问题。

Can anyone help, either be explaining the best way to set this up with the WINAPI or by pointing me to some material online.任何人都可以提供帮助,要么解释使用 WINAPI 进行设置的最佳方法,要么给我指点一些在线资料。 I've spent days looking, plenty on creating 1 windows with controls.我花了几天时间寻找,大量关于创建 1 windows 与控制。 Very happy to follow tutorials and experiment to learn more.很高兴按照教程和实验来了解更多信息。

Thanks jwezorek I got very close to your updated code last night but still couldn't get the child events to work.谢谢 jwezorek 我昨晚非常接近你更新的代码,但仍然无法让子事件工作。 Finally cracked it using your updated code and putting the page switch buttons in the same pane as the other buttons so all clicks were handled on a pane basis in the child winproc.最后使用您更新的代码破解它,并将页面切换按钮与其他按钮放在同一窗格中,以便所有点击都在子 winproc 中以窗格为基础进行处理。 Thank you all for your help.感谢大家的帮助。 Code below in case it's of interest/use to anyone else.下面的代码以防其他人感兴趣/使用它。

#include <windows.h>

#define PANE1_ID 101
#define BUTTON11_ID 102
#define BUTTON12_ID 103
#define BUTTON_TO_PAGE_1 104
#define PANE2_ID 201
#define BUTTON21_ID 202
#define BUTTON22_ID 203
#define BUTTON_TO_PAGE_2 204

LRESULT CALLBACK parentWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK childWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HINSTANCE g_hinst;
static HWND g_pane1;
static HWND g_pane2;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    g_hinst = hInstance;
    MSG msg = { 0 };

    // Parent window definition
    WNDCLASS parentWindow = { 0 };
    parentWindow.lpfnWndProc = parentWndProc;
    parentWindow.hInstance = hInstance;
    parentWindow.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    parentWindow.lpszClassName = L"MainWindow";
    if (!RegisterClass(&parentWindow))
        return 1;

    // Child window definition
    WNDCLASS childWindow = { 0 };
    childWindow.lpfnWndProc = childWndProc;
    childWindow.hInstance = hInstance;
    childWindow.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    childWindow.lpszClassName = L"Pane";
    if (!RegisterClass(&childWindow))
        return 1;

    // Create main window
    if (!CreateWindow(parentWindow.lpszClassName, L"grouped buttons", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, 0, 0, hInstance, NULL))
        return 2;

    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

LRESULT CALLBACK parentWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        // create pane 2 with button then hide the pane and the button to switch to pane 1
        g_pane2 = CreateWindow(L"Pane", L"", WS_CHILD | WS_VISIBLE, 20, 20, 250, 200, hWnd, (HMENU)PANE2_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Button 2.1", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 50, 10, 180, 35, g_pane2, (HMENU)BUTTON21_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Button 2.2", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 50, 40, 180, 35, g_pane2, (HMENU)BUTTON22_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Back to Page 1", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 50, 130, 180, 35, g_pane2, (HMENU)BUTTON_TO_PAGE_1, g_hinst, 0);
        ShowWindow(g_pane2, SW_HIDE);
        UpdateWindow(g_pane2);

        // create pane 1 with buttons and show it and the button to switch to pane 2
        g_pane1 = CreateWindow(L"Pane", L"", WS_CHILD | WS_VISIBLE, 20, 20, 250, 200, hWnd, (HMENU)PANE1_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Button 1.1", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 10, 180, 35, g_pane1, (HMENU)BUTTON11_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Button 1.2", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 40, 180, 35, g_pane1, (HMENU)BUTTON12_ID, g_hinst, 0);
        CreateWindow(L"BUTTON", L"Go to page 2", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 130, 180, 35, g_pane1, (HMENU)BUTTON_TO_PAGE_2, g_hinst, 0);
        ShowWindow(g_pane1, SW_SHOW);
        UpdateWindow(g_pane1);

        break;

    case WM_CLOSE:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

LRESULT CALLBACK childWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == WM_COMMAND) {
        switch (wParam) {
        case BUTTON_TO_PAGE_2: 
            {
            // MessageBox(hWnd, L"You pressed go to page 2", L"Button Pressed", MB_OK);
            ShowWindow(g_pane1, SW_HIDE);
            ShowWindow(g_pane2, SW_SHOW);
            }
            break;
        case BUTTON11_ID:
            MessageBox(NULL, L"Button 1.1", L"Page 1 Button", 0);
            break;
        case BUTTON12_ID:
            MessageBox(NULL, L"Button 1.2", L"Page 1 Button", 0);
            break;
        case BUTTON_TO_PAGE_1:
            {
            // MessageBox(hWnd, L"You pressed go to page 1", L"Button Pressed", MB_OK);
            ShowWindow(g_pane2, SW_HIDE);
            ShowWindow(g_pane1, SW_SHOW);
            }
            break;
        case BUTTON21_ID:
            MessageBox(NULL, L"Button 2.1", L"Page 2 Button", 0);
            break;
        case BUTTON22_ID:
            MessageBox(NULL, L"Button 2.2", L"Page 2 Button", 0);
            break;
        }
        return 0;
    }
    else {
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

I'm a hobbyist programmer coming back to C++ after many years away from programming and new to winapi so sorry for the "basic" GUI question.我是一名业余程序员,在远离编程多年后又回到 C++ 并且对 winapi 很陌生,所以对于“基本”GUI 问题感到抱歉。 I'm trying to find the best practice for implementing the following, very common, behaviour.我正在尝试找到实现以下非常常见的行为的最佳实践。

From a users perspective this is the behaviour I want to create.从用户的角度来看,这是我想要创建的行为。 I have 1 window with some buttons in it.我有 1 个 window,里面有一些按钮。 The user clicks on 1 of the buttons and the window contents appears to change to show different buttons/text fields etc. The user interacts with these controls then finally clicks a "back" button and they are returned to the first screen.用户单击其中一个按钮,window 的内容似乎会发生变化以显示不同的按钮/文本字段等。用户与这些控件交互,然后最后单击“返回”按钮,它们将返回到第一个屏幕。

This behaviour is so common I thought it would be easy to find examples and best practices for implementing it but clearly I'm not asking the right questions in google.这种行为非常普遍,我认为很容易找到实施它的示例和最佳实践,但显然我没有在谷歌中提出正确的问题。 Not sure if the right way forward is a new window, a child window and how to set up winproc to capture the events in these 2 options, ie a winproc for each window or child or 1 massive winproc for everything.不确定正确的前进方向是否是新的 window、子 window 以及如何设置 winproc 以捕获这两个选项中的事件,即每个 windowproc 或所有内容的 winproc Hence the best practice question.因此,最佳实践问题。

Can anyone help, either be explaining the best way to set this up with the WINAPI or by pointing me to some material online.任何人都可以提供帮助,或者解释使用 WINAPI 进行设置的最佳方法,或者将我指向一些在线材料。 I've spent days looking, plenty on creating 1 windows with controls.我花了几天时间寻找,大量使用控件创建 1 windows。 Very happy to follow tutorials and experiment to learn more.很高兴按照教程和实验来了解更多信息。

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

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