His reply:
The old way of doing drag and drop, from before the COM based was introduced, uses the DragAcceptFiles API function and the WM_DROPFILES message.
ChangeWindowMessageFilter* only works on windows messages, I.e. it only works with the old WM_DROPFILES based drag drop method.
The Drag and Drop Component Suite does not implement WM_DROPFILES based drag and drop but, as I said, one of demos has a Delphi example of how to do it.
A bit of Googling ( https://www.google.dk/search?q=%22c%2B%2B+builder%22+WM_DROPFILES ) found an old example of how to do it with C++ Builder: What a drag ( http://bcbjournal.org/articles/vol1/9709/What_a_drag!.htm ) !
I'm sure there are many more.{quote}
This is exactly what I needed and I got it working now, tested on: VISTA, Windows 7 and Windows 8.1, no issues on XP.
For the sake of completeness and should other people be looking for this as wel, here is my code:
PS. I find the 'Elevated' state earlier and use a variable, but that's not really necessary I think. Just setting the filter will work ok.
PS2. I use a TreeView object to 'drop' files on.
in the header (.h)
{code}
Classes::TWndMethod TVOldWindowProc;
void __fastcall TVNewWindowProc(Messages::TMessage &Msg) ;
typedef BOOL (WINAPI *PFN_CHANGEWINDOWMESSAGEFILTEREX) (HWND , UINT, DWORD, void* /*PCHANGEFILTERSTRUCT*/ );
PFN_CHANGEWINDOWMESSAGEFILTEREX pfnChangeWindowMessageFilterEx ;
typedef BOOL (WINAPI *PFN_CHANGEWINDOWMESSAGEFILTER) (UINT, DWORD);
PFN_CHANGEWINDOWMESSAGEFILTER pfnChangeWindowMessageFilter ;
{code}
in the constructor (.cpp)
{code}
DragAcceptFiles(TreeView->Handle, true);
TVOldWindowProc = TreeView->WindowProc; ;
TreeView->WindowProc = TVNewWindowProc;
if (Elevated)
{
HMODULE hModule = GetModuleHandle (TEXT("user32.dll"));
pfnChangeWindowMessageFilterEx = (PFN_CHANGEWINDOWMESSAGEFILTEREX) GetProcAddress (hModule, "ChangeWindowMessageFilterEx");
if (!pfnChangeWindowMessageFilterEx) // < Windows 7
{
pfnChangeWindowMessageFilter = (PFN_CHANGEWINDOWMESSAGEFILTER) GetProcAddress (hModule, "ChangeWindowMessageFilter"); // VISTA
}
if (pfnChangeWindowMessageFilterEx)
{
if ((*pfnChangeWindowMessageFilterEx) (TreeView->Handle, WM_DROPFILES, MSGFLT_ADD, NULL) &&
(*pfnChangeWindowMessageFilterEx) (TreeView->Handle, WM_COPYDATA, MSGFLT_ADD, NULL) &&
(*pfnChangeWindowMessageFilterEx) (TreeView->Handle, 0x0049, MSGFLT_ADD, NULL) )
{
/* Success */
}
}
else if (pfnChangeWindowMessageFilter)
{
if ((*pfnChangeWindowMessageFilter) (WM_DROPFILES, MSGFLT_ADD) &&
(*pfnChangeWindowMessageFilter) (WM_COPYDATA, MSGFLT_ADD) &&
(*pfnChangeWindowMessageFilter) (0x0049, MSGFLT_ADD) )
{
/* Success */
}
}
}
{code}
As can be seen in previous code, I subclass the TreeView's WindowProc property:
PS. InitImageFile() is my own code, doing stuff with the dropped file.
{code}
void __fastcall TFinder::TVNewWindowProc(Messages::TMessage &Msg)
{
if( TVOldWindowProc ) TVOldWindowProc( Msg );
if (Msg.Msg == WM_CREATE)
{
if (Elevated)
{
if (pfnChangeWindowMessageFilterEx)
{
if ((*pfnChangeWindowMessageFilterEx) (TreeView->Handle, WM_DROPFILES, MSGFLT_ADD, NULL) &&
(*pfnChangeWindowMessageFilterEx) (TreeView->Handle, WM_COPYDATA, MSGFLT_ADD, NULL) &&
(*pfnChangeWindowMessageFilterEx) (TreeView->Handle, 0x0049, MSGFLT_ADD, NULL) )
{
/* Success */
}
}
else if (pfnChangeWindowMessageFilter)
{
if ((*pfnChangeWindowMessageFilter) (WM_DROPFILES, MSGFLT_ADD) &&
(*pfnChangeWindowMessageFilter) (WM_COPYDATA, MSGFLT_ADD) &&
(*pfnChangeWindowMessageFilter) (0x0049, MSGFLT_ADD) )
{
/* Success */
}
}
}
}
else if (Msg.Msg == WM_DROPFILES)
{
String FileName;
FileName.SetLength(MAX_PATH*2);
int Cnt = DragQueryFile((HDROP)Msg.WParam, -1, NULL, NULL);
for (int x = 0 ; x < Cnt ; x++)
{
DragQueryFile((HDROP)Msg.WParam, x, FileName.c_str(), FileName.Length());
if (FileExists(FileName))
{
InitImageFile(FileName, NULL) ;
}
}
DragFinish((HDROP)Msg.WParam);
}
}
{code}