Discussion:
Send HDROP data with WM_DROPFILES message.
(too old to reply)
Joseph Scandura
2003-10-20 19:04:41 UTC
Permalink
We assume MS SoundRecorder is running and the file
c:\temp\test.wav exists.

We're trying to send a WM_DROPFILES message to MS
SoundRecorder.
We don't know exactly the format of the structure to send
as an HDROP parameter to the SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L) function.

The message is actually recieved by the Sound Recorder.
However it pops up a message saying:
"File cannot be opened" with random characters (indicating
reading from a non-allocated, or corrupted memory
location) at the end.

We're using the structures STGMEDIUM and DROPFILES as
below.

What are we missing?


int main(int argc, char* argv[])
{
HWND hWndSoundRec = FindWindow ("SoundRec", NULL);

if (hWndSoundRec)
{
HGLOBAL hGlobal = GlobalAlloc (GMEM_FIXED,
sizeof ("k:\\temp\\test.wav") + 2);
char *strFile = (char*) GlobalLock
(hGlobal);
strcpy (strFile, "c:\\temp\\test.wav");
strFile [strlen ("c:\\temp\\test.wav") +
1] = NULL;

POINT point;
point.x = 100;
point.y = 100;

DROPFILES oDropFiles;
oDropFiles.pFiles = (long) &strFile;
oDropFiles.fNC = FALSE;
oDropFiles.fWide = FALSE;
oDropFiles.pt = point;


STGMEDIUM oMedium;
oMedium.tymed = 1;
oMedium.hGlobal = &oDropFiles;

//Send Message with a file reference.
BOOL bSent = SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L);

BOOL bRet = GlobalUnlock (hGlobal);
GlobalFree (hGlobal);
}
return 0;
}
Henk Devos
2003-10-20 22:52:34 UTC
Permalink
wParam should be a HGLOBAL not a STGMEDIUM.
i.e. use the hGlobal you have as the wParam.

Henk Devos
http://www.whirlingdervishes.com
Post by Joseph Scandura
We assume MS SoundRecorder is running and the file
c:\temp\test.wav exists.
We're trying to send a WM_DROPFILES message to MS
SoundRecorder.
We don't know exactly the format of the structure to send
as an HDROP parameter to the SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L) function.
The message is actually recieved by the Sound Recorder.
"File cannot be opened" with random characters (indicating
reading from a non-allocated, or corrupted memory
location) at the end.
We're using the structures STGMEDIUM and DROPFILES as
below.
What are we missing?
int main(int argc, char* argv[])
{
HWND hWndSoundRec = FindWindow ("SoundRec", NULL);
if (hWndSoundRec)
{
HGLOBAL hGlobal = GlobalAlloc (GMEM_FIXED,
sizeof ("k:\\temp\\test.wav") + 2);
char *strFile = (char*) GlobalLock
(hGlobal);
strcpy (strFile, "c:\\temp\\test.wav");
strFile [strlen ("c:\\temp\\test.wav") +
1] = NULL;
POINT point;
point.x = 100;
point.y = 100;
DROPFILES oDropFiles;
oDropFiles.pFiles = (long) &strFile;
oDropFiles.fNC = FALSE;
oDropFiles.fWide = FALSE;
oDropFiles.pt = point;
STGMEDIUM oMedium;
oMedium.tymed = 1;
oMedium.hGlobal = &oDropFiles;
file://Send Message with a file reference.
BOOL bSent = SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L);
BOOL bRet = GlobalUnlock (hGlobal);
GlobalFree (hGlobal);
}
return 0;
}
Jim Barry
2003-10-20 23:24:05 UTC
Permalink
Post by Joseph Scandura
We're trying to send a WM_DROPFILES message to MS
SoundRecorder.
We don't know exactly the format of the structure to send
as an HDROP parameter to the SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L) function.
The message is actually recieved by the Sound Recorder.
"File cannot be opened" with random characters (indicating
reading from a non-allocated, or corrupted memory
location) at the end.
As Henk correctly points out, the WPARAM should be an HGLOBAL containing the DROPFILES structure. Try the following code snippet. It seems to be important to use PostMessage rather than SendMessage, I'm not too sure why that is.

int main(int argc, char* argv[])
{
if (HWND hwnd = FindWindow ("SoundRec", 0))
{
char filename[] = "c:\\temp\\test.wav";
if (HGLOBAL hGlobal =
GlobalAlloc(GHND, sizeof(DROPFILES) + strlen(filename) + 2))
{
DROPFILES * df = static_cast<DROPFILES *>(GlobalLock(hGlobal));
df->pFiles = sizeof(DROPFILES);
strcpy(reinterpret_cast<char *>(df + 1), filename);
GlobalUnlock(hGlobal);
if (!PostMessage(hwnd, WM_DROPFILES, (WPARAM)hGlobal, 0))
GlobalFree(hGlobal);
}
}
return 0;
}
--
Jim Barry, MVP for Windows SDK
"Honor Bound to Defend Freedom" - slogan displayed at the gates of Camp
Delta, Guantanamo Bay, Cuba, where over 600 prisoners are held indefinitely
by the U.S. military, without trial, in defiance of international law.
ilm
2003-10-21 18:06:57 UTC
Permalink
Post by Joseph Scandura
int main(int argc, char* argv[])
{
if (HWND hwnd = FindWindow ("SoundRec", 0))
{
char filename[] = "c:\\temp\\test.wav";
if (HGLOBAL hGlobal =
GlobalAlloc(GHND, sizeof(DROPFILES) + strlen(filename) + 2))
{
DROPFILES * df = static_cast<DROPFILES *>(GlobalLock(hGlobal));
df->pFiles = sizeof(DROPFILES);
strcpy(reinterpret_cast<char *>(df + 1), filename);
GlobalUnlock(hGlobal);
if (!PostMessage(hwnd, WM_DROPFILES, (WPARAM)hGlobal, 0))
GlobalFree(hGlobal);
}
}
return 0;
}
Hey, that's extremely interesting. I suppose a similar technique could
be used to "relay" any WM_DROPFILES message my window receives to a
window in another process? Any idea how that would look like?

