子窗体弹出位置错误

原创 2007年02月07日 20:33:00

在设计窗体时通常会把子窗体的 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 里面定义一个环境变量,这样以后你只要给其它工程的路径里面添加这个环境变量,这些工程都可以使用你修改过的代码了。至于修改源码的一些方法和技巧,请参考 如何访问私有成员变量和函数

 

C++模板的定制二:定制C++类

 C++模板的定制二:定制C++类       类模板的基本语法如下:       template        class classname{       ……};T可以是任何类型,下面我就举一...
  • winmain
  • winmain
  • 2001-11-09 20:33:00
  • 686

VC 常见问题百问

(1) 如何通过代码获得应用程序主窗口的 指针?主窗口的 指针保存在CWinThread::m_pMainWnd中,调用AfxGetMainWnd实现。AfxGetMainWnd() ->ShowWi...
  • jerry4711
  • jerry4711
  • 2009-03-05 09:44:00
  • 259

WPF 弹出渐变透明窗体,指定在父窗体以及控件的位置

  • 2011年06月14日 15:10
  • 122KB
  • 下载

C# 子窗体在父窗体中显示位置

C#怎么设置子窗体在主窗体中居中显示 问题的开始是由C#传传看主群里的印醒提出来的,下面我来说一下解决方案吧其实表面上看是很简单的 开始吧,现在有两个窗体Form1主窗体,Form2子窗体 而且...
  • u012391923
  • u012391923
  • 2016-10-27 14:12:57
  • 4270

ASP.net弹出子窗体与关闭窗体技巧

ASP.net弹出子窗体与关闭窗体技巧 首先,在pageload里写入以下代码:Response.Write("window.opener=null;wind...
  • lvfeng19806001
  • lvfeng19806001
  • 2012-10-22 10:26:53
  • 7347

解决PopupWindow在android7.0弹出位置错误问题

解决PopupWindow在android7.0弹出位置错误问题最近用了Android7.0手机打开做的项目,发现之前做的PopupWindow弹出位置都在屏幕顶部弹出,翻开代码, pop.s...
  • josnz
  • josnz
  • 2017-02-17 18:22:50
  • 1189

设置子窗体相对父窗体打开的位置

  • 2011年08月11日 21:30
  • 30KB
  • 下载

Javascript弹出子窗口

1、Javascript弹出子窗口可以通过多种方式实现,下面介绍几种方法(1) 通过window对象的open()方法,open()方法将会产生一个新的window窗口对象 //IE7里不支持 ...
  • zheng2008hua
  • zheng2008hua
  • 2011-04-18 08:44:00
  • 7332

C#:Win32 Hooks(一)让下一个弹出子窗体自动显示在父窗体中心

/* ---------------------------------------------------------- 文件名称:FormHelper.cs 作者:秦建辉 MSN:splash...
  • jhqin
  • jhqin
  • 2012-05-08 09:42:17
  • 2355

C#子窗体精确定位到父窗体的某个位…

弹出的子窗体精确定位在父窗体的某个位置,需要有目标坐标(这里将子窗体的位置设置为父窗体中一个panel的位置,需要将panel的坐标转换成屏幕坐标) lvlv_CauseForm cf = new l...
  • K346K346
  • K346K346
  • 2015-07-19 00:20:36
  • 2826
收藏助手
不良信息举报
您举报文章:子窗体弹出位置错误
举报原因:
原因补充:

(最多只允许输入30个字)