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() {