如何知道TToolButton的MenuItem是否被删除?
在用于托管菜单条目的所有者绘制工具栏(具有其MenuItem和Grouped属性集的TToolButtons)的上下文中,我想知道是否删除了相应的menuitem。问题是OnAdvancedCustomDrawButton中的State属性不反映该信息。
单击工具按钮时,其Down属性为true,但在上面的特定情况下(MenuItem set和Grouped = True),在菜单被删除后,另一个OnAdvancedCustomDrawButton被触发,但这次将Down设置为false。
这意味着我最终绘制了一个NOT down状态的按钮。
查看VCL的来源,似乎有关删除哪个工具按钮的信息存储在TToolBar的FMenuButton专用字段中,并且通过Perform(TB_SETHOTITEM)通知Windows热状态,但这些都不提供读访问权限。 ..
此外,VCL通过私有FTempMenu执行下拉列表,因此无法访问其句柄。
PS:FWIW如果使用hacky解决方案,唯一可用的私有字段似乎是FButtonMenu,它必须与CustomDraw中的Button.MenuItem进行比较,其他私有fiel要么没有尽早设置(如FMenuButton),要么是私有的具有可变位置的变量(如MenuButtonIndex)。尽管如此仍然不太令人满意。
没有找到相关结果
已邀请:
3 个回复
呸溉
变量跟踪下拉菜单状态。不幸的是,变量是私有的,你不能从外部访问它,“黑客”技巧不起作用。私有它也不提供RTTI! 有两种可能的解决方案: 修改VCL并添加一个使FMenuDropped可从外部使用的属性 转到ComCtrls.pas,找到
声明,转到公共部分并添加:
从您的代码中,您可以检查工具栏是否有下拉菜单。不幸的是,它需要修改VCL。从来没有一个好主意,很难在几个程序员之间同步。 使用hack直接访问FMenuDropped字段,而无需更改VCL 为此,您需要获得
字段的偏移量。一旦你得到它,你可以写这样的东西:
实际上是Delphi 2010的正确常量!这是获得常数的一种非常快捷的方法。 转到编译器设置,检查“使用调试DCU编译” 打开ComCtrls.pas,转到
,在那里放置制动点。 启动应用程序,拿一张纸和一支笔。当程序在制动点停止时打开Debug Inspector。为此,只需将光标放在字段名称,任何字段上,然后按Alt + F5。使用Debug Inspector窗口按Ctrl + N以显示允许您检查任何内容的通用
编辑器。输入
。注意纸上的结果。 再次按Ctrl + N,此时输入
。注意第二个数字。 你需要的常数是第二个和第一个之间的差异。而已! 当然有一些可能的问题。首先,这取决于您正在使用的确切Delphi版本。如果需要在不同版本的Delphi编译器上编译代码,则需要使用聪明的
。尽管如此,这是可行的。 (编辑):您可以使用相同的技术访问任何类的任何私有字段。但是在执行此操作之前,您需要多次思考,因为私有字段因某种原因而变为私有字段。
哩翔购
现在,无论您使用TToolBar,现在都可以访问名为MenuDropped的新属性。
淑灯
通知。这可用于跟踪启动菜单的按钮:
请注意,'OnAdvancedCustomDrawButton'中的'DroppedDown'变量与按钮的'Down'状态不同步,它只反映下拉箭头的'down'状态。 我相信这是问题的原因:当工具栏具有
扩展样式且其按钮没有
样式时,只有按钮的下拉箭头部分在其菜单启动时被按下。事实上,按钮不是“向下”。 AFAIU,你想要按下按钮即使这样。不幸的是,VCL没有公开任何属性以使按钮'wholedropdown'。 可以在按钮上设置此样式:
然后下拉部分将不会与按钮分开操作,或者更准确地说,没有单独的下拉部分,因此每当其菜单启动时,将设置按钮的向下/按下状态。 但是由于VCL没有意识到按钮的状态会造成一个问题;每当VCL更新按钮时,都需要重新设置样式。