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"
41 #include "wx/msw/private.h"
42 #ifndef __WXMICROWIN__
43 #include "wx/msw/dib.h"
46 #if wxUSE_RESOURCE_LOADING_IN_MSW
47 #include "wx/msw/curico.h"
48 #include "wx/msw/curicop.h"
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 IMPLEMENT_DYNAMIC_CLASS(wxCursor
, wxGDIObject
)
57 // ----------------------------------------------------------------------------
59 // ----------------------------------------------------------------------------
61 // Current cursor, in order to hang on to cursor handle when setting the cursor
63 static wxCursor
*gs_globalCursor
= NULL
;
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 class wxCursorModule
: public wxModule
74 gs_globalCursor
= new wxCursor
;
81 delete gs_globalCursor
;
82 gs_globalCursor
= (wxCursor
*)NULL
;
86 // ============================================================================
88 // ============================================================================
90 // ----------------------------------------------------------------------------
92 // ----------------------------------------------------------------------------
94 wxCursorRefData::wxCursorRefData()
99 m_destroyCursor
= TRUE
;
102 void wxCursorRefData::Free()
106 #ifndef __WXMICROWIN__
107 if ( m_destroyCursor
)
108 ::DestroyCursor((HCURSOR
)m_hCursor
);
115 // ----------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------
123 wxCursor::wxCursor( const wxImage
& image
)
125 //image has to be 32x32
126 wxImage image32
= image
.Scale(32,32);
127 unsigned char * rgbBits
= image32
.GetData();
128 int w
= image32
.GetWidth() ;
129 int h
= image32
.GetHeight() ;
130 bool bHasMask
= image32
.HasMask() ;
131 int imagebitcount
= (w
*h
)/8;
133 unsigned char r
, g
, b
;
134 unsigned char * bits
= new unsigned char [imagebitcount
];
135 unsigned char * maskBits
= new unsigned char [imagebitcount
];
137 int i
,j
, i8
; unsigned char c
, cMask
;
138 for (i
=0; i
<imagebitcount
; i
++)
142 //unlike gtk, the pixels go in the opposite order in the bytes
146 // possible overflow if we do the summation first ?
147 c
= rgbBits
[(i8
+j
)*3]/3 + rgbBits
[(i8
+j
)*3+1]/3 + rgbBits
[(i8
+j
)*3+2]/3 ;
148 //if average value is > mid grey
150 bits
[i
] = bits
[i
] | cMask
;
156 r
= image32
.GetMaskRed() ;
157 g
= image32
.GetMaskGreen() ;
158 b
= image32
.GetMaskBlue() ;
160 for (i
=0; i
<imagebitcount
; i
++)
168 if (rgbBits
[(i8
+j
)*3] == r
&& rgbBits
[(i8
+j
)*3+1] == g
&& rgbBits
[(i8
+j
)*3+2] == b
)
169 maskBits
[i
] = maskBits
[i
] | cMask
;
176 for (i
=0; i
<imagebitcount
; i
++)
180 int hotSpotX
= image32
.GetOptionInt(wxCUR_HOTSPOT_X
);
181 int hotSpotY
= image32
.GetOptionInt(wxCUR_HOTSPOT_Y
);
182 if (hotSpotX
< 0 || hotSpotX
>= w
)
184 if (hotSpotY
< 0 || hotSpotY
>= h
)
187 wxCursorRefData
*refData
= new wxCursorRefData
;
189 refData
->m_hCursor
= (WXHCURSOR
) CreateCursor ( wxGetInstance(), hotSpotX
, hotSpotY
, w
, h
, /*AND*/ maskBits
, /*XOR*/ bits
);
196 wxCursor::wxCursor(const char WXUNUSED(bits
)[],
198 int WXUNUSED(height
),
199 int WXUNUSED(hotSpotX
), int WXUNUSED(hotSpotY
),
200 const char WXUNUSED(maskBits
)[])
204 wxCursor::wxCursor(const wxString
& cursor_file
,
206 int hotSpotX
, int hotSpotY
)
208 #ifdef __WXMICROWIN__
211 wxCursorRefData
*refData
= new wxCursorRefData
;
214 if (flags
== wxBITMAP_TYPE_CUR_RESOURCE
)
217 refData
->m_hCursor
= (WXHCURSOR
) LoadImage(wxGetInstance(), cursor_file
, IMAGE_CURSOR
, 0, 0, 0);
219 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), cursor_file
);
222 else if (flags
== wxBITMAP_TYPE_CUR
)
225 refData
->m_hCursor
= (WXHCURSOR
) LoadImage(wxGetInstance(), cursor_file
, IMAGE_CURSOR
, 0, 0, LR_LOADFROMFILE
);
227 #if wxUSE_RESOURCE_LOADING_IN_MSW
228 refData
->m_hCursor
= (WXHCURSOR
) ReadCursorFile(WXSTRINGCAST cursor_file
, wxGetInstance(), &refData
->m_width
, &refData
->m_height
);
232 else if (flags
== wxBITMAP_TYPE_ICO
)
234 #if wxUSE_RESOURCE_LOADING_IN_MSW
235 refData
->m_hCursor
= (WXHCURSOR
) IconToCursor(WXSTRINGCAST cursor_file
, wxGetInstance(), hotSpotX
, hotSpotY
, &refData
->m_width
, &refData
->m_height
);
238 else if (flags
== wxBITMAP_TYPE_BMP
)
240 #if wxUSE_RESOURCE_LOADING_IN_MSW
242 HPALETTE hPalette
= 0;
243 bool success
= wxReadDIB(WXSTRINGCAST cursor_file
, &hBitmap
, &hPalette
) != 0;
247 DeleteObject(hPalette
);
251 refData
->m_hCursor
= (WXHCURSOR
) MakeCursorFromBitmap(wxGetInstance(), hBitmap
, &pnt
);
252 DeleteObject(hBitmap
);
256 #if WXWIN_COMPATIBILITY_2
258 #endif // WXWIN_COMPATIBILITY_2
263 // Cursors by stock number
264 wxCursor::wxCursor(int cursor_type
)
266 #ifdef __WXMICROWIN__
269 wxCursorRefData
*refData
= new wxCursorRefData
;
274 case wxCURSOR_ARROWWAIT
:
276 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_APPSTARTING
);
280 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_WAIT
);
283 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_IBEAM
);
286 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_CROSS
);
288 case wxCURSOR_SIZENWSE
:
289 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENWSE
);
291 case wxCURSOR_SIZENESW
:
292 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENESW
);
294 case wxCURSOR_SIZEWE
:
295 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZEWE
);
297 case wxCURSOR_SIZENS
:
298 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_SIZENS
);
302 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
307 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_HAND"));
310 case wxCURSOR_BULLSEYE
:
312 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BULLSEYE"));
315 case wxCURSOR_PENCIL
:
317 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PENCIL"));
320 case wxCURSOR_MAGNIFIER
:
322 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_MAGNIFIER"));
325 case wxCURSOR_NO_ENTRY
:
327 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_NO_ENTRY"));
330 case wxCURSOR_LEFT_BUTTON
:
332 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
335 case wxCURSOR_RIGHT_BUTTON
:
337 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
340 case wxCURSOR_MIDDLE_BUTTON
:
342 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
345 case wxCURSOR_SIZING
:
347 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_SIZING"));
352 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_WATCH"));
355 case wxCURSOR_SPRAYCAN
:
357 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_ROLLER"));
360 case wxCURSOR_PAINT_BRUSH
:
362 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PBRUSH"));
365 case wxCURSOR_POINT_LEFT
:
367 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PLEFT"));
370 case wxCURSOR_POINT_RIGHT
:
372 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PRIGHT"));
375 case wxCURSOR_QUESTION_ARROW
:
377 // refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
378 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
383 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BLANK"));
388 refData
->m_hCursor
= (WXHCURSOR
) LoadCursor((HINSTANCE
) NULL
, IDC_ARROW
);
392 // no need to destroy the stock cursors
394 //m_refData->m_destroyCursor = FALSE;
398 wxCursor::~wxCursor()
402 // ----------------------------------------------------------------------------
403 // Global cursor setting
404 // ----------------------------------------------------------------------------
406 const wxCursor
*wxGetGlobalCursor()
408 return gs_globalCursor
;
411 void wxSetCursor(const wxCursor
& cursor
)
415 #ifndef __WXMICROWIN__
416 ::SetCursor(GetHcursorOf(cursor
));
419 if ( gs_globalCursor
)
420 *gs_globalCursor
= cursor
;