子窗体弹出位置错误

在设计窗体时通常会把子窗体的 Position 设置成 poMainFormCenter。也就是说,子窗体弹出的位置是主窗体的正中。但是如果把主窗体拖动到屏幕左下角,而且主窗体的50%部分已经超出了屏幕范围,这个时候主窗体的正中其实已经不在屏幕范围之内了。这个时候弹出的子窗体可能部分或者完全处在屏幕之外了。

具体解决方法:修改 Forms.pas,修改 procedure TcustomForm.CMShowingChanged(var Message: Tmessage);

procedure TCustomForm.CMShowingChanged(var Message: TMessage);
const
  ShowCommands: 
array[TWindowState] of Integer =
    (SW_SHOWNORMAL, SW_SHOWMINNOACTIVE, SW_SHOWMAXIMIZED);
var
  X, Y: Integer;
  NewActiveWindow: HWnd;
  CenterForm: TCustomForm;
begin
  
if not (csDesigning in ComponentState) and (fsShowing in FFormState) then
    
raise EInvalidOperation.Create(SVisibleChanged);
  Application.UpdateVisible;
  Include(FFormState, fsShowing);
  
try
    
if not (csDesigning in ComponentState) then
    
begin
      
if Showing then
      
begin
        
try
          DoShow;
        
except
          Application.HandleException(Self);
        
end;
        
if (FPosition = poScreenCenter) or
           ((FPosition = poMainFormCenter) 
and (FormStyle = fsMDIChild)) then
        
begin
          
if FormStyle = fsMDIChild then
          
begin
            X := (Application.MainForm.ClientWidth - Width) 
div 2;
            Y := (Application.MainForm.ClientHeight - Height) 
div 2;
          
end else
          
begin
            X := (Screen.Width - Width) 
div 2;
            Y := (Screen.Height - Height) 
div 2;
          
end;
          
if X < Screen.DesktopLeft then
            X := Screen.DesktopLeft;
          
if Y < Screen.DesktopTop then
            Y := Screen.DesktopTop;
          
if Y > Screen.WorkAreaHeight - Height then  //PATCH
            Y := Screen.WorkAreaHeight - Height;      
//PATCH
          SetBounds(X, Y, Width, Height);
          
if Visible then SetWindowToMonitor;
        
end
        
else if FPosition in [poMainFormCenter, poOwnerFormCenter] then
        
begin
          CenterForm := Application.MainForm;
          
if (FPosition = poOwnerFormCenter) and (Owner is TCustomForm) then
            CenterForm := TCustomForm(Owner);
          
if Assigned(CenterForm) then
          
begin
            X := ((CenterForm.Width - Width) 
div 2) + CenterForm.Left;
            Y := ((CenterForm.Height - Height) 
div 2) + CenterForm.Top;
          
end else
          
begin
            X := (Screen.Width - Width) 
div 2;
            Y := (Screen.Height - Height) 
div 2;
          
end;
          
if X < Screen.DesktopLeft then
            X := Screen.DesktopLeft;
          
if Y < Screen.DesktopTop then
            Y := Screen.DesktopTop;
          
if Y > Screen.WorkAreaHeight - Height then  //PATCH
            Y := Screen.WorkAreaHeight - Height;      
//PATCH
          SetBounds(X, Y, Width, Height);
          
if Visible then SetWindowToMonitor;
        
end
        
else if FPosition = poDesktopCenter then
        
begin
          
if FormStyle = fsMDIChild then
          
begin
            X := (Application.MainForm.ClientWidth - Width) 
div 2;
            Y := (Application.MainForm.ClientHeight - Height) 
div 2;
          
end else
          
begin
            X := (Screen.DesktopWidth - Width) 
div 2;
            Y := (Screen.DesktopHeight - Height) 
div 2;
          
end;
          
if X < Screen.DesktopLeft then              //PATCH
            X := Screen.DesktopLeft;                  
//
          
if Y < Screen.DesktopTop then               //
            Y := Screen.DesktopTop;                   
//
          
if Y > Screen.WorkAreaHeight - Height then  //
            Y := Screen.WorkAreaHeight - Height;      
//PATCH
          SetBounds(X, Y, Width, Height);
        
end;


好了!大功告成。将修改后的 Forms.pas 复制到您的工程目录下,再次编译您的程序。这个问题消失了。

此外,对于修改 Delphi 的源文件,我建议把所有修改过的源文件都放在一个新的目录 (例如 PatchedVCLs),然后在 Delphi 里面定义一个环境变量,这样以后你只要给其它工程的路径里面添加这个环境变量,这些工程都可以使用你修改过的代码了。至于修改源码的一些方法和技巧,请参考 如何访问私有成员变量和函数  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值