Search code examples
delphiwinapivcl

How to set custom cursor for the form's title bar, system menu icon and minimize, maximize and close buttons?


Is there a Windows API for setting up a custom cursor for the form's title bar, system menu icon and minimize, maximize and close buttons?

I'm having a function for loading and setting cursors for a given control:

type

 TFrm_Main = class(TForm)
   ....
 private
  procedure SetCursor_For(AControl: TControl; ACursor_FileName: string;
    Const ACurIndex: Integer);
 ...
 end;
 const
   crOpenCursor = 1;
   crRotateCursor = 2;
   crCursor_Water = 3;

 var
   Frm_Main: TFrm_Main;
 ...
 procedure TFrm_Main.SetCursor_For(AControl: TControl; ACursor_FileName: 
  string; const ACurIndex: Integer);
 begin
   Screen.Cursors[ACurIndex] := Loadcursorfromfile(PWideChar(ACursor_FileName));
   AControl.Cursor := ACurIndex;
 end;

And I'm using it this way for the form:

SetCursor_For(Frm_Main, 'Cursors\Cursor_Rotate.ani', crRotateCursor);

But I'm missing a way to setup cursor for particular form parts like form title bar, system menu icon and minimize, maximize and close buttons. Is there a way to set cursor for these form parts?


Solution

  • Handle the WM_SETCURSOR message and test the message parameter's HitTest field for one of the following hit test code values, and set the cursor by using SetCursor function returning True to the message Result (Windows API macros TRUE and FALSE coincidentally match to the Delphi's Boolean type values, so you can only typecast there):

    For example:

    type
      TForm1 = class(TForm)
      private
        procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
      end;
    
    implementation
    
    procedure TForm1.WMSetCursor(var Msg: TWMSetCursor);
    begin
      case Msg.HitTest of
        HTCAPTION:
        begin
          Msg.Result := LRESULT(True);
          Winapi.Windows.SetCursor(Screen.Cursors[crHandPoint]);
        end;
        HTSYSMENU:
        begin
          Msg.Result := LRESULT(True);
          Winapi.Windows.SetCursor(Screen.Cursors[crHelp]);
        end;
        HTMINBUTTON:
        begin
          Msg.Result := LRESULT(True);
          Winapi.Windows.SetCursor(Screen.Cursors[crUpArrow]);
        end;
        HTMAXBUTTON:
        begin
          Msg.Result := LRESULT(True);
          Winapi.Windows.SetCursor(Screen.Cursors[crSizeAll]);
        end;
        HTCLOSE:
        begin
          Msg.Result := LRESULT(True);
          Winapi.Windows.SetCursor(Screen.Cursors[crNo]);
        end;
      else
        inherited;
      end;
    end;