Finding the Windows task bar using the SHAppBarMessage API call

By: Corbin Dunn

Abstract: How to find what side of the screen that the task bar is located at

Finding the Windows task bar
By Corbin Dunn
Delphi Developer Support

You may have come across a need to find the Windows task bar. This can be a simple task with Delphi. The Windows API call SHAppBarMessage allows you to get information about the task bar (also called the app bar by some). Visit here on the MSDN to find out more information about what you can do with this call. This document concentrates on passing it a message of ABM_GETTASKBARPOS.

If you would like to follow along, you can create a new Application, or you can download the complete source from Borland's CodeCentral.

The first thing you may be wondering is what unit the API call is in. On the MSDN one can find out that it is declared in shellapi.h. In Delphi, it is in ShellApi.pas, so add ShellApi to your uses list. We can then code up a simple function that finds its position and bounding rectangle:

// FindTaskBar returns the Task Bar's position, and fills in
// ARect with the current bounding rectangle.
function FindTaskBar(var ARect: TRect): Integer;
var
	AppData: TAppBarData;
begin
  // 'Shell_TrayWnd' is the name of the task bar's window
  AppData.Hwnd := FindWindow('Shell_TrayWnd', nil);
  if AppData.Hwnd = 0 then
    RaiseLastWin32Error;
  AppData.cbSize := SizeOf(TAppBarData);
  // SHAppBarMessage will return False (0) when an error
  // happens.
  if SHAppBarMessage(ABM_GETTASKBARPOS, AppData) = 0 then
    raise Exception.Create('SHAppBarMessage returned false when trying ' +
      'to find the Task Bar''s position');
  // Otherwise, we had success, so fill in the results.
  Result := AppData.uEdge;
  ARect := AppData.rc;
end;

Once you have added this code to your application, you can use the function. Add a TLabel and a TButton to your form. Then, in the button click, add the following code:

procedure TForm1.Button1Click(Sender: TObject);
var
  Rect: TRect;
  DestLeft: Integer;
  DestTop: Integer;
begin
  DestLeft := Left;
  DestTop := Top;
  case FindTaskBar(Rect) of
    ABE_BOTTOM:
    begin
      DestLeft := Trunc((Screen.Width - Width) / 2.0);
      DestTop := Rect.Top - Height;
    end;
    ABE_LEFT:
    begin
      DestTop := Trunc((Screen.Height - Height) / 2.0);
      DestLeft := Rect.Right;
    end;
    ABE_RIGHT:
    begin
      DestTop := Trunc((Screen.Height - Height) / 2.0);
      DestLeft := Rect.Left - Width;
    end;
    ABE_TOP:
    begin
      DestLeft := Trunc((Screen.Width - Width) / 2.0);
      DestTop := Rect.Bottom;
    end;
  end;
  Label1.Caption := Format('Found at Top: %d Left: %d Bottom: %d Right: %d)',
    [Rect.Top, Rect.Left, Rect.Bottom, Rect.Right]);
  // Move us to the task bar
  while (Left <> DestLeft) or (Top <> DestTop) do
  begin
    if Left < DestLeft then
      Left := Left + 1
    else if Left <> DestLeft then
      Left := Left - 1;

    if Top < DestTop then
      Top := Top + 1
    else if Top <> DestTop then
      Top := Top - 1;

    Application.ProcessMessages;
  end;
end;

That's it! You should now be able to find the task bars current position.

Download the complete source from Borland's CodeCentral.



Server Response from: ETNASC04