gpt4 book ai didi

delphi - 如何知道TToolButton的MenuItem是否被下拉?

转载 作者:行者123 更新时间:2023-12-03 15:55:17 24 4
gpt4 key购买 nike

在用于承载菜单项的所有者绘制工具栏(设置了 MenuItem 和 Grouped 属性的 TToolButtons)的上下文中,我想知道是否删除了相应的菜单项。问题是 OnAdvancedCustomDrawButton 中的 State 属性不反射(reflect)该信息。

当单击工具按钮时,其 Down 属性为 true,但在上面的特定情况下(MenuItem 设置且 Grouped=True),在菜单被删除后,另一个 OnAdvancedCustomDrawButton 被触发,但这次 Down 设置为 false。

这意味着我最终会绘制处于“未按下”状态的按钮。

查看 VCL 的源代码,似乎有关哪个工具按钮被删除的信息存储在 TToolBar 的 FMenuButton private 字段中,并且通过 Perform(TB_SETHOTITEM) 向 Windows 通知热状态,但是这些都不提供读取访问...

VCL 还通过私有(private) FTempMenu 执行下拉菜单,因此无法访问其句柄。

PS: FWIW如果使用hacky解决方案,唯一可用的私有(private)字段似乎是FButtonMenu,它必须与CustomDraw中的Button.MenuItem进行比较,其他私有(private)字段要么不是尽早设置(如 FMenuButton)或者是具有可变位置的私有(private)变量(如 MenuButtonIndex)。但仍然不太令人满意。

最佳答案

获取菜单下拉状态是有问题的,弹出菜单的代码非常复杂,使用了一些消息 Hook 。它通常不是您想要触及的代码。幸运的是,工具栏本身使用 FMenuDropped 变量来跟踪下拉菜单状态。不幸的是,该变量是私有(private),您无法从外部访问它,“黑客”技巧不起作用。由于是私有(private)的,它也不提供 RTTI!

有两种可能的解决方案:

修改 VCL 并添加一个属性,使 FMenuDropped 从外部可用

转到 ComCtrls.pas,找到 TToolBar = class(TToolWindow) 声明,转到公共(public)部分并添加以下内容:

property MenuDropped:Boolean read FMenuDropped;

通过您的代码,您将能够检查工具栏是否有下拉菜单。不幸的是,它需要对 VCL 进行修改。从来都不是一个好主意,很难在多个程序员之间同步。

使用 hack 直接访问 FMenuDropped 字段,无需更改 VCL

为此,您需要获取 FMenuDropped 字段的偏移量。一旦你明白了,你可以写这样的东西:

if PBoolean(Integer(Toolbar1) + 865)^ then
DoStuffIfMenuIsDropped
else
OtherStuffIfMenuIsNotDropped;

865 实际上是 Delphi 2010 的正确常量!这是获取常数的非常快速方法。

  • 转到编译器设置,选中“使用调试 DCU 进行编译”
  • 打开 ComCtrls.pas,转到程序 TToolButton.Paint,在其中放置一个制动点。
  • 启动应用程序,拿一张纸和一支笔。当程序在制动点停止时,打开调试检查器。为此,只需将光标放在字段名称(任何字段)上,然后按 Alt+F5。在“调试检查器”窗口中,按 Ctrl+N 显示通用的 Inspect 编辑器,该编辑器允许您检查任何内容。输入整数(FToolbar)。记下纸上的结果。
  • 再次按 Ctrl+N,这次输入 Integer(@FToolBar.FMenuDropped)。请注意第二个数字。
  • 您需要的常数是第二个和第一个之间的差。 就是这样!

当然存在一些可能的问题。首先,这取决于您使用的确切 Delphi 版本。如果代码需要在不同版本的Delphi编译器上编译,则需要使用巧妙的$IFDEF。尽管如此,这是可行的。

(编辑):您可以使用相同的技术来访问任何类的任何 Private 字段。但在执行此操作之前,您需要考虑很多次,因为私有(private)字段被设为私有(private)是有原因的。

关于delphi - 如何知道TToolButton的MenuItem是否被下拉?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5487900/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com