1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/cursor.cpp 
   3 // Purpose:     wxCursor class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) 1997-2003 Julian Smart and Vadim Zeitlin 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "cursor.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  34     #include "wx/bitmap.h" 
  36     #include "wx/cursor.h" 
  37     #include "wx/settings.h" 
  41 #include "wx/module.h" 
  43 #include "wx/msw/private.h" 
  45 // define functions missing in MicroWin 
  47     static inline void DestroyCursor(HCURSOR
) { } 
  48     static inline void SetCursor(HCURSOR
) { } 
  49 #endif // __WXMICROWIN__ 
  51 // ---------------------------------------------------------------------------- 
  53 // ---------------------------------------------------------------------------- 
  55 class WXDLLEXPORT wxCursorRefData 
: public wxGDIImageRefData
 
  58     // the second parameter is used to tell us to delete the cursor when we're 
  59     // done with it (normally we shouldn't call DestroyCursor() this is why it 
  60     // doesn't happen by default) 
  61     wxCursorRefData(HCURSOR hcursor 
= 0, bool takeOwnership 
= false); 
  63     virtual ~wxCursorRefData() { Free(); } 
  68     // return the size of the standard cursor: notice that the system only 
  69     // supports the cursors of this size 
  70     static wxCoord 
GetStandardWidth(); 
  71     static wxCoord 
GetStandardHeight(); 
  76     // standard cursor size, computed on first use 
  77     static wxSize ms_sizeStd
; 
  80 // ---------------------------------------------------------------------------- 
  82 // ---------------------------------------------------------------------------- 
  84 IMPLEMENT_DYNAMIC_CLASS(wxCursor
, wxGDIObject
) 
  86 // ---------------------------------------------------------------------------- 
  88 // ---------------------------------------------------------------------------- 
  90 // Current cursor, in order to hang on to cursor handle when setting the cursor 
  92 static wxCursor 
*gs_globalCursor 
= NULL
; 
  94 // ---------------------------------------------------------------------------- 
  96 // ---------------------------------------------------------------------------- 
  98 class wxCursorModule 
: public wxModule
 
 101     virtual bool OnInit() 
 103         gs_globalCursor 
= new wxCursor
; 
 108     virtual void OnExit() 
 110         delete gs_globalCursor
; 
 111         gs_globalCursor 
= (wxCursor 
*)NULL
; 
 115 // ============================================================================ 
 117 // ============================================================================ 
 119 // ---------------------------------------------------------------------------- 
 121 // ---------------------------------------------------------------------------- 
 123 wxSize 
wxCursorRefData::ms_sizeStd
; 
 125 wxCoord 
wxCursorRefData::GetStandardWidth() 
 128         ms_sizeStd
.x 
= wxSystemSettings::GetMetric(wxSYS_CURSOR_X
); 
 133 wxCoord 
wxCursorRefData::GetStandardHeight() 
 136         ms_sizeStd
.y 
= wxSystemSettings::GetMetric(wxSYS_CURSOR_Y
); 
 141 wxCursorRefData::wxCursorRefData(HCURSOR hcursor
, bool destroy
) 
 143     m_hCursor 
= (WXHCURSOR
)hcursor
; 
 147         m_width 
= GetStandardWidth(); 
 148         m_height 
= GetStandardHeight(); 
 151     m_destroyCursor 
= destroy
; 
 154 void wxCursorRefData::Free() 
 159         if ( m_destroyCursor 
) 
 160             ::DestroyCursor((HCURSOR
)m_hCursor
); 
 167 // ---------------------------------------------------------------------------- 
 169 // ---------------------------------------------------------------------------- 
 175 wxCursor::wxCursor(const wxImage
& image
) 
 177     // image has to be of the standard cursor size, otherwise we won't be able 
 179     const int w 
= wxCursorRefData::GetStandardWidth(); 
 180     const int h 
= wxCursorRefData::GetStandardHeight(); 
 182     const int hotSpotX 
= image
.GetOptionInt(wxCUR_HOTSPOT_X
); 
 183     const int hotSpotY 
= image
.GetOptionInt(wxCUR_HOTSPOT_Y
); 
 185     wxASSERT_MSG( hotSpotX 
>= 0 && hotSpotX 
< w 
&& 
 186                     hotSpotY 
>= 0 && hotSpotY 
< h
, 
 187                   _T("invalid cursor hot spot coordinates") ); 
 189     HCURSOR hcursor 
= wxBitmapToHCURSOR
 
 191                         wxBitmap(image
.Scale(w
, h
)), 
 197         wxLogWarning(_("Failed to create cursor.")); 
 201     m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 204 wxCursor::wxCursor(const char WXUNUSED(bits
)[], 
 206                    int WXUNUSED(height
), 
 207                    int WXUNUSED(hotSpotX
), int WXUNUSED(hotSpotY
), 
 208                    const char WXUNUSED(maskBits
)[]) 
 212 // MicroWin doesn't have support needed for the other ctors 
 213 #ifdef __WXMICROWIN__ 
 215 wxCursor::wxCursor(const wxString
& WXUNUSED(filename
), 
 217                    int WXUNUSED(hotSpotX
), 
 218                    int WXUNUSED(hotSpotY
)) 
 222 wxCursor::wxCursor(int WXUNUSED(cursor_type
)) 
 226 #else // !__WXMICROWIN__ 
 228 wxCursor::wxCursor(const wxString
& filename
, 
 236         case wxBITMAP_TYPE_CUR_RESOURCE
: 
 237             hcursor 
= ::LoadCursor(wxGetInstance(), filename
); 
 241         case wxBITMAP_TYPE_CUR
: 
 242             hcursor 
= ::LoadCursorFromFile(filename
); 
 246         case wxBITMAP_TYPE_ICO
: 
 247             hcursor 
= wxBitmapToHCURSOR
 
 249                        wxIcon(filename
, wxBITMAP_TYPE_ICO
), 
 255         case wxBITMAP_TYPE_BMP
: 
 256             hcursor 
= wxBitmapToHCURSOR
 
 258                        wxBitmap(filename
, wxBITMAP_TYPE_BMP
), 
 265             wxFAIL_MSG( _T("unknown cursor resource type") ); 
 272         m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 276 // Cursors by stock number 
 277 wxCursor::wxCursor(int idCursor
) 
 279     // all wxWindows standard cursors 
 280     static const struct StdCursor
 
 282         // is this a standard Windows cursor? 
 285         // the cursor name or id 
 289         {  true, NULL                        
}, // wxCURSOR_NONE 
 290         {  true, IDC_ARROW                   
}, // wxCURSOR_ARROW 
 291         { false, _T("wxCURSOR_RIGHT_ARROW")  }, // wxCURSOR_RIGHT_ARROW 
 292         { false, _T("wxCURSOR_BULLSEYE")     }, // wxCURSOR_BULLSEYE 
 293         {  true, IDC_ARROW                   
}, // wxCURSOR_CHAR 
 294         {  true, IDC_CROSS                   
}, // wxCURSOR_CROSS 
 295         { false, _T("wxCURSOR_HAND")         }, // wxCURSOR_HAND 
 296         {  true, IDC_IBEAM                   
}, // wxCURSOR_IBEAM 
 297         {  true, IDC_ARROW                   
}, // wxCURSOR_LEFT_BUTTON 
 298         { false, _T("wxCURSOR_MAGNIFIER")    }, // wxCURSOR_MAGNIFIER 
 299         {  true, IDC_ARROW                   
}, // wxCURSOR_MIDDLE_BUTTON 
 300         {  true, IDC_NO                      
}, // wxCURSOR_NO_ENTRY 
 301         { false, _T("wxCURSOR_PAINT_BRUSH")  }, // wxCURSOR_PAINT_BRUSH 
 302         { false, _T("wxCURSOR_PENCIL")       }, // wxCURSOR_PENCIL 
 303         { false, _T("wxCURSOR_POINT_LEFT")   }, // wxCURSOR_POINT_LEFT 
 304         { false, _T("wxCURSOR_POINT_RIGHT")  }, // wxCURSOR_POINT_RIGHT 
 305         {  true, IDC_HELP                    
}, // wxCURSOR_QUESTION_ARROW 
 306         {  true, IDC_ARROW                   
}, // wxCURSOR_RIGHT_BUTTON 
 307         {  true, IDC_SIZENESW                
}, // wxCURSOR_SIZENESW 
 308         {  true, IDC_SIZENS                  
}, // wxCURSOR_SIZENS 
 309         {  true, IDC_SIZENWSE                
}, // wxCURSOR_SIZENWSE 
 310         {  true, IDC_SIZEWE                  
}, // wxCURSOR_SIZEWE 
 311         {  true, IDC_SIZEALL                 
}, // wxCURSOR_SIZING 
 312         { false, _T("wxCURSOR_SPRAYCAN")     }, // wxCURSOR_SPRAYCAN 
 313         {  true, IDC_WAIT                    
}, // wxCURSOR_WAIT 
 314         {  true, IDC_WAIT                    
}, // wxCURSOR_WATCH 
 315         { false, _T("wxCURSOR_BLANK")        }, // wxCURSOR_BLANK 
 316         {  true, IDC_APPSTARTING             
}, // wxCURSOR_ARROWWAIT 
 318         // no entry for wxCURSOR_MAX 
 321     wxCOMPILE_TIME_ASSERT( WXSIZEOF(stdCursors
) == wxCURSOR_MAX
, 
 322                            CursorsIdArrayMismatch 
); 
 324     wxCHECK_RET( idCursor 
> 0 && (size_t)idCursor 
< WXSIZEOF(stdCursors
), 
 325                  _T("invalid cursor id in wxCursor() ctor") ); 
 327     const StdCursor
& stdCursor 
= stdCursors
[idCursor
]; 
 329     HCURSOR hcursor 
= ::LoadCursor(stdCursor
.isStd 
? NULL 
: wxGetInstance(), 
 334         wxLogLastError(_T("LoadCursor")); 
 338         m_refData 
= new wxCursorRefData(hcursor
); 
 342 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 344 wxCursor::~wxCursor() 
 348 // ---------------------------------------------------------------------------- 
 349 // other wxCursor functions 
 350 // ---------------------------------------------------------------------------- 
 352 bool wxCursor::operator==(const wxCursor
& cursor
) const 
 355         return !cursor
.m_refData
; 
 357     return cursor
.m_refData 
&& 
 358                 ((wxCursorRefData 
*)m_refData
)->m_hCursor 
== 
 359                 ((wxCursorRefData 
*)cursor
.m_refData
)->m_hCursor
; 
 362 wxGDIImageRefData 
*wxCursor::CreateData() const 
 364     return new wxCursorRefData
; 
 367 // ---------------------------------------------------------------------------- 
 368 // Global cursor setting 
 369 // ---------------------------------------------------------------------------- 
 371 const wxCursor 
*wxGetGlobalCursor() 
 373     return gs_globalCursor
; 
 376 void wxSetCursor(const wxCursor
& cursor
) 
 380         ::SetCursor(GetHcursorOf(cursor
)); 
 382         if ( gs_globalCursor 
) 
 383             *gs_globalCursor 
= cursor
;