Элемент радио в TMainMenu не использует точки, а галочки

Использование стандартного VCL. Если элемент меню в TMainMenu имеет RadioItem и назначен GroupItem, обычно используется точка для обозначения свойства Checked — один из радиоэлементов отмечен и отмечен точкой. сильный>. RadioItem свойство переключается с галочки на точки. Вот как я хочу, чтобы он вел себя.

Стандартное меню  с точкой в ​​качестве радиоиндикатора

Однако, если я назначу TImageList для TMainMenu, точка вместо этого станет галочкой, даже если для свойства RadioItem установлено значение true.

Отметьте, если используется TImageList

Это похоже на ошибку в Delphi/C++ Builder, но, возможно, я что-то упустил. Пока список изображений не назначен меню, вместо этого галочки отображаются точками.

Есть ли способ назначить список изображений в главное меню, но при этом радиоэлементы будут вести себя как радиоэлементы (иметь точку вместо галочки)?

Кроме того, если это ошибка, исправлена ​​ли она в последующих версиях Delphi/C++ Builder (я использую RAD Studio 2010)?

Я не ищу обходных путей, таких как «назначить собственное точечное изображение» или «использовать сторонний компонент главного меню». Только стандартные компоненты VCL. Причина в том, что сторонние компоненты обычно не заботятся о доступности (поддержка программ чтения с экрана), и мне нужна поддержка для этого.

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

Зазубренные края галочки

Пример кода:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TMainMenu *mm;
TImageList *il;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
struct
    {
    TComponent* operator()(TComponent* fOwner, const UnicodeString &fCaption, const UnicodeString &fName, bool fDefault, bool fRadioItem, int fImgIndex, int fGroupIndex, bool fChecked)
        {
        TMenuItem* mi  = new TMenuItem(fOwner);
        mi->Name       = fName;
        mi->Caption    = fCaption;
        mi->Default    = fDefault;
        mi->RadioItem  = fRadioItem;
        mi->ImageIndex = fImgIndex;
        mi->GroupIndex = fGroupIndex;
        mi->Checked    = fChecked;

        if (fOwner->InheritsFrom(__classid(TMainMenu)))
            {
            static_cast<TMainMenu*>(fOwner)->Items->Add(mi);
            }
        else if (fOwner->InheritsFrom(__classid(TMenuItem)))
            {
            static_cast<TMenuItem*>(fOwner)->Add(mi);
            }

        return mi;
        }
    } AddMenuItem;

TComponent* own;
mm = new TMainMenu(this);
il = new TImageList(this);

own = AddMenuItem(mm, "File", "mmFile", 0, 0, -1, 0, 0);
      AddMenuItem(own, "Radio 1",  "mmFileRadio1", 0, 1, -1, 1, 1);
      AddMenuItem(own, "Radio 2",  "mmFileRadio2", 0, 1, -1, 1, 0);

//mm->Images = il;      // Comment this line = dot, uncomment this line = checkmark
}

person Coder12345    schedule 09.05.2019    source источник
comment
Назначение ImageList делает меню отрисовываемым владельцем, и, по крайней мере, в более старых версиях код отрисовки VCL не принимает во внимание элементы радио, элемент меню рисуется либо отмеченным, либо не отмеченным, когда вы не применяете свое собственное изображение. Я не смогу до завтра проверить, как ведут себя новые версии   -  person Remy Lebeau    schedule 10.05.2019
comment
Я не могу воспроизвести это с XE2. Для главного меню с назначенным списком изображений; Если выбран радиоэлемент с изображением, изображение отображается утопленным. Если выбран радиоэлемент без изображения, радио отрисовывается.   -  person Sertac Akyuz    schedule 10.05.2019
comment
@SertacAkyuz Тогда он может под капотом заменить системную радиоточку на собственное изображение. Я заметил, что он растягивает уродливое растровое изображение галочки (если используется высокий DPI), поэтому может быть то, что описывает Реми Лебо, что он становится владельцем. Я добавлю несколько скриншотов в свой исходный пост, чтобы проиллюстрировать это.   -  person Coder12345    schedule 10.05.2019
comment
В случае с радиоточками их рисует ОС, а не VCL, поэтому имеет смысл использовать изображения с высоким разрешением при необходимости. В случае с галочками VCL может или не может отрисовывать их (он рисует утопленные изображения владельцем), а VCL в D2010 вообще не поддерживает High-DPI, так что это имеет смысл что изображения растягиваются в этом случае.   -  person Remy Lebeau    schedule 10.05.2019
comment
@Coder — в конечном итоге VCL вызывает (когда включены темы) DrawThemeBackground с идентификатором части 11 (MENU_POPUPCHECK).   -  person Sertac Akyuz    schedule 10.05.2019
comment
Кроме того, если это ошибка, исправлена ​​ли она в последующих версиях Delphi/C++ Builder (я использую RAD Studio 2010)? - Если бы в вопросе было mcve, я мог бы попробовать в Сиэтл.   -  person GolezTrol    schedule 10.05.2019
comment
Добавлен пример @GolezTrol C++.   -  person Coder12345    schedule 10.05.2019


Ответы (1)


Поскольку никто не отвечает, я отвечаю на свой вопрос. Если у кого-то есть лучший ответ, не стесняйтесь добавлять, и я с удовольствием отмечу его как ответ.

По сути, я решил проблему, не назначая TImageList главному меню, что позволяет избежать проблемы и рисовать элементы радио с кружком. Если возникнет необходимость добавить изображения позже, мне придется искать другие решения, но пока это работает.

person Coder12345    schedule 15.05.2019
comment
Да, это сработало и для меня. При использовании изображений он использует пользовательский рисунок вместо системы Windows. И это создает совершенно новый пул неожиданного поведения. Особенно мы используем старые версии Delphi. То же самое происходит, когда вы используете стили VCL. - person H.Hasenack; 17.05.2019