16.5 File Manager Extension Example

The following example shows the FMExtensionProc function for a sample extension DLL. It demonstrates how an extension processes the menu commands and notification messages sent by File Manager.

HINSTANCE hinst;
HMENU hmenu;
WORD wMenuDelta;
BOOL fMultiple = FALSE;
BOOL fLFN = FALSE;

DWORD FAR PASCAL FMExtensionProc(hwnd, wMsg, lParam)
HWND hwnd;
WORD wMsg;
LONG lParam;
{
    char szBuf[200];
    int count;

    switch (wMsg) {
        case FMEVENT_LOAD:

            #define lpload  ((LPFMS_LOAD)lParam)

            /* Save the menu-item delta value. */

            wMenuDelta = lpload->wMenuDelta;

            /* Fill the FMS_LOAD structure. */

            lpload->dwSize = sizeof(FMS_LOAD);
            lstrcpy(lpload->szMenuName, "&Extension");

            /* Return the handle of the menu. */

            return (DWORD) (lpload->hMenu = LoadMenu(hinst,
                MAKEINTRESOURCE(MYMENU)));
            break;

        case FMEVENT_UNLOAD:

            /* Perform any cleanup procedures here. */

            break;

        case FMEVENT_INITMENU:

            /* Copy the menu-item delta value and menu handle. */

            wMenuDelta = LOWORD(lParam);
            hmenu = (HMENU) HIWORD(lParam);

            /*
             * Add check marks to menu items as appropriate. Add menu-
             * item delta values to menu-item identifiers to specify the
             * menu items to check.
             */

            CheckMenuItem(hmenu, wMenuDelta + MULTIPLE,
                fMultiple ? MF_BYCOMMAND | MF_CHECKED :
                            MF_BYCOMMAND | MF_UNCHECKED);
            CheckMenuItem(hmenu, wMenuDelta + LFN,
                fLFN ? MF_BYCOMMAND | MF_CHECKED :
                       MF_BYCOMMAND | MF_UNCHECKED);
            break;

        case FMEVENT_USER_REFRESH:
            MessageBox(hwnd, "User refresh event", "Hey!", MB_OK);
            break;

        case FMEVENT_SELCHANGE:
            OutputDebugString("Sel change\r\n");
            break;

        /*
         * The following messages are generated when the user chooses
         * items from the extension menu.
         */

        case GETFOCUS:
            wsprintf(szBuf, "Focus %d", (int)SendMessage(hwnd,
                FM_GETFOCUS, 0, 0L));
            MessageBox(hwnd, szBuf, "Focus", MB_OK);
            break;

       
case GETCOUNT:
            count = (int)SendMessage(hwnd,
                fLFN ? FM_GETSELCOUNTLFN : FM_GETSELCOUNT, 0, 0L);

            wsprintf(szBuf, "%d files selected", count);
            MessageBox(hwnd, szBuf, "Selection Count", MB_OK);
            break;

        case GETFILE:
        {
            FMS_GETFILESEL file;

            count = (int) SendMessage(hwnd,
                fLFN ? FM_GETSELCOUNTLFN : FM_GETSELCOUNT,
                FMFOCUS_DIR, 0L);

            while (count >= 1) {

                /* Selection indices are zero-based (0 is first). */

                count--;
                SendMessage(hwnd, FM_GETFILESEL, count,
                    (LONG) (LPFMS_GETFILESEL)&file);
                OemToAnsi(file.szName, file.szName);
                wsprintf(szBuf, "file %s\nSize %ld",
                    (LPSTR)file.szName, file.dwSize);
                MessageBox(hwnd, szBuf, "File Information", MB_OK);

                if (!fMultiple)
                        break;
            }
            break;
        }

        case GETDRIVE:
        {
            FMS_GETDRIVEINFO drive;

            SendMessage(hwnd, FM_GETDRIVEINFO, 0,
                (LONG) (LPFMS_GETDRIVEINFO)&drive);

            OemToAnsi(drive.szVolume, drive.szVolume);
            OemToAnsi(drive.szShare, drive.szShare);

            wsprintf(szBuf,
        "%s\nFree Space %ld\nTotal Space %ld\nVolume %s\nShare %s",
                (LPSTR) drive.szPath, drive.dwFreeSpace,
                drive.dwTotalSpace, (LPSTR) drive.szVolume,
                (LPSTR) drive.szShare);
            MessageBox(hwnd, szBuf, "Drive Info", MB_OK);
            break;
        }

        case LFN:
            fLFN = !fLFN;
            break;

        case MULTIPLE:
            fMultiple = !fMultiple;
            break;

        case REFRESH:
        case REFRESHALL:
            SendMessage(hwnd, FM_REFRESH_WINDOWS,
                wMsg == REFRESHALL, 0L);
            break;

        case RELOAD:
            PostMessage(hwnd, FM_RELOAD_EXTENSIONS, 0, 0L);
            break;
    }
    return NULL;
}