gpt4 book ai didi

delphi - 如何定位 TOpenDialog

转载 作者:行者123 更新时间:2023-12-03 15:45:35 25 4
gpt4 key购买 nike

我有一个 Delphi 应用程序,它使用 TOpenDialog 让用户选择文件。默认情况下,打开的对话框显示在当前监视器的中心,而当前监视器可能距离应用程序窗口“数英里”。我希望对话框以 TOpenDialog 的所有者控件为中心显示,如果做不到这一点,我将选择应用程序的主窗口。

以下代码是有效的,它源自 TJvOpenDialog,它给了我一些关于如何执行此操作的提示:

type
TMyOpenDialog = class(TJvOpenDialog)
private
procedure SetPosition;
protected
procedure DoFolderChange; override;
procedure WndProc(var Msg: TMessage); override;
end;

procedure TMyOpenDialog.SetPosition;
begin
var
Monitor: TMonitor;
ParentControl: TWinControl;
Res: LongBool;
begin
if (Assigned(Owner)) and (Owner is TWinControl) then
ParentControl := (Owner as TWinControl)
else if Application.MainForm <> nil then
ParentControl := Application.MainForm
else begin
// this code was already in TJvOpenDialog
Monitor := Screen.Monitors[0];
Res := SetWindowPos(ParentWnd, 0,
Monitor.Left + ((Monitor.Width - Width) div 2),
Monitor.Top + ((Monitor.Height - Height) div 3),
Width, Height,
SWP_NOACTIVATE or SWP_NOZORDER);
exit; // =>
end;
// this is new
Res := SetWindowPos(GetParent(Handle), 0,
ParentControl.Left + ((ParentControl.Width - Width) div 2),
ParentControl.Top + ((ParentControl.Height - Height) div 3),
Width, Height,
SWP_NOACTIVATE or SWP_NOZORDER);
end;

procedure TMyOpenDialog.DoFolderChange
begin
inherited DoFolderChange; // call inherited first, it sets the dialog style etc.
SetPosition;
end;

procedure TMyOpenDialog.WndProc(var Msg: TMessage);
begin
case Msg.Msg of
WM_ENTERIDLE: begin
// This has never been called in my tests, but since TJVOpenDialog
// does it I figured there may be some fringe case which requires
// SetPosition being called from here.
inherited; // call inherited first, it sets the dialog style etc.
SetPosition;
exit;
end;
end;
inherited;
end;

“作品种类”意味着第一次打开对话框时,它会显示在所有者窗体的中心。但是,如果我然后关闭对话框,移动窗口并再次打开对话框,SetWindowPos 似乎没有任何效果,即使它确实返回 true。对话框在与第一次相同的位置打开。

这是在 Windows XP 上运行的 Delphi 2007,目标机也运行 Windows XP。

最佳答案

我只能通过将 OwnerHwnd 的虚假值传递给对话框的 Execute 方法来重现您所描述的行为。

然后,该窗口句柄将传递到底层 Windows 公共(public)控件,事实上,如果在显示对话框时不将其设置为事件窗体的句柄,您的对话框将会出现其他问题。

例如,当我调用 Execute 并传递 Application.Handle 时,该对话框始终出现在同一个窗口上的一个相当奇怪的位置,无论我的主窗体在哪里。

当我调用 Execute 并将句柄传递给主窗体时,对话框出现在主窗体的顶部,稍微向右和向下移动。无论表单位于哪个监视器上都是如此。

我使用的是 Delphi 2010,我不知道您的 Delphi 版本上是否有 Execute 的重载版本。即使您没有可用的方法,您仍然应该能够创建一个派生类,为 OwnerHwnd 传递更合理的值。

虽然我没有 100% 确凿的证据证明这是您的问题,但我认为这一观察将使您得到满意的解决方案。

关于delphi - 如何定位 TOpenDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5381188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com