解决子窗体弹出位置错误的问题的方法
在设计窗体时通常会把子窗体的 Position 设置成 poMainFormCenter。也就是说,子窗体弹出的位置是主窗体的正中。但是如果把主窗体拖动到屏幕左下角,而且主窗体的50%部分已经超出了屏幕范围,这个时候主窗体的正中其实已经不在屏幕范围之内了。这个时候弹出的子窗体可能部分或者完全处在屏幕之外了。
具体解决方法:修改 Forms.pas,修改 procedure TcustomForm.CMShowingChanged(var Message: Tmessage);
procedureTCustomForm.CMShowingChanged(varMessage:TMessage);
const
ShowCommands:array[TWindowState]ofInteger=
(SW_SHOWNORMAL,SW_SHOWMINNOACTIVE,SW_SHOWMAXIMIZED);
var
X,Y:Integer;
NewActiveWindow:HWnd;
CenterForm:TCustomForm;
begin
ifnot(csDesigninginComponentState)and(fsShowinginFFormState)then
raiseEInvalidOperation.Create(SVisibleChanged);
Application.UpdateVisible;
Include(FFormState,fsShowing);
try
ifnot(csDesigninginComponentState)then
begin
ifShowingthen
begin
try
DoShow;
except
Application.HandleException(Self);
end;
if(FPosition=poScreenCenter)or
((FPosition=poMainFormCenter)and(FormStyle=fsMDIChild))then
begin
ifFormStyle=fsMDIChildthen
begin
X:=(Application.MainForm.ClientWidth-Width)div2;
Y:=(Application.MainForm.ClientHeight-Height)div2;
endelse
begin
X:=(Screen.Width-Width)div2;
Y:=(Screen.Height-Height)div2;
end;
ifX<Screen.DesktopLeftthen
X:=Screen.DesktopLeft;
ifY<Screen.DesktopTopthen
Y:=Screen.DesktopTop;
ifY>Screen.WorkAreaHeight-Heightthen//PATCH
Y:=Screen.WorkAreaHeight-Height;//PATCH
SetBounds(X,Y,Width,Height);
ifVisiblethenSetWindowToMonitor;
end
elseifFPositionin[poMainFormCenter,poOwnerFormCenter]then
begin
CenterForm:=Application.MainForm;
if(FPosition=poOwnerFormCenter)and(OwnerisTCustomForm)then
CenterForm:=TCustomForm(Owner);
ifAssigned(CenterForm)then
begin
X:=((CenterForm.Width-Width)div2)+CenterForm.Left;
Y:=((CenterForm.Height-Height)div2)+CenterForm.Top;
endelse
begin
X:=(Screen.Width-Width)div2;
Y:=(Screen.Height-Height)div2;
end;
ifX<Screen.DesktopLeftthen
X:=Screen.DesktopLeft;
ifY<Screen.DesktopTopthen
Y:=Screen.DesktopTop;
ifY>Screen.WorkAreaHeight-Heightthen//PATCH
Y:=Screen.WorkAreaHeight-Height;//PATCH
SetBounds(X,Y,Width,Height);
ifVisiblethenSetWindowToMonitor;
end
elseifFPosition=poDesktopCenterthen
begin
ifFormStyle=fsMDIChildthen
begin
X:=(Application.MainForm.ClientWidth-Width)div2;
Y:=(Application.MainForm.ClientHeight-Height)div2;
endelse
begin
X:=(Screen.DesktopWidth-Width)div2;
Y:=(Screen.DesktopHeight-Height)div2;
end;
ifX<Screen.DesktopLeftthen//PATCH
X:=Screen.DesktopLeft;//
ifY<Screen.DesktopTopthen//
Y:=Screen.DesktopTop;//
ifY>Screen.WorkAreaHeight-Heightthen//
Y:=Screen.WorkAreaHeight-Height;//PATCH
SetBounds(X,Y,Width,Height);
end;
好了!大功告成。将修改后的 Forms.pas 复制到您的工程目录下,再次编译您的程序。这个问题消失了。
此外,对于修改 Delphi 的源文件,我建议把所有修改过的源文件都放在一个新的目录 (例如 PatchedVCLs),然后在 Delphi 里面定义一个环境变量,这样以后你只要给其它工程的路径里面添加这个环境变量,这些工程都可以使用你修改过的代码了。至于修改源码的一些方法和技巧,请参考 如何访问私有成员变量和函数。
本文地址:http://www.45fan.com/dnjc/73084.html