【发布时间】: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