我有一个使用TOpenDialog的Delphi应用程序,让用户选择文件。默认情况下,打开对话框显示在当前监视器的中心位置,这可能与应用程序窗口相距很远。我希望对话框显示在TOpenDialog的所有者控件中心,如果不行,我愿意将其显示在应用程序的主窗口中。
以下代码基本可行,它源于TJvOpenDialog,给了我一些提示:
“kind of works”的意思是,第一次打开对话框时,它会显示在所有者窗体的中心。但是,如果我关闭对话框,移动窗口并再次打开对话框,即使SetWindowPos返回true,它似乎没有任何效果。对话框以与第一次相同的位置打开。
这是在运行Windows XP的Delphi 2007上进行的,目标框也在运行Windows XP。
以下代码基本可行,它源于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;
“kind of works”的意思是,第一次打开对话框时,它会显示在所有者窗体的中心。但是,如果我关闭对话框,移动窗口并再次打开对话框,即使SetWindowPos返回true,它似乎没有任何效果。对话框以与第一次相同的位置打开。
这是在运行Windows XP的Delphi 2007上进行的,目标框也在运行Windows XP。
TMyOpenDialog.WndProc
:注意 with 的危害:with **Msg** do case **Msg** of
。小贴士:不要使用 with!如果你认为你找到了一个适合使用它的地方 - 你其实没有!!**/endrant** PS:你应该始终确保适当地设置Msg.Result
- 否则你可能会遇到意外行为。 - Disillusioned