【问题标题】:TComponet / any other Superclass and its child item detectionTComponet / 任何其他超类及其子项检测
【发布时间】:2011-01-08 17:52:50
【问题描述】:

我在表单上有弹出菜单控件(grr,我很可能会将其设为动态 - 讨厌静态工具)。它有带有子菜单的项目。 SubMenu 有三个菜单项(TMenuItem 类)。

每当带有 SubMenu 的 Item 或 SubMenu Items 调用过程时,我需要通过在 if..then 语句中获取 Sender 参数来检查。

我用类型转换和超类操作尝试了不同的变化,但没有运气。我认为有可能是这样的:

if FindControl(MenuItemWithSubMenu.Handle) = TControl(Sender as TComponent).Parent then ...

但是,当然,正确的类型转换和命令..

任何想法表示赞赏。

社区要求的其他信息:

代码 itsef(如果我只是通过组件名称 prop 检查)如下所示:

procedure TForm1.xClick(Sender: TObject); // procedure that has attached onClick from    PopupActionBar1 Items
begin    
if ((TComponent(Sender).Name = 'Unloadresources1') or  // PopupActionBar1.Items[3]
     (TComponent(Sender).Name = 'VKPCache11')       or // PopupActionBar1.Items[3].Items[0]
     (TComponent(Sender).Name = 'VKPCache21')       or // PopupActionBar1.Items[3].Items[1]
     (TComponent(Sender).Name = 'AllCache31')       or // PopupActionBar1.Items[3].Items[2]
     (ActLoadVal = 2)) and (PopupActionBar1.Items[3].Caption = 'Delete VKP Cache') then begin .. end;
end;

问题在于,如果程序用户想要在运行时添加/拖放/插入组件或控件或对象,这是一种较弱的方法并且需要额外的编码。这样,程序本身会自动代替我完成工作-知道要调用什么以及何时调用:)

在(静态)Form1 是(静态)PopupActionBar1。它有四个项目。第四个项目有子菜单 - 三个项目。

带有子菜单项(PopupActionBar1.Items[3])的第四项和三个子菜单项(PopupActionBar1.Items[3].Items[0 .. 2] OnClick 事件处理程序都设置为包含 If..Then 语句的过程以上。

任务 - 通过评估 Sender 参数并使用其 OOP 功能 - 检查是否已从 PopupActionBar1.Items[3] 菜单项或其子菜单项( PopupActionBar1.Items[3].Items[0] 或 PopupActionBar1.Items [3].Items[1] 或 PopupActionBar1.Items[3].Items[2] )。

我尝试了各种语法...还尝试使用 TControl、TWinControl、TComponent 进行类型转换操作 ..(不使用 TObject 是因为它没有父级(不包括 OLE)..

【问题讨论】:

  • 您的代码驻留在哪个事件中?另外,我不确定您要达到的目标。能详细点吗?
  • 以什么方式?代码片段?图表?
  • 请添加更详细的代码,因为您的问题(基于 Sertac 回答下的讨论)似乎比现在制定的要复杂得多。
  • 相信!需要更多信息?
  • 不提供答案以免误解,但您确实不应该将处理程序附加到“UnloadResources1”(除非您计划即时修改子项),处理程序将在显示子菜单,然后在用户进行选择时再次触发。除此之外,我会去“如果(Sender is TMenuItem)和(TMenuItem(Sender).Parent = UnloadResources1)那么”。

标签: delphi controls parent menuitem sender


【解决方案1】:

您不需要找到该项目,它已经是发件人。 IE。你可以做

procedure TForm1.MyItem1Click(Sender: TObject);
begin
  if Sender = MyItem1 then
    [...]
  else if Sender = MyItem2 then

我一般使用 tag 属性来区分触发处理程序的 MenuItem。不优雅,但很有效。

procedure TForm1.Item1Click(Sender: TObject);
begin
  case TMenuItem(Sender).Tag of
    0: [..];
    1: [..];
    [..]

必须记住将所有菜单项的 OnClick 事件设置为指向同一个处理程序。这是我不记得的事情,直到我看到点击一个没有效果..

【讨论】:

  • 是的,我知道 - 这是超级简单的方法并提供静态检测,因此 - 应用程序没有分配和发送者动态。以下是一些情况 - 用户通过拖放添加新项目, - 通过 WM(黑客等)或任何其他我没有处理过或根本无法知道它的特性的方式,而无需高级鼠标和 VCL WM 处理,但无论如何必须是由一个程序处理。这就是为什么我需要将它们检测为父 TMenuItem 的死者/孩子的原因。感谢标签的想法,但这只是另一种方式,唯一真正的区别是标签是公共属性:)
  • @HX_unbanned:我还是不明白。例如,如果您在 WM_COMMAND 处理程序中处理点击,您可以通过“MyItem := PopupMenu1.FindItem(Message.ItemID, fkCommand);”找到一个项目,这将是有意义的。但是,如果您在 OnClick 处理程序中,“发件人”您的项目。
  • 是的,这是我的物品。所以 - 我检查这个项目( =Sender )是带有 SubMenus 的项目还是项目在 SubMenu 内 :) if..then 蹩脚和基本(非动态)方法中的语句如下所示: if (TComponent(Sender) .Name = 'MenuWithSubMenus') 或 (TComponent(Sender).Name = 'MenuWithSubMenus_SubMenu1') 或 TComponent(Sender).Name = 'MenuWithSubMenus_SubMenu2' ) ... 那么 ... 但是如果我检查 Sender 是 MenuWithSubMenus 或者它是MenuWithSubMenus 的任何子菜单,我可以通过在设计时或运行时分配 OnClick 事件来自动附加到必要的东西。现在清楚了吗?
  • 不完全。 :-( 如果一段时间内没有出现任何问题,也许您会编辑问题以包含代码的更广泛方面,并回答 Uwe 的问题(在哪种情况下......)。
  • 在主要问题中添加了更多描述性评论:)
猜你喜欢
  • 2011-10-16
  • 2013-06-11
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
相关资源
最近更新 更多