#14697: Native drag image support (MSW)

38 views
Skip to first unread message

wxTrac

unread,
Sep 25, 2012, 1:42:58 PM9/25/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697>

#14697: Native drag image support (MSW)
-----------------------------------+----------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native | Blockedby:
Patch: 1 | Blocking:
-----------------------------------+----------------------------------------
Add support to wxDataObject, wxDropTarget, wxDropSource to be able to
create a native drag image. Added wxDropSourceHelper which can create an
drag image based on a wxImage or on the image provided by the associated
window. This helper can be initalized explicitly before the drag operation
or implicitly by using the new corresponding functions in wxDropSource.
For MSW the dataobject has been adjusted to accommodate the auxilary
formats which the operating system uses for its own purposes (drag image
bits and other administration).


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697>

wxTrac

unread,
Sep 25, 2012, 2:55:03 PM9/25/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:1>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------
Changes (by vadz):

* keywords: dnd drag image native => dnd drag image native docs-needed
* priority: normal => low
* status: new => confirmed


Comment:

Thanks, this would be useful to have but we really need some documentation
and an example of using this in the dnd sample, otherwise nobody would
even know about it.

I also wonder about the whole idea of "aux data" -- what does it all mean
and what is it for? It would be nice to have some more in depth
explanation of it in the comments.

Also, a couple of minor remarks:

1. Why does `wxDropSourceHelper` need to be public? AFAICS it's only used
in the implementation code.
1. It would be better to avoid including `shlobj.h` from a public header,
forward declaring `IDropTargetHelper` should be enough.
1. `DATASTORAGES` is a really bad name, we don't use all caps for the
type names.
1. It should also use `wxVector<>` instead of `std::vector<>` (nothing in
the rest of the code should need any changes).
1. It seems inconsistent to pass an image to `CreateDragImageFromImage()`
but not a window to `CreateDragImageFromWindow()`.
1. It also looks like it `CreateDragImageFromImage()` should take a
`wxCursor` in the first place because it already is a `wxBitmap` with a
hot spot. Using `wxImage` here is rather strange because if you already
have a `wxCursor`, `wxIcon` or `wxBitmap` you'd need to convert it to
`wxImage` only to convert it back in this code.
1. It would be nice to use style consistent with the rest of the files
you modify, i.e.
* Put spaces around `if` conditions.
* Avoid blank single line comments.

Thanks in advance!


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:1>

wxTrac

unread,
Sep 26, 2012, 6:18:01 AM9/26/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:2>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by PeterO):

Hereby some additional documentation (I don't know exactly where I have to
place this in the comments):

Explanation:

wxDataObject contains the data we want to transfer: text, bitmap etc. To
add data to the data object we use SetData which stores the data in a
specific format. To be able to show a drag image while dragging, even
beyond the borders of our program, the operating system has to store the
image somewhere accessible and in a format known to all clients. Therefore
Windows saves the data image into the data object in a format called
'DragImageBits'. Besides that Windows may save other data in specific
formats for its own housekeeping and extended functionality (eg.
DragSourceHelperFlags, InShellDragLoop, DragContext, IsComputingImage,
IsShowingLayered etc). These formats aren't very well documented.).
So additional to our own SetData calls to set the content data, the
system uses the same SetData to saves its own data. wxDataObject checks if
the format of the data set by SetData is accepted. The Windows formats are
unknown and therefore rejected. But to be able to support the native drag
images we have to accept these formats as well. So if the data hasn't a
format set by the user (the format of the content: text, bitmap etc) we
assume that it's system data and save it in the data object as well. So
now wxDataObject will contain content data (text, bitmap) and system data
(drag image etc). If data is requested from the data object in GetData, a
check is made first if the data is system data else we continue to check
the content formats.

Usage:

To be able to accept drag images (Windows drag images as well, eg.
folder from Explorer) nothing has to be done. wxDropTarget handles all
operations/requests and will show the image.

To be able to create a drag image on starting a drag-drop operation, one
have to call wxDropSource::CreateDragImageFromWindow/Bitmap before calling
DoDragDrop.

Responding to your other questions:

1. dnd sample: The new patch contains a adjusted dnd sample as well. The
window show native window images from outside. Text and shape which will
be dragged from the window will be shown in/outside as well.
1. aux data: The aux data is thus the system data. I've changed the name
'AuxData' to 'SystemData' if that covers the load more clearly.
1. wxDropSourceHelper: I removed it completely. The corresponding
functions in wxDropSource will now do the job.
1. shlobj.h: Has forward declared IDropTargetHelper and moved shlobj.h to
the cpp file.
1. DATASTORAGES: Is called Data now.
1. std::vector<>: Changed to wxVector<>
1. CreateDragImageFromImage: Changed name to CreateDragImageFromBitmap
and accepting now a wxBitmap.
1. CreateDragImageFromWindow: Added window argument.
1. Style consistent: Adjusted but maybe I overlooked something.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:2>

