Bug 187125 - [DND] Image effect not showing in RTL - for 3.3.1
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
index 5aea527..e97018a 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
@@ -102,6 +102,7 @@
Transfer[] transferAgents = new Transfer[0];
DragSourceEffect dragEffect;
Composite topControl;
+ int hwndDrag;
// ole interfaces
COMObject iDropSource;
@@ -114,6 +115,7 @@
static final String DEFAULT_DRAG_SOURCE_EFFECT = "DEFAULT_DRAG_SOURCE_EFFECT"; //$NON-NLS-1$
static final String DRAGSOURCEID = "DragSource"; //$NON-NLS-1$
static final int CFSTR_PERFORMEDDROPEFFECT = Transfer.registerType("Performed DropEffect"); //$NON-NLS-1$
+ static final TCHAR WindowClass = new TCHAR (0, "#32770", true);
/**
* Creates a new <code>DragSource</code> to handle dragging from the specified <code>Control</code>.
@@ -297,12 +299,38 @@
display.setData(key, new Boolean(true));
ImageList imagelist = null;
Image image = event.image;
+ hwndDrag = 0;
+ topControl = null;
if (image != null) {
imagelist = new ImageList(SWT.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() & SWT.RIGHT_TO_LEFT) != 0) {
+ offset = image.getBounds().width;
+ RECT rect = new RECT ();
+ OS.GetClientRect (topControl.handle, rect);
+ hwndDrag = OS.CreateWindowEx (
+ OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT,
+ WindowClass,
+ null,
+ OS.WS_CHILD | OS.WS_CLIPSIBLINGS,
+ 0, 0,
+ rect.right - rect.left, rect.bottom - rect.top,
+ topControl.handle,
+ 0,
+ 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
@@ -317,16 +345,27 @@
int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
OS.RedrawWindow (topControl.handle, null, 0, flags);
}
- OS.ImageList_DragEnter(topControl.handle, dragEvent.x - location.x, dragEvent.y - location.y);
+ POINT pt = new POINT ();
+ pt.x = dragEvent.x;
+ pt.y = dragEvent.y;
+ OS.MapWindowPoints (0, hwndDrag, pt, 1);
+ OS.ImageList_DragEnter(hwndDrag, pt.x, pt.y);
}
- int result = COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
- if (imagelist != null) {
- OS.ImageList_DragLeave(topControl.handle);
- OS.ImageList_EndDrag();
- imagelist.dispose();
- topControl = null;
+ int result = COM.DRAGDROP_S_CANCEL;
+ try {
+ result = COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect);
+ } finally {
+ // ensure that we don't leave transparent window around
+ if (hwndDrag != 0) {
+ OS.ImageList_DragLeave(hwndDrag);
+ OS.ImageList_EndDrag();
+ imagelist.dispose();
+ if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag);
+ hwndDrag = 0;
+ topControl = null;
+ }
+ display.setData(key, oldValue);
}
- display.setData(key, oldValue);
int operation = osToOp(pdwEffect[0]);
if (dataEffect == DND.DROP_MOVE) {
operation = (operation == DND.DROP_NONE || operation == DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE;
@@ -453,8 +492,9 @@
}
private int QueryContinueDrag(int fEscapePressed, int grfKeyState) {
+ if (topControl != null && topControl.isDisposed()) return COM.DRAGDROP_S_CANCEL;
if (fEscapePressed != 0){
- if (topControl != null) OS.ImageList_DragLeave(topControl.handle);
+ if (hwndDrag != 0) OS.ImageList_DragLeave(hwndDrag);
return COM.DRAGDROP_S_CANCEL;
}
/*
@@ -466,15 +506,15 @@
int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON;
// if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2;
if ((grfKeyState & mask) == 0) {
- if (topControl != null) OS.ImageList_DragLeave(topControl.handle);
+ if (hwndDrag != 0) OS.ImageList_DragLeave(hwndDrag);
return COM.DRAGDROP_S_DROP;
}
- if (topControl != 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 != 0) {
+ POINT pt = new POINT ();
+ OS.GetCursorPos (pt);
+ OS.MapWindowPoints (0, hwndDrag, pt, 1);
+ OS.ImageList_DragMove(pt.x, pt.y);
}
return COM.S_OK;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
index a134b26..e7bf47e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -89,6 +89,11 @@
}
int hDC = OS.GetDC(0);
int hDC1 = OS.CreateCompatibleDC(hDC);
+ if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) {
+ if ((table.getStyle() & SWT.RIGHT_TO_LEFT) != 0) {
+ OS.SetLayout(hDC1, OS.LAYOUT_RTL | OS.LAYOUT_BITMAPORIENTATIONPRESERVED);
+ }
+ }
int bitmap = OS.CreateCompatibleBitmap(hDC, bounds.width, bounds.height);
int hOldBitmap = OS.SelectObject(hDC1, bitmap);
RECT rect = new RECT();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
index 0beb423..5e793db 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -86,7 +86,7 @@
for (int i = 1; i < count; i++) {
bounds = bounds.union(selection[i].getBounds(0));
}
- int hDC = OS.GetDC(0);
+ int hDC = OS.GetDC(tree.handle);
int hDC1 = OS.CreateCompatibleDC(hDC);
int bitmap = OS.CreateCompatibleBitmap(hDC, bounds.width, bounds.height);
int hOldBitmap = OS.SelectObject(hDC1, bitmap);
@@ -104,7 +104,7 @@
}
OS.SelectObject(hDC1, hOldBitmap);
OS.DeleteDC (hDC1);
- OS.ReleaseDC (0, hDC);
+ OS.ReleaseDC (tree.handle, hDC);
Display display = tree.getDisplay();
dragSourceImage = Image.win32_new(display, SWT.BITMAP, bitmap);
return dragSourceImage;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index 4db838a..da7d192 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -827,6 +827,7 @@
public static final int LANG_NEUTRAL = 0x0;
public static final int LANG_USER_DEFAULT = 1 << 10;
public static final int LAYOUT_RTL = 0x1;
+ public static final int LAYOUT_BITMAPORIENTATIONPRESERVED = 0x8;
public static final int LBN_DBLCLK = 0x2;
public static final int LBN_SELCHANGE = 0x1;
public static final int LBS_EXTENDEDSEL = 0x800;