Как настроить несколько групп переключателей для правильного порядка табуляции и взаимодействия с клавиатурой (WIN32)?

Во-первых, это не MFC.
Вот урезанная версия графического интерфейса, над которым я работал:

введите здесь описание изображения

Как видите, я (попытался) создать две разные группы, Icon и Button, используя код:

    index->hAddT.hwndIndex[2] = CreateWindowEx(NULL,L"BUTTON",L"Icon",WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
    200,135,120,170,WINDOWHANDLE,(HMENU)IDC_RADIOGROUP,(HINSTANCE)GetWindowLong(WINDOWHANDLE,GWL_HINSTANCE),NULL);

У меня есть проблема, и вы, вероятно, видите, что для окна есть только один переключатель. Это означает, что пользователь не может выбрать один переключатель из группы значков и один из группы кнопок. Я инициализировал каждую радиокнопку так:

    index->hAddT.hwndIndex[3] = CreateWindowEx(NULL,L"BUTTON",L"Information",WS_CHILD | BS_AUTORADIOBUTTON | WS_VISIBLE,
    205,155,100,20,WINDOWHANDLE,(HMENU)IDC_RADIO1,(HINSTANCE)GetWindowLong(WINDOWHANDLE,GWL_HINSTANCE),NULL);       

Я хотел бы каким-то образом отделить группу переключателей «Значок» от группы переключателей «Кнопка», если это имеет смысл, и, следовательно, будет иметь один переключатель, доступный для каждой группы. Как это будет возможно, потребуется ли мне сделать новое окно и новую процедуру обратного вызова только для того, чтобы иметь дополнительный переключатель. Должен быть другой способ сгруппировать дочерние элементы таким образом.

2 отдельные группы переключатели в том же виде WINAPI (без MFC) Ссылка не пригодилась для моей цели.

У меня есть «Программирование для Windows Fifth Edition» Чарльза Петцольда рядом со мной в качестве ссылки, и он заявляет в разделе «Групповые поля»: «Групповые поля часто используются для включения других элементов управления кнопками», но реального примера этого нет.


person James    schedule 25.11.2012    source источник


Ответы (2)


Вопреки распространенному мнению, вам НЕ нужен элемент управления групповым ящиком или любой другой такой внешний «контейнер» (которым групповой ящик в любом случае не является, это просто артефакт кнопки). Ниже описано, как это можно сделать, не не требуя группового поля. Если вам нужен групповой блок, который функционально помогает в описанном здесь макете, перейдите к части EDIT этого ответа, где я объясню, как можно достичь конкретных желаний OP.

«Банки» кнопок Auto-Radio работают с использованием двух ключевых атрибутов стиля окна: WS_GROUP и WS_TABSTOP. Сделайте следующее для ваших двух «банков», которые я буду ласково называть Bank1 и Bank2:

  1. Банк 1: первый переключатель должен иметь оба WS_GROUP | WS_TABSTOP в стиле элемента управления. остальные переключатели должны иметь ни один из них и должны располагаться в родственном порядке (это означает, что в сценарии DIALOG они сразу следуют друг за другом; при динамическом создании они создаются последовательно).

  2. Первый дочерний элемент управления после вашего последнего переключателя в Bank1 должен иметь как минимум стиль WS_GROUP, а WS_GROUP | WS_TABSTOP, если это элемент управления с табуляцией.

  3. Банк 2: первый переключатель должен иметь оба WS_GROUP | WS_TABSTOP в стиле элемента управления. остальные переключатели должны иметь ни один из них и должны располагаться в родственном порядке (это означает, что в сценарии DIALOG они сразу следуют друг за другом; при динамическом создании они создаются последовательно).

  4. Первый дочерний элемент управления после вашего последнего переключателя в Bank2 должен иметь как минимум стиль WS_GROUP, а WS_GROUP | WS_TABSTOP, если это элемент управления с табуляцией.

