]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/cursor.cpp
wxITEM_FOO instead of wxItem_Foo, for the sake of consistency
[wxWidgets.git] / src / msw / cursor.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: cursor.cpp
3// Purpose: wxCursor class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "cursor.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/list.h"
33 #include "wx/utils.h"
34 #include "wx/app.h"
35 #include "wx/bitmap.h"
36 #include "wx/icon.h"
37 #include "wx/cursor.h"
38#endif
39
40#include "wx/module.h"
41#include "wx/msw/private.h"
42#ifndef __WXMICROWIN__
43#include "wx/msw/dib.h"
44#endif
45
46#if wxUSE_RESOURCE_LOADING_IN_MSW
47 #include "wx/msw/curico.h"
48 #include "wx/msw/curicop.h"
49#endif
50
51// ----------------------------------------------------------------------------
52// wxWin macros
53// ----------------------------------------------------------------------------
54
55IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject)
56
57// ----------------------------------------------------------------------------
58// globals
59// ----------------------------------------------------------------------------
60
61// Current cursor, in order to hang on to cursor handle when setting the cursor
62// globally
63static wxCursor *gs_globalCursor = NULL;
64
65// ----------------------------------------------------------------------------
66// private classes
67// ----------------------------------------------------------------------------
68
69class wxCursorModule : public wxModule
70{
71public:
72 virtual bool OnInit()
73 {
74 gs_globalCursor = new wxCursor;
75
76 return TRUE;
77 }
78
79 virtual void OnExit()
80 {
81 delete gs_globalCursor;
82 gs_globalCursor = (wxCursor *)NULL;
83 }
84};
85
86// ============================================================================
87// implementation
88// ============================================================================
89
90// ----------------------------------------------------------------------------
91// wxCursorRefData
92// ----------------------------------------------------------------------------
93
94wxCursorRefData::wxCursorRefData()
95{
96 m_width = 32;
97 m_height = 32;
98
99 m_destroyCursor = TRUE;
100}
101
102void wxCursorRefData::Free()
103{
104 if ( m_hCursor )
105 {
106#ifndef __WXMICROWIN__
107 if ( m_destroyCursor )
108 ::DestroyCursor((HCURSOR)m_hCursor);
109#endif
110
111 m_hCursor = 0;
112 }
113}
114
115// ----------------------------------------------------------------------------
116// Cursors
117// ----------------------------------------------------------------------------
118
119wxCursor::wxCursor()
120{
121}
122
123wxCursor::wxCursor( const wxImage & image )
124{
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;
132
133 unsigned char r, g, b ;
134 unsigned char * bits = new unsigned char [imagebitcount];
135 unsigned char * maskBits = new unsigned char [imagebitcount];
136
137 int i,j, i8; unsigned char c, cMask;
138 for (i=0; i<imagebitcount; i++)
139 {
140 bits[i] = 0;
141 i8 = i * 8;
142//unlike gtk, the pixels go in the opposite order in the bytes
143 cMask = 128;
144 for (j=0; j<8; j++)
145 {
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
149 if (c>127)
150 bits[i] = bits[i] | cMask ;
151 cMask = cMask / 2 ;
152 }
153 }
154 if (bHasMask)
155 {
156 r = image32.GetMaskRed() ;
157 g = image32.GetMaskGreen() ;
158 b = image32.GetMaskBlue() ;
159
160 for (i=0; i<imagebitcount; i++)
161 {
162 maskBits[i] = 0x0;
163 i8 = i * 8;
164
165 cMask = 128;
166 for (j=0; j<8; j++)
167 {
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 ;
170 cMask = cMask / 2 ;
171 }
172 }
173 }
174 else
175 {
176 for (i=0; i<imagebitcount; i++)
177 maskBits[i]= 0x0 ;
178 }
179
180 int hotSpotX = image32.GetOptionInt(wxCUR_HOTSPOT_X);
181 int hotSpotY = image32.GetOptionInt(wxCUR_HOTSPOT_Y);
182 if (hotSpotX < 0 || hotSpotX >= w)
183 hotSpotX = 0;
184 if (hotSpotY < 0 || hotSpotY >= h)
185 hotSpotY = 0;
186
187 wxCursorRefData *refData = new wxCursorRefData;
188 m_refData = refData;
189 refData->m_hCursor = (WXHCURSOR) CreateCursor ( wxGetInstance(), hotSpotX, hotSpotY, w, h, /*AND*/ maskBits, /*XOR*/ bits );
190
191 delete [] bits ;
192 delete [] maskBits;
193
194}
195
196wxCursor::wxCursor(const char WXUNUSED(bits)[],
197 int WXUNUSED(width),
198 int WXUNUSED(height),
199 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY),
200 const char WXUNUSED(maskBits)[])
201{
202}
203
204wxCursor::wxCursor(const wxString& cursor_file,
205 long flags,
206 int hotSpotX, int hotSpotY)
207{
208#ifdef __WXMICROWIN__
209 m_refData = NULL;
210#else
211 wxCursorRefData *refData = new wxCursorRefData;
212 m_refData = refData;
213
214 if (flags == wxBITMAP_TYPE_CUR_RESOURCE)
215 {
216#ifdef __WIN95__
217 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, 0);
218#else
219 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), cursor_file);
220#endif
221 }
222 else if (flags == wxBITMAP_TYPE_CUR)
223 {
224#ifdef __WIN95__
225 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
226#else
227#if wxUSE_RESOURCE_LOADING_IN_MSW
228 refData->m_hCursor = (WXHCURSOR) ReadCursorFile(WXSTRINGCAST cursor_file, wxGetInstance(), &refData->m_width, &refData->m_height);
229#endif
230#endif
231 }
232 else if (flags == wxBITMAP_TYPE_ICO)
233 {
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);
236#endif
237 }
238 else if (flags == wxBITMAP_TYPE_BMP)
239 {
240#if wxUSE_RESOURCE_LOADING_IN_MSW
241 HBITMAP hBitmap = 0;
242 HPALETTE hPalette = 0;
243 bool success = wxReadDIB(WXSTRINGCAST cursor_file, &hBitmap, &hPalette) != 0;
244 if (!success)
245 return;
246 if (hPalette)
247 DeleteObject(hPalette);
248 POINT pnt;
249 pnt.x = hotSpotX;
250 pnt.y = hotSpotY;
251 refData->m_hCursor = (WXHCURSOR) MakeCursorFromBitmap(wxGetInstance(), hBitmap, &pnt);
252 DeleteObject(hBitmap);
253#endif
254 }
255
256#if WXWIN_COMPATIBILITY_2
257 refData->SetOk();
258#endif // WXWIN_COMPATIBILITY_2
259
260#endif
261}
262
263// Cursors by stock number
264wxCursor::wxCursor(int cursor_type)
265{
266#ifdef __WXMICROWIN__
267 m_refData = NULL;
268#else
269 wxCursorRefData *refData = new wxCursorRefData;
270 m_refData = refData;
271
272 switch (cursor_type)
273 {
274 case wxCURSOR_ARROWWAIT:
275#ifndef __WIN16__
276 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_APPSTARTING);
277 break;
278#endif
279 case wxCURSOR_WAIT:
280 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_WAIT);
281 break;
282 case wxCURSOR_IBEAM:
283 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_IBEAM);
284 break;
285 case wxCURSOR_CROSS:
286 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_CROSS);
287 break;
288 case wxCURSOR_SIZENWSE:
289 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENWSE);
290 break;
291 case wxCURSOR_SIZENESW:
292 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENESW);
293 break;
294 case wxCURSOR_SIZEWE:
295 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZEWE);
296 break;
297 case wxCURSOR_SIZENS:
298 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENS);
299 break;
300 case wxCURSOR_CHAR:
301 {
302 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
303 break;
304 }
305 case wxCURSOR_HAND:
306 {
307 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_HAND"));
308 break;
309 }
310 case wxCURSOR_BULLSEYE:
311 {
312 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BULLSEYE"));
313 break;
314 }
315 case wxCURSOR_PENCIL:
316 {
317 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PENCIL"));
318 break;
319 }
320 case wxCURSOR_MAGNIFIER:
321 {
322 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_MAGNIFIER"));
323 break;
324 }
325 case wxCURSOR_NO_ENTRY:
326 {
327 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_NO_ENTRY"));
328 break;
329 }
330 case wxCURSOR_LEFT_BUTTON:
331 {
332 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
333 break;
334 }
335 case wxCURSOR_RIGHT_BUTTON:
336 {
337 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
338 break;
339 }
340 case wxCURSOR_MIDDLE_BUTTON:
341 {
342 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
343 break;
344 }
345 case wxCURSOR_SIZING:
346 {
347 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_SIZING"));
348 break;
349 }
350 case wxCURSOR_WATCH:
351 {
352 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_WATCH"));
353 break;
354 }
355 case wxCURSOR_SPRAYCAN:
356 {
357 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_ROLLER"));
358 break;
359 }
360 case wxCURSOR_PAINT_BRUSH:
361 {
362 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PBRUSH"));
363 break;
364 }
365 case wxCURSOR_POINT_LEFT:
366 {
367 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PLEFT"));
368 break;
369 }
370 case wxCURSOR_POINT_RIGHT:
371 {
372 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PRIGHT"));
373 break;
374 }
375 case wxCURSOR_QUESTION_ARROW:
376 {
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"));
379 break;
380 }
381 case wxCURSOR_BLANK:
382 {
383 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BLANK"));
384 break;
385 }
386 case wxCURSOR_RIGHT_ARROW:
387 {
388 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_RIGHT_ARROW"));
389 break;
390 }
391 default:
392 case wxCURSOR_ARROW:
393 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
394 break;
395 }
396
397 // no need to destroy the stock cursors
398 // TODO: check this
399 //m_refData->m_destroyCursor = FALSE;
400#endif
401}
402
403wxCursor::~wxCursor()
404{
405}
406
407// ----------------------------------------------------------------------------
408// Global cursor setting
409// ----------------------------------------------------------------------------
410
411const wxCursor *wxGetGlobalCursor()
412{
413 return gs_globalCursor;
414}
415
416void wxSetCursor(const wxCursor& cursor)
417{
418 if ( cursor.Ok() )
419 {
420#ifndef __WXMICROWIN__
421 ::SetCursor(GetHcursorOf(cursor));
422#endif
423
424 if ( gs_globalCursor )
425 *gs_globalCursor = cursor;
426 }
427}
428
429