【问题标题】:Taskbar width, height and position任务栏宽度、高度和位置
【发布时间】:2011-06-29 10:28:12
【问题描述】:

我需要获取任务栏的宽度和高度。我还需要任务栏的位置。我怎样才能得到这个?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    根据您需要该信息的目的,您可能需要查看Forms.TScreen.WorkAreaRect,因为以这种方式标识的工作区不仅减去任务栏,还减去任何其他“栏”这可能会限制可用的桌面空间。

    您可以在代码中简单地使用Screen.WorkAreaRect,因为Screen: TScreen 变量在Forms 单元中声明并由VCL 初始化。

    【讨论】:

      【解决方案2】:

      好吧,由于这个问题是关于如何获取任务栏坐标的,所以我决定发布另一个版本,说明如何通过使用 SHAppBarMessage 函数和 ABM_GETTASKBARPOS 消息参数来实现这一点。

      我发布了两个版本;一个有一个没有给定的任务栏句柄。请注意,如果您发送ABM_GETTASKBARPOS 消息,您应该在APPBARDATA 结构中指定hWnd 成员,正如ABM_GETTASKBARPOS 描述中提到的那样。所以第一个版本对于这种情况是安全的。第二个虽然有效,但形式上是错误的。

      uses ShellAPI;
      
      procedure TForm1.Button1Click(Sender: TObject);
      var
        Data: TAppBarData;
      begin
        Data.hWnd := FindWindow('Shell_TrayWnd', nil);
        Data.cbSize := SizeOf(TAppBarData);
      
        if Data.hWnd <> 0 then
          if SHAppBarMessage(ABM_GETTASKBARPOS, Data) = 1 then
            ShowMessage(
                            'Left: ' + IntToStr(Data.rc.Left) + 'px ; ' +
                            'Top: ' + IntToStr(Data.rc.Top) + 'px ; ' +
                            'Width: ' + IntToStr(Data.rc.Right - Data.rc.Left) + 'px ; ' +
                            'Height: ' + IntToStr(Data.rc.Bottom - Data.rc.Top) + 'px'
                        );
      end;
      

      请注意,此版本(未指定 TAppBarData.hWnd 成员)虽然有效,但根据 MSDN 是错误的。

      procedure TForm1.Button2Click(Sender: TObject);
      var
        Data: TAppBarData;
      begin
        Data.cbSize := SizeOf(TAppBarData);
      
        if SHAppBarMessage(ABM_GETTASKBARPOS, Data) = 1 then
          ShowMessage(
                          'Left: ' + IntToStr(Data.rc.Left) + 'px ; ' +
                          'Top: ' + IntToStr(Data.rc.Top) + 'px ; ' +
                          'Width: ' + IntToStr(Data.rc.Right - Data.rc.Left) + 'px ; ' +
                          'Height: ' + IntToStr(Data.rc.Bottom - Data.rc.Top) + 'px'
                      );
      end;
      

      【讨论】:

      • @Prund 仍然使用 findwindow 或者现在没有错? ce iti mai place sa vrb aiurea
      【解决方案3】:

      这就是我所拥有的(在 Win95 十年制造的 ;-) 并且仍在工作):

      • GetTaskBarBounds
      • GetTaskBarSize
      • GetTaskBarAlignment

      代码如下:

      const
       W95_EXPLORERCLASSNAME = 'Shell_TrayWnd';
      
      function GetTaskBarBounds : TRect;
      begin
       GetWindowRect( FindWindow( W95_EXPLORERCLASSNAME, '' ), Result );
      end;
      
      function GetTaskBarSize : TPoint;
      var
       TaskBarBounds : TRect;
      
      begin
       TaskBarBounds:=GetTaskBarBounds;
       with( TaskBarBounds ) do
        Result:=Point( Right - abs( Left ), Bottom - abs( Top ) );
      end;
      
      function GetTaskBarAlignment : TAlign;
      var
       TaskBarBounds : TRect;
      
      begin
       Result:=alNone;
      
       if( FindWindow( W95_EXPLORERCLASSNAME, '' ) > 0 ) then
        begin
         TaskBarBounds:=GetTaskBarBounds;
      
         with( TaskBarBounds ) do
          // At Left or at top of screen ?
          if( Left <= 0 ) and ( Top <= 0 ) then
           begin
            if( Bottom >= 480 ) then
             Result:=alLeft
            else Result:=alTop;
           end
          else begin
                if( Left <= 0 ) then
                 Result:=alBottom
                else Result:=alRight;
               end;
        end;
      end;
      

      【讨论】:

        【解决方案4】:

        这是获取方向的方法

        type
           TTaskBarPos = (_TOP, _BOTTOM, _LEFT, _RIGHT, _NONE);
        
        function GetTaskBarPos: TTaskBarPos;
        var
           hTaskbar: HWND;
           T: TRect;
           scrW, scrH: integer;
        begin
           hTaskBar := FindWindow('Shell_TrayWnd', nil);
           if hTaskbar <> 0 then
           begin
             GetWindowRect(hTaskBar, T);
             ScrW := Screen.Width;
             ScrH := Screen.Height;
             if (T.Top > scrH div 2) and (T.Right >= scrW) then
               Result := _BOTTOM
             else if (T.Top < scrH div 2) and (T.Bottom <= scrW div 2) then
               Result := _TOP
             else if (T.Left < scrW div 2) and (T.Top <= 0) then
               Result := _LEFT
             else 
             if T.Left >= ScrW div 2 then
               Result := _RIGHT;
           end;
        end;
        
        procedure TForm1.Button5Click(Sender: TObject);
        var
           TaskBarPos: TTaskBarPos;
        begin
           TaskBarPos := GetTaskBarPos;
           case TaskBarPos of
             _LEFT: ShowMessage('Left Position');
             _TOP: ShowMessage('Top Position');
             _RIGHT: ShowMessage('Right Position');
             _BOTTOM: ShowMessage('Bottom Position');
           end;
        end;
        

        【讨论】:

        • T 变量保存坐标。任务栏的,所以用它来获得你需要的东西;)
        • 老实说这种感觉hacky,因为它依赖于FindWindow。如果用户使用非标准任务栏,这将失败,如果有多个“栏”,则会失败,而且我不确定在具有多个监视器的系统上会发生什么。
        • @daemon_x 底线是任务栏不是用来画画的。它是系统所有的。
        • hacky 与否我看不到编码大师大卫和 prund 2 位超级英雄及时送回解决德尔福编程问题的有效解决方案。我觉得你的 cmets 很无聊,我想这个网站是关于多个用户在研究解决方案,然后有人投票选出最佳解决方案,还是我错了?
        • 某事告诉我这段代码没有正确考虑多个显示器。
        【解决方案5】:

        我从http://www.delphitips.net/2007/08/26/taskbar-position 得到了这个代码,我试过了,效果很好。即使任务栏的大小发生变化,它也能正常工作。

        代码放在下面。

        procedure TForm1.Button1Click(Sender: TObject);
        var
          hTaskbar: HWND;
          T: TRect;
          ScrW, ScrH: Integer;
        begin
          ScrW := Screen.Width;
          ScrH := Screen.Height;
          hTaskBar := FindWindow('Shell_TrayWnd', nil);
          GetWindowRect(hTaskBar, T);
          if (T.Top > ScrH div 2) and (T.Right >= ScrW) then
            ShowMessage('Bottom of the screen')
          else if (T.Top < ScrH div 2) and (T.Bottom <= ScrW div 2) then
            ShowMessage('Top of the screen')
          else if (T.left < ScrW div 2) and (T.Top <= 0) then
            ShowMessage('Left side of the screen')
          else
            ShowMessage('Right side of the screen');
        end;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-07
          • 2013-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多