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 // ---------------------------------------------------------------------------- 
  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" 
  40 #include "wx/module.h" 
  42 #include "wx/msw/private.h" 
  44 // define functions missing in MicroWin 
  46     static inline void DestroyCursor(HCURSOR
) { } 
  47     static inline void SetCursor(HCURSOR
) { } 
  48 #endif // __WXMICROWIN__ 
  50 // ---------------------------------------------------------------------------- 
  52 // ---------------------------------------------------------------------------- 
  54 class WXDLLEXPORT wxCursorRefData 
: public wxGDIImageRefData
 
  57     // the second parameter is used to tell us to delete the cursor when we're 
  58     // done with it (normally we shouldn't call DestroyCursor() this is why it 
  59     // doesn't happen by default) 
  60     wxCursorRefData(HCURSOR hcursor 
= 0, bool takeOwnership 
= false); 
  62     virtual ~wxCursorRefData() { Free(); } 
  67     // return the size of the standard cursor: notice that the system only 
  68     // supports the cursors of this size 
  69     static wxCoord 
GetStandardWidth(); 
  70     static wxCoord 
GetStandardHeight(); 
  75     // standard cursor size, computed on first use 
  76     static wxSize ms_sizeStd
; 
  79 // ---------------------------------------------------------------------------- 
  81 // ---------------------------------------------------------------------------- 
  83 IMPLEMENT_DYNAMIC_CLASS(wxCursor
, wxGDIObject
) 
  85 // ---------------------------------------------------------------------------- 
  87 // ---------------------------------------------------------------------------- 
  89 // Current cursor, in order to hang on to cursor handle when setting the cursor 
  91 static wxCursor 
*gs_globalCursor 
= NULL
; 
  93 // ---------------------------------------------------------------------------- 
  95 // ---------------------------------------------------------------------------- 
  97 class wxCursorModule 
: public wxModule
 
 100     virtual bool OnInit() 
 102         gs_globalCursor 
= new wxCursor
; 
 107     virtual void OnExit() 
 109         delete gs_globalCursor
; 
 110         gs_globalCursor 
= (wxCursor 
*)NULL
; 
 114 // ============================================================================ 
 116 // ============================================================================ 
 118 // ---------------------------------------------------------------------------- 
 120 // ---------------------------------------------------------------------------- 
 122 wxSize 
wxCursorRefData::ms_sizeStd
; 
 124 wxCoord 
wxCursorRefData::GetStandardWidth() 
 127         ms_sizeStd
.x 
= wxSystemSettings::GetMetric(wxSYS_CURSOR_X
); 
 132 wxCoord 
wxCursorRefData::GetStandardHeight() 
 135         ms_sizeStd
.y 
= wxSystemSettings::GetMetric(wxSYS_CURSOR_Y
); 
 140 wxCursorRefData::wxCursorRefData(HCURSOR hcursor
, bool destroy
) 
 142     m_hCursor 
= (WXHCURSOR
)hcursor
; 
 146         m_width 
= GetStandardWidth(); 
 147         m_height 
= GetStandardHeight(); 
 150     m_destroyCursor 
= destroy
; 
 153 void wxCursorRefData::Free() 
 157         if ( m_destroyCursor 
) 
 158             ::DestroyCursor((HCURSOR
)m_hCursor
); 
 164 // ---------------------------------------------------------------------------- 
 166 // ---------------------------------------------------------------------------- 
 172 wxCursor::wxCursor(const wxImage
& image
) 
 174     // image has to be of the standard cursor size, otherwise we won't be able 
 176     const int w 
= wxCursorRefData::GetStandardWidth(); 
 177     const int h 
= wxCursorRefData::GetStandardHeight(); 
 179     const int hotSpotX 
= image
.GetOptionInt(wxCUR_HOTSPOT_X
); 
 180     const int hotSpotY 
= image
.GetOptionInt(wxCUR_HOTSPOT_Y
); 
 182     wxASSERT_MSG( hotSpotX 
>= 0 && hotSpotX 
< w 
&& 
 183                     hotSpotY 
>= 0 && hotSpotY 
< h
, 
 184                   _T("invalid cursor hot spot coordinates") ); 
 186     HCURSOR hcursor 
= wxBitmapToHCURSOR
 
 188                         wxBitmap(image
.Scale(w
, h
)), 
 194         wxLogWarning(_("Failed to create cursor.")); 
 198     m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 201 wxCursor::wxCursor(const char WXUNUSED(bits
)[], 
 203                    int WXUNUSED(height
), 
 204                    int WXUNUSED(hotSpotX
), int WXUNUSED(hotSpotY
), 
 205                    const char WXUNUSED(maskBits
)[]) 
 209 // MicroWin doesn't have support needed for the other ctors 
 210 #ifdef __WXMICROWIN__ 
 212 wxCursor::wxCursor(const wxString
& WXUNUSED(filename
), 
 214                    int WXUNUSED(hotSpotX
), 
 215                    int WXUNUSED(hotSpotY
)) 
 219 wxCursor::wxCursor(int WXUNUSED(cursor_type
)) 
 223 #else // !__WXMICROWIN__ 
 225 wxCursor::wxCursor(const wxString
& filename
, 
 233         case wxBITMAP_TYPE_CUR_RESOURCE
: 
 234             hcursor 
= ::LoadCursor(wxGetInstance(), filename
); 
 237         case wxBITMAP_TYPE_CUR
: 
 238             hcursor 
= ::LoadCursorFromFile(filename
); 
 241         case wxBITMAP_TYPE_ICO
: 
 242             hcursor 
= wxBitmapToHCURSOR
 
 244                        wxIcon(filename
, wxBITMAP_TYPE_ICO
), 
 250         case wxBITMAP_TYPE_BMP
: 
 251             hcursor 
= wxBitmapToHCURSOR
 
 253                        wxBitmap(filename
, wxBITMAP_TYPE_BMP
), 
 260             wxFAIL_MSG( _T("unknown cursor resource type") ); 
 267         m_refData 
= new wxCursorRefData(hcursor
, true /* delete it later */); 
 269 #if WXWIN_COMPATIBILITY_2 
 270         ((wxCursorRefData 
*)m_refData
)->SetOk(); 
 271 #endif // WXWIN_COMPATIBILITY_2 
 275 // Cursors by stock number 
 276 wxCursor::wxCursor(int idCursor
) 
 278     // all wxWindows standard cursors 
 279     static const struct StdCursor
 
 281         // is this a standard Windows cursor? 
 284         // the cursor name or id 
 288         {  true, NULL                        
}, // wxCURSOR_NONE 
 289         {  true, IDC_ARROW                   
}, // wxCURSOR_ARROW 
 290         { false, _T("wxCURSOR_RIGHT_ARROW")  }, // wxCURSOR_RIGHT_ARROW 
 291         { false, _T("wxCURSOR_BULLSEYE")     }, // wxCURSOR_BULLSEYE 
 292         {  true, IDC_ARROW                   
}, // wxCURSOR_CHAR 
 293         {  true, IDC_CROSS                   
}, // wxCURSOR_CROSS 
 294         { false, _T("wxCURSOR_HAND")         }, // wxCURSOR_HAND 
 295         {  true, IDC_IBEAM                   
}, // wxCURSOR_IBEAM 
 296         {  true, IDC_ARROW                   
}, // wxCURSOR_LEFT_BUTTON 
 297         { false, _T("wxCURSOR_MAGNIFIER")    }, // wxCURSOR_MAGNIFIER 
 298         {  true, IDC_ARROW                   
}, // wxCURSOR_MIDDLE_BUTTON 
 299         {  true, IDC_NO                      
}, // wxCURSOR_NO_ENTRY 
 300         { false, _T("wxCURSOR_PAINT_BRUSH")  }, // wxCURSOR_PAINT_BRUSH 
 301         { false, _T("wxCURSOR_PENCIL")       }, // wxCURSOR_PENCIL 
 302         { false, _T("wxCURSOR_POINT_LEFT")   }, // wxCURSOR_POINT_LEFT 
 303         { false, _T("wxCURSOR_POINT_RIGHT")  }, // wxCURSOR_POINT_RIGHT 
 304         {  true, IDC_HELP                    
}, // wxCURSOR_QUESTION_ARROW 
 305         {  true, IDC_ARROW                   
}, // wxCURSOR_RIGHT_BUTTON 
 306         {  true, IDC_SIZENESW                
}, // wxCURSOR_SIZENESW 
 307         {  true, IDC_SIZENS                  
}, // wxCURSOR_SIZENS 
 308         {  true, IDC_SIZENWSE                
}, // wxCURSOR_SIZENWSE 
 309         {  true, IDC_SIZEWE                  
}, // wxCURSOR_SIZEWE 
 310         {  true, IDC_SIZEALL                 
}, // wxCURSOR_SIZING 
 311         { false, _T("wxCURSOR_SPRAYCAN")     }, // wxCURSOR_SPRAYCAN 
 312         {  true, IDC_WAIT                    
}, // wxCURSOR_WAIT 
 313         {  true, IDC_WAIT                    
}, // wxCURSOR_WATCH 
 314         { false, _T("wxCURSOR_BLANK")        }, // wxCURSOR_BLANK 
 315         {  true, IDC_APPSTARTING             
}, // wxCURSOR_ARROWWAIT 
 317         // no entry for wxCURSOR_MAX 
 320     wxCOMPILE_TIME_ASSERT( WXSIZEOF(stdCursors
) == wxCURSOR_MAX
, 
 321                            CursorsIdArrayMismatch 
); 
 323     wxCHECK_RET( idCursor 
> 0 && (size_t)idCursor 
< WXSIZEOF(stdCursors
), 
 324                  _T("invalid cursor id in wxCursor() ctor") ); 
 326     const StdCursor
& stdCursor 
= stdCursors
[idCursor
]; 
 328     HCURSOR hcursor 
= ::LoadCursor(stdCursor
.isStd 
? NULL 
: wxGetInstance(), 
 333         wxLogLastError(_T("LoadCursor")); 
 337         m_refData 
= new wxCursorRefData(hcursor
); 
 341 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 343 wxCursor::~wxCursor() 
 347 // ---------------------------------------------------------------------------- 
 348 // other wxCursor functions 
 349 // ---------------------------------------------------------------------------- 
 351 bool wxCursor::operator==(const wxCursor
& cursor
) const 
 354         return !cursor
.m_refData
; 
 356     return cursor
.m_refData 
&& 
 357                 ((wxCursorRefData 
*)m_refData
)->m_hCursor 
== 
 358                 ((wxCursorRefData 
*)cursor
.m_refData
)->m_hCursor
; 
 361 wxGDIImageRefData 
*wxCursor::CreateData() const 
 363     return new wxCursorRefData
; 
 366 // ---------------------------------------------------------------------------- 
 367 // Global cursor setting 
 368 // ---------------------------------------------------------------------------- 
 370 const wxCursor 
*wxGetGlobalCursor() 
 372     return gs_globalCursor
; 
 375 void wxSetCursor(const wxCursor
& cursor
) 
 379         ::SetCursor(GetHcursorOf(cursor
)); 
 381         if ( gs_globalCursor 
) 
 382             *gs_globalCursor 
= cursor
;