wxTrac

unread,
Sep 29, 2012, 10:42:39 AM9/29/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:3>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by vadz):

Thanks, I understand it much better now.

But I see 2 problems in the dnd sample:

1. If I now drag anything from it, I get a lot of memory leaks on exit. I
didn't have time to debug them but this really should be fixed.
1. This is much more minor, but the drag image for the text is rather
ugly because of the use of "colour key" which replaces some of the pixels
in the text itself with background colour. `SHDRAGIMAGE` documentation
states "Turn off antialiasing when drawing text. Otherwise, artifacts
could occur at the edges, between the text color and the color key." but
we don't provide a simple way to do it. So perhaps we shouldn't be using
the colour key at all instead?

Other than that we also need the documentation for the new
`CreateDragImageFrom{Bitmap,Window}()` methods in `interface/wx/dnd.h`,
could you please add them there and put "@since 2.9.5" in their
description?

Thanks in advance!


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:3>

wxTrac

unread,
Sep 29, 2012, 12:41:54 PM9/29/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:4>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by vadz):

Ah, and one other thing: the patch uses `CopyStgMedium()` which requires
linking with `urlmon.lib` that we don't currently use and so linking
simply fails when using it as is. We probably don't want to require
linking with `urlmon.lib` as this would require people to update all their
projects when upgrading to 2.9 so if we really need this function we
should load it dynamically. But perhaps an even simpler solution would be
to avoid using it and just call `AddRef()` on `STGMEDIUM::IStream` or
`IStorage` member as I think the only types of storage medium we can have
here are `TYMED_ISTREAM` or `TYMED_ISTORAGE`, don't we?


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:4>

wxTrac

unread,
Oct 1, 2012, 11:29:33 AM10/1/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:5>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by PeterO):

I applied your suggestions:

1. Regarding the dnd sample: The memory leak has been solved and the
quality of the text drag image improved.
1. I've adjusted the documentation.
1. I've created a local implementation !CopyStgMedium, so urlmon.lib is
not necessary anmore.

Patch v3 contains it all.

Regards,

Peter


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:5>

wxTrac

unread,
Oct 12, 2012, 8:32:09 PM10/12/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:6>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by vadz):

Sorry for the delay, I've finally looked at this patch again and will
apply its `wxDropTarget` part soon with only minor changes. The most
important of them is that I did '''not''' make the various drag image
support functions virtual, I really don't think this makes much sense and
I'd rather not make them part of public API at all to be able to change
them in the future.

I'm much more ambivalent about the `wxDropSource` part though because:

1. It's not clear how does this combine with the existing
`wxDropSource::SetCursor()`, perhaps it would be better to extend the
existing function to cover this functionality instead of adding a new one?
They do seem rather similar.
1. Related: it doesn't look like it's ever going to be possible to
implement something so MSW-specific for the other platforms. Again,
`SetCursor()` interface is much more reasonable from portability point of
view.
1. Using a window for drag image doesn't seem to work well for me, the
"window" image is always empty and doesn't represent the actual window
contents at all. Any idea why?

Anyhow, I'm attaching my modified version of the patch but I think it
needs more work before being applied and probably some API rethink.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:6>

wxTrac

unread,
Oct 13, 2012, 6:53:48 PM10/13/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:7>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by VZ):

(In [72668]) Display system-provided drag images during drag-and-drop in
wxMSW.

This is especially useful when dragging files from Explorer as it provides
big, informative drag images for them that can be easily displayed using
Windows shell support for them.

See #14697.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:7>

wxTrac

unread,
Oct 14, 2012, 9:46:20 AM10/14/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:8>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by PeterO):

About remark nr. 3:

The Microsoft documentation explains that on invoking
DragSourceHelper::InitializeFromWindow, ''the window receives a
DI_GETDRAGIMAGE message whereby lparam holds a pointer to an SHDRAGIMAGE
structure. The handler should fill the structure with the drag image
bitmap information.'' (See http://msdn.microsoft.com/en-
us/library/windows/desktop/bb762036(v=vs.85).aspx).

So a window has to have a handler that fills the structure with bitmap
info. Just a basic wxWindow (or derived window) will do nothing. But
wxListCtrl/wxTreeCtrl do have them. They are based on the native Windows
list/tree view which handles this event and filling the structure with an
appropriate bitmap based on the dragged items.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:8>

wxTrac

unread,
Oct 14, 2012, 10:43:00 AM10/14/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:9>

#14697: Native drag image support (MSW)
-----------------------------------------------+----------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: confirmed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Keywords: dnd drag image native docs-needed | Blockedby:
Patch: 1 | Blocking:
-----------------------------------------------+----------------------------

