Mercurial > projects > dwt-win
diff 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 |
line wrap: on
line diff
--- a/dwt/dnd/DragSource.d Mon Mar 17 21:47:05 2008 +0100 +++ b/dwt/dnd/DragSource.d Wed Mar 19 21:48:31 2008 +0100 @@ -131,6 +131,7 @@ Transfer[] transferAgents; DragSourceEffect dragEffect; Composite topControl; + HWND hwndDrag; // ole interfaces _IDropSourceImpl iDropSource; @@ -143,6 +144,7 @@ static const char[] DEFAULT_DRAG_SOURCE_EFFECT = "DEFAULT_DRAG_SOURCE_EFFECT"; //$NON-NLS-1$ static const char[] DRAGSOURCEID = "DragSource"; //$NON-NLS-1$ static const int CFSTR_PERFORMEDDROPEFFECT; + static final TCHAR[] WindowClass = "#32770\0"; static this(){ CFSTR_PERFORMEDDROPEFFECT = Transfer.registerType("Performed DropEffect"); //$NON-NLS-1$ } @@ -298,17 +300,43 @@ uint[1] pdwEffect; int operations = opToOs(getStyle()); Display display = control.getDisplay(); - char[] key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ + char[] key = "dwt.internal.win32.runMessagesInIdle"; //$NON-NLS-1$ Object oldValue = display.getData(key); display.setData(key, new ValueWrapperBool(true)); ImageList imagelist = null; Image image = event.image; + hwndDrag = null; + topControl = null; if (image !is null) { imagelist = new ImageList(DWT.NONE); imagelist.add(image); topControl = control.getShell(); - OS.ImageList_BeginDrag(imagelist.getHandle(), 0, 0, 0); - Point location = topControl.getLocation(); + /* + * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT. + * The fix is to create a transparent window that covers the shell client + * area and use it during the drag to prevent the image from being inverted. + * On XP if the shell is RTL, the image is not displayed. + */ + int offset = 0; + hwndDrag = topControl.handle; + if ((topControl.getStyle() & DWT.RIGHT_TO_LEFT) !is 0) { + offset = image.getBounds().width; + RECT rect; + OS.GetClientRect (topControl.handle, &rect); + hwndDrag = OS.CreateWindowEx ( + OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT, + WindowClass.ptr, + null, + OS.WS_CHILD | OS.WS_CLIPSIBLINGS, + 0, 0, + rect.right - rect.left, rect.bottom - rect.top, + topControl.handle, + null, + OS.GetModuleHandle (null), + null); + OS.ShowWindow (hwndDrag, OS.SW_SHOW); + } + OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offset, 0); /* * Feature in Windows. When ImageList_DragEnter() is called, * it takes a snapshot of the screen If a drag is started @@ -323,16 +351,29 @@ int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; OS.RedrawWindow (topControl.handle, null, null, flags); } - OS.ImageList_DragEnter(topControl.handle, dragEvent.x - location.x, dragEvent.y - location.y); + POINT pt; + pt.x = dragEvent.x; + pt.y = dragEvent.y; + OS.MapWindowPoints (control.handle, null, &pt, 1); + RECT rect; + OS.GetWindowRect (hwndDrag, &rect); + OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top); } - int result = COM.DoDragDrop(iDataObject, iDropSource, operations, pdwEffect.ptr); - if (imagelist !is null) { - OS.ImageList_DragLeave(topControl.handle); - OS.ImageList_EndDrag(); - imagelist.dispose(); - topControl = null; + int result = COM.DRAGDROP_S_CANCEL; + try { + result = COM.DoDragDrop(iDataObject, iDropSource, operations, pdwEffect.ptr); + } finally { + // ensure that we don't leave transparent window around + if (hwndDrag !is null) { + OS.ImageList_DragLeave(hwndDrag); + OS.ImageList_EndDrag(); + imagelist.dispose(); + if (hwndDrag !is topControl.handle) OS.DestroyWindow(hwndDrag); + hwndDrag = null; + topControl = null; + } + display.setData(key, oldValue); } - display.setData(key, oldValue); int operation = osToOp(pdwEffect[0]); if (dataEffect is DND.DROP_MOVE) { operation = (operation is DND.DROP_NONE || operation is DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE; @@ -459,8 +500,9 @@ } package .LRESULT QueryContinueDrag(int fEscapePressed, DWORD grfKeyState) { + if (topControl !is null && topControl.isDisposed()) return COM.DRAGDROP_S_CANCEL; if (fEscapePressed !is 0){ - if (topControl !is null) OS.ImageList_DragLeave(topControl.handle); + if (hwndDrag !is null) OS.ImageList_DragLeave(hwndDrag); return COM.DRAGDROP_S_CANCEL; } /* @@ -472,15 +514,16 @@ int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON; // if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2; if ((grfKeyState & mask) is 0) { - if (topControl !is null) OS.ImageList_DragLeave(topControl.handle); + if (hwndDrag !is null) OS.ImageList_DragLeave(hwndDrag); return COM.DRAGDROP_S_DROP; } - if (topControl !is null) { - Display display = getDisplay(); - Point pt = display.getCursorLocation(); - Point location = topControl.getLocation(); - OS.ImageList_DragMove(pt.x - location.x, pt.y - location.y); + if (hwndDrag !is null) { + POINT pt; + OS.GetCursorPos (&pt); + RECT rect; + OS.GetWindowRect (hwndDrag, &rect); + OS.ImageList_DragMove (pt.x - rect.left, pt.y - rect.top); } return COM.S_OK; }