双显示器问题

时间:2017-01-31 06:02:42

标签: delphi

我在Delphi 5中有一个Windows应用程序。

我有两台显示器。当我的应用程序运行时,父项将显示在第一台监视器上。当我将父窗口移动到第二个监视器并单击按钮时,此子窗口将保留在第一个监视器上。有没有办法让子窗口与父窗口保持一致,无论父窗口位于何处?我搜索了相关的内容,但解决方案是在C#而不是Delphi中,我在Delphi中很新。子表单在运行时创建。

function BeforeCreateForm(Session:ISmSession;var IsDLL: Boolean):HWND;
var
  SmGUIServices: ISmGUIServices;
  MainWindowHandle:HWND;
begin
  MainWindowHandle:=0;
  IsDLL := false;
  if (Application.Handle = 0) and (Session <> nil) then
  begin
    IsDLL := true;
    SmGUIServices := (Session.Services.Item[TDM_SmarTeamServices[srvSmGUIService]] as ISmGUIServices);
    if SmGUIServices <> nil then
    {$IFNDEF BUILTPACKAGE}
       MainWindowHandle:=ForceIntegerToHwnd(SmGUIServices.MainWindowHandle);
    {$ENDIF}
  end;
  result:=MainWindowHandle;
end { of BeforeCreateForm } ;

procedure TSmForm.AfterCreateForm(Session:ISmSession; SmHelpContext:TDM_Int32; IsDLL: boolean);
begin

  if SmSession<>Session then
    SmSession:= Session;
  if SmHelpContext > 0 then
    HelpContext:=SmHelpContext;

  if (IsDLL) then
  begin
    if (Icon.Empty) and (ParentHWND <> 0) then
      SendMessage(Handle, WM_SETICON, 1, SendMessage(ParentHWND, WM_GETICON, 1, 0));
  end;
end { of TSmForm.AfterCreateForm } ;


constructor TSmForm.Create(AOwner: TComponent;Session:ISmSession;SmHelpContext:TDM_Int32);
var
  IsDLL: Boolean;
begin
  ParentHWND:=BeforeCreateForm(Session, IsDLL);
  HelpContext := 0;
  SmSession:= Session;
  inherited Create(AOwner);
  AfterCreateForm(Session,SmHelpContext, IsDLL);
end;



procedure TSmForm.CreateParams(var Params: TCreateParams);

var
  SmGuiServices: ISmGuiServices;
  MDIChild : TIMDIChildForm;
  MultiTabType :TDM_Int16;
  I:Integer;

begin
  inherited CreateParams(Params);
  if ParentHWND <> 0 then
  begin
     Params.WndParent:=ParentHWND;

    SmGUIServices := (SmSession.Services.Item[TDM_SmarTeamServices[srvSmGUIService]] as ISmGUIServices);
    for I := SmGUIServices.SmViewWindows.Count - 1 downto 0 do
    begin
      if(SmGUIServices.SmViewWindows.item[I].SmView<>nil) then  
      if(SmGUIServices.SmViewWindows.item[I].SmView.ViewType <> vwtBomView) then       
      begin                                                                            
      MDIChild := TIMDIChildForm((SmGUIServices.SmViewWindows.item[I] as ISmRawViewWindow).SmViewWindowHandle);

      MultiTabType:=GetMultiTabType( MDIChild.tabSmView, MDIChild.tabSmView.ActivePage.PageIndex);

        if UpperCase(SmSession.ApplicationName) = 'MYAPP' then
        (MDIChild.MDIViewer.ViewerType = 10))) then  

        begin

         // Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST;
          Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
         Params.WndParent := GetDesktopWindow;


          exit;
        end

        else
        begin
          if (MultiTabType = MT_Viewer) then
          begin
            Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST;
            exit;
          end;
        end;

      end;                  
    end;   
  end;
end;

1 个答案:

答案 0 :(得分:1)

感谢David确认D5支持DefaultMonitor

如果您将DefaultMonitor设置为dmActiveForm,那么它应该可以实现您的目标。请注意,该文档指定您的应用程序必须具有正确的主表单。您还需要确保此设置与您正在执行的任何其他操作发生冲突。

有些注意事项:

  • 默认情况下,DefaultMonitor仅在您首次显示表单时启动。之后Position设置为poDesigned以记住表单的位置。
  • 如果您希望隐藏并重新显示在其他显示器上,则您将重置TheForm.Postion := poScreenCenter;或最适合您的选项。请记住,用户可能会因为没有“回忆”其位置的形式而感到恼火。
  • 另请注意,MDI表单的规则会发生重大变化。如果你正在黑客攻击MDI表单而没有正确设置属性期望奇怪的行为。

除此之外,如果您实际上没有显示损坏的代码,我无法建议您如何修复损坏的代码。