2011-06-29 104 views

回答

7

那麼,因爲這個問題是如何獲得任務欄座標組成,我決定發佈另一個版本的如何通過使用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; 
+1

+1 [SHAppBarMessage](http://msdn.microsoft.com/en-us/library/bb762108(v = vs.85).aspx) –

+0

@Prund仍然使用findwindow或現在它沒有錯? ce iti mai place sa vrb aiurea – opc0de

0

這裏是你怎麼弄的方向

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; 
+0

T變量保存座標。的任務欄,所以用它來得到你所需要的;) – opc0de

+1

老實說,這個感覺'hacky',因爲它依賴於'FindWindow'。如果用戶使用非標準的任務欄,則會失敗,如果有多個「欄」,則會失敗,但我不確定在具有多個監視器的系統上會發生什麼情況。 –

+3

這是可怕的哈克。工作區域是正確的解決方案。 –

8

根據你所需要的是信息,你可能想看看Forms.TScreen.WorkAreaRect,因爲確定了這樣的工作區域減去不僅任務欄,但也可能會限制可用桌面空間的任何其他「酒吧」。

您可以簡單地在代碼中使用Screen.WorkAreaRect,因爲在Forms單元中聲明Screen: TScreen變量並由VCL初始化該變量。

+0

迄今爲止最好的回答...謝謝! –

0

我從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; 
2

這是我有什麼(在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;