Макет, подобный приведенному выше, позволяет вам переходить к банку переключателей и использовать клавиши со стрелками для переключения выбора. Затем вы снова делаете «вкладку», чтобы покинуть этот банк и перейти к следующей вкладке. Помните, диалоговый менеджер всегда будет переходить к следующему дочернему элементу управления WS_TABTOP, когда вы нажмете клавишу Tab (или ранее с помощью Shift-Tab). Если элемент управления, к которому осуществляется переход, имеет автоматический тип, выбранный элемент управления будет «выбранным» элементом управления в самой последней группе WS_GROUP.

Если это поможет, возьмите альбом для рисования, нарисуйте его на бумаге и наклейте «T» на позиции табуляции и «G» на атрибуты группы, как описано выше. Вероятно, это будет намного яснее после визуализации. Посмотрите на скрипт ресурса диалога, чтобы увидеть, как они работают вместе, и получить больше информации.

Примечания: Если вы хотите использовать групповые поля вокруг них, вы можете это сделать. Диспетчер диалогов работает, связывая элементы управления с группами на основе последнего элемента управления, отмеченного WS_GROUP, и первый после этого элемент управления, имеющий WS_TABSTOP, считается точкой перехода с табуляции для этой группы. Вставка сначала группового поля (который не может быть вкладкой), а затем элементов управления переключателем с WS_TABSTOP на первом переключателе (на этот раз без WS_GROUP), также будет работать. Обычно мне проще просто расположить мои переключатели без зависимости от групповых полей.

РЕДАКТИРОВАТЬ Изображение говорит тысячу слов

Для вашей картины я бы, вероятно, создал следующих детей в следующем порядке:

  1. Групповое поле «Значок», включая стиль WS_GROUP.
  2. Авторадиокнопка "Информация", включая WS_TABSTOP
  3. Все остальные переключатели группы «Значок». НЕ включайте WS_TABSTOP или WS_GROUP.
  4. Групповой бокс "Кнопка", включая стиль WS_GROUP. Это закрывает текущую группу управления и запускает следующую.
  5. Авто-кнопка "AbortretryIgnore", включая WS_TABSTOP
  6. Все остальные переключатели группы «Кнопка». НЕ включайте WS_TABSTOP или WS_GROUP.
  7. Следующий элемент управления после переключателей «Кнопка» должен включать WS_GROUP. Это закрывает текущую группу управления и запускает следующую.

Очевидно, что все другие стили управления дочерними элементами, видимость и т. д. также должны использоваться правильно, и, конечно же, все дочерние элементы должны иметь уникальные идентификаторы. Я предполагаю, что вы уже прикрыли все остальное.

person WhozCraig    schedule 25.11.2012
comment
Бонусные баллы, если вы могли бы указать на документацию MSDN, описывающую это. - person Thomas; 27.11.2012
comment
@Thomas Дословный текст, описывающий, как работает WS_GROUP, можно кратко найти здесь , но лучшее (и я использую этот термин вольно) описание от MS: здесь. По крайней мере, последний представляет концепцию клавиши со стрелкой с некоторой разумной ясностью. - person WhozCraig; 27.11.2012
comment
Дух. извините, я пропустил это , который, вероятно, лучший из всех. Весь документ содержит тонну информации об эффективном программировании диалогов. - person WhozCraig; 27.11.2012

Обратите внимание, что это также работает с группой флажков, что является допустимым вариантом использования.

Обратите внимание, что в случае, если первая радиокнопка может быть отключена (например, по условиям выполнения), вы должны сделать первую активную кнопку в стиле WS_TABSTOP. Вот несколько строк кода, подтверждающих это:

    // Set WS_TABSTOP to the group's first enabled item
    for (HWND hwnd = GetDlgItem(IDC_FIRSTITEM) /*the first*/; hwnd != NULL && !::IsWindowEnabled(hwnd); hwnd = ::GetWindow(hwnd, GW_HWNDNEXT))
    {
        if ((GetWindowLong(hwnd, GWL_STYLE) & WS_GROUP) != 0)
            hwnd = NULL;
    }
    if (hwnd != NULL)
        ModifyStyle(hwnd, 0, WS_TABSTOP, 0);
person Nick    schedule 15.04.2020