--- ---

WinAMP has this very useful feature. If you drag it to the edge of the screen it will automatically position itself. Sometimes you want to make room on the screen but you don't want to minimize your program and again you want to see it in full. The only way is the put it in a corner and set it exactly to the screen border. Well, this can be quite a challenge :-)

But there's no need to panic. All we have to do is intercept when the window is being moved and adjust it as needed.

This code adjusts the window within 30 pixels.

    type
      Form1 = class(TForm)
        ...
        procedure WMExitSizeMove(var Msg: TMessage); message WM_EXITSIZEMOVE;
        ...
      end;

    procedure TForm1.WMExitSizeMove(var Msg: TMessage);
    var
      Pabd: APPBARDATA;
      iScreenWidth, iScreenHeight: Integer;
      ScreenRect, TaskBarRect: TRect;
    begin
      if Msg.Msg = WM_EXITSIZEMOVE then
      begin
        Pabd.cbSize := SizeOf(APPBARDATA);
        SHAppBarMessage(ABM_GETTASKBARPOS, Pabd);

        iScreenWidth := GetSystemMetrics(SM_CXSCREEN);
        iScreenHeight := GetSystemMetrics(SM_CYSCREEN);
        ScreenRect := Rect(0, 0, iScreenWidth, iScreenHeight);
        TaskBarRect := Pabd.rc;

        if (TaskBarRect.Left = -2) and (TaskBarRect.Bottom = iScreenHeight + 2)
          and (TaskBarRect.Right = iScreenWidth + 2) then
          ScreenRect.Bottom := TaskBarRect.Top
        else if (TaskBarRect.Top = -2) and (TaskBarRect.Left = -2)
          and (TaskBarRect.Right = iScreenWidth + 2) then
          ScreenRect.Top := TaskBarRect.Bottom
        else if (TaskBarRect.Left = -2) and (TaskBarRect.Top = -2)
          and (TaskBarRect.Bottom = iScreenHeight + 2) then
          ScreenRect.Left := TaskBarRect.Right
        else if (TaskBarRect.Right = iScreenWidth + 2) and (TaskBarRect.Top = -2)
          and (TaskBarRect.Bottom = iScreenHeight + 2) then
          ScreenRect.Right := TaskBarRect.Left;

        if Left < ScreenRect.Left + 30 then
          Left := ScreenRect.Left;
        if Top < ScreenRect.Top + 30 then
          Top := ScreenRect.Top;
        if Left + Width > ScreenRect.Right - 30 then
          Left := ScreenRect.Right - Width;
        if Top + Height > ScreenRect.Bottom - 30 then
          Top := ScreenRect.Bottom - Height;
      end;
      Msg.Result := 1;
    end;

Thanks to Thomas Jones for fixing a bug in the code that calculates which side of the screen the window should snap to.