使用此处提供的示例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事件无法接收任何停靠的表单,从而导致关闭按钮停止工作。
答案 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}}