// A simple DLL for File Manager Extentions.
// Build for Windows NT build .340 (October 92 SDK release).
//
// Note: you must export FMExtentionProc from your .def file.  You
// list this DLL as a File Manager extention by adding a line in
// your ...\NT\winfile.ini under [Add On].  There can be no more than
// five entries accepted by the File Manager.  For the entry, specify
// the DLL and it's path, or place it in a directory like ...\nt\system.


#include <windows.h>
#include <WFEXT.h>
#include <string.h>
#include "my_fmext.h"

HWND	   ghListBox;
WORD	   gwFilesDropped = 0;	// Total number of files dropped
POINT	   gpointDrop = {0,0};	// Point where the files were dropped
static	   HINSTANCE	hInstDll;



BOOL WINAPI DLLEntryPoint (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved)
{
  hInstDll = hDLL;   //Save hinstance of DLL to be used for LoadMenu() later.
  return TRUE;
}

LONG WINAPI FMExtensionProc (HWND hWndFileMan, WORD wMsg, LONG lParam)
{
   WNDCLASS wc;
   HWND	    hMainWnd;
   RECT     rectMain;
   HMENU    hSubMenu;

   UINT     wDelta;

   switch (wMsg)
    {
    case FMEVENT_LOAD:
      {
      hSubMenu = LoadMenu (hInstDll, "My_FMExtentionMenu");
      wDelta	= ((LPFMS_LOAD)lParam)->wMenuDelta;
      ((LPFMS_LOAD)lParam)->dwSize = sizeof(FMS_LOAD);
      strcpy(((LPFMS_LOAD)lParam)->szMenuName, "&Extention");
      ((LPFMS_LOAD)lParam)->hMenu = hSubMenu;

        wc.style = NULL;
        wc.lpfnWndProc = MainWndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
	wc.hInstance = GetCurrentProcess();	 //hinstance of FileManager.
	wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wc.hCursor = LoadCursor (NULL, IDC_ARROW);
        wc.hbrBackground = GetStockObject (WHITE_BRUSH);
        wc.lpszMenuName =  "DragDropMenu";
        wc.lpszClassName = "DragDropWClass";

        if (!RegisterClass (&wc))
	    return (FALSE);
	return (LONG) hSubMenu;
      }

    case IDM_MYFMEXT:

      {
      hMainWnd = CreateWindow ("DragDropWClass",
			    "Drag and Drop Window for FileManager Extention",
                            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
                            | WS_MINIMIZEBOX,
                            CW_USEDEFAULT,
                            CW_USEDEFAULT,
			    MAIN_WIDTH,
			    MAIN_HEIGHT,
			    CW_USEDEFAULT,
                            NULL,
                            NULL,
			    GetCurrentProcess(),
                            NULL);

      if (!hMainWnd)
        return (FALSE);

      GetClientRect (hMainWnd, &rectMain);

      ghListBox = CreateWindow ("ListBox",
                        NULL,
                        WS_CHILD | WS_VSCROLL | LBS_NOINTEGRALHEIGHT
                        | LBS_SORT | WS_VISIBLE,
                        0,
                        32,
                        rectMain.right - rectMain.left,
                        rectMain.bottom - rectMain.top - 32,
                        hMainWnd,
			NULL,
			GetCurrentProcess(),
			NULL);

      if (!ghListBox)
	return (FALSE);

      // Register the the main window for Drag/Drop messages.
      DragAcceptFiles (hMainWnd, TRUE);

      ShowWindow (hMainWnd, SW_SHOWNORMAL);
      UpdateWindow (hMainWnd);
      return (0);
      }

    default:
      {
	return (0);
      }
    }

   return TRUE;
}


//**************************************************************************
//
//  FUNCTION: MainWndProc()
//
//  PURPOSE:
//
//  This function handles messages belonging to the main window.
//  It also handles and processes Drag/Drop messages.
//
//**************************************************************************

long FAR PASCAL MainWndProc (HWND hWnd,   UINT message,
                             WPARAM wParam, LPARAM lParam)
{
    HANDLE  hFilesInfo;
    WORD    wIndex;
    char    szFileName [FILE_NAME_LENGTH];

    switch (message)
    {
        case WM_DROPFILES:
            hFilesInfo = (HANDLE) wParam;

            // Retrieve the window coordinates of the mouse
            // pointer when the drop was made
            DragQueryPoint ((HANDLE) wParam, (LPPOINT) &gpointDrop);

            // Get the total number of files dropped
            gwFilesDropped = DragQueryFile (hFilesInfo,
                                           (UINT)-1,
                                           NULL,
                                           0);

            // Retrieve each file name and add to the list box
            for (wIndex=0; wIndex < gwFilesDropped; wIndex++)
            {
                DragQueryFile (hFilesInfo,
                               wIndex,
                               (LPSTR) szFileName,
                               FILE_NAME_LENGTH);

                SendMessage (ghListBox,
                             LB_ADDSTRING,
                             0,
                             (LONG) (LPSTR) szFileName);
            } // for

            DragFinish (hFilesInfo);
            break;

        default:
            return (DefWindowProc (hWnd, message, wParam, lParam));

    } // switch (message)

    return (0);

} // MainWndProc()
