如何将模态对话框保持在动态创建的表单之上? (CreateParams - 覆盖)
我正在动态创建一个覆盖 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
TColorDialog
派生自TCommonDialog
,它有两个可用的Execute()
重载版本 - 已经存在多年的传统无参数版本和较新的版本将父级 HWND
作为输入参数的重载。您可能会调用前者。该重载使用当前活动TForm
的Handle
属性(仅当TApplication.ModalPopupMode
属性未设置为pmNone),如果需要,则返回到
MainForm
的Handle
。如果您想要更多控制,则应该直接调用其他重载,然后可以将动态表单的Handle
属性作为参数值传递。TColorDialog
derives fromTCommonDialog
, which has two overloaded versions ofExecute()
available - the legacy parameterless version that has existed for years, and a newer overload that takes a parentHWND
as an input parameter. You are likely calling the former. That overload uses theHandle
property of the currently activeTForm
(only if theTApplication.ModalPopupMode
property is not set topmNone
), falling back to theHandle
of theMainForm
if needed. If you want more control, you should call the other overload directly instead, then you can pass the dynamic form'sHandle
property as the parameter value.