Date: | July 24, 2008 / year-entry #249 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20080724-00/?p=21483 |
Comments: | 8 |
Summary: | Most people, when they think of the IDropTarget interface, think only of implementing a drop target. But you can read the contract from the other side, because the description of how a drag source interacts with a drop target tells you how to be a drag source. To summarize, the sequence of drop target operations... |
Most people, when they think of the
To summarize, the sequence of drop target operations go like this:
Let's write a simple program that drops one file onto another. #include <windows.h> #include <shlobj.h> #include <shellapi.h> #include <tchar.h> ... Insert the function GetUIObjectOfFile here ... int __cdecl wmain(int argc, WCHAR **argv) { if (argc == 3 && SUCCEEDED(CoInitialize(NULL))) { IDataObject *pdto; if (SUCCEEDED(GetUIObjectOfFile(NULL, argv[1], IID_IDataObject, (void**)&pdto))) { IDropTarget *pdt; if (SUCCEEDED(GetUIObjectOfFile(NULL, argv[2], IID_IDropTarget, (void**)&pdt))) { POINTL pt = { 0, 0 }; DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_LINK; if (SUCCEEDED(pdt->DragEnter(pdto, MK_LBUTTON, pt, &dwEffect))) { dwEffect &= DROPEFFECT_COPY | DROPEFFECT_LINK; if (dwEffect) { pdt->Drop(pdto, MK_LBUTTON, pt, &dwEffect); } else { pdt->DragLeave(); } } pdt->Release(); } pdto->Release(); } CoUninitialize(); } return 0; } This is a pretty straightforward implementation of the host side of the drag/drop protocol. Run this program with the full paths to two files, the first being the file to drop, and the second being the file you want to drop it onto. (Modifying this program to accept relative paths is left as an exercise for the reader.) For example, you might try fakedrop c:\autoexec.bat c:\windows\notepad.exe
Now, sure, dropping a file on a program is nothing exciting.
You could've just run the program with the file as the
command line argument, after all.
But that's looking at it too narrowly;
you are simulating a drop operation,
after all.
For example,
you can drop a file onto a shortcut to a printer, and the
file will print;
or you can drop a file onto a folder and it will be copied
there (since we specified
Oh wait, that last example with
|
Comments (8)
Comments are closed. |
…uhm… the Leave called in both cases?!.. I think it is a typo. The code is correct though.
It’s been a really long time since I played with this stuff, but isn’t there a pointer to a window’s drop target stuffed into one of its properties?
I seem to remember having to hack around this to allow VB6 to support richer drag and drops.
I’m really rusty on my Win32, but was there a way to get a marshalled pointer to that drop target? Curious for old times sake.
Oops… looks like it’s explained here:
"The reason why the taskbar doesn’t do this is that there is no such function GetDropTargetFromWindow function."
http://blogs.msdn.com/oldnewthing/archive/2004/11/24/269237.aspx
I imagine the reason you can’t is because applications should just start the drag and let the user drop it in the right spot. It’s drag and drop, not some form of DDE! :)
Thank you!
I often start a drag&drop operation in IE with e.g. a link by acciedent and don’t want to navigate to that page.
I didn’t know that I could press ESC! That’s a great tip!
(I always tried to drag it to an area that does no harm, like the tray^H^H^H^Hnotification area or let’s say "the clock" ;-) )
So… Is this the preferred way of printing an arbitrary file to a specific printer?
I need to target a specific printer and I can’t render the documents myself. ShellExecute("print", …) only targets the default printer, but I have a specific printer in mind.
Simulating a file drop provides me with a workaround, but I can’t help thinking that there surely must be an easier way. How does the shell trick the document’s application to print to a specific printer?
Rune, have you looked at PrintTo?
Thanks Greg! IFileViewer::PrintTo looks promising, but the description of the IFileViewer interface gives me pause. I’ll just have to give it a try I guess.
Rune, I just meant using the printto verb instead of the print verb in ShellExecute.