tags:

views:

522

answers:

3

I'm trying to decipher CHtmlView's behaviour when files are dragged into the client area, so I've created a new MFC app and commented out the CHtmlView line that navigates to MSDN on startup. In my main frame, I've overridden CWnd::OnDropFiles() with a function that shows a message box, to see when WM_DROPFILES is sent.

OnDropFiles() gets triggered on all except the first time you try to drag a file into the application. Uniquely, that first time appears to be interpreted by the application as a request to display the data in the file rather than a request to open the file. I've tried overriding OnDrop() from the view class, but it's never called.

Why is the first time different? How can I catch all attempts to drag a file into my app?

A: 

What I would recommend is to switch to HTMLayout -- it's waaaay better than CHtmlView.

Anton Gogolev
Thanks, but I've already found a workaround that would be less hassle than incorporating third-party code: navigate to a blank page on startup. What I'm after is an answer to the question about CHtmlView.
Tommy Herbert
A: 

Preface: I'm extrapolating from documentation I've found, and am not concerned if I'm wrong. Please make sure the following explanation makes sense, ie try it, before voting-up my answer or accepting it :)

After Googling OnDropFiles, I discovered that it's inherited from the CWnd class: (MSDN page)


According to that MSDN article:

Parameters
hDropInfo

A pointer to an internal data structure that describes the dropped files. This handle is used by the DragFinish, DragQueryFile, and DragQueryPoint Windows functions to retrieve information about the dropped files.

Quoting later:

"The framework calls this member function when the user releases the left mouse button over a window that has registered itself as the recipient of dropped files.

"Typically, a derived class will be designed to support dropped files and it will register itself during window construction.

This member function is called by the framework to allow your application to handle a Windows message. The parameters passed to your function reflect the parameters received by the framework when the message was received. If you call the base-class implementation of this function, that implementation will use the parameters originally passed with the message and not the parameters you supply to the function."


That appears to indicate that until the function has been registered, it won't work 'as expected'.

Therefore, I believe that what's happening is that the first time you drop something onto the CHTMLView, it registers itself, and only then 'works as expected'.

If my understanding is correct, then a new question is raised, which is how can you force the registration of the View. From the related links on the MSDN Technote, it looks like you can force DragAcceptFiles (see here) to run, which would otherwise be triggered when the drop event finished.

warren
Thanks for looking into it, but I think that's not it. DragAcceptFiles() is called from the boilerplate code generated for the app class's InitInstance() function. InitInstance() runs when the program launches, and has certainly finished before I start dragging and dropping things.
Tommy Herbert
ok - well, that's what it looked like. Sorry it wasn't right.
warren
+1  A: 

This is part of the underlying WebBrowser control behaviour. CHtmlView sets RegisterAsDropTarget to true by default, which means the control intercepts the drop operation and performs its own processing.

If you want to inhibit it, call SetRegisterAsDropTarget(FALSE) in your OnInitialUpdate implementation. All drop operations will then interact with the main window.

Sunlight
Brilliant - thanks!
Tommy Herbert