According to this article, to allow Drop Only on the Target, we have to
Use SubclassDlgItem() to re-route that one message to the dialog object so that all of the handling can be done there.
Mr. DanRollins (the author of the article) also provides an example
class CEditDropNotif : public CEdit
{
virtual BOOL PreTranslateMessage(MSG* pMsg) {
if ( pMsg->message == WM_DROPFILES ) {
GetParent()->SendMessage(WM_DROPFILES, pMsg->wParam, pMsg->lParam);
return TRUE; // eat it
}
return FALSE; // allow default processing
}
};
BOOL CMyDlg::OnInitDialog()
{
...
static CEditDropNotif cEd; // must persist (usually a dlg member)
cEd.SubclassDlgItem( IDC_EDIT1, this );
::DragAcceptFiles( cEd.m_hWnd, true ); // the editbox, not the dialog
...
But I don't understand why Edit control (CEdit) has the Accept Files in the properties window (Visual Studio Resource view), but can't register the message WM_DROPFILES for itself without having to create an inherited class (or it can but I haven't known yet).
I see that we can register the click message for button by the following code
BEGIN_MESSAGE_MAP(CSimpleDlg, CDialogEx)
...
ON_BN_CLICKED(IDC_BTN_01, &CSimpleDlg::OnBnClickedBtn01)
END_MESSAGE_MAP()
Is there a way I can do similar for drag drop event, like
ON_DRAW_DROP(IDC_TXT_01, &CSimpleDlg::OnDragDrop01)//Is exist?
The answer is: Nope. ON_BN_CLICKED macro maps a member function that handles BN_CLICKED notification sent via WM_COMMAND message. The notifications are sent to control's parent (although MFC has also a "reflection" mechanism that forwards the notifications to controls). WM_DROPFILES is a general Windows message, not a notification so that's it: if you want to handle it then you have to derive from CEdit.
See also: