|
-
June 17th, 2009, 08:18 PM
#1
Implementing drag n drop in a CRichEditView?
I have an SDI app (VS 2005, C++) that serializes a unique type of binary file with a unique (I think) suffix, *.mtx. I would like to be able to drag an *.mtx file from Windows Explorer to the CRichEditView main window of the interface. I could easily implement such a process provided that I could intercept the file path of the dragged and dropped file. As it is, the drag n drop action only produces a graphic square with the filename in it.
There are several methods available to the CRichEditView which appear relevant to the problem. These are: OnDragEnter, OnDragLeave, OnDragOver, OnDrop. In addition, there is apparently an OnBeginDrag which does not appear in the ProprertyPage class view for CRichEditView, but has appeared on several postings on the subject.
As a first step, I would like to capture the pathname of the file that a user drags onto the CREView window. The following code doesnt ever get called during a drag n drop of an *.mtx file
Code:
BOOL CMyRichEditView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
{
// TODO: Add your specialized code here and/or call the base class
CFile * pFile = pDataObject->GetFileData(CF_TEXT);
CString csFileName = pFile->GetFileName();
CString csFilePath = pFile->GetFilePath();
MessageBox(csFileName);
return CRichEditView::OnDrop(pDataObject, dropEffect, point);
}
Can anyone help me to capture the drop file name?
mpliam
-
June 19th, 2009, 09:46 PM
#2
Re: Implementing drag n drop in a CRichEditView?
Sorry to be a drag about it, but I havn't been able to solve this problem on my own.
Microsoft says, right in the VC 2005 OnEnDropfiles override method for CRichEditView
// The control will not send OnEnDropfiles notification unless you override the
// CRichEditView::OnInitDialog() function to send the EM_SETEVENTMASK message
// to the control with the ENM_DROPFILES flag ORed into the lParam mask.
OK. Sounds simple enough. So I set up a trial SDI app cleverly named 'RichDrag' with the following code snippets:
Code:
void CRichDragView::OnInitialUpdate()
{
CRichEditView::OnInitialUpdate();
LRESULT lResult = SendMessage(EM_GETEVENTMASK, 0, 0);
SendMessage(EM_SETEVENTMASK, 0, lResult |ENM_DROPFILES | ENM_DRAGDROPDONE);
//SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0);
// Set the printing margins (720 twips = 1/2 inch)
SetMargins(CRect(720, 720, 720, 720));
}
//..
void CRichDragView::OnEnDropfiles(NMHDR *pNMHDR, LRESULT *pResult)
{
ENDROPFILES *pEnDropFiles = reinterpret_cast<ENDROPFILES *>(pNMHDR);
// TODO: The control will not send this notification unless you override the
// CRichEditView::OnInitDialog() function to send the EM_SETEVENTMASK message
// to the control with the ENM_DROPFILES flag ORed into the lParam mask.
// TODO: Add your control notification handler code here
TRACE0("Notified file dropped\n");
*pResult = 0;
}
But when I drag a *.txt (app default) or any other file onto the RichEditView from Windows Explorer, I get a neat little box with the filename in it, but the OnEnDropfiles function never gets called.
Can't someone please tell me what I am doing wrong?
mpliam
-
June 22nd, 2009, 04:58 AM
#3
Re: Implementing drag n drop in a CRichEditView?
Hi Mike.
Microsoft says that you have to send the EM_SETEVENTMASK message to the CONTOL not to the View itself. Try something like this in your OnInitialUpdate handler:
Code:
...
CRichEditCtrl *reCtrl = GetRichEditCtrl();
LRESULT lResult = reCtrl->SendMessage(EM_GETEVENTMASK, 0, 0);
reCtrl->SendMessage(EM_SETEVENTMASK, 0, lResult |ENM_DROPFILES | ENM_DRAGDROPDONE);
...
regards
Markus
-
June 23rd, 2009, 02:22 PM
#4
Re: Implementing drag n drop in a CRichEditView?
Thanks, Markus. Sounds like a good idea, but it doesnt work.
FWIW, you need designate GetrichEditCtrl() as an address in memory.
Code:
...
CRichEditCtrl *reCtrl = &GetRichEditCtrl();
LRESULT lResult = reCtrl->SendMessage(EM_GETEVENTMASK, 0, 0);
reCtrl->SendMessage(EM_SETEVENTMASK, 0, lResult |ENM_DROPFILES | ENM_DRAGDROPDONE);
...
In any case, OnEnDropfiles never gets called when dragging a file from the Windows Explorer and dropping it onto the CRichEditView window. The result is exactly the same as described above. 
Furthermore, check this out: http://msdn.microsoft.com/en-us/libr...66(VS.85).aspx
The EN_DROPFILES message notifies a rich edit control parent window that the user is attempting to drop files into the control. A rich edit control sends this notification message in the form of a WM_NOTIFY message when it receives the WM_DROPFILES message. wParam Specifies the control identifier. lParam Pointer to an ENDROPFILES structure that receives dropped files information. For a rich edit control to receive WM_DROPFILES messages, the parent window must register the control as a drop target by using the DragAcceptFiles function. The control does not register itself. To receive EN_DROPFILES notifications, specify ENM_DROPFILES in the mask sent with the EM_SETEVENTMASK message.
But this doesnt work either:
Code:
CRichEditCtrl *reCtrl = &GetRichEditCtrl();
LRESULT lResult = reCtrl->SendMessage(EM_GETEVENTMASK, 0, 0);
reCtrl->SendMessage(EM_SETEVENTMASK, 0, lResult |ENM_DROPFILES | ENM_DRAGDROPDONE);
reCtrl->DragAcceptFiles(1);
DragAcceptFiles(1);
Some strange sh%$ going on here.
Last edited by Mike Pliam; June 23rd, 2009 at 04:01 PM.
mpliam
-
June 24th, 2009, 06:11 AM
#5
Re: Implementing drag n drop in a CRichEditView?
What if you just add a handler for the WM_DROPFILES message to your view class? It is possible to get the filename via DragQueryFile in there.
Have a look at this:
http://www.codeguru.com/cpp/cpp/cpp_...rint.php/c4059
Last edited by maglite; June 24th, 2009 at 06:14 AM.
-
June 24th, 2009, 11:57 AM
#6
Re: Implementing drag n drop in a CRichEditView?
Nice try, maglite, but it doesnt work, at least for me when I carefully followed the method described in
http://www.codeguru.com/cpp/cpp/cpp_...rint.php/c4059
Note that this post was in 2003. Also, the entire method is utilized by the CMainFrame class, not the View class. The author's a bit vague on where exactly to put the DragAcceptFile(s) (and he left off the terminal 's' which puzzled me for a bit).
Also note that the MFC Wizard generated app file contains the following cryptic notes in the InitInstance function:
//..
// The one and only window has been initialized, so show and update it
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
// call DragAcceptFiles only if there's a suffix
// In an SDI app, this should occur after ProcessShellCommand
// Enable drag/drop open
m_pMainWnd->DragAcceptFiles();
return TRUE;
which I interpret to indicate that the DragAcceptFiles has already been called !!
The final result of my efforts to utilize the method described by author Danish Qamar in the Codeguru article cited, is the generation of 72
First-chance exception at 0x774242eb in RichDrag.exe: Microsoft C++ exception: Error at memory location 0x0012c2a8..
messages after the first drag and drop, and the CMainFrame::OnDropFiles method is never called.
It is nothing short of amazing to me that there is so much misleading information about a subject that should be fairly simple and straightforward. In fact, I have spent several years trying to sort out this problem and have been up many dead-ends.
If anyone out there knows how to solve this problem, PLEASE HELP!
mpliam
-
June 24th, 2009, 11:29 PM
#7
Re: Implementing drag n drop in a CRichEditView?
I searched google for "MFC CRichEditCtrl Drag and Drop", and the 4th link gave me:
http://www.codeproject.com/KB/cpp/TextEdit.aspx
It's a VC6 project, so I converted it to VC2005, compiled it, ran it and dragged a .h file from the project onto it. It worked as expected. If you haven't looked at this sample, check it out.
-
June 25th, 2009, 01:23 AM
#8
Re: Implementing drag n drop in a CRichEditView?
Thanks, Arjay.
Yes, I have experimented with David Nash's Text Editor in the past. Notice that the formatting is a bit odd. David explains this as follows:
Originally, I tried to build this application using CRichEditView. There was a problem however. If the CRichEditView was set to read only, the drag and drop editing behaved as expected, but when the read only was removed, I lost programmatic control of the drag-and-drop. Without read only set, the default behavior of CRichEditView's drag-and drop took over.
I've never found a solution to this particular problem so I've selected to create the text window using CRichEditCtrl instead. If anyone reading this knows how to get CRichEditView to look after the drag-and-drop, let me know.
//..
Since I wasn't using an MFC view, as I elected to dispense with the Document View architecture entirely ...
This does shed some light on the fact that implementing file drag and drop in a CRichEditView is a long-standing problem. Unfortunately, I need to implement file drag and drop in an SDI CRichEditView using Document View architecture. It does not appear that anyone has come up with a suitable work around thus far.
Thank you again, Arjay for bringing to mind this important code.
mpliam
-
June 25th, 2009, 08:22 PM
#9
Re: Implementing drag n drop in a CRichEditView?
Mike, if possible, could you code with doc/view but keep the view hidden and use the rich edit control as described in the link?
-
June 26th, 2009, 04:29 PM
#10
Re: Implementing drag n drop in a CRichEditView?
Interesting idea, Arjay. I will see what I can do with it. Thanks.
mpliam
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|