如何将模态对话框保持在动态创建的表单之上? (CreateParams - 覆盖)

发布于 2024-12-07 14:59:39 字数 1520 浏览 1 评论 0原文

我正在动态创建一个覆盖 CreateParams 的表单,以便我可以将其显示在任务栏上。从动态创建的表单中,我调用 TColorDialog,但一旦显示,我的表单将进入 MainForm 下方,而 ColorDialog 位于其顶部。

ColorDialog 关闭后,动态表单将返回到 MainForm。

我看到在 ColorDialog 执行方法上有一个可以传递的句柄,但我不确定我是否走在正确的轨道上?

如果我单击 MainForm 上的对话框,它会闪烁,但是如何让动态创建的表单“拥有”此对话框,而 MainForm 位于后面?

我像这样创建表单:

procedure TMain.Button1Click(Sender: TObject);
var
  SEMArcF: TWriteSEMArcFrm;
begin
  SEMArcF := TWRiteSEMArcFrm.Create(nil);
  SEMArcF.Show;
end; 

并且在 OnClose 事件上释放它:

procedure TWriteSEMArcFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

我像这样重写 CreateParams:

procedure TWriteSEMArcFrm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  if (FormStyle = fsNormal) then begin
    Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
    Params.WndParent := GetDesktopWindow;
  end;
end;

并显示 ColorDialog,我要么创建它,要么只是在表单上有一个 TColorDialog 组件,无论哪种方式都会导致相同的结果。我希望它由动态表单拥有。

编辑 我现在添加:

Application.ModalPopupMode := pmAuto;

完整代码:

procedure TWriteSEMArcFrm.btnBackColourClick(Sender: TObject);
var
  ColorDlg: TColorDialog;
begin
  Application.ModalPopupMode := pmAuto;
  ColorDlg := TColorDialog.Create(nil);
  try
    if ColorDlg.Execute then
    re.Color := ColorDlg.Color;
  finally
    ColorDlg.Free;
  end;
end;

这工作正常,但是通过设置它会出现任何异常行为吗?

谢谢克里斯

I am dynamically creating a Form that overrides the CreateParams so that I can have it displayed on the TaskBar. From the dynamically created Form, I am calling a TColorDialog but once it is displayed my Form will go under the MainForm with the ColorDialog on top of that.

After the ColorDialog is closed the dynamic Form will return back over the MainForm.

I see that on the ColorDialog Execute method there is a Handle that can be passed but I am not sure if I am on the right track with that?

If I click under the Dialog on the MainForm it will flash but how can I have the dynamically created Form "own" this Dialog with the MainForm at the back?

I create the Form like this:

procedure TMain.Button1Click(Sender: TObject);
var
  SEMArcF: TWriteSEMArcFrm;
begin
  SEMArcF := TWRiteSEMArcFrm.Create(nil);
  SEMArcF.Show;
end; 

and it is freed on the OnClose Event:

procedure TWriteSEMArcFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

I am overriding the CreateParams like this:

procedure TWriteSEMArcFrm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  if (FormStyle = fsNormal) then begin
    Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
    Params.WndParent := GetDesktopWindow;
  end;
end;

and to show the ColorDialog I either create it or just have a TColorDialog Component on the Form, either way will result in the same. I want it to be owned by the dynamic Form.

EDIT
I now add:

Application.ModalPopupMode := pmAuto;

The full code:

procedure TWriteSEMArcFrm.btnBackColourClick(Sender: TObject);
var
  ColorDlg: TColorDialog;
begin
  Application.ModalPopupMode := pmAuto;
  ColorDlg := TColorDialog.Create(nil);
  try
    if ColorDlg.Execute then
    re.Color := ColorDlg.Color;
  finally
    ColorDlg.Free;
  end;
end;

This works fine but could there be any unusual behaviour by setting this?

Thank you

Chris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人 2024-12-14 14:59:40

TColorDialog 派生自 TCommonDialog,它有两个可用的 Execute() 重载版本 - 已经存在多年的传统无参数版本和较新的版本将父级 ​​HWND 作为输入参数的重载。您可能会调用前者。该重载使用当前活动 TFormHandle 属性(仅当 TApplication.ModalPopupMode 属性未设置为 pmNone),如果需要,则返回到 MainFormHandle。如果您想要更多控制,则应该直接调用其他重载,然后可以将动态表单的 Handle 属性作为参数值传递。

TColorDialog derives from TCommonDialog, which has two overloaded versions of Execute() available - the legacy parameterless version that has existed for years, and a newer overload that takes a parent HWND as an input parameter. You are likely calling the former. That overload uses the Handle property of the currently active TForm (only if the TApplication.ModalPopupMode property is not set to pmNone), falling back to the Handle of the MainForm if needed. If you want more control, you should call the other overload directly instead, then you can pass the dynamic form's Handle property as the parameter value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文