2014-03-24 70 views
-2

我有一个应用程序,我有一个MDI窗体作为主窗体和几个MDI子窗体打开应该为 我也有一些没有MDI子窗体,我希望能够只显示在MDI区域内。我可以获得非MDI表格作为MDI孩子吗?

我已经做了一个从Vcl.Forms继承的单元,并具有以下代码,使我可以控制窗体,如果我试图移动他们 但我不能让它像这样的函数工作时窗体我首先展示。当我尝试移动它,它跳到正确到位

procedure TForm.WMMoving(var aMessage: TWMMoving); 
var 
    FormSquare: ^TRect; 
    WorkSquare: TRect; 
begin 
    WorkSquare := GetWorkSquare; 
    FormSquare := Pointer(aMessage.DragRect); 

    if FormSquare^.Left < WorkSquare.Left then 
    begin 
     FormSquare^.Right := FormSquare^.Right - (FormSquare^.Left - WorkSquare.Left); 
     FormSquare^.Left := WorkSquare.Left; 
    end 
    else if FormSquare^.Right > WorkSquare.Right then 
    begin 
     FormSquare^.Left := FormSquare^.Left - (FormSquare^.Right - WorkSquare.Right); 
     FormSquare^.Right := WorkSquare.Right; 
    end; 

    if FormSquare^.Top < WorkSquare.Top then 
    begin 
     FormSquare^.Bottom := FormSquare^.Bottom - (FormSquare^.Top - WorkSquare.Top); 
     FormSquare^.Top := WorkSquare.Top; 
    end 
    else if FormSquare^.Bottom > WorkSquare.Bottom then 
    begin 
     FormSquare^.Top := FormSquare^.Top - (FormSquare^.Bottom - WorkSquare.Bottom); 
     FormSquare^.Bottom := WorkSquare.Bottom; 
    end; 
end; 

的GetWorkSquare是获取无论是MDI形式或桌面工作区的功能。 MinTop是我添加的一个值,可以让表单在我经常使用的功能区菜单下跳转。

function GetWorkSquare: TRect; 
var 
    ClientRect: TRect; 
begin 
    if Assigned(Application.MainForm) then 
    begin 
     if Application.MainForm.FormStyle = fsMDIForm then 
     begin 
      Winapi.Windows.GetWindowRect(Application.MainForm.ClientHandle, ClientRect); 
      if ClientRect.Top < MinTop then 
      ClientRect.Top := MinTop; 
     end 
     else 
     SystemParametersInfo(SPI_GETWORKAREA, 0, @ClientRect, 0); 
    end; 
    ClientRect.Top  := ClientRect.Top + 5; 
    ClientRect.Left  := ClientRect.Left + 5; 
    ClientRect.Right  := ClientRect.Right - 5; 
    ClientRect.Bottom  := ClientRect.Bottom - 5; 
    Result    := ClientRect; 
end; 

澄清:所显示的代码工作已经显示出,如果我尝试将其移动 功能GetWorkSquare返回的形式被获准在移动屏幕上的区域在窗体上 - 醚MDI内容器或如果没有MDI的整个屏幕 我需要的是,当表格打开时,必须与在GetWorkSquare返回

正如我可以听到你说的是,我需要的是让我的开放功能检查主窗体是否为MDI容器,然后打开窗体不同 我有一个窗体,我打开它,如

function ShowUsers: boolean; 
begin 
    with TfrmUsers.Create(nil) do 
    try 
     Result := ShowModal = mrOK; 
    finally 
     Free; 
    end; 
end; 

对代码更改有什么建议可以帮助我实现这一点?

+1

你为什么不让这些其他形式为MDI儿童? –

+0

主要是因为我在其他没有MDI主窗体的应用程序中使用它们,也是因为它们中的很多显示为模态窗体,因为我需要一个返回值,并且这无法用MDI子窗体来完成 – OZ8HP

回答

0

看来你需要这些形式在某些项目中是MDI儿童,但在其他项目中是正常形式。因此,只需在运行时设置FormStyle属性即可满足您的需求。

+0

但是,如果窗体需要显示模式这不会工作,我需要的形式是模态 – OZ8HP

+0

为什么它不工作。将FormStyle设置为fsNormal后,只需使用ShowModal显示窗体。 –

+0

MDI孩子不会显示模式,我需要确保用户在等待表单输入时不会点击其他表单。除了模态形式之外,我无法完成这项工作。 – OZ8HP

1

要回答这个问题,在您的标题:

你有MDI子和模态之间进行选择,作为MDI子不能模态。

以下是您可能想要研究的两个方向。

第一个是决定将您的应用程序显示为MDI子项或Modal形式,如David所建议的。

如果您重新设计了一下,这可能会最好,因此当您将它用作MDI子项时,您没有OK/Cancel类似的行为(您需要考虑UI流)。

这就需要编写一个框架,其中大部分用户界面位于框架中,而周围的位是(继承的)表单以处理表单样式和模式。

另一种可能性是查看大多数Web和移动应用程序中的用户交互流程。大多数这些环境不支持大型模式表单,因此与传统的Windows应用程序具有非常不同的流程。

该领域的一个有趣答案是Android: How to get a modal dialog or similar modal behavior?,这个在JavaScript UX领域:UX: message boxes are mostly evil

许多程序员和组织都难以获得用户体验,因为许多程序员和组织都陷入了旧模式的咒语中。