Dokowanie formularza na ekranie

0

Witam

Nie wiem, jak zaprogramować formularz (okno) tak, żeby po "przyssaniu się" do brzegu ekranu redukował obszar roboczy pulpitu, tak jak to robi główne okno Lupy Microsoft (można przyssać do dowolnej krawędzi i o szerokość okna zmniejsza się przestrzeń systemu Windows) lub Pasek Skrótów Office (standardowo z prawej strony). Podobno w ten sam sposób będzie funkcjonowało okno paska SideBar w Windows Vista (dawniej Longhorn).Zmaksymalizowane okna nie chowają się za formularz lub nie zasłaniają go, wykorzystują tylko wolną przestrzeń, która jest tym formularzem ograniczona.
Na moje potrzeby wystarczył aby moj porgram był tylko na gorze ekranu, nie musi byc <ort>przesowany </ort>na booki ekranu.

Jak to zrobić?

0
unit untAppBar;

interface

uses
  ShellAPI,
  Forms,
  Types,
  Windows,
  Messages;

const
  APPBAR_CALLBACK = WM_USER + 6438;

type
  TAppBar = class
  private
    FAppBarData: TAppBarData;
    FEdge:       UINT;
    FRect:       TRect;
    FAppForm:    TForm;
    FRegistered: Boolean;
    procedure AppBarRegister;
    procedure AppBarSetPos;
    procedure AppBarPosChanged;
  public
    constructor Create(AForm: TForm);
    destructor Destroy; override;

    procedure RegisterAppBar(uEdge: UINT);
    procedure AppBarCallback(hwndAccessBar: HWND; uNotifyMsg: UINT; lParam: 
      LPARAM);
  end;

implementation

{ TAppBar }

procedure TAppBar.AppBarCallback(hwndAccessBar: HWND; uNotifyMsg: UINT; lParam: LPARAM);
begin
  FAppBarData.hWnd := hwndAccessBar;
  case uNotifyMsg of
    {ABN_STATECHANGE:
    begin
      uState := SHAppBarMessage(ABM_GETSTATE, FAppBarData);

      SetWindowPos(hwndAccessBar,
        (ABS_ALWAYSONTOP and uState) or HWND_TOPMOST or HWND_BOTTOM,
        0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
    end;
    ABN_FULLSCREENAPP:
    begin
      if lParam > 0 then
        SetWindowPos(hwndAccessBar,
          (ABS_ALWAYSONTOP and uState) or HWND_TOPMOST or HWND_BOTTOM,
          0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)
      else
      begin
        uState := SHAppBarMessage(ABM_GETSTATE, abd);
        if (uState <> 0 and ABS_ALWAYSONTOP) then
          SetWindowPos(hwndAccessBar, HWND_TOPMOST,
            0, 0, 0, 0,
            SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
      end;
    end;     }
    ABN_POSCHANGED:
      AppBarPosChanged;
  end;
end;

procedure TAppBar.AppBarPosChanged;
var
  AppBArWidth, AppBarHeight: integer;
begin
  with FAppBarData do
  begin
    GetWindowRect(hWnd, FRect);
    AppBarWidth := rc.Right - rc.Left;
    AppBarHeight := rc.Bottom - rc.Top;

    FRect.Top := 0;
    FRect.Left := 0;
    FRect.Right := GetSystemMetrics(SM_CXSCREEN);
    FRect.Bottom := GetSystemMetrics(SM_CYSCREEN);

    case FEdge of
      ABE_LEFT: rc.Right := rc.Left + AppBarWidth;
      ABE_RIGHT: rc.Left := rc.Right - AppBarWidth;
      ABE_TOP: rc.Bottom := rc.Top + AppBarHeight;
      ABE_BOTTOM: rc.Top := rc.Bottom - AppBarHeight;
    end;

    AppBarSetPos;
  end;
end;

procedure TAppBar.AppBarRegister;
begin
  SHAppBarMessage(ABM_NEW, FAppBarData);
  FRegistered := True;
  AppBarSetPos;
end;

procedure TAppBar.AppBarSetPos;
var
  AppBArWidth, AppBarHeight: integer;
begin
  with FAppBarData do
  begin
    AppBArWidth  := 0;
    AppBarHeight := 0;

    rc.Top := 0;
    rc.Left := 0;
    rc.Right := GetSystemMetrics(SM_CXSCREEN);
    rc.Bottom := GetSystemMetrics(SM_CYSCREEN);

    uEdge := FEdge;

    if FEdge in [ABE_LEFT, ABE_RIGHT] then
    begin
      AppBarWidth := FRect.Right - FRect.Left;
      rc.Top := 0;
      rc.Bottom := GetSystemMetrics(SM_CYSCREEN);
    end
    else
    begin
      AppBarHeight := FRect.Bottom - FRect.Top;
      rc.Left  := 0;
      rc.Right := GetSystemMetrics(SM_CXSCREEN);
    end;

    SHAppBarMessage(ABM_QUERYPOS, FAppBarData);

    case FEdge of
      ABE_LEFT: rc.Right := rc.Left + AppBarWidth;
      ABE_RIGHT: rc.Left := rc.Right - AppBarWidth;
      ABE_TOP: rc.Bottom := rc.Top + AppBarHeight;
      ABE_BOTTOM: rc.Top := rc.Bottom - AppBarHeight;
    end;

    SHAppBarMessage(ABM_SETPOS, FAppBarData);

    MoveWindow(hWnd, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, True);

    FAppForm.BoundsRect := rc;
  end;
end;

constructor TAppBar.Create(AForm: TForm);
begin
  FAppForm := AForm;
  FRect := AForm.BoundsRect;
  FAppBarData.cbSize := SizeOf(APPBARDATA);
  FAppBarData.hWnd := FAppForm.Handle;
  FAppBarData.uCallbackMessage := APPBAR_CALLBACK;
  FRegistered := False;
end;

destructor TAppBar.Destroy;
begin
  if FRegistered then
    SHAppBarMessage(ABM_REMOVE, FAppBarData);
  inherited;
end;

procedure TAppBar.RegisterAppBar(uEdge: UINT);
begin
  FEdge := uEdge;
  AppBarRegister;
end;

end.

użycie:

var
  FAppBar: TAppBar;

//w oncreate formy
FAppBar := TAppBar.Create(Self);
FAppBar.RegisterAppBar(ABE_BOTTOM); //z której strony ma być

//WAŻNE w ondestroy
FAppBar.Free;
0

niby wszystko ok, kompiluje sie ladnie, odcina mi ekran, tylko forma nie pojawia sie tam tylko ukada sie pod spodem jak reszta aplikacji, czym to moze byc spowodowane??, moze wersja systemu, ja mam XP SP2

0

Znalazłem takie coś, tylko ze to przykład w C#

http://cms.technalab.com/?p=3

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1