TPanel作为MDI应用程序中的启动画面

WeG*_*ars 3 delphi

我想在一个表单中间显示一个TPanel,它是其他表单的MDI父级.某种"泼溅"的形式,但并不完全.该面板将包含用户将调用misc的链接/按钮/快捷方式.功能.

主要要求是当我点击MDI子项时,TPanel应该放在MDI子表单下面.但是,就目前而言,TPanel将始终保持在MDI子表单之上.

调用Panel.SendToBack将使面板消失.我能怎么做?

kob*_*bik 6

您需要覆盖Panel,WindowProc以便面板始终位于MDI子项后面,例如:

TMainForm = class(TForm)
...
private
  FPanelWndProc: TWndMethod;
  procedure PanelWndProc(var M: TMessage);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Windows.SetParent(Panel1.Handle, ClientHandle);
  // Override Panel1 WindowProc
  FPanelWndProc := Panel1.WindowProc;
  Panel1.WindowProc := PanelWndProc;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  // Restore Panel1 WindowProc
  Panel1.WindowProc := FPanelWndProc;
end;

procedure TMainForm.PanelWndProc(var M: TMessage);
var
  P: ^WINDOWPOS;
begin
  if M.Msg = WM_WINDOWPOSCHANGING then
  begin
    P := Pointer(M.LParam);
    // Always place panel at bottom
    P.hwndInsertAfter := HWND_BOTTOM;
  end;
  FPanelWndProc(M);
end;
Run Code Online (Sandbox Code Playgroud)

注意:要快速测试代码,可以通过创建MDI应用程序 File -> New -> MDI Application


编辑:上面的代码剂量实际上回答了你的初始问题.如果你想让你的" Panel以某种方式表现为MDI孩子 "(你的评论引用),那么简单地(......嗯......)使用MDI Child表单.即使用创建新表单.FormStyle = fsMDIChild,然后使用如下内容:

SetWindowLong(Child.Handle, GWL_STYLE, 
   GetWindowLong(Child.Handle, GWL_STYLE) and not (WS_BORDER or WS_DLGFRAME or WS_SIZEBOX));
Run Code Online (Sandbox Code Playgroud)

删除它的边框(因为简单的设置.BorderStyle = bsNone不起作用).
在表单上放置您需要的任何内容,一旦单击它,它将移动到其他MDI表单之上.

  • @NGLN,我完全回答了OP的要求.当使用按钮时,OP可能会或可能不想将面板置于前面.那不是问题. (4认同)
  • 这正是MDI孩子的表现! (3认同)
  • 据我所知,OP要求专家组始终支持MDI儿童. (2认同)