Click here to Skip to main content
15,175,960 members
Articles / Mobile Apps / Windows Phone 7
Technical Blog
Posted 25 Aug 2010

Tagged as

Stats

24.7K views
10 bookmarked

How to Enable Drag and Drop for an Elevated MFC Application on Vista/Windows 7

Rate me:
Please Sign up or sign in to vote.
4.75/5 (4 votes)
25 Aug 2010CPOL2 min read
How to enable drag and drop for an elevated MFC application on Vista/Windows 7

Finding good information on how to enable drag and drop for MFC applications is hard enough (why?). But just when you think you should have it working, you hit a very solid wall: UIPI (User Interface Privilege Isolation, a variant of UAC, User Account Control). Because of "security" reasons, UIPI disables drag and drop from medium integrity processes (Explorer) to high integrity (aka elevated) processes by filtering out most window messages, including those required for drag and drop. In essence, drag and drop from Explorer to your elevated application does not work.

To waste your time, Microsoft added the API function ChangeWindowMessageFilter that lets specific window messages through (punching a hole in the UIPI "firewall"), but just adding WM_DROPFILES to the list of allowed messages does not help. Drag and drop uses more than just WM_DROPFILES. But where is a list of the window messages required for drag and drop? Even the venerable Raymond Chen refused to explain how to make it work. Well, here is how.

Basic Drag and Drop

This assumes you have a dialog-based MFC application. I have implemented this with Visual Studio 2008 SP1.

C++
DragAcceptFiles ();         // entire dialog
m_oPath.DragAcceptFiles (); // control represented by variable m_oPath
C++
BEGIN_MESSAGE_MAP(<dialog class name>, CDialog)
ON_WM_DROPFILES()
END_MESSAGE_MAP()
C++
afx_msg void OnDropFiles(HDROP hDropInfo);
  1. In your dialog's OnInitDialog method, enable drag and drop. You can either do this for the entire dialog or a specific control:
  2. Add ON_WM_DROPFILES() to your message map, e.g.:
  3. Add an event handler for drop events. In your dialog's header file:

And in the CPP file:

C++
void <dialog class name>::OnDropFiles (HDROP dropInfo)
{
CString sFile;
DWORD nBuffer = 0;

// Get the number of files dropped
UINT nFilesDropped = DragQueryFile (dropInfo, 0xFFFFFFFF, NULL, 0);

// If more than one, only use the first
if (nFilesDropped > 0)
{
// Get the buffer size for the first filename
nBuffer = DragQueryFile (dropInfo, 0, NULL, 0);

// Get path and name of the first file
DragQueryFile (dropInfo, 0, sFile.GetBuffer (nBuffer + 1), nBuffer + 1);
sFile.ReleaseBuffer ();

// Do something with the path
}

// Free the memory block containing the dropped-file information
DragFinish(dropInfo);
}

UAC and Elevation

Now comes the interesting part. All of the above will work - unless your application runs elevated. As mentioned earlier, WM_DROPFILES messages are simply filtered out by UIPI. You can re-enable individual messages by calling ChangeWindowMessageFilter (<message>, MSGFLT_ADD), but enabling WM_DROPFILES alone is not sufficient. Here is my first attempt to work around that:

C++
for (int i = 0; i <= WM_DROPFILES; i++)
{
ChangeWindowMessageFilter (i, MSGFLT_ADD);
}

Hooray! Drag and drop works! But letting all messages through is probably a little bit too much. So I tried to narrow things down.

After some trial and error, I came up with the following list of messages you need to allow through the UIPI filter in order to enable drag and drop:

C++
ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter (0x0049, MSGFLT_ADD);

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

HelgeKlein
Helge Klein GmbH
Germany Germany
Helge Klein is an independent consultant and developer. As a consultant, he has worked in Windows and Citrix projects for various larger German corporations. As a developer, he architected sepago's user profile management product sepagoPROFILE whose successor is now available as Citrix Profile Management. In 2009 Helge received the Citrix Technology Professional (CTP) Award, in 2011 he was nominated a Microsoft Most Valuable Professional (MVP).

Helge's professional interests are focused on Microsoft server technologies, various Citrix products and programming in several languages. He publishes his knowledge in English in his blog at http://helgeklein.com/blog. Helge can also be found on Twitter as @HelgeKlein. He has presented on many occasions, e.g. Citrix TechEdge Munich 2009, ice Lingen (2009 and 2011), PubForum (2010 and 2011), Microsoft TechDay Online 2010, Citrix Synergy 2011 and 2012.

Helge is the author of SetACL, a powerful tool for managing Windows permissions from the command line or from scripts and programs. SetACL is open source and has been downloaded more than 500,000 times. SetACL's modern cousin SetACL Studio comes with an intuitive graphical user interface and is available for a small fee. Another popular tool, Delprof2, automates the deletion of user profiles.

Helge lives in Cologne, Germany.

Comments and Discussions

 
Questionit doesn't work Pin
SB200319-Jul-20 8:29
MemberSB200319-Jul-20 8:29 
GeneralCOleDropTarget::Register Pin
David Pritchard16-Jul-15 5:55
MemberDavid Pritchard16-Jul-15 5:55 
Generalif only it would work for RegisterDragDrop Pin
umeca745-Mar-11 2:03
Memberumeca745-Mar-11 2:03 
GeneralRe: if only it would work for RegisterDragDrop Pin
guozhaowen1-Aug-11 23:08
Memberguozhaowen1-Aug-11 23:08 
GeneralRe: if only it would work for RegisterDragDrop Pin
Member 1085110424-Apr-18 15:28
MemberMember 1085110424-Apr-18 15:28 
QuestionVB Version? Pin
Marcin H30-Aug-10 11:08
MemberMarcin H30-Aug-10 11:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.