Simon
Jim Barry
2003-10-21 23:32:29 UTC
Permalink
Post by ilm
Hey, that's extremely interesting. I suppose a similar technique could
be used to "relay" any WM_DROPFILES message my window receives to a
window in another process? Any idea how that would look like?
How do you mean, other than making sure that DefWindowProc does not get a chance to free the HGLOBAL before it reaches the target?
--
Jim Barry, MVP for Windows SDK
"Honor Bound to Defend Freedom" - slogan displayed at the gates of Camp
Delta, Guantanamo Bay, Cuba, where over 600 prisoners are held indefinitely
by the U.S. military, without trial, in defiance of international law.
ilm
2003-10-23 12:32:05 UTC
Permalink
Post by Jim Barry
Post by ilm
Hey, that's extremely interesting. I suppose a similar technique could
be used to "relay" any WM_DROPFILES message my window receives to a
window in another process? Any idea how that would look like?
How do you mean, other than making sure that DefWindowProc does not get a chance to free the HGLOBAL before it reaches the target?
Well I actually meant making a copy of the entire original message and
all its associated data.
Jim Barry
2003-10-24 00:18:47 UTC
Permalink
Post by ilm
Well I actually meant making a copy of the entire original message and
all its associated data.
There shouldn't be any need to copy the data, the HGLOBAL can just be passed on as-is.

- Jim
unknown
2003-10-24 06:45:25 UTC
Permalink
No it can't. Separate address spaces, y'know.
Post by ilm
Well I actually meant making a copy of the entire original message and
all its associated data.
There shouldn't be any need to copy the data, the HGLOBAL can just be passed
on as-is.

- Jim
Henk Devos
2003-10-24 08:29:20 UTC
Permalink
But in the specific case of HDROP, Windows handles this in some way and
copies the data to the other address space.
Post by unknown
No it can't. Separate address spaces, y'know.
Post by ilm
Well I actually meant making a copy of the entire original message and
all its associated data.
There shouldn't be any need to copy the data, the HGLOBAL can just be passed
on as-is.
- Jim
Paul Baker
2003-10-24 12:57:54 UTC
Permalink
I agree with Jim and Henk. You're thinking too much!

Paul
Post by Henk Devos
But in the specific case of HDROP, Windows handles this in some way and
copies the data to the other address space.
Post by unknown
No it can't. Separate address spaces, y'know.
Post by ilm
Well I actually meant making a copy of the entire original message and
all its associated data.
There shouldn't be any need to copy the data, the HGLOBAL can just be
passed
Post by unknown
on as-is.
- Jim
Jim Barry
2003-10-26 21:51:46 UTC
Permalink
Post by Henk Devos
But in the specific case of HDROP, Windows handles this in
some way and copies the data to the other address space.
Yes, exactly. (Well, not for HDROP generally, but for WM_DROPFILES in particular.) DoDragDrop would otherwise have great difficulty in delivering WM_DROPFILES messages to windows with WS_EX_ACCEPTFILES set. I must correct my earlier statement about freeing the handle - the destination process will receive a copy of the HGLOBAL, so the source process should free the original handle (i.e. call DragFinish) after forwarding it.

- Jim
George
2003-10-26 05:01:14 UTC
Permalink
This technique works for a lot applications, but not work for:
Window Media Player, RealOne Player;
Netscape, Internet Explorer;
Window Explorers.
Post by Jim Barry
Post by Joseph Scandura
We're trying to send a WM_DROPFILES message to MS
SoundRecorder.
We don't know exactly the format of the structure to send
as an HDROP parameter to the SendMessage (hWndSoundRec,
WM_DROPFILES, (WPARAM) &oMedium, 0L) function.
The message is actually recieved by the Sound Recorder.
"File cannot be opened" with random characters (indicating
reading from a non-allocated, or corrupted memory
location) at the end.
As Henk correctly points out, the WPARAM should be an HGLOBAL containing the DROPFILES structure. Try the following code snippet. It seems to be important to use PostMessage rather than SendMessage, I'm not too sure why that is.
int main(int argc, char* argv[])
{
if (HWND hwnd = FindWindow ("SoundRec", 0))
{
char filename[] = "c:\\temp\\test.wav";
if (HGLOBAL hGlobal =
GlobalAlloc(GHND, sizeof(DROPFILES) + strlen(filename) + 2))
{
DROPFILES * df = static_cast<DROPFILES *>(GlobalLock(hGlobal));
df->pFiles = sizeof(DROPFILES);
strcpy(reinterpret_cast<char *>(df + 1), filename);
GlobalUnlock(hGlobal);
if (!PostMessage(hwnd, WM_DROPFILES, (WPARAM)hGlobal, 0))
GlobalFree(hGlobal);
}
}
return 0;
}
Jim Barry
2003-10-26 21:55:33 UTC
Permalink
Post by George
Window Media Player, RealOne Player;
Netscape, Internet Explorer;
Window Explorers.
That will be because these applications do not actually handle the WM_DROPFILES message. Instead, they implement IDropTarget and call RegisterDragDrop. Unfortunately, there is currently no documented method of retrieving the IDropTarget interface associated with a window.

- Jim

a***@discussions.microsoft.com
2003-10-21 17:58:09 UTC
Permalink
Thanks a lot guys, we got it fixed.
Loading...