Mercurial > projects > dwt-win
comparison dwt/dnd/DragSource.d @ 194:3afcd4ddcf90
Update to SWT 3.3.2
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Wed, 19 Mar 2008 21:48:31 +0100 |
parents | 04e357b8343d |
children | ab60f3309436 |
comparison
equal
deleted
inserted
replaced
193:d0bbd290530f | 194:3afcd4ddcf90 |
---|---|
129 Control control; | 129 Control control; |
130 Listener controlListener; | 130 Listener controlListener; |
131 Transfer[] transferAgents; | 131 Transfer[] transferAgents; |
132 DragSourceEffect dragEffect; | 132 DragSourceEffect dragEffect; |
133 Composite topControl; | 133 Composite topControl; |
134 HWND hwndDrag; | |
134 | 135 |
135 // ole interfaces | 136 // ole interfaces |
136 _IDropSourceImpl iDropSource; | 137 _IDropSourceImpl iDropSource; |
137 _IDataObjectImpl iDataObject; | 138 _IDataObjectImpl iDataObject; |
138 int refCount; | 139 int refCount; |
141 int dataEffect = DND.DROP_NONE; | 142 int dataEffect = DND.DROP_NONE; |
142 | 143 |
143 static const char[] DEFAULT_DRAG_SOURCE_EFFECT = "DEFAULT_DRAG_SOURCE_EFFECT"; //$NON-NLS-1$ | 144 static const char[] DEFAULT_DRAG_SOURCE_EFFECT = "DEFAULT_DRAG_SOURCE_EFFECT"; //$NON-NLS-1$ |
144 static const char[] DRAGSOURCEID = "DragSource"; //$NON-NLS-1$ | 145 static const char[] DRAGSOURCEID = "DragSource"; //$NON-NLS-1$ |
145 static const int CFSTR_PERFORMEDDROPEFFECT; | 146 static const int CFSTR_PERFORMEDDROPEFFECT; |
147 static final TCHAR[] WindowClass = "#32770\0"; | |
146 static this(){ | 148 static this(){ |
147 CFSTR_PERFORMEDDROPEFFECT = Transfer.registerType("Performed DropEffect"); //$NON-NLS-1$ | 149 CFSTR_PERFORMEDDROPEFFECT = Transfer.registerType("Performed DropEffect"); //$NON-NLS-1$ |
148 } | 150 } |
149 /** | 151 /** |
150 * Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control</code>. | 152 * Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control</code>. |
296 if (!event.doit || transferAgents is null || transferAgents.length is 0 ) return; | 298 if (!event.doit || transferAgents is null || transferAgents.length is 0 ) return; |
297 | 299 |
298 uint[1] pdwEffect; | 300 uint[1] pdwEffect; |
299 int operations = opToOs(getStyle()); | 301 int operations = opToOs(getStyle()); |
300 Display display = control.getDisplay(); | 302 Display display = control.getDisplay(); |
301 char[] key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ | 303 char[] key = "dwt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ |
302 Object oldValue = display.getData(key); | 304 Object oldValue = display.getData(key); |
303 display.setData(key, new ValueWrapperBool(true)); | 305 display.setData(key, new ValueWrapperBool(true)); |
304 ImageList imagelist = null; | 306 ImageList imagelist = null; |
305 Image image = event.image; | 307 Image image = event.image; |
308 hwndDrag = null; | |
309 topControl = null; | |
306 if (image !is null) { | 310 if (image !is null) { |
307 imagelist = new ImageList(DWT.NONE); | 311 imagelist = new ImageList(DWT.NONE); |
308 imagelist.add(image); | 312 imagelist.add(image); |
309 topControl = control.getShell(); | 313 topControl = control.getShell(); |
310 OS.ImageList_BeginDrag(imagelist.getHandle(), 0, 0, 0); | 314 /* |
311 Point location = topControl.getLocation(); | 315 * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT. |
316 * The fix is to create a transparent window that covers the shell client | |
317 * area and use it during the drag to prevent the image from being inverted. | |
318 * On XP if the shell is RTL, the image is not displayed. | |
319 */ | |
320 int offset = 0; | |
321 hwndDrag = topControl.handle; | |
322 if ((topControl.getStyle() & DWT.RIGHT_TO_LEFT) !is 0) { | |
323 offset = image.getBounds().width; | |
324 RECT rect; | |
325 OS.GetClientRect (topControl.handle, &rect); | |
326 hwndDrag = OS.CreateWindowEx ( | |
327 OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT, | |
328 WindowClass.ptr, | |
329 null, | |
330 OS.WS_CHILD | OS.WS_CLIPSIBLINGS, | |
331 0, 0, | |
332 rect.right - rect.left, rect.bottom - rect.top, | |
333 topControl.handle, | |
334 null, | |
335 OS.GetModuleHandle (null), | |
336 null); | |
337 OS.ShowWindow (hwndDrag, OS.SW_SHOW); | |
338 } | |
339 OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offset, 0); | |
312 /* | 340 /* |
313 * Feature in Windows. When ImageList_DragEnter() is called, | 341 * Feature in Windows. When ImageList_DragEnter() is called, |
314 * it takes a snapshot of the screen If a drag is started | 342 * it takes a snapshot of the screen If a drag is started |
315 * when another window is in front, then the snapshot will | 343 * when another window is in front, then the snapshot will |
316 * contain part of the other window, causing pixel corruption. | 344 * contain part of the other window, causing pixel corruption. |
321 OS.UpdateWindow (topControl.handle); | 349 OS.UpdateWindow (topControl.handle); |
322 } else { | 350 } else { |
323 int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; | 351 int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; |
324 OS.RedrawWindow (topControl.handle, null, null, flags); | 352 OS.RedrawWindow (topControl.handle, null, null, flags); |
325 } | 353 } |
326 OS.ImageList_DragEnter(topControl.handle, dragEvent.x - location.x, dragEvent.y - location.y); | 354 POINT pt; |
327 } | 355 pt.x = dragEvent.x; |
328 int result = COM.DoDragDrop(iDataObject, iDropSource, operations, pdwEffect.ptr); | 356 pt.y = dragEvent.y; |
329 if (imagelist !is null) { | 357 OS.MapWindowPoints (control.handle, null, &pt, 1); |
330 OS.ImageList_DragLeave(topControl.handle); | 358 RECT rect; |
331 OS.ImageList_EndDrag(); | 359 OS.GetWindowRect (hwndDrag, &rect); |
332 imagelist.dispose(); | 360 OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top); |
333 topControl = null; | 361 } |
334 } | 362 int result = COM.DRAGDROP_S_CANCEL; |
335 display.setData(key, oldValue); | 363 try { |
364 result = COM.DoDragDrop(iDataObject, iDropSource, operations, pdwEffect.ptr); | |
365 } finally { | |
366 // ensure that we don't leave transparent window around | |
367 if (hwndDrag !is null) { | |
368 OS.ImageList_DragLeave(hwndDrag); | |
369 OS.ImageList_EndDrag(); | |
370 imagelist.dispose(); | |
371 if (hwndDrag !is topControl.handle) OS.DestroyWindow(hwndDrag); | |
372 hwndDrag = null; | |
373 topControl = null; | |
374 } | |
375 display.setData(key, oldValue); | |
376 } | |
336 int operation = osToOp(pdwEffect[0]); | 377 int operation = osToOp(pdwEffect[0]); |
337 if (dataEffect is DND.DROP_MOVE) { | 378 if (dataEffect is DND.DROP_MOVE) { |
338 operation = (operation is DND.DROP_NONE || operation is DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE; | 379 operation = (operation is DND.DROP_NONE || operation is DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE; |
339 } else { | 380 } else { |
340 if (dataEffect !is DND.DROP_NONE) { | 381 if (dataEffect !is DND.DROP_NONE) { |
457 package .LRESULT GiveFeedback(DWORD dwEffect) { | 498 package .LRESULT GiveFeedback(DWORD dwEffect) { |
458 return COM.DRAGDROP_S_USEDEFAULTCURSORS; | 499 return COM.DRAGDROP_S_USEDEFAULTCURSORS; |
459 } | 500 } |
460 | 501 |
461 package .LRESULT QueryContinueDrag(int fEscapePressed, DWORD grfKeyState) { | 502 package .LRESULT QueryContinueDrag(int fEscapePressed, DWORD grfKeyState) { |
503 if (topControl !is null && topControl.isDisposed()) return COM.DRAGDROP_S_CANCEL; | |
462 if (fEscapePressed !is 0){ | 504 if (fEscapePressed !is 0){ |
463 if (topControl !is null) OS.ImageList_DragLeave(topControl.handle); | 505 if (hwndDrag !is null) OS.ImageList_DragLeave(hwndDrag); |
464 return COM.DRAGDROP_S_CANCEL; | 506 return COM.DRAGDROP_S_CANCEL; |
465 } | 507 } |
466 /* | 508 /* |
467 * Bug in Windows. On some machines that do not have XBUTTONs, | 509 * Bug in Windows. On some machines that do not have XBUTTONs, |
468 * the MK_XBUTTON1 and OS.MK_XBUTTON2 bits are sometimes set, | 510 * the MK_XBUTTON1 and OS.MK_XBUTTON2 bits are sometimes set, |
470 * for the extra buttons only when they exist. | 512 * for the extra buttons only when they exist. |
471 */ | 513 */ |
472 int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON; | 514 int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON; |
473 // if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2; | 515 // if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2; |
474 if ((grfKeyState & mask) is 0) { | 516 if ((grfKeyState & mask) is 0) { |
475 if (topControl !is null) OS.ImageList_DragLeave(topControl.handle); | 517 if (hwndDrag !is null) OS.ImageList_DragLeave(hwndDrag); |
476 return COM.DRAGDROP_S_DROP; | 518 return COM.DRAGDROP_S_DROP; |
477 } | 519 } |
478 | 520 |
479 if (topControl !is null) { | 521 if (hwndDrag !is null) { |
480 Display display = getDisplay(); | 522 POINT pt; |
481 Point pt = display.getCursorLocation(); | 523 OS.GetCursorPos (&pt); |
482 Point location = topControl.getLocation(); | 524 RECT rect; |
483 OS.ImageList_DragMove(pt.x - location.x, pt.y - location.y); | 525 OS.GetWindowRect (hwndDrag, &rect); |
526 OS.ImageList_DragMove (pt.x - rect.left, pt.y - rect.top); | |
484 } | 527 } |
485 return COM.S_OK; | 528 return COM.S_OK; |
486 } | 529 } |
487 | 530 |
488 private void onDispose() { | 531 private void onDispose() { |