FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour cursor type change
Posts: 1392
Joined: Mon May 14, 2007 09:49 AM
cursor type change
Posted: Mon Dec 01, 2025 08:21 AM

Hi,

How to make the cursor type change (cursorhand, cursorarray, etc.) when hovering the mouse cursor over different xBrowse columns?

Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM
Re: cursor type change
Posted: Mon Dec 01, 2025 08:31 AM

Dear Yuri,

To change the cursor type when hovering over different xBrowse columns, you need to use the browse's bMMoved codeblock to detect which column the mouse is over and then call the appropriate cursor function.

Solution

Use the browse's bMMoved codeblock to intercept mouse movement and change the cursor based on the column position:

Code (foxpro): Select all Collapse
oBrw:bMMoved := { |nRow, nCol, nFlags, oBrw| ;
   ColumnCursorChange( nRow, nCol, oBrw ) }

Then implement a function that determines which column is under the mouse and sets the appropriate cursor:

Code (foxpro): Select all Collapse
FUNCTION ColumnCursorChange( nRow, nCol, oBrw )
   LOCAL oCol, nColPos
   
   nColPos := oBrw:MouseColPos( nCol )
   
   IF nColPos > 0
      oCol := oBrw:ColAtPos( nColPos )
      
      // Change cursor based on column
      DO CASE
         CASE oCol:cHeader == "Name"
            CursorHand()
         CASE oCol:cHeader == "Amount"  
            CursorArrow()
         OTHERWISE
            CursorArrow()
      ENDCASE
   ENDIF
   
RETURN NIL

Key References

The base TWindow class shows the pattern for cursor handling using oCursor property or within mouse movement: 0-cite-0

The TXBrowse::MouseMove() method already implements cursor changes for column resizing (CursorWE) and normal areas (CursorArrow): 0-cite-1

Available cursor functions are defined in the TCursor class, supporting predefined types like "ARROW", "HAND", "WAIT", etc.: 0-cite-2

Notes

  • The MouseColPos() method returns the column position at the given mouse coordinates
  • The ColAtPos() method returns the column object at a specific display position
  • You can identify columns by their cHeader property, creation order, or other attributes
  • Standard cursor functions available include: CursorArrow(), CursorHand(), CursorWE(), CursorNS(), CursorIBeam(), CursorWait(), etc.
  • The bMMoved codeblock receives parameters: nRow, nCol, nFlags, and the browse object itself
  • Make sure your cursor changes don't interfere with xBrowse's built-in cursor handling for column resizing operations

Citations

File: source/classes/window.prg (L3417-3444)

Code (text): Select all Collapse
METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TWindow

   if ::oCursor != nil
      SetCursor( ::oCursor:hCursor )
   else
      CursorArrow()
   endif

   ::SetMsg( ::cMsg )

   ::CheckToolTip( nRow, nCol )

   if ::OnMouseMove != nil
      if ValType( ::OnMouseMove ) == "B"
         Eval( ::OnMouseMove, Self, nRow, nCol, nKeyFlags )
      endif
      if ValType( ::OnMouseMove ) == "C"
         OSend( Self, ::OnMouseMove, Self, nRow, nCol, nKeyFlags )
      endif
   endif

   if ::bMMoved != nil
      return Eval( ::bMMoved, nRow, nCol, nKeyFlags )
   endif

   TrackMouseEvent( ::hWnd, TME_LEAVE )

return 0

File: source/classes/xbrowse.prg (L5319-5335)

Code (text): Select all Collapse
   nLen := ::LastDisplayPos()

   for nFor := 1 to nLen
      oCol := ::ColAtPos( nFor )
      if oCol:lAllowSizing .and. ;
         nCol >= ( oCol:nDisplayCol + oCol:nWidth - 1 ) .and. ;
         nCol <= ( oCol:nDisplayCol + oCol:nWidth + 1 ) .and. ;
         ( ::nColDividerStyle > 0 .or. nRow < ::HeaderHeight() )
         CursorWE()
         return 0
      endif
   next

   nFor  := ::MouseColPos( nCol )
   if nFor > 0 .and. nFor <= nLen
      // Column visible in window
      CursorArrow()

File: source/classes/cursor.prg (L54-114)

Code (text): Select all Collapse
METHOD SetSource( cSource, cPredef ) CLASS TCursor

   local nAt, aTypes, cExt
   local hCursor, lPreDef := .f.

   if !Empty( cSource ) .and. Upper( Left( cSource, 7 ) ) == "PREDEF:"
      cPredef  := Upper( AllTrim( SubStr( cSource, 8 ) ) )
      cSource  := ""
   endif

   DEFAULT cSource := ""

   if ! Empty( cPredef )
      cPredef := Upper( cPredef )
      if ( nAt := AScan( { "ARROW", "IBEAM", "WAIT",;
                           "CROSS", "UPARROW", "SIZE",;
                           "ICON", "SIZENWSE", "SIZENESW",;
                           "SIZEWE", "SIZENS" }, cPredef ) ) != 0
         aTypes = { IDC_ARROW, IDC_IBEAM, IDC_WAIT,;
                    IDC_CROSS, IDC_UPARROW, IDC_SIZE,;
                    IDC_ICON, IDC_SIZENWSE, IDC_SIZENESW,;
                    IDC_SIZEWE, IDC_SIZENS }
         hCursor = LoadCursor( 0, aTypes[ nAt ] )

         lPredef = .T.
      else
         if cPredef == "HAND"
            hCursor = GetCursorHand()

         elseif cPredef == "STOP"
            hCursor = GetCursorStop()

         elseif cPredef == "DRAG"
            hCursor = GetCursorDrag()

         elseif cPredef == "SEARCH"
            hCursor = GetCursorSearch()

         else
            MsgAlert( FWString( "Wrong predefined cursor type!" ) )
         endif
      endif
      if !Empty( hCursor )
         cSource  := "PREDEF:" + cPreDef
      endif
   elseif ( ( cExt := Lower( cFileEXt( cSource ) ) ) == "cur" .or. cExt == "ico" ) .and. ;
            File( cSource )
      hCursor = LoadCursorFromFile( cSource )
   elseif !Empty( cSource )
      hCursor = LoadCursor( GetResources(), cSource )
   endif

   if !Empty( hCursor )
      ::End()
      ::hCursor   := hCursor
      ::lPreDef   := lPreDef
      ::protSource:= cSource
   endif

return !Empty( hCursor )
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 1392
Joined: Mon May 14, 2007 09:49 AM
Re: cursor type change
Posted: Mon Dec 01, 2025 09:28 AM

Thanks !!

Continue the discussion