【问题标题】:TPageControl tab area OnMouseEnter OnMouseLeave eventsTPageControl 选项卡区域 OnMouseEnter OnMouseLeave 事件
【发布时间】:2010-12-28 09:38:36
【问题描述】:

我需要为 TPageControl 组件的特定区域捕获 "OnMouseEnter" 和 "0nMouseLeave"。对于那个特定区域,我的意思是整个“标签页眉”矩形。

问题是,页面控件没有捕获消息(我正在捕获内部控制消息 CM_MOUSEENTER 和 CM_MOUSELEAVE)在“空”空间中。

我的目标是当用户将鼠标悬停在红框区域(并且绘图只是小菜一碟)时在右侧空白处绘制一个小箭头,并在离开该区域时将其擦除。而且我不关心选项卡的溢出(这会导致绘制滚动双按钮) - 这永远不会发生。

这是工作代码,但这不是明确的解决方案,我不喜欢它。必须有另一种(更干净)的方式来做到这一点。

type
  TPageControl = class(ComCtrls.TPageControl)
  protected
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
  end;

procedure TPageControl.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  Canvas.TextOut(Width - 130, 5, 'CMMouseLeave'); // display result
end;

procedure TPageControl.WMNCHitTest(var Message: TWMNCHitTest);
var TabHeaderRect: TRect;
begin
  if Message.Result = 0 then // if Message.Result = HTNOWHERE ...
    begin
      TabHeaderRect := ClientRect;
      TabHeaderRect.Bottom := Top + 21;

      if PtInRect(TabHeaderRect, ScreenToClient(Point(Message.XPos, Message.YPos))) then
        Canvas.TextOut(Width - 130, 5, 'WMNCHitTest   '); // display result

      Message.Result := HTCLIENT;
    end
  else
    inherited;
end;

【问题讨论】:

  • 我知道肯定可以给例如页面控件下具有适当高度的面板,并为页面控件的 OnMouseEnter 和 OnMouseLeave 和面板共享相同的事件,但我需要认真地将其包装在一个组件中。

标签: delphi winapi


【解决方案1】:

显然,空白空间不属于控件的客户区,因此该控件不会获得该区域的任何与鼠标相关的 Windows 消息。您将不得不使用表单的鼠标事件。或者将页面控件放在面板中(使用alClient)并使用面板的鼠标事件。

如果您不止一次需要此功能,您可以创建一个新组件来完成此操作(组合面板和页面控件以实现所需的行为)。

【讨论】:

  • 有可能以某种方式。也许使用 WM_NCHITTEST 或其他东西。据我测试,WindowFromPoint 函数即使对于空白区域也会返回 TPageControl 句柄,所以我希望该区域中的页面控件本身捕获了一些消息。而空白区域属于页面控件的客户区,不是吗?由于删除背景消息,我认为它是透明的。
  • @daemon - 不,如果它是客户区,你会得到你的鼠标进入/离开消息。然后尝试,在 WM_NCHITTEST 处理程序中,如果命中测试是 HTTRANSPARENT,则将其修改为 HTCLIENT,并查看 VCL 的离开/进入事件是否正在触发。
  • 为你们+1。这个 WM_NCHITTEST 消息让我很生气。唯一的问题是我不知道何时捕获和释放鼠标。在上面的代码中,我没有捕获鼠标并且它可以工作。从我的角度来看,当光标进入页面控件时,我应该观察(捕获)鼠标,但我不知道用户是否将光标带到了空白部分。所以我永远不能说,是的,你在我的空地上。这就是为什么我接受这个答案的原因。我将修改 TPageControl 以创建并将其自身放置在面板上,并将 OnMouseEnter 和 0nMouseLeave 分配给它。感谢您的宝贵时间。
【解决方案2】:

您确定要为页面控件本身而不是为它包含的 TTabSheet 实例处理 OnMouseEnter/OnMouseLeave 吗?

【讨论】:

  • 是的。我在重写的 TPageControl 类中处理 CM_MOUSEENTER 和 CM_MOUSELEAVE。
猜你喜欢
  • 2013-07-06
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-20
  • 2017-12-28
  • 2016-09-22
  • 1970-01-01
相关资源
最近更新 更多