Link to home
Start Free TrialLog in
Avatar of chris rrr
chris rrrFlag for United States of America

asked on

Drag N Drop Text To Dialog

I know how to drag and drop a file to a dialog. I already have this in place.
My problem is that I also would like to be able to drag and drop text (mainly specific contents of a file) to my dialog.

Example:
I have a text file that says: "My dog is my best friend."
Now if I select just "dog is my" and drag it from the text file, is there a way to get the event so I can process the drag text "dog is my".
I would like to keep the DropFiles part working as well.

NOTE: this text file is not part of my app, it could be any text editor, text field, html file... anything that gives the cursor signal to dragDrop.
ALSO: I have copy & paste working but would like to also have the dragDrop text.
 
Thanks

Chris
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To implement Ole Drag & Drop (which is something different than File Drag & Drop) you need 3 COM objects that implements 3 COM interfaces:
IDataObject - carries data (in your case in CF_TEXT format)
IDropSource - for example decides if continue dragging
IDropTarget - used by drag & drop target window (in your case it may be EDIT box).

If you use MFC the task is much easier - there are C++ classes that implements these interfaces.
COleDropSource(), COleDropTarget(), COleDataObject(), COleDataSource()

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_drag_and_drop_.28.ole.29.asp
For example Windows Wordpad implements this feature. You can use it for tests.
Avatar of chris rrr

ASKER

OK did a little test and I found that richEdit boxes give this functionality. If I place this in my dialog, then I could use it (but I don't want there to be a text box there). Or I could subclass it , and do my drawing right inside the control instead of my dialog? ... don't know.

Any Ideas?

If not I believe that I will just close this question. Sounds like more time than I can spend on it.

The following is from MSDN:

HOWTO: Use Drag-Drop in an Edit Control or a Combo Box
Article ID: Q86724

The information in this article applies to:
Microsoft Windows Software Development Kit (SDK)
Microsoft Win32 Software Development Kit (SDK)


SUMMARY
In the Microsoft Windows environment, an application can register an edit control or a combo box as a drag-drop client through the DragAcceptFiles function. The application must also subclass the control to process the WM_DROPFILES message that Windows sends when the user drops a file.



MORE INFORMATION
The following seven steps demonstrate how to implement drag-drop in an edit control. The procedure to implement drag-drop in a combo box is identical.

1. Add SHELL.LIB to the list of libraries required to build the file.

2. Add the name of the subclass procedure (MyDragDropProc) to the

   EXPORTS section of the module definition (DEF) file.


3. Include the SHELLAPI.H file in the application's source code.
4. Declare the following procedure and variables:


      BOOL FAR PASCAL MyDragDropProc(HWND, unsigned, WORD, LONG);

      FARPROC lpfnDragDropProc, lpfnOldEditProc;
      char    szTemp64[64];


5. Add the following code to the initialization of the dialog box:

      case WM_INITDIALOG:
         // ... other code

         // ------- edit control section --------
         hWndTemp = GetDlgItem(hDlg, IDD_EDITCONTROL);
         DragAcceptFiles(hWndTemp, TRUE);

         // subclass the drag-drop edit control
         lpfnDragDropProc = MakeProcInstance(MyDragDropProc, hInst);

         if (lpfnDragDropProc)
            lpfnOldEditProc = SetWindowLong(hWndTemp, GWL_WNDPROC,
                  (DWORD)(FARPROC)lpfnDragDropProc);
         break;


6. Write a subclass window procedure for the edit control.

      BOOL FAR PASCAL MyDragDropProc(HWND hWnd, unsigned message,
                                     WORD wParam, LONG lParam)
      {
         int wFilesDropped;

         switch (message)
            {
         case WM_DROPFILES:
            // Retrieve number of files dropped
            // To retrieve all files, set iFile parameter
            // to -1 instead of 0
            wFilesDropped = DragQueryFile((HDROP)wParam, 0,
                  (LPSTR)szTemp64, 63);

            if (wFilesDropped)
               {
               // Parse the file path here, if desired
               SendMessage(hWnd, WM_SETTEXT, 0, (LPSTR)szTemp64);
               }
            else
               MessageBeep(0);

            DragFinish((HDROP)wParam);
            break;

         default:
            return CallWindowProc(lpfnOldEditProc, hWnd, message,
                  wParam, lParam);
            break;
         }
         return TRUE;
      }


7. After the completion of the dialog box procedure, free the edit
   control subclass procedure.

      if (lpfnDragDropProc)
         FreeProcInstance(lpfnDragDropProc);
I cannot get this to work with MFC?
I assume the dragDropProc would have to be a global var, but it still doesn't work.

I get cast errors:

Here :
         lpfnDragDropProc = MakeProcInstance(MyDragDropProc, hInst);

&

Here :
         if (lpfnDragDropProc)
            lpfnOldEditProc = SetWindowLong(hWndTemp, GWL_WNDPROC,
                  (DWORD)(FARPROC)lpfnDragDropProc);
Oh, and the lib file is not shell.lib it is shell32.lib
Do you want it to work in MFC ?

Derive you EDIT interface class from CEdit (add new MFC class, choose CEdit as a base class)

Add to the class derived from CEdit:

ON_MESSAGE(WM_DROPFILES, OnDropFiles)

between

BEGIN_MESSAGE_MAP(...)          // in .cpp file
...
<- here
...
END_MESSAGE_MAP

Add function declaration

afx_msg LRESULT OnDropFiles(WPARAM, LPARAM)

in class declaration

after

//}}AFX_MESSAGE

and before

DECLARE_MESSAGE_MAP

add implementation to .cpp file

LRESULT ClassName::OnDropFiles(WPARAM, LPARAM)
{
...
}

"Oh, and the lib file is not shell.lib it is shell32.lib"

Is it a problem ? You have 32-bit aplication so you should use 32-bit version of library. It has its version of DragQueryFile().
In OnInitDialog() handler call m_edit.DragAcceptFiles(TRUE);

Where m_edit is of type CYourEditDerivedClass (use clas Wizard to add it)
Thanks you mrblue for your time
I have Updated from 200pts to 300pts

One quick question...
Is is going to be possible to do make the OnDropFiles work on the dialog and not on the CEdit subclass?
Earlier I posted that the drag and drop works fine if I use a RichEdit control.
 ** See post: Date: 05/08/2006 01:21AM PDT

I am hoping to be able to use my dialogs normal drag and drop for files and for text.
I can easily test if file exists and know if it is text or file.

I have drag and drop working on my dialog right now, but if I drag text then I don't even get the event.
"I have drag and drop working on my dialog right now, but if I drag text then I don't even get the event."

I am not sure if I understand you well. What does it mean "working" if you "don't get event" ?

If you want some window to accept WM_DROPFILES you need call
   DragAcceptFiles(TRUE);
for that window.

For dialog box in MFC just call
  DragAcceptFiles(TRUE);
in
  OnInitDialog()

You have also do the same thing for dialog class as for derived CEdit class - define message handler in dialog class.

Sorry for the confusion.
I have drag and drop working if I drag a file from explorer ( I get an event if I drop over my dialog if it is related to a file). (this must have to do with dropFile?)
However, if I drag from a textfield or text editor ( some text ), when I move my cursor over my dialog, I get the dragDrop icon, But if I drop the text over my dialog I get no event.

Hope this makes sense.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks,
I will give it a shot.