Article

From:
To:
Peter Van Hove
Subject:
Re: Drag & Drop to elevated app on Windows 8 fails [Edit]
Newsgroup:
embarcadero.public.cppbuilder.nativeapi

Re: Drag & Drop to elevated app on Windows 8 fails [Edit]

As reported I asked Anders Melander to weigh in because I'm using the TDropFileTarget component from Anders' Drag&Drop suite ( http://melander.dk/delphi/dragdrop/ )

His reply:

{quote}The Drag and Drop Component Suite implements COM based drag and drop. See Transferring Shell Objects with Drag-and-Drop and the Clipboard ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb776905%28v=vs.85%29.aspx ) for a longer explanation.

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}
FYI: Phrase searches are enclosed in either single or double quotes
 
 
Originally created by
Tamarack Associates
Fri, 29 Mar 2024 05:05:49 UTC
Copyright © 2009-2024
HREF Tools Corp.