Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

Adding Drag and Drop to Your Application

Many applications in Windows allow the user to work with files graphically by dragging the files from a drag-and-drop file source, such as Explorer, to the window for an application that can accept the files. This function can be implemented in two ways. The first is with OLE. The second method uses Windows messages to support drag-and-drop.

Enabling Drag and Drop

To enable drag and drop in a window of your application, you use the CWnd::DragAcceptFiles() call to enable the receipt of WM_DROPFILES messages. The single parameter for CWnd::DragAcceptFiles() is a BOOL. You can omit the parameter, because it defaults to TRUE, or you can call it with FALSE to disable drag and drop.

The drag and drop capability can be called from any object derived from CWnd, after its window is created. In the example in this section, you will put a call in the OnCreate() function of the main frame class, after the window is created by the call to CMDIFrameWnd::OnCreate(). This process allows the application to accept files that are dropped anywhere in its main window.

Handling WM_DROPFILES Messages

Next you implement a handler for the WM_DROPFILES message and add an entry to the message map. This is done best with the ClassWizard, which creates a default handler for you. The default handler defers to CMDIFrameWnd::OnDropFiles(), which tries to open a new document view pair for the files that were dragged.

If you want to do something more specific with the dropped files, you can implement your handler for OnDropFiles() something like this:

void CMainFrame::OnDropFiles(HDROP hDropInfo)
{
    UINT i;
    UINT nFiles = ::DragQueryFile(hDropInfo, (UINT) -1, NULL, 0);
    for (i = 0; i < nFiles; i++)
    {
        TCHAR szFileName[_MAX_PATH];
        ::DragQueryFile(hDropInfo, i, szFileName, _MAX_PATH);
        ProcessMyFile(szFileName);
    }  // end for
    ::DragFinish(hDropInfo);
} // end OnDropFiles()

In this example, you can see that you call DragQueryFile() with a second parameter of -1 (0xFFFFFFFF), which returns the number of files that were dropped. You then use this value to loop through all the files, again using DragQueryInfo() to return the full pathname of the file. After you have the filename, you can do with it as you please; just make sure that you call DragFinish() to clean up when you are finished. If you don't do this, your application will leak a bit of memory each time you handle dropped files.

Share ThisShare This

Informit Network