【问题标题】:Radio item in TMainMenu not using dots but checkmarksTMainMenu 中的单选项目不使用点,而是使用复选标记
【发布时间】:2019-05-09 17:58:41
【问题描述】:

使用标准 VCL。如果TMainMenu 中的菜单项具有RadioItem 并且分配了GroupItem,则通常它使用 来指示Checked 属性-选中其中一个radioitems 并指示RadioItem 属性从复选标记切换为点。这就是我希望它的行为方式。

但是,如果我将TImageList 分配给TMainMenu,即使RadioItem 属性设置为true 也会变成复选标记

这似乎是 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
}

【问题讨论】:

  • 分配一个 ImageList 使菜单被所有者绘制,并且至少在旧版本中,VCL 的绘制代码不考虑单选项,当你不考虑时,菜单项被选中或未选中' t 应用您自己的图像。直到明天我才能检查新版本的行为方式
  • 我不能用 XE2 重现这个。对于具有指定图像列表的主菜单;如果选择了带有图像的单选项目,则图像被绘制为凹进的。如果选择了没有图像的单选项目,则会绘制单选。
  • @SertacAkyuz 然后它可能会在引擎盖下用自定义图像替换系统无线电点。我注意到它拉伸了勾号的丑陋位图图像(如果使用高 DPI),所以 Remy Lebeau 描述的可能是它变成了 ownerdraw。我将在我的原始帖子中添加一些屏幕截图来说明这一点。
  • 在单选点的情况下,操作系统正在绘制它们,而不是 VCL,因此操作系统在需要时使用高 DPI 图像是有道理的。在复选标记的情况下,VCL 可能会或可能不会绘制那些(它确实是所有者绘制的凹进图像),而 D2010 中的 VCL 根本不支持 High-DPI,所以这是有道理的在这种情况下,图像会被拉伸。
  • “另外,如果它是一个错误,是否在后续的 Delphi/C++ Builder 版本中修复(我使用的是 RAD Studio 2010)?” - 如果有问题中的 mcve,我本可以在西雅图尝试。

标签: delphi menu c++builder menuitem c++builder-2010


【解决方案1】:

由于没有人回答,我正在回答我自己的问题。如果有人有更好的回复,请随时添加,我很乐意将其标记为回复。

基本上我通过不将TImageList分配给主菜单来解决问题,这样可以避免问题并用圆圈绘制单选项目。如果以后需要添加图像,我将不得不寻找其他解决方案,但现在这可行。

【讨论】:

  • 是的,这也对我有用。使用图像时,它使用自定义绘图而不是 windows 系统。这带来了一个全新的意外行为池。特别是我们使用较旧的 delphi 版本。使用 VCL 样式时也会发生同样的情况。
猜你喜欢
  • 2016-03-12
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多