子窗体弹出位置错误

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

在Qt中,如果你想创建一个带有背景遮罩、弹出窗口,并保持父窗口变灰的效果,你可以通过以下几个步骤来实现: 1. **背景遮罩**: 使用`QGraphicsOpacityEffect`可以创建一个透明度效果,将它应用到父窗口上,使其看起来像变灰。首先,你需要在主窗体上添加这个效果: ```cpp QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this); this->setGraphicsEffect(effect); effect->setOpacity(0.5); // 设置透明度,这里设为50%灰度,可以根据需要调整 ``` 2. **弹出窗口**: 使用`QDialog`或`QWindow`等类创建一个新的窗口作为遮罩。当显示窗口时,确保父窗口暂停接受事件处理: ```cpp QDialog dialog; dialog.setModal(true); // 设置为模态窗口,以便阻塞父窗口直到关闭 dialog.setAttribute(Qt::WA_TranslucentBackground, true); // 使窗口半透明 dialog.show(); QApplication::processEvents(); // 暂停处理父窗口事件,直到遮罩关闭 ``` 3. **窗口的显示和关闭**: 当窗口准备好展示内容后,打开并设置其大小、位置等属性。关闭窗口时,移除遮罩效果或者隐藏窗口,继续处理父窗口的事件。 ```cpp dialog.exec(); // 窗口显示,调用exec()函数启动事件循环 // 窗口关闭后... parentWindow->removeGraphicsEffect(effect); // 如果使用QGraphicsOpacityEffect,移除效果 parentWindow->show(); // 父窗口恢复可见性 ``` 注意,以上代码片段是一个简化的示例,实际项目中可能需要更多的错误检查和定制化处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值