问题
The big picuture: I am trying to inject my own own wrapper around explorer's drag n drop. My code is injected into explorer, and I try to replace the drop target with my own.
In order to do this I am doing:
- Find all explorer windows (using EnumWindows and checking process association for each window).
- For each window I am running the following (do nothing) code:
IDropTarget* lpDT = (IDropTarget *)GetProp(hwnds[i], L"OleDropTargetInterface"); //get existing drop target
HRESULT res1 = ::RevokeDragDrop(hwnds[i]); //revoke existing drop target
HRESULT res2 = ::RegisterDragDrop(hwnds[i], lpDT); //and re-register the drop target
For now, the code does not change the drop target. I am simply un-registering and re-registering the same target.
After running it on all explorer windows I get res1 == "The application called an interface that was marshalled for a different thread." for every window I find.
If I ignore the error (just for testing), and go ahead with replacement, the then explorer stops dragging files on the desktop (just to change the icon location). Btw, surprisingly, dragging files between 2 different folders still works.
My code is running from an explorer thread (injected into explorer).
Is there any way around this problem?
回答1:
The GetProp returns a pointer to the drop target without caring about marshaling it (pure pointer). As pointed out to me in this answer, although I am getting a pointer to the drop target, it is not really marshaled to my thread. I can tell you that calling revokeDragDrop on the pointer (even if it did not really belong to my thread) was messing up the drop target, and then failing.
Since I have no way of obtaining the drop target from the other thread holding it, I gave up on this and took an alternate route.
来源:https://stackoverflow.com/questions/10697991/hooking-explorer-drag-drop-fails