Question

I have created a Dialog using WTL, inheriting from CDialogImpl class, inside the main dialog I have created another dialog and inside this second child dialog a list control. I wanted to add drag& drop functionality to the list control, I have read on the web about the WM_DROPFILES method and about the Ole Drop Target, I have chosen the later one. I have implemented the IDropTarget interface methods in accordance to this. I have set the accept files option to TRUE in all my dialogues, I have instantiated the IDropTarget in the child dialogue class and called the following methods in its WM_INITDIALOGUE handler:

//drag& drop 
        lpDropTarget = (LPDROPTARGET)new TDropTarget(m_hWnd);
        CoLockObjectExternal(lpDropTarget, true, true);

        // register the HWND as a drop target
        RegisterDragDrop(m_hWnd, lpDropTarget);

lpDropTarget is instantiated as follows:

LPDROPTARGET lpDropTarget;

And that's about it. Haven't really used Ole before so I have tried the following scenarios in search of luck:

  1. I have registered with RegisterDragDrop for the List control HWND and set it's parent dialogue to receive the notification WM_OLEDROP WM_USER + 1 that I send. Ok the cursor for drag & drop showed but no calls to the implementation of the functions of IDataTarget.

  2. RegisterDragDrop for child dialogue & notifications for it also.

  3. RegisterDragDrop for the main Dialog & notifications for it also.

In the later cases ( 2 & 3) the cursor for drag& drop didn't even appeared, it showed me the no-drag & drop allowed one. Now, all the dialogues and list control have been set to accept files from the visual studio designer. I am limited to using only ATL /WTL/WINAPI, no MFC. What am I doing wrong?

Was it helpful?

Solution

For you WM_DROPFILES is the only thing you need to handle. No need to fiddle with IDropTarget etc.

If your application does not need to run in Admin mode, do not run it in admin mode. Disable the linker setting for the same (UAC Execution Level = asInvoker). Also, run VS in non-Admin mode, so that your application also starts are non-Admin process. This way, Explorer.exe would be able to send WM_DROPFILES message to your application.

If your application need to run as Admin mode, you need to allow other applications to send set of few messages to your application (window). Do the following:

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

You may also want to use newer function: ChangeWindowMessageFilterEx.

Note that, if your application must run as Admin, and you need to dynamically locate one of these function using GetProcAddress, so that your application can run on OS where this function is not available (eg. Windows XP).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top