【问题标题】:Start program on a second monitor?在第二台显示器上启动程序?
【发布时间】:2010-09-17 09:50:48
【问题描述】:

有没有办法在 Delphi 或 C++Builder 中指定应用程序出现在哪个监视器上?

我正在为客户开发一个简单的程序,该程序在辅助显示器上显示由酒店系统生成的厨房订单。目前他们需要在启动后手动将窗口拖到第二台显示器上。

【问题讨论】:

    标签: delphi c++builder multiple-monitors point-of-sale


    【解决方案1】:

    全局 Screen 对象(Forms 的一部分)具有 Monitors 的概念。我认为这是在 Delphi 6 或 7 左右添加的。以下代码将起作用:

    // Put the form in the upper left corner of the 2nd monitor
    //   if more then one monitor is present.
    if Screen.MonitorCount > 1 then
    begin
      Left := Screen.Monitors[1].Left;
      Top := Screen.Monitors[1].Top;
    end;
    

    您可以使用从该位置的任何正偏移将其放在该监视器中的任何位置。您也可以从那里获取宽度和高度以了解尺寸。

    【讨论】:

      【解决方案2】:

      在程序关闭之前保存窗口位置并在启动时恢复它们。多显示器显示只是增加了桌面的大小;其他显示器表面只是具有同一 X/Y 平面的不同部分,其原点位于主显示器的左上角。

      这可以由any of several components 自动为您完成。

      顺便说一句,Forms 单元中的 Screen 变量有一个名为 MonitorCount 的属性和另一个可索引的属性 Monitors[Index: Integer]: TMonitor。 TMonitor 具有指示左侧、顶部、宽度、高度等属性,因此您需要的所有信息都在那里。

      【讨论】:

      • 谢谢,我按照你和 Jim 的建议使用了 Screen.MonitorCount。
      • 您还应该在启动时使用设置之前验证保存的监视器。否则,如果用户移除曾经存在的监视器,您的窗口将根本不会显示在屏幕上。
      • 在负屏幕坐标上启动应用程序总是很有趣,看用户如何让应用程序显示......
      【解决方案3】:
      procedure TMDIChild.btnShowMonClick(Sender: TObject);
      begin
          if Screen.MonitorCount > 1 then
          begin
            FormShow.Left:=Screen.Monitors[1].Left;
            FormShow.Top:=Screen.Monitors[1].Top;
            FormShow.Width:=Screen.Monitors[1].Width;
            FormShow.Height:=Screen.Monitors[1].Height;
          end
          else
          begin
              FormShow.Show;
          end;
      end;
      

      【讨论】:

        【解决方案4】:

        不是您的问题所暗示的答案,但是您不能在应用程序关闭时存储窗口设置(大小、位置、最大化状态),然后在启动时应用它们吗?

        【讨论】:

        • 这是最简单的实现
        • 这个有问题。如果在应用程序使用第二个 montor 后将其从计算机中删除,会发生什么情况? (MySql Query Brower 有这个问题)
        【解决方案5】:

        我不久前在 Delphi 5 中做过类似的事情:

        procedure TForm18.FormCreate(Sender: TObject);
        var
          Mon: TMonitor;
          MonitorIdx: Integer;
        begin
          MonitorIdx := 1; // better read from configuration
          if (MonitorIdx <> Monitor.MonitorNum) and (MonitorIdx < Screen.MonitorCount) then begin
            Mon := Screen.Monitors[MonitorIdx];
            Left := Left + Mon.Left - Monitor.Left;
            Top := Top + Mon.Top - Monitor.Top;
          end;
        end;
        

        【讨论】:

          【解决方案6】:

          Windows 将允许您在 CreateWindow API 调用中指定窗口的坐标。我对 Delphi 或 C++Builder 了解不够,不知道您是否有权访问该过程的那部分。

          您还可以在 WM_CREATE 处理程序中移动窗口。

          EnumDisplayMonitors 将为您提供系统中每个监视器的坐标。


          显然,Delphi 和 C++ Builder 具有使这个答案有些无关紧要的功能。我会把它留在这里,以防有人遇到这个问题,但需要在不同的环境中回答它。

          【讨论】:

          • Delphi 具有涵盖所有这些功能的抽象,从 Screen.Monitors 集合到用于控制表单位置的预构造事件。
          【解决方案7】:

          我对 Windows 系统做的不多,所以我建议像这样 hack。

          获取可视桌面的宽度(两台显示器合并),将其除以一半,然后将其作为起始位置。

          您还可以查看 api 告诉您 monitor2 的尺寸。

          【讨论】:

          • 只有在两台显示器的桌面尺寸相同时才有效。
          • @ReOsless:是的。就像我说的那样,这是一个 hack。
          猜你喜欢
          • 1970-01-01
          • 2011-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多