所有者绘制的TPageControl OnMouse事件在将表单作为选项卡停靠时无法触发

时间:2011-12-02 21:05:14

标签: delphi user-interface tpagecontrol

使用此处提供的示例How to implement a close button for a TTabsheet of a TPageControl结合将表单父级设置为带有匹配标题的标签页我能够将我的页面控件与附加为TTabSheet的表单一起使用并添加关闭按钮和图像列表中的图像就像你在今天的网络浏览器上看到的一样。

当我改变

procedure TMainfrm.SOTest(Sender: TObject);
var
  ATab: TTabSheet;
  AForm: TMyForm;
begin
  { Tabbed }
  ATab:= TTabSheet.Create(MainPageControl);
  ATab.PageControl := MainPageControl;
  MainPageControl.ActivePage := ATab;
  AForm:= TMyForm.Create(ATab);
  AForm.Show;
  ATab.Caption := AForm.Caption;
end;

procedure TMainfrm.SOTest(Sender: TObject);
var
  AForm: TMyForm;
begin
  AForm:= TMyForm.Create(Application);
  AForm.Show;
  AForm.DragKind := dkDock;
  AForm.DragMode := dmAutomatic;
  AForm.ManualDock(MainPageControl,MainPageControl,alClient);
  AForm.Caption := 'StackOverFlow';
end;

OnMouse事件无法接收任何停靠的表单,从而导致关闭按钮停止工作。

1 个答案:

答案 0 :(得分:1)

问题是,您正在设置页面控件的DockSite属性(尽管问题中未提及)。设置DockSite时,如果按下鼠标左键,则会创建一个拖动对象,然后该对象捕获鼠标(这样就可以自动拖出表单)。因此,此对象处理鼠标消息,直到释放捕获为止,这是在WM_LBUTTONUP TDragObject.WndProc中的WM_LBUTTONDOWN情况下完成的。

重写WndProc,派生一个新类并放置一个消息处理程序等将不起作用,因为当拖动对象捕获鼠标时,页面控件不会传递任何鼠标消息。即使使用Application.OnMessage也是笨拙的,因为每次点击鼠标时Msg.hwnd都会指向不同的窗口。

例如,您可以通过一种方式或另一种子类控制页面控件,以便能够拦截type TPageControl = class(comctrls.TPageControl) private procedure WmLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN; end; TMainfrm = class(TForm) .. procedure TPageControl.WmLButtonDown(var Msg: TWMLButtonDown); var I: Integer; begin inherited; // mouse will be captured here for I := 0 to Length(Mainfrm.FCloseButtonsRect) - 1 do begin if PtInRect(Mainfrm.FCloseButtonsRect[I], SmallPointToPoint(Msg.Pos)) then begin ReleaseCapture; // and released here Break; end; end; end; ,在那里执行测试,如果点击位于选项卡上,则释放捕获。一个非常脏的基于链接问题的快速示例:

{{1}}