]> git.saurik.com Git - wxWidgets.git/blob - src/msw/cursor.cpp
Don't complain under MicroWindows if a wxDC's HDC is NULL - it happens
[wxWidgets.git] / src / msw / cursor.cpp
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
55 IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxCursorBase)
56
57 // ----------------------------------------------------------------------------
58 // globals
59 // ----------------------------------------------------------------------------
60
61 // Current cursor, in order to hang on to cursor handle when setting the cursor
62 // globally
63 static wxCursor *gs_globalCursor = NULL;
64
65 // ----------------------------------------------------------------------------
66 // private classes
67 // ----------------------------------------------------------------------------
68
69 class wxCursorModule : public wxModule
70 {
71 public:
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
94 wxCursorRefData::wxCursorRefData()
95 {
96 m_width = 32;
97 m_height = 32;
98
99 m_destroyCursor = FALSE;
100 }
101
102 void 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
119 wxCursor::wxCursor()
120 {
121 }
122
123 wxCursor::wxCursor(const char WXUNUSED(bits)[],
124 int WXUNUSED(width),
125 int WXUNUSED(height),
126 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY),
127 const char WXUNUSED(maskBits)[])
128 {
129 }
130
131 wxCursor::wxCursor(const wxString& cursor_file,
132 long flags,
133 int hotSpotX, int hotSpotY)
134 {
135 #ifdef __WXMICROWIN__
136 m_refData = NULL;
137 #else
138 wxCursorRefData *refData = new wxCursorRefData;
139 m_refData = refData;
140
141 refData->m_destroyCursor = FALSE;
142
143 if (flags == wxBITMAP_TYPE_CUR_RESOURCE)
144 {
145 #ifdef __WIN95__
146 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, 0);
147 #else
148 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), cursor_file);
149 #endif
150 }
151 else if (flags == wxBITMAP_TYPE_CUR)
152 {
153 #ifdef __WIN95__
154 refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), cursor_file, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
155 #else
156 #if wxUSE_RESOURCE_LOADING_IN_MSW
157 refData->m_hCursor = (WXHCURSOR) ReadCursorFile(WXSTRINGCAST cursor_file, wxGetInstance(), &refData->m_width, &refData->m_height);
158 refData->m_destroyCursor = TRUE;
159 #endif
160 #endif
161 }
162 else if (flags == wxBITMAP_TYPE_ICO)
163 {
164 #if wxUSE_RESOURCE_LOADING_IN_MSW
165 refData->m_hCursor = (WXHCURSOR) IconToCursor(WXSTRINGCAST cursor_file, wxGetInstance(), hotSpotX, hotSpotY, &refData->m_width, &refData->m_height);
166 refData->m_destroyCursor = TRUE;
167 #endif
168 }
169 else if (flags == wxBITMAP_TYPE_BMP)
170 {
171 #if wxUSE_RESOURCE_LOADING_IN_MSW
172 HBITMAP hBitmap = 0;
173 HPALETTE hPalette = 0;
174 bool success = wxReadDIB(WXSTRINGCAST cursor_file, &hBitmap, &hPalette) != 0;
175 if (!success)
176 return;
177 if (hPalette)
178 DeleteObject(hPalette);
179 POINT pnt;
180 pnt.x = hotSpotX;
181 pnt.y = hotSpotY;
182 refData->m_hCursor = (WXHCURSOR) MakeCursorFromBitmap(wxGetInstance(), hBitmap, &pnt);
183 refData->m_destroyCursor = TRUE;
184 DeleteObject(hBitmap);
185 #endif
186 }
187
188 #if WXWIN_COMPATIBILITY_2
189 refData->SetOk();
190 #endif // WXWIN_COMPATIBILITY_2
191
192 #endif
193 }
194
195 // Cursors by stock number
196 wxCursor::wxCursor(int cursor_type)
197 {
198 #ifdef __WXMICROWIN__
199 m_refData = NULL;
200 #else
201 wxCursorRefData *refData = new wxCursorRefData;
202 m_refData = refData;
203
204 switch (cursor_type)
205 {
206 case wxCURSOR_ARROWWAIT:
207 #ifndef __WIN16__
208 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_APPSTARTING);
209 break;
210 #endif
211 case wxCURSOR_WAIT:
212 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_WAIT);
213 break;
214 case wxCURSOR_IBEAM:
215 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_IBEAM);
216 break;
217 case wxCURSOR_CROSS:
218 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_CROSS);
219 break;
220 case wxCURSOR_SIZENWSE:
221 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENWSE);
222 break;
223 case wxCURSOR_SIZENESW:
224 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENESW);
225 break;
226 case wxCURSOR_SIZEWE:
227 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZEWE);
228 break;
229 case wxCURSOR_SIZENS:
230 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_SIZENS);
231 break;
232 case wxCURSOR_CHAR:
233 {
234 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
235 break;
236 }
237 case wxCURSOR_HAND:
238 {
239 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_HAND"));
240 break;
241 }
242 case wxCURSOR_BULLSEYE:
243 {
244 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BULLSEYE"));
245 break;
246 }
247 case wxCURSOR_PENCIL:
248 {
249 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PENCIL"));
250 break;
251 }
252 case wxCURSOR_MAGNIFIER:
253 {
254 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_MAGNIFIER"));
255 break;
256 }
257 case wxCURSOR_NO_ENTRY:
258 {
259 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_NO_ENTRY"));
260 break;
261 }
262 case wxCURSOR_LEFT_BUTTON:
263 {
264 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
265 break;
266 }
267 case wxCURSOR_RIGHT_BUTTON:
268 {
269 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
270 break;
271 }
272 case wxCURSOR_MIDDLE_BUTTON:
273 {
274 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
275 break;
276 }
277 case wxCURSOR_SIZING:
278 {
279 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_SIZING"));
280 break;
281 }
282 case wxCURSOR_WATCH:
283 {
284 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_WATCH"));
285 break;
286 }
287 case wxCURSOR_SPRAYCAN:
288 {
289 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_ROLLER"));
290 break;
291 }
292 case wxCURSOR_PAINT_BRUSH:
293 {
294 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PBRUSH"));
295 break;
296 }
297 case wxCURSOR_POINT_LEFT:
298 {
299 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PLEFT"));
300 break;
301 }
302 case wxCURSOR_POINT_RIGHT:
303 {
304 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_PRIGHT"));
305 break;
306 }
307 case wxCURSOR_QUESTION_ARROW:
308 {
309 // refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
310 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
311 break;
312 }
313 case wxCURSOR_BLANK:
314 {
315 refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_BLANK"));
316 break;
317 }
318 default:
319 case wxCURSOR_ARROW:
320 refData->m_hCursor = (WXHCURSOR) LoadCursor((HINSTANCE) NULL, IDC_ARROW);
321 break;
322 }
323 #endif
324 }
325
326 wxCursor::~wxCursor()
327 {
328 }
329
330 // ----------------------------------------------------------------------------
331 // Global cursor setting
332 // ----------------------------------------------------------------------------
333
334 const wxCursor *wxGetGlobalCursor()
335 {
336 return gs_globalCursor;
337 }
338
339 void wxSetCursor(const wxCursor& cursor)
340 {
341 if ( cursor.Ok() )
342 {
343 #ifndef __WXMICROWIN__
344 ::SetCursor(GetHcursorOf(cursor));
345 #endif
346
347 if ( gs_globalCursor )
348 *gs_globalCursor = cursor;
349 }
350 }
351
352