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 // ---------------------------------------------------------------------------- 
 176 wxCursor::wxCursor(const wxImage
& image
) 
 178     // image has to be of the standard cursor size, otherwise we won't be able 
 180     const int w 
= wxCursorRefData::GetStandardWidth(); 
 181     const int h 
= wxCursorRefData::GetStandardHeight(); 
 183     const int hotSpotX 
= image
.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X
); 
 184     const int hotSpotY 
= image
.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y
); 
 186     wxASSERT_MSG( hotSpotX 
>= 0 && hotSpotX 
< w 
&& 
 187                     hotSpotY 
>= 0 && hotSpotY 
< h
, 
 188                   _T("invalid cursor hot spot coordinates") ); 
 190     HCURSOR hcursor 
= wxBitmapToHCURSOR
 
 192                         wxBitmap(image
.Scale(w
, h
)), 
 198         wxLogWarning(_("Failed to create cursor.")); 
 202     m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 206 wxCursor::wxCursor(const char WXUNUSED(bits
)[], 
 208                    int WXUNUSED(height
), 
 209                    int WXUNUSED(hotSpotX
), int WXUNUSED(hotSpotY
), 
 210                    const char WXUNUSED(maskBits
)[]) 
 214 // MicroWin doesn't have support needed for the other ctors 
 215 #ifdef __WXMICROWIN__ 
 217 wxCursor::wxCursor(const wxString
& WXUNUSED(filename
), 
 219                    int WXUNUSED(hotSpotX
), 
 220                    int WXUNUSED(hotSpotY
)) 
 224 wxCursor::wxCursor(int WXUNUSED(cursor_type
)) 
 228 #else // !__WXMICROWIN__ 
 230 wxCursor::wxCursor(const wxString
& filename
, 
 238         case wxBITMAP_TYPE_CUR_RESOURCE
: 
 239             hcursor 
= ::LoadCursor(wxGetInstance(), filename
); 
 243         case wxBITMAP_TYPE_CUR
: 
 244             hcursor 
= ::LoadCursorFromFile(filename
); 
 248         case wxBITMAP_TYPE_ICO
: 
 249             hcursor 
= wxBitmapToHCURSOR
 
 251                        wxIcon(filename
, wxBITMAP_TYPE_ICO
), 
 257         case wxBITMAP_TYPE_BMP
: 
 258             hcursor 
= wxBitmapToHCURSOR
 
 260                        wxBitmap(filename
, wxBITMAP_TYPE_BMP
), 
 267             wxFAIL_MSG( _T("unknown cursor resource type") ); 
 274         m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 278 // Cursors by stock number 
 279 wxCursor::wxCursor(int idCursor
) 
 281     // all wxWidgets standard cursors 
 282     static const struct StdCursor
 
 284         // is this a standard Windows cursor? 
 287         // the cursor name or id 
 291         {  true, NULL                        
}, // wxCURSOR_NONE 
 292         {  true, IDC_ARROW                   
}, // wxCURSOR_ARROW 
 293         { false, _T("WXCURSOR_RIGHT_ARROW")  }, // wxCURSOR_RIGHT_ARROW 
 294         { false, _T("WXCURSOR_BULLSEYE")     }, // wxCURSOR_BULLSEYE 
 295         {  true, IDC_ARROW                   
}, // WXCURSOR_CHAR 
 296         {  true, IDC_CROSS                   
}, // WXCURSOR_CROSS 
 297         { false, _T("WXCURSOR_HAND")         }, // wxCURSOR_HAND 
 298         {  true, IDC_IBEAM                   
}, // WXCURSOR_IBEAM 
 299         {  true, IDC_ARROW                   
}, // WXCURSOR_LEFT_BUTTON 
 300         { false, _T("WXCURSOR_MAGNIFIER")    }, // wxCURSOR_MAGNIFIER 
 301         {  true, IDC_ARROW                   
}, // WXCURSOR_MIDDLE_BUTTON 
 302         {  true, IDC_NO                      
}, // WXCURSOR_NO_ENTRY 
 303         { false, _T("WXCURSOR_PBRUSH")       }, // wxCURSOR_PAINT_BRUSH 
 304         { false, _T("WXCURSOR_PENCIL")       }, // wxCURSOR_PENCIL 
 305         { false, _T("WXCURSOR_PLEFT")        }, // wxCURSOR_POINT_LEFT 
 306         { false, _T("WXCURSOR_PRIGHT")       }, // wxCURSOR_POINT_RIGHT 
 307         {  true, IDC_HELP                    
}, // WXCURSOR_QUESTION_ARROW 
 308         {  true, IDC_ARROW                   
}, // WXCURSOR_RIGHT_BUTTON 
 309         {  true, IDC_SIZENESW                
}, // WXCURSOR_SIZENESW 
 310         {  true, IDC_SIZENS                  
}, // WXCURSOR_SIZENS 
 311         {  true, IDC_SIZENWSE                
}, // WXCURSOR_SIZENWSE 
 312         {  true, IDC_SIZEWE                  
}, // WXCURSOR_SIZEWE 
 313         {  true, IDC_SIZEALL                 
}, // WXCURSOR_SIZING 
 314         { false, _T("WXCURSOR_PBRUSH")       }, // wxCURSOR_SPRAYCAN 
 315         {  true, IDC_WAIT                    
}, // WXCURSOR_WAIT 
 316         { false, _T("WXCURSOR_WATCH")        }, // WXCURSOR_WATCH 
 317         { false, _T("WXCURSOR_BLANK")        }, // wxCURSOR_BLANK 
 318         {  true, IDC_APPSTARTING             
}, // wxCURSOR_ARROWWAIT 
 320         // no entry for wxCURSOR_MAX 
 323     wxCOMPILE_TIME_ASSERT( WXSIZEOF(stdCursors
) == wxCURSOR_MAX
, 
 324                            CursorsIdArrayMismatch 
); 
 326     wxCHECK_RET( idCursor 
> 0 && (size_t)idCursor 
< WXSIZEOF(stdCursors
), 
 327                  _T("invalid cursor id in wxCursor() ctor") ); 
 329     const StdCursor
& stdCursor 
= stdCursors
[idCursor
]; 
 331     HCURSOR hcursor 
= ::LoadCursor(stdCursor
.isStd 
? NULL 
: wxGetInstance(), 
 336         wxLogLastError(_T("LoadCursor")); 
 340         m_refData 
= new wxCursorRefData(hcursor
); 
 344 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 346 wxCursor::~wxCursor() 
 350 // ---------------------------------------------------------------------------- 
 351 // other wxCursor functions 
 352 // ---------------------------------------------------------------------------- 
 354 bool wxCursor::operator==(const wxCursor
& cursor
) const 
 357         return !cursor
.m_refData
; 
 359     return cursor
.m_refData 
&& 
 360                 ((wxCursorRefData 
*)m_refData
)->m_hCursor 
== 
 361                 ((wxCursorRefData 
*)cursor
.m_refData
)->m_hCursor
; 
 364 wxGDIImageRefData 
*wxCursor::CreateData() const 
 366     return new wxCursorRefData
; 
 369 // ---------------------------------------------------------------------------- 
 370 // Global cursor setting 
 371 // ---------------------------------------------------------------------------- 
 373 const wxCursor 
*wxGetGlobalCursor() 
 375     return gs_globalCursor
; 
 378 void wxSetCursor(const wxCursor
& cursor
) 
 382         ::SetCursor(GetHcursorOf(cursor
)); 
 384         if ( gs_globalCursor 
) 
 385             *gs_globalCursor 
= cursor
;