28
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2005 IBM Corporation and others.
|
|
3 * All rights reserved. This program and the accompanying materials
|
|
4 * are made available under the terms of the Eclipse Public License v1.0
|
|
5 * which accompanies this distribution, and is available at
|
|
6 * http://www.eclipse.org/legal/epl-v10.html
|
|
7 *
|
|
8 * Contributors:
|
|
9 * IBM Corporation - initial API and implementation
|
|
10 *******************************************************************************/
|
|
11 module dwt.graphics.Cursor;
|
|
12
|
|
13
|
|
14 import dwt.DWT;
|
|
15 import dwt.DWTError;
|
|
16 import dwt.internal.win32.OS;
|
|
17
|
|
18 import dwt.graphics.Resource;
|
|
19 import dwt.graphics.Device;
|
|
20 import dwt.graphics.ImageData;
|
|
21 import dwt.graphics.RGB;
|
|
22 import dwt.graphics.PaletteData;
|
|
23 import dwt.graphics.Image;
|
|
24
|
|
25 import tango.text.convert.Format;
|
|
26
|
|
27 /**
|
|
28 * Instances of this class manage operating system resources that
|
|
29 * specify the appearance of the on-screen pointer. To create a
|
|
30 * cursor you specify the device and either a simple cursor style
|
|
31 * describing one of the standard operating system provided cursors
|
|
32 * or the image and mask data for the desired appearance.
|
|
33 * <p>
|
|
34 * Application code must explicitly invoke the <code>Cursor.dispose()</code>
|
|
35 * method to release the operating system resources managed by each instance
|
|
36 * when those instances are no longer required.
|
|
37 * </p>
|
|
38 * <dl>
|
|
39 * <dt><b>Styles:</b></dt>
|
|
40 * <dd>
|
|
41 * CURSOR_ARROW, CURSOR_WAIT, CURSOR_CROSS, CURSOR_APPSTARTING, CURSOR_HELP,
|
|
42 * CURSOR_SIZEALL, CURSOR_SIZENESW, CURSOR_SIZENS, CURSOR_SIZENWSE, CURSOR_SIZEWE,
|
|
43 * CURSOR_SIZEN, CURSOR_SIZES, CURSOR_SIZEE, CURSOR_SIZEW, CURSOR_SIZENE, CURSOR_SIZESE,
|
|
44 * CURSOR_SIZESW, CURSOR_SIZENW, CURSOR_UPARROW, CURSOR_IBEAM, CURSOR_NO, CURSOR_HAND
|
|
45 * </dd>
|
|
46 * </dl>
|
|
47 * <p>
|
|
48 * Note: Only one of the above styles may be specified.
|
|
49 * </p>
|
|
50 */
|
|
51
|
|
52 public final class Cursor : Resource {
|
|
53
|
|
54 /**
|
|
55 * the handle to the OS cursor resource
|
|
56 * (Warning: This field is platform dependent)
|
|
57 * <p>
|
|
58 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT
|
|
59 * public API. It is marked public only so that it can be shared
|
|
60 * within the packages provided by DWT. It is not available on all
|
|
61 * platforms and should never be accessed from application code.
|
|
62 * </p>
|
|
63 */
|
|
64 public HCURSOR handle;
|
|
65
|
|
66 bool isIcon;
|
|
67
|
|
68 /**
|
|
69 * data used to create a HAND cursor.
|
|
70 */
|
|
71 static const byte[] HAND_SOURCE = [
|
|
72 cast(byte)0xf9,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
73 cast(byte)0xf0,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
74 cast(byte)0xf0,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
75 cast(byte)0xf0,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
76 cast(byte)0xf0,cast(byte)0x3f,cast(byte)0xff,cast(byte)0xff,
|
|
77 cast(byte)0xf0,cast(byte)0x07,cast(byte)0xff,cast(byte)0xff,
|
|
78 cast(byte)0xf0,cast(byte)0x03,cast(byte)0xff,cast(byte)0xff,
|
|
79 cast(byte)0xf0,cast(byte)0x00,cast(byte)0xff,cast(byte)0xff,
|
|
80
|
|
81 cast(byte)0x10,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
82 cast(byte)0x00,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
83 cast(byte)0x80,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
84 cast(byte)0xc0,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
85 cast(byte)0xe0,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
86 cast(byte)0xf0,cast(byte)0x00,cast(byte)0x7f,cast(byte)0xff,
|
|
87 cast(byte)0xf8,cast(byte)0x00,cast(byte)0xff,cast(byte)0xff,
|
|
88 cast(byte)0xfc,cast(byte)0x01,cast(byte)0xff,cast(byte)0xff,
|
|
89
|
|
90 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
91 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
92 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
93 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
94 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
95 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
96 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
97 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
98
|
|
99 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
100 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
101 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
102 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
103 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
104 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
105 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,
|
|
106 cast(byte)0xff,cast(byte)0xff,cast(byte)0xff,cast(byte)0xff
|
|
107 ];
|
|
108 static const byte[] HAND_MASK = [
|
|
109 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
110 cast(byte)0x06,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
111 cast(byte)0x06,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
112 cast(byte)0x06,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
113 cast(byte)0x06,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
114 cast(byte)0x06,cast(byte)0xc0,cast(byte)0x00,cast(byte)0x00,
|
|
115 cast(byte)0x06,cast(byte)0xd8,cast(byte)0x00,cast(byte)0x00,
|
|
116 cast(byte)0x06,cast(byte)0xd8,cast(byte)0x00,cast(byte)0x00,
|
|
117
|
|
118 cast(byte)0x07,cast(byte)0xdb,cast(byte)0x00,cast(byte)0x00,
|
|
119 cast(byte)0x67,cast(byte)0xfb,cast(byte)0x00,cast(byte)0x00,
|
|
120 cast(byte)0x3f,cast(byte)0xff,cast(byte)0x00,cast(byte)0x00,
|
|
121 cast(byte)0x1f,cast(byte)0xff,cast(byte)0x00,cast(byte)0x00,
|
|
122 cast(byte)0x0f,cast(byte)0xff,cast(byte)0x00,cast(byte)0x00,
|
|
123 cast(byte)0x07,cast(byte)0xff,cast(byte)0x00,cast(byte)0x00,
|
|
124 cast(byte)0x03,cast(byte)0xfe,cast(byte)0x00,cast(byte)0x00,
|
|
125 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
126
|
|
127 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
128 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
129 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
130 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
131 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
132 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
133 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
134 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
135
|
|
136 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
137 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
138 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
139 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
140 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
141 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
142 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,
|
|
143 cast(byte)0x00,cast(byte)0x00,cast(byte)0x00,cast(byte)0x00
|
|
144 ];
|
|
145
|
|
146 /**
|
|
147 * Prevents uninitialized instances from being created outside the package.
|
|
148 */
|
|
149 this() {
|
|
150 }
|
|
151
|
|
152 /**
|
|
153 * Constructs a new cursor given a device and a style
|
|
154 * constant describing the desired cursor appearance.
|
|
155 * <p>
|
|
156 * You must dispose the cursor when it is no longer required.
|
|
157 * </p>
|
|
158 *
|
|
159 * @param device the device on which to allocate the cursor
|
|
160 * @param style the style of cursor to allocate
|
|
161 *
|
|
162 * @exception IllegalArgumentException <ul>
|
|
163 * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
|
|
164 * <li>ERROR_INVALID_ARGUMENT - when an unknown style is specified</li>
|
|
165 * </ul>
|
|
166 * @exception DWTError <ul>
|
|
167 * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
|
|
168 * </ul>
|
|
169 *
|
|
170 * @see DWT#CURSOR_ARROW
|
|
171 * @see DWT#CURSOR_WAIT
|
|
172 * @see DWT#CURSOR_CROSS
|
|
173 * @see DWT#CURSOR_APPSTARTING
|
|
174 * @see DWT#CURSOR_HELP
|
|
175 * @see DWT#CURSOR_SIZEALL
|
|
176 * @see DWT#CURSOR_SIZENESW
|
|
177 * @see DWT#CURSOR_SIZENS
|
|
178 * @see DWT#CURSOR_SIZENWSE
|
|
179 * @see DWT#CURSOR_SIZEWE
|
|
180 * @see DWT#CURSOR_SIZEN
|
|
181 * @see DWT#CURSOR_SIZES
|
|
182 * @see DWT#CURSOR_SIZEE
|
|
183 * @see DWT#CURSOR_SIZEW
|
|
184 * @see DWT#CURSOR_SIZENE
|
|
185 * @see DWT#CURSOR_SIZESE
|
|
186 * @see DWT#CURSOR_SIZESW
|
|
187 * @see DWT#CURSOR_SIZENW
|
|
188 * @see DWT#CURSOR_UPARROW
|
|
189 * @see DWT#CURSOR_IBEAM
|
|
190 * @see DWT#CURSOR_NO
|
|
191 * @see DWT#CURSOR_HAND
|
|
192 */
|
|
193 public this(Device device, int style) {
|
|
194 if (device is null) device = Device.getDevice();
|
|
195 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
196 this.device = device;
|
|
197 int lpCursorName = 0;
|
|
198 switch (style) {
|
|
199 case DWT.CURSOR_HAND: lpCursorName = OS.IDC_HAND; break;
|
|
200 case DWT.CURSOR_ARROW: lpCursorName = OS.IDC_ARROW; break;
|
|
201 case DWT.CURSOR_WAIT: lpCursorName = OS.IDC_WAIT; break;
|
|
202 case DWT.CURSOR_CROSS: lpCursorName = OS.IDC_CROSS; break;
|
|
203 case DWT.CURSOR_APPSTARTING: lpCursorName = OS.IDC_APPSTARTING; break;
|
|
204 case DWT.CURSOR_HELP: lpCursorName = OS.IDC_HELP; break;
|
|
205 case DWT.CURSOR_SIZEALL: lpCursorName = OS.IDC_SIZEALL; break;
|
|
206 case DWT.CURSOR_SIZENESW: lpCursorName = OS.IDC_SIZENESW; break;
|
|
207 case DWT.CURSOR_SIZENS: lpCursorName = OS.IDC_SIZENS; break;
|
|
208 case DWT.CURSOR_SIZENWSE: lpCursorName = OS.IDC_SIZENWSE; break;
|
|
209 case DWT.CURSOR_SIZEWE: lpCursorName = OS.IDC_SIZEWE; break;
|
|
210 case DWT.CURSOR_SIZEN: lpCursorName = OS.IDC_SIZENS; break;
|
|
211 case DWT.CURSOR_SIZES: lpCursorName = OS.IDC_SIZENS; break;
|
|
212 case DWT.CURSOR_SIZEE: lpCursorName = OS.IDC_SIZEWE; break;
|
|
213 case DWT.CURSOR_SIZEW: lpCursorName = OS.IDC_SIZEWE; break;
|
|
214 case DWT.CURSOR_SIZENE: lpCursorName = OS.IDC_SIZENESW; break;
|
|
215 case DWT.CURSOR_SIZESE: lpCursorName = OS.IDC_SIZENWSE; break;
|
|
216 case DWT.CURSOR_SIZESW: lpCursorName = OS.IDC_SIZENESW; break;
|
|
217 case DWT.CURSOR_SIZENW: lpCursorName = OS.IDC_SIZENWSE; break;
|
|
218 case DWT.CURSOR_UPARROW: lpCursorName = OS.IDC_UPARROW; break;
|
|
219 case DWT.CURSOR_IBEAM: lpCursorName = OS.IDC_IBEAM; break;
|
|
220 case DWT.CURSOR_NO: lpCursorName = OS.IDC_NO; break;
|
|
221 default:
|
|
222 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
223 }
|
|
224 handle = OS.LoadCursor(null, cast(wchar*)lpCursorName);
|
|
225 /*
|
|
226 * IDC_HAND is supported only on Windows 2000 and Windows 98.
|
|
227 * Create a hand cursor if running in other Windows platforms.
|
|
228 */
|
|
229 if (handle is null && style is DWT.CURSOR_HAND) {
|
|
230 int width = OS.GetSystemMetrics(OS.SM_CXCURSOR);
|
|
231 int height = OS.GetSystemMetrics(OS.SM_CYCURSOR);
|
|
232 if (width is 32 && height is 32) {
|
|
233 auto hInst = OS.GetModuleHandle(null);
|
|
234 if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED);
|
|
235 handle = OS.CreateCursor(hInst, 5, 0, 32, 32, HAND_SOURCE.ptr, HAND_MASK.ptr);
|
|
236
|
|
237 }
|
|
238 }
|
|
239 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
|
|
240 if (device.tracking) device.new_Object(this);
|
|
241 }
|
|
242
|
|
243 /**
|
|
244 * Constructs a new cursor given a device, image and mask
|
|
245 * data describing the desired cursor appearance, and the x
|
|
246 * and y coordinates of the <em>hotspot</em> (that is, the point
|
|
247 * within the area covered by the cursor which is considered
|
|
248 * to be where the on-screen pointer is "pointing").
|
|
249 * <p>
|
|
250 * The mask data is allowed to be null, but in this case the source
|
|
251 * must be an ImageData representing an icon that specifies both
|
|
252 * color data and mask data.
|
|
253 * <p>
|
|
254 * You must dispose the cursor when it is no longer required.
|
|
255 * </p>
|
|
256 *
|
|
257 * @param device the device on which to allocate the cursor
|
|
258 * @param source the color data for the cursor
|
|
259 * @param mask the mask data for the cursor (or null)
|
|
260 * @param hotspotX the x coordinate of the cursor's hotspot
|
|
261 * @param hotspotY the y coordinate of the cursor's hotspot
|
|
262 *
|
|
263 * @exception IllegalArgumentException <ul>
|
|
264 * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
|
|
265 * <li>ERROR_NULL_ARGUMENT - if the source is null</li>
|
|
266 * <li>ERROR_NULL_ARGUMENT - if the mask is null and the source does not have a mask</li>
|
|
267 * <li>ERROR_INVALID_ARGUMENT - if the source and the mask are not the same
|
|
268 * size, or if the hotspot is outside the bounds of the image</li>
|
|
269 * </ul>
|
|
270 * @exception DWTError <ul>
|
|
271 * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
|
|
272 * </ul>
|
|
273 */
|
|
274 public this(Device device, ImageData source, ImageData mask, int hotspotX, int hotspotY) {
|
|
275 if (device is null) device = Device.getDevice();
|
|
276 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
277 this.device = device;
|
|
278 if (source is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
279 if (mask is null) {
|
|
280 if (source.getTransparencyType() !is DWT.TRANSPARENCY_MASK) {
|
|
281 DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
282 }
|
|
283 mask = source.getTransparencyMask();
|
|
284 }
|
|
285 /* Check the bounds. Mask must be the same size as source */
|
|
286 if (mask.width !is source.width || mask.height !is source.height) {
|
|
287 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
288 }
|
|
289 /* Check the hotspots */
|
|
290 if (hotspotX >= source.width || hotspotX < 0 ||
|
|
291 hotspotY >= source.height || hotspotY < 0) {
|
|
292 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
293 }
|
|
294 /* Convert depth to 1 */
|
|
295 mask = ImageData.convertMask(mask);
|
|
296 source = ImageData.convertMask(source);
|
|
297
|
|
298 /* Make sure source and mask scanline pad is 2 */
|
|
299 byte[] sourceData = ImageData.convertPad(source.data, source.width, source.height, source.depth, source.scanlinePad, 2);
|
|
300 byte[] maskData = ImageData.convertPad(mask.data, mask.width, mask.height, mask.depth, mask.scanlinePad, 2);
|
|
301
|
|
302 /* Create the cursor */
|
|
303 auto hInst = OS.GetModuleHandle(null);
|
|
304 if (OS.IsWinCE) DWT.error (DWT.ERROR_NOT_IMPLEMENTED);
|
|
305 handle = OS.CreateCursor(hInst, hotspotX, hotspotY, source.width, source.height, sourceData.ptr, maskData.ptr);
|
|
306 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
|
|
307 if (device.tracking) device.new_Object(this);
|
|
308 }
|
|
309
|
|
310 /**
|
|
311 * Constructs a new cursor given a device, image data describing
|
|
312 * the desired cursor appearance, and the x and y coordinates of
|
|
313 * the <em>hotspot</em> (that is, the point within the area
|
|
314 * covered by the cursor which is considered to be where the
|
|
315 * on-screen pointer is "pointing").
|
|
316 * <p>
|
|
317 * You must dispose the cursor when it is no longer required.
|
|
318 * </p>
|
|
319 *
|
|
320 * @param device the device on which to allocate the cursor
|
|
321 * @param source the image data for the cursor
|
|
322 * @param hotspotX the x coordinate of the cursor's hotspot
|
|
323 * @param hotspotY the y coordinate of the cursor's hotspot
|
|
324 *
|
|
325 * @exception IllegalArgumentException <ul>
|
|
326 * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
|
|
327 * <li>ERROR_NULL_ARGUMENT - if the image is null</li>
|
|
328 * <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the bounds of the
|
|
329 * image</li>
|
|
330 * </ul>
|
|
331 * @exception DWTError <ul>
|
|
332 * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
|
|
333 * </ul>
|
|
334 *
|
|
335 * @since 3.0
|
|
336 */
|
|
337 public this(Device device, ImageData source, int hotspotX, int hotspotY) {
|
|
338 if (device is null) device = Device.getDevice();
|
|
339 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
340 this.device = device;
|
|
341 if (source is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
|
|
342 /* Check the hotspots */
|
|
343 if (hotspotX >= source.width || hotspotX < 0 ||
|
|
344 hotspotY >= source.height || hotspotY < 0) {
|
|
345 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
|
|
346 }
|
|
347 ImageData mask = source.getTransparencyMask();
|
|
348 int[] result = Image.init(device, null, source, mask);
|
|
349 auto hBitmap = cast(HBITMAP)result[0];
|
|
350 auto hMask = cast(HBITMAP)result[1];
|
|
351 /* Create the icon */
|
|
352 ICONINFO info;
|
|
353 info.fIcon = false;
|
|
354 info.hbmColor = hBitmap;
|
|
355 info.hbmMask = hMask;
|
|
356 info.xHotspot = hotspotX;
|
|
357 info.yHotspot = hotspotY;
|
|
358 handle = OS.CreateIconIndirect(&info);
|
|
359 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
|
|
360 OS.DeleteObject(hBitmap);
|
|
361 OS.DeleteObject(hMask);
|
|
362 isIcon = true;
|
|
363 if (device.tracking) device.new_Object(this);
|
|
364 }
|
|
365
|
|
366 /**
|
|
367 * Disposes of the operating system resources associated with
|
|
368 * the cursor. Applications must dispose of all cursors which
|
|
369 * they allocate.
|
|
370 */
|
|
371 public void dispose () {
|
|
372 if (handle is null) return;
|
|
373 if (device.isDisposed()) return;
|
|
374
|
|
375 /*
|
|
376 * It is an error in Windows to destroy the current
|
|
377 * cursor. Check that the cursor that is about to
|
|
378 * be destroyed is the current cursor. If so, set
|
|
379 * the current cursor to be IDC_ARROW. Note that
|
|
380 * Windows shares predefined cursors so the call to
|
|
381 * LoadCursor() does not leak.
|
|
382 */
|
|
383 // TEMPORARY CODE
|
|
384 // if (OS.GetCursor() is handle) {
|
|
385 // OS.SetCursor(OS.LoadCursor(0, OS.IDC_ARROW));
|
|
386 // }
|
|
387
|
|
388 if (isIcon) {
|
|
389 OS.DestroyIcon(handle);
|
|
390 } else {
|
|
391 /*
|
|
392 * The MSDN states that one should not destroy a shared
|
|
393 * cursor, that is, one obtained from LoadCursor.
|
|
394 * However, it does not appear to do any harm, so rather
|
|
395 * than keep track of how a cursor was created, we just
|
|
396 * destroy them all. If this causes problems in the future,
|
|
397 * put the flag back in.
|
|
398 */
|
|
399 if (!OS.IsWinCE) OS.DestroyCursor(handle);
|
|
400 }
|
|
401 handle = null;
|
|
402 if (device.tracking) device.dispose_Object(this);
|
|
403 device = null;
|
|
404 }
|
|
405
|
|
406 /**
|
|
407 * Compares the argument to the receiver, and returns true
|
|
408 * if they represent the <em>same</em> object using a class
|
|
409 * specific comparison.
|
|
410 *
|
|
411 * @param object the object to compare with this object
|
|
412 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
|
|
413 *
|
|
414 * @see #hashCode
|
|
415 */
|
|
416 public override int opEquals (Object object) {
|
|
417 if (object is this) return true;
|
|
418 if (!(cast(Cursor)object)) return false;
|
|
419 Cursor cursor = cast(Cursor) object;
|
|
420 return device is cursor.device && handle is cursor.handle;
|
|
421 }
|
|
422
|
|
423 /**
|
|
424 * Returns an integer hash code for the receiver. Any two
|
|
425 * objects that return <code>true</code> when passed to
|
|
426 * <code>equals</code> must return the same value for this
|
|
427 * method.
|
|
428 *
|
|
429 * @return the receiver's hash
|
|
430 *
|
|
431 * @see #equals
|
|
432 */
|
|
433 public override hash_t toHash () {
|
|
434 return cast(hash_t)handle;
|
|
435 }
|
|
436
|
|
437 /**
|
|
438 * Returns <code>true</code> if the cursor has been disposed,
|
|
439 * and <code>false</code> otherwise.
|
|
440 * <p>
|
|
441 * This method gets the dispose state for the cursor.
|
|
442 * When a cursor has been disposed, it is an error to
|
|
443 * invoke any other method using the cursor.
|
|
444 *
|
|
445 * @return <code>true</code> when the cursor is disposed and <code>false</code> otherwise
|
|
446 */
|
|
447 public bool isDisposed() {
|
|
448 return handle is null;
|
|
449 }
|
|
450
|
|
451 /**
|
|
452 * Returns a string containing a concise, human-readable
|
|
453 * description of the receiver.
|
|
454 *
|
|
455 * @return a string representation of the receiver
|
|
456 */
|
|
457 public char[] toString () {
|
|
458 if (isDisposed()) return "Cursor {*DISPOSED*}";
|
|
459 return Format( "Cursor {{{}}", handle );
|
|
460 }
|
|
461
|
|
462 /**
|
|
463 * Invokes platform specific functionality to allocate a new cursor.
|
|
464 * <p>
|
|
465 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
|
|
466 * API for <code>Cursor</code>. It is marked public only so that it
|
|
467 * can be shared within the packages provided by DWT. It is not
|
|
468 * available on all platforms, and should never be called from
|
|
469 * application code.
|
|
470 * </p>
|
|
471 *
|
|
472 * @param device the device on which to allocate the color
|
|
473 * @param handle the handle for the cursor
|
|
474 * @return a new cursor object containing the specified device and handle
|
|
475 */
|
|
476 public static Cursor win32_new(Device device, HCURSOR handle) {
|
|
477 if (device is null) device = Device.getDevice();
|
|
478 Cursor cursor = new Cursor();
|
|
479 cursor.handle = handle;
|
|
480 cursor.device = device;
|
|
481 return cursor;
|
|
482 }
|
|
483
|
|
484 }
|