1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxCursor class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
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"
35 #include "wx/bitmap.h"
37 #include "wx/cursor.h"
40 #include "wx/module.h"
42 #include "wx/msw/private.h"
43 #ifndef __WXMICROWIN__
44 #include "wx/msw/dib.h"
47 #if wxUSE_RESOURCE_LOADING_IN_MSW
48 #include "wx/msw/curico.h"
49 #include "wx/msw/curicop.h"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 IMPLEMENT_DYNAMIC_CLASS(wxCursor
, wxGDIObject
)
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 // Current cursor, in order to hang on to cursor handle when setting the cursor
64 static wxCursor
*gs_globalCursor
= NULL
;
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 class wxCursorModule
: public wxModule
75 gs_globalCursor
= new wxCursor
;
82 delete gs_globalCursor
;
83 gs_globalCursor
= (wxCursor
*)NULL
;
87 // ============================================================================
89 // ============================================================================
91 // ----------------------------------------------------------------------------
93 // ----------------------------------------------------------------------------
95 wxCursorRefData::wxCursorRefData()
100 m_destroyCursor
= TRUE
;
103 void wxCursorRefData::Free()
107 #ifndef __WXMICROWIN__
108 if ( m_destroyCursor
)
109 ::DestroyCursor((HCURSOR
)m_hCursor
);
116 // ----------------------------------------------------------------------------
118 // ----------------------------------------------------------------------------
124 wxCursor::wxCursor( const wxImage
& image
)
126 //image has to be 32x32
127 wxImage image32
= image
.Scale(32,32);
128 unsigned char * rgbBits
= image32
.GetData();
129 int w
= image32
.GetWidth() ;
130 int h
= image32
.GetHeight() ;
131 bool bHasMask
= image32
.HasMask() ;
132 int imagebitcount
= (w
*h
)/8;
134 unsigned char r
, g
, b
;
135 unsigned char * bits
= new unsigned char [imagebitcount
];
136 unsigned char * maskBits
= new unsigned char [imagebitcount
];
138 int i
,j
, i8
; unsigned char c
, cMask
;
139 for (i
=0; i
<imagebitcount
; i
++)
143 //unlike gtk, the pixels go in the opposite order in the bytes
147 // possible overflow if we do the summation first ?
148 c
= rgbBits
[(i8
+j
)*3]/3 + rgbBits
[(i8
+j
)*3+1]/3 + rgbBits
[(i8
+j
)*3+2]/3 ;
149 //if average value is > mid grey
151 bits
[i
] = bits
[i
] | cMask
;
157 r
= image32
.GetMaskRed() ;
158 g
= image32
.GetMaskGreen() ;
159 b
= image32
.GetMaskBlue() ;
161 for (i
=0; i
<imagebitcount
; i
++)
169 if (rgbBits
[(i8
+j
)*3] == r
&& rgbBits
[(i8
+j
)*3+1] == g
&& rgbBits
[(i8
+j
)*3+2] == b
)
170 maskBits
[i
] = maskBits
[i
] | cMask
;
177 for (i
=0; i
<imagebitcount
; i
++)
181 int hotSpotX
= image32
.GetOptionInt(wxCUR_HOTSPOT_X
);
182 int hotSpotY
= image32
.GetOptionInt(wxCUR_HOTSPOT_Y
);
183 if (hotSpotX
< 0 || hotSpotX
>= w
)
185 if (hotSpotY
< 0 || hotSpotY
>= h
)
188 wxCursorRefData
*refData
= new wxCursorRefData
;
190 refData
->m_hCursor
= (WXHCURSOR
) CreateCursor ( wxGetInstance(), hotSpotX
, hotSpotY
, w
, h
, /*AND*/ maskBits
, /*XOR*/ bits
);
197 wxCursor::wxCursor(const char WXUNUSED(bits
)[],
199 int WXUNUSED(height
),
200 int WXUNUSED(hotSpotX
), int WXUNUSED(hotSpotY
),
201 const char WXUNUSED(maskBits
)[])
205 wxCursor::wxCursor(const wxString
& cursor_file
,
207 int hotSpotX
, int hotSpotY
)
209 #ifdef __WXMICROWIN__
212 wxCursorRefData
*refData
= new wxCursorRefData
;
215 if (flags
== wxBITMAP_TYPE_CUR_RESOURCE
)
218 refData
->m_hCursor
= (WXHCURSOR
) LoadImage(wxGetInstance(), cursor_file
, IMAGE_CURSOR
, 0, 0, 0);
220 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), cursor_file
);
223 else if (flags
== wxBITMAP_TYPE_CUR
)
226 refData
->m_hCursor
= (WXHCURSOR
) LoadImage(wxGetInstance(), cursor_file
, IMAGE_CURSOR
, 0, 0, LR_LOADFROMFILE
);
228 #if wxUSE_RESOURCE_LOADING_IN_MSW
229 refData
->m_hCursor
= (WXHCURSOR
) ReadCursorFile(WXSTRINGCAST cursor_file
, wxGetInstance(), &refData
->m_width
, &refData
->m_height
);
233 else if (flags
== wxBITMAP_TYPE_ICO
)
235 #if wxUSE_RESOURCE_LOADING_IN_MSW
236 refData
->m_hCursor
= (WXHCURSOR
) IconToCursor(WXSTRINGCAST cursor_file
, wxGetInstance(), hotSpotX
, hotSpotY
, &refData
->m_width
, &refData
->m_height
);
239 else if (flags
== wxBITMAP_TYPE_BMP
)
241 #if wxUSE_RESOURCE_LOADING_IN_MSW
243 HPALETTE hPalette
= 0;
244 bool success
= wxReadDIB(WXSTRINGCAST cursor_file
, &hBitmap
, &hPalette
) != 0;
248 DeleteObject(hPalette
);
252 refData
->m_hCursor
= (WXHCURSOR
) MakeCursorFromBitmap(wxGetInstance(), hBitmap
, &pnt
);
253 DeleteObject(hBitmap
);
257 #if WXWIN_COMPATIBILITY_2
259 #endif // WXWIN_COMPATIBILITY_2
264 // Cursors by stock number
265 wxCursor::wxCursor(int cursor_type
)
267 #ifdef __WXMICROWIN__
270 wxCursorRefData
*refData
= new wxCursorRefData
;
275 case wxCURSOR_ARROWWAIT
:
277 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_APPSTARTING
);
281 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_WAIT
);
284 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_IBEAM
);
287 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_CROSS
);
289 case wxCURSOR_SIZENWSE
:
290 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENWSE
);
292 case wxCURSOR_SIZENESW
:
293 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENESW
);
295 case wxCURSOR_SIZEWE
:
296 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZEWE
);
298 case wxCURSOR_SIZENS
:
299 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENS
);
303 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
308 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_HAND"));
311 case wxCURSOR_BULLSEYE
:
313 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BULLSEYE"));
316 case wxCURSOR_PENCIL
:
318 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PENCIL"));
321 case wxCURSOR_MAGNIFIER
:
323 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_MAGNIFIER"));
326 case wxCURSOR_NO_ENTRY
:
328 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_NO_ENTRY"));
331 case wxCURSOR_LEFT_BUTTON
:
333 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
336 case wxCURSOR_RIGHT_BUTTON
:
338 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
341 case wxCURSOR_MIDDLE_BUTTON
:
343 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
346 case wxCURSOR_SIZING
:
348 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_SIZING"));
353 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_WATCH"));
356 case wxCURSOR_SPRAYCAN
:
358 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_ROLLER"));
361 case wxCURSOR_PAINT_BRUSH
:
363 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PBRUSH"));
366 case wxCURSOR_POINT_LEFT
:
368 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PLEFT"));
371 case wxCURSOR_POINT_RIGHT
:
373 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PRIGHT"));
376 case wxCURSOR_QUESTION_ARROW
:
378 // refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
379 // refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
380 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_HELP
);
385 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BLANK"));
388 case wxCURSOR_RIGHT_ARROW
:
390 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_RIGHT_ARROW"));
395 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
399 // no need to destroy the stock cursors
401 //m_refData->m_destroyCursor = FALSE;
405 wxCursor::~wxCursor()
409 // ----------------------------------------------------------------------------
410 // Global cursor setting
411 // ----------------------------------------------------------------------------
413 const wxCursor
*wxGetGlobalCursor()
415 return gs_globalCursor
;
418 void wxSetCursor(const wxCursor
& cursor
)
422 #ifndef __WXMICROWIN__
423 ::SetCursor(GetHcursorOf(cursor
));
426 if ( gs_globalCursor
)
427 *gs_globalCursor
= cursor
;