Comment(by VZ):

(In [72673]) Provide stand-in IDropTargetHelper definition to fix VC6
build.

VC6 SDK doesn't define this interface, so do it ourselves to fix its build
after the changes of r72668.

See #14697.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:9>

wxTrac

unread,
Oct 14, 2012, 10:55:34 AM10/14/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:10>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: closed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: fixed | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------
Changes (by VZ):

* status: confirmed => closed
* resolution: => fixed


Comment:

(In [72674]) Make GetClippingBox() work for wxPrinterDC in wxGTK.

GetClippingBox() implementation relies on wxDCImpl::m_clip[XY][12] being
updated in DoSetClippingRegion() but this wasn't done here. Fix this by
adding
the code to do this to the base class version of this method and calling
it
from wxGtkPrinterDCImpl.

Also, refactor wxGCDCImpl to reuse the same code instead of duplicating
it.

Closes #14697.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:10>

wxTrac

unread,
Oct 14, 2012, 10:57:25 AM10/14/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:11>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: reopened
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------
Changes (by vadz):

* status: closed => reopened
* resolution: fixed =>


Comment:

Replying to [comment:8 PeterO]:
> About remark nr. 3:
>
> The Microsoft documentation explains that on invoking
DragSourceHelper::InitializeFromWindow, ''the window receives a
DI_GETDRAGIMAGE message whereby lparam holds a pointer to an SHDRAGIMAGE
structure. The handler should fill the structure with the drag image
bitmap information.'' (See http://msdn.microsoft.com/en-
us/library/windows/desktop/bb762036(v=vs.85).aspx).
>
> So a window has to have a handler that fills the structure with bitmap
info. Just a basic wxWindow (or derived window) will do nothing. But
wxListCtrl/wxTreeCtrl do have them. They are based on the native Windows
list/tree view which handles this event and filling the structure with an
appropriate bitmap based on the dragged items.

I see, thanks, I didn't know about this message. So actually we'd also
need to have a matching event (or maybe MSW-only virtual callback) to
allow providing it if we do this...

P.S. Sorry for the above commit message with a wrong ticket number, it was
a typo and is unrelated to this ticket.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:11>

wxTrac

unread,
Oct 16, 2012, 4:40:44 PM10/16/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:12>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: reopened
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------

Comment(by chowette):

Replying to [comment:9 VZ]:
> (In [72673]) Provide stand-in IDropTargetHelper definition to fix VC6
build.
>
> VC6 SDK doesn't define this interface, so do it ourselves to fix its
build
> after the changes of r72668.
>
> See #14697.

Unfortunately, VC6 is also missing declaration of {{{ CLSID_DragDropHelper
}}}
see [http://buildbot.tt-
solutions.com/wx/builders/XPSP2%20VC6%20wxMSW%20trunk%20release/builds/2772/steps/compile/logs/stdio]


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:12>

wxTrac

unread,
Oct 16, 2012, 6:28:22 PM10/16/12
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:13>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: closed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: fixed | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------
Changes (by VZ):

* status: reopened => closed
* resolution: => fixed


Comment:

(In [72692]) Define CLSID_DragDropHelper ourselves to fix VC6 build.

VC6 SDK doesn't define CLSID_DragDropHelper constant neither, so do it
ourselves too to complete the changes of r72673.

Closes #14697.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:13>

wxTrac

unread,
Mar 4, 2014, 9:07:20 AM3/4/14
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:14>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: closed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: fixed | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------

Comment(by VZ):

(In [76076]) Don't accept data in unsupported format in wxMSW dnd code.

We wrongly pretended to accept the data in formats which we didn't
actually
accept and showed misleading cursors to the user.

Fix this by partially reverting some of the changes of r72668 (see
#14697).

Closes #16042.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:14>

wxTrac

unread,
Mar 4, 2014, 9:07:50 AM3/4/14
to wx-...@googlegroups.com
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:15>

#14697: Native drag image support (MSW)
--------------------------+-------------------------------------------------
Reporter: PeterO | Owner:
Type: enhancement | Status: closed
Priority: low | Milestone:
Component: wxMSW | Version: 2.9.4
Resolution: fixed | Keywords: dnd drag image native docs-needed
Blockedby: | Patch: 1
Blocking: |
--------------------------+-------------------------------------------------

Comment(by VZ):

(In [76078]) Don't accept data in unsupported format in wxMSW dnd code.

We wrongly pretended to accept the data in formats which we didn't
actually
accept and showed misleading cursors to the user.

Fix this by partially reverting some of the changes of r72668 (see
#14697).

Closes #16042.


--
Ticket URL: <http://trac.wxwidgets.org/ticket/14697#comment:15>
Reply all
Reply to author
Forward
0 new messages