Проблема с повторной инициализацией диалогового окна - PullRequest
0 голосов
/ 25 августа 2018

У меня следующая проблема. В моем проекте c ++ я хотел создать диалоговое окно для ввода настроек для приложения, которое будет использоваться. Окно создается при нажатии в меню: application -> robot settings.

Я создал окно следующим образом:

void Robot_Settings::CreateSettingsWindow(HWND hWnd, RECT& windowSize)
{
GetWindowRect(hWnd, &windowSize);

HWND hSDlg = CreateWindowW(
    L"SettingsDialogClass",
    NULL,
    WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_CLIPSIBLINGS,
    (windowSize.right - SETTINGS_WINDOW_SIZE) / 2,
    (windowSize.bottom - SETTINGS_WINDOW_SIZE) / 2,
    SETTINGS_WINDOW_SIZE,
    SETTINGS_WINDOW_SIZE,
    hWnd,
    NULL,
    NULL,
    NULL
);
}

тогда у меня есть процедура окна:

LRESULT CALLBACK Robot_Settings::SettingsDialogProcedure(HWND hSDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
    switch (wParam)
    {
    case SETTINGS_BUTTON_SAVE:
        collectInputs(hSDlg);
        break;
    case SETTINGS_BUTTON_CANCEL:
        DestroyWindow(hSDlg);
        break;
    }
case WM_CREATE:
    AddControlsToSettingsDialog(hSDlg);
    break;
case WM_DESTROY:
    DestroyWindow(hSDlg);
    break;
default:
    return DefWindowProcW(hSDlg, msg, wParam, lParam);
}
}

И я добавляю внутренние элементы управления на WM_CREATE:

void Robot_Settings::AddControlsToSettingsDialog(HWND hSDlg)
{
// Create Text info about amount input
CreateWindowW(
    L"Static",
    L"Input the amount of robots you want to get simulated:",
    WS_VISIBLE | WS_CHILD,
    (int)(SETTINGS_WINDOW_SIZE * 0.15),
    (int)(SETTINGS_WINDOW_SIZE * 0.2),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    hSDlg,
    NULL,
    NULL,
    NULL
);

// Create Text info about formation input
CreateWindowW(
    L"Static",
    L"Input the formation of th robots in this format -> \"x-x-x-x\" where x is the amount of robots you want to have in each row:",
    WS_VISIBLE | WS_CHILD,
    (int)(SETTINGS_WINDOW_SIZE * 0.15),
    (int)(SETTINGS_WINDOW_SIZE * 0.4),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    hSDlg,
    NULL,
    NULL,
    NULL
);

// Create Text info about speed input
CreateWindowW(
    L"Static",
    L"Input the speed calculated in squares per second at which you want the robots to move:",
    WS_VISIBLE | WS_CHILD,
    (int)(SETTINGS_WINDOW_SIZE * 0.15),
    (int)(SETTINGS_WINDOW_SIZE * 0.6),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    (int)(SETTINGS_WINDOW_SIZE / 2),
    hSDlg,
    NULL,
    NULL,
    NULL
);

// Create TextField for amount input
hAmount = CreateWindowW(
    L"Edit",
    L"",
    WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.7),
    (int)(SETTINGS_WINDOW_SIZE * 0.2),
    100,
    20,
    hSDlg,
    NULL,
    NULL,
    NULL
);
//formation radio buttons
CreateWindowW(
    L"BUTTON",
    L"Formation",
    WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 
    (int)(SETTINGS_WINDOW_SIZE * 0.7),
    (int)(SETTINGS_WINDOW_SIZE * 0.35),
    120,
    120,
    hSDlg,
    NULL,
    NULL,
    NULL);

hTriangle = CreateWindowW(
    L"BUTTON",
    L"Triangle",
    WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.72),
    (int)(SETTINGS_WINDOW_SIZE * 0.4),
    100,
    20,
    hSDlg,
    (HMENU) ID_RADIO_TRIANGLE,
    NULL,
    NULL);

hRectangle = CreateWindowW(
    L"BUTTON",
    L"Rectangle",
    WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.72),
    (int)(SETTINGS_WINDOW_SIZE * 0.45),
    100,
    20,
    hSDlg,
    (HMENU) ID_RADIO_RECTANGLE,
    NULL,
    NULL);

hRhombus = CreateWindowW(
    L"BUTTON",
    L"Rhombus",
    WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.72),
    (int)(SETTINGS_WINDOW_SIZE * 0.5),
    100,
    20,
    hSDlg,
    (HMENU) ID_RADIO_RHOMBUS,
    NULL,
    NULL);

// Create TextField for speed input
hSpeed = CreateWindowW(
    L"Edit",
    L"",
    WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.7),
    (int)(SETTINGS_WINDOW_SIZE * 0.6),
    100,
    20,
    hSDlg,
    NULL,
    NULL,
    NULL
);
// Create button Cancel
CreateWindowW(
    L"Button",
    L"Cancel",
    WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.7),
    (int)(SETTINGS_WINDOW_SIZE * 0.8),
    100,
    40,
    hSDlg,
    (HMENU)SETTINGS_BUTTON_CANCEL,
    NULL,
    NULL
);

// Create button Save
CreateWindowW(
    L"Button",
    L"Save",
    WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP,
    (int)(SETTINGS_WINDOW_SIZE * 0.7 - 110),
    (int)(SETTINGS_WINDOW_SIZE * 0.8),
    100,
    40,
    hSDlg,
    (HMENU)SETTINGS_BUTTON_SAVE,
    NULL,
    NULL
);
}

Итак, моя проблема в том, что каждый раз, когда я пытаюсь ввести какой-либо текст или щелкнуть переключатели, окно кажется переинициализированным или перекрашенным (не могу понять, что происходит, но в любом случае это не нормальное поведение). И если вы включите радиокнопку rectangle, окно закроется.

Вы можете найти весь проект по адресу: https://github.com/JamesHawkJ/cpp/tree/master/WycieczkaRobotow

Не могли бы вы помочь мне решить эту проблему?

1 Ответ

0 голосов
/ 25 августа 2018

Каждый раз, когда вы получаете сообщение WM_COMMAND от любого элемента управления, кроме SETTINGS_BUTTON_SAVE или SETTINGS_BUTTON_CANCEL, ваша оконная процедура сбрасывается до случая WM_CREATE и вызывает AddControlsToSettingsDialog.Вы создаете все больше и больше дочерних окон, расположенных друг над другом.

Также объявлено, что SettingsDialogProcedure возвращает LRESULT, но может достигать закрывающей скобки, не встречая оператора return.Это проявляет неопределенное поведение.

...