自定义绘图 TPopupMenu 似乎不起作用

Custom Drawing TPopupMenu doesn't seem to work

使用 C++ Builder 2009。试验看看我是否可以为 Windows 11

改进 TPopupMenu(还有 TMainMenu

我的 AdvancedDrawItem 函数从未被调用。我不确定为什么。我错过了什么傻事吗?

//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    // Init done here for the sake of small code sample
    PopupMenu1->OwnerDraw = true ;
    PopupMenu1->Items->OnAdvancedDrawItem = AdvancedDrawItem ;
    
    
    PopupMenu1->Popup(Left + Button2->Left + 50, Top + Button2->Top + 50) ;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::AdvancedDrawItem(TObject *Sender, TCanvas *ACanvas, const TRect &ARect, TOwnerDrawState State)
{
    TMenuItem *Item = (TMenuItem*)Sender ;
    
    TTextFormat TF = TTextFormat() << tfVerticalCenter << tfSingleLine << tfEndEllipsis << tfLeft ;
    
    ACanvas->TextRect((TRect&)ARect, (String&)Item->Caption, TF) ;
}
//---------------------------------------------------------------------------

PS。在另一个复杂得多的项目中,我确实让它在继承自 TPopupMenu 的对象中触发。我现在很困惑为什么我不能让这个简单的代码工作。但是,我开始意识到这是一个半任务,因为 DrawThemeBackground() 在此事件期间似乎没有做任何事情,而我有点依赖它。此外,在绘画时考虑快捷方式、图标等将成为 PITA。

PopupMenu1->Items->OnAdvancedDrawItem = AdvancedDrawItem ;

这是错误的。您需要将 OnAdvancedDrawItem 处理程序分配给菜单中每个单独的 visible TMenuItem(即 test1test2),而不是到拥有这些项目的 TPopupMenu::Items 集合。

ACanvas->TextRect((TRect&)ARect, (String&)Item->Caption, TF) ;

两种类型转换都是错误的。

由于您没有使用允许 TextRect() 修改参数值(tfCalcRecttfModifyString)的 TF 标志,您可以使用 const_cast 替换第一个:

const_cast<TRect&>(ARect)

但是,技术上没有合法的方法将右值(例如TMenuItem::Caption的return值)转换为左值引用,需要变量或函数调用,所以只需使用一个变量:

String str = Item->Caption;
ACanvas->TextRect(const_cast<TRect&>(ARect), str, TF);

在这种情况下,您也可以为第一个参数使用变量:

TRect rect = ARect;
String str = Item->Caption;
ACanvas->TextRect(rect, str, TF);