#c builder #vcl
Вопрос:
Использование C Builder 2009. Экспериментирую, чтобы посмотреть, смогу ли я улучшить TPopupMenu
(также TMainMenu
) Windows 11
Моя AdvancedDrawItem
функция никогда не вызывается. Я не знаю, почему. Я упускаю что-то глупое?
//--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { // Init done here for the sake of small code sample PopupMenu1-gt;OwnerDraw = true ; PopupMenu1-gt;Items-gt;OnAdvancedDrawItem = AdvancedDrawItem ; PopupMenu1-gt;Popup(Left Button2-gt;Left 50, Top Button2-gt;Top 50) ; } //--------------------------------------------------------------------------- void __fastcall TForm1::AdvancedDrawItem(TObject *Sender, TCanvas *ACanvas, const TRect amp;ARect, TOwnerDrawState State) { TMenuItem *Item = (TMenuItem*)Sender ; TTextFormat TF = TTextFormat() lt;lt; tfVerticalCenter lt;lt; tfSingleLine lt;lt; tfEndEllipsis lt;lt; tfLeft ; ACanvas-gt;TextRect((TRectamp;)ARect, (Stringamp;)Item-gt;Caption, TF) ; } //---------------------------------------------------------------------------
пс. В другом проекте с гораздо большей сложностью я заставляю его срабатывать в объекте, который наследуется от TPopupMenu
. В данный момент я совершенно сбит с толку, почему я не могу заставить этот простой код работать. Тем не менее, я начинаю понимать, что это полуторная задача, поскольку DrawThemeBackground()
, похоже, ничего не делает во время этого события, и я как бы полагался на это. Кроме того, учет ярлыков, значков и т. Д. Во время рисования будет ПИТОЙ.
Ответ №1:
PopupMenu1-gt;Items-gt;OnAdvancedDrawItem = AdvancedDrawItem ;
Это неправильно. Вам нужно назначить OnAdvancedDrawItem
обработчик каждому отдельному пользователю, видимому TMenuItem
в меню (т. Е. test1
и test2
), а не TPopupMenu::Items
коллекции, которой принадлежат элементы.
ACanvas-gt;TextRect((TRectamp;)ARect, (Stringamp;)Item-gt;Caption, TF) ;
Оба типа неверны.
Поскольку вы не используете TF
флаг, позволяющий TextRect()
изменять значения параметров ( tfCalcRect
или tfModifyString
), вы можете использовать const_cast
для замены первого:
const_castlt;TRectamp;gt;(ARect)
Но технически нет законного способа преобразовать значение rvalue (например, возвращаемое значение TMenuItem::Caption
) в ссылку на значение lvalue, требуется вызов переменной или функции, поэтому просто используйте переменную:
String str = Item-gt;Caption; ACanvas-gt;TextRect(const_castlt;TRectamp;gt;(ARect), str, TF);
В этом случае вы также можете использовать переменную для 1-го параметра:
TRect rect = ARect; String str = Item-gt;Caption; ACanvas-gt;TextRect(rect, str, TF);
Комментарии:
1. Ах да, конечно, теперь я вижу, что упустил из виду. Если вы знаете классный трюк, чтобы каким-то образом заставить (древний компилятор)
TPopupMenu
нарисовать фон до того, как он нарисует значок, иclHighlightText
при выборе цвета текста, дайте мне знать, и я отправлю вопрос 😉2. Почему вы не можете справиться со всем этим в своем
On(Advanced)DrawItem
обработчике?3. Ну, вот к чему, я боюсь, все это приведет. Я все еще надеялся на чудо 🙂 Есть о чем подумать. Ярлыки, значки и т.д.