ToDoMenu.pas
上传用户:fh681027
上传日期:2022-07-23
资源大小:1959k
文件大小:5k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit ToDoMenu;
  2. interface
  3. uses
  4.   Windows, ActiveX, ComObj, ShlObj, ShellApi;
  5. type
  6.   TToDoMenu = class(TComObject, IUnknown, IContextMenu, IShellExtInit)
  7.   private
  8.     fFileName: string;
  9.   protected
  10.     {Declare IContextMenu methods here}
  11.     function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
  12.       uFlags: UINT): HResult; stdcall;
  13.     function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
  14.     function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
  15.       pszName: LPSTR; cchMax: UINT): HResult; stdcall;
  16.     {Declare IShellExtInit methods here}
  17.     function IShellExtInit.Initialize = InitShellExt;
  18.     function InitShellExt (pidlFolder: PItemIDList; lpdobj: IDataObject;
  19.       hKeyProgID: HKEY): HResult; stdcall;
  20.   end;
  21.   TToDoMenuFactory = class (TComObjectFactory)
  22.   public
  23.     procedure UpdateRegistry (Register: Boolean); override;
  24.   end;
  25. const
  26.   Class_ToDoMenuMenu: TGUID =
  27.     '{CDF05220-DB84-11D1-B9F1-004845400FAA}';
  28. implementation
  29. uses
  30.   ComServ, Messages, SysUtils, Registry;
  31. // IShellExtInit method
  32. function TToDoMenu.InitShellExt(pidlFolder: PItemIDList;
  33.   lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall;
  34. var
  35.   medium: TStgMedium;
  36.   fe: TFormatEtc;
  37. begin
  38.   Result := E_FAIL;
  39.   // check if the lpdobj pointer is nil
  40.   if Assigned (lpdobj) then
  41.   begin
  42.     with fe do
  43.     begin
  44.       cfFormat := CF_HDROP;
  45.       ptd := nil;
  46.       dwAspect := DVASPECT_CONTENT;
  47.       lindex := -1;
  48.       tymed := TYMED_HGLOBAL;
  49.     end;
  50.     // transform the lpdobj data to a storage medium structure
  51.     Result := lpdobj.GetData(fe, medium);
  52.     if not Failed (Result) then
  53.     begin
  54.       // check if only one file is selected
  55.       if DragQueryFile (medium.hGlobal, $FFFFFFFF, nil, 0) = 1 then
  56.       begin
  57.         SetLength (fFileName, 1000);
  58.         DragQueryFile (medium.hGlobal, 0, PChar (fFileName), 1000);
  59.         // realign string
  60.         fFileName := PChar (fFileName);
  61.         Result := NOERROR;
  62.       end
  63.       else
  64.         Result := E_FAIL;
  65.     end;
  66.     ReleaseStgMedium(medium);
  67.   end;
  68. end;
  69. // context menu methods
  70. function TToDoMenu.QueryContextMenu(Menu: HMENU;
  71.   indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
  72. begin
  73.   // add entry only if the program is running
  74.   if FindWindow ('TToDoFileForm', nil) <> 0 then
  75.   begin
  76.     // add a new item to context menu
  77.     InsertMenu (Menu, indexMenu,
  78.       MF_STRING or MF_BYPOSITION, idCmdFirst,
  79.       'Send to ToDoFile');
  80.     // Return number of menu items added
  81.     Result := 1;
  82.   end
  83.   else
  84.     Result := 0;
  85. end;
  86. function TToDoMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
  87. var
  88.   hwnd: THandle;
  89.   cds: CopyDataStruct;
  90. begin
  91.   Result := NOERROR;
  92.   // Make sure we are not being called by an application
  93.   if HiWord(Integer(lpici.lpVerb)) <> 0 then
  94.   begin
  95.     Result := E_FAIL;
  96.     Exit;
  97.   end;
  98.   // Make sure we aren't being passed an invalid argument number
  99.   if LoWord(lpici.lpVerb) > 0 then
  100.   begin
  101.     Result := E_INVALIDARG;
  102.     Exit;
  103.   end;
  104.   // execute the command specified by lpici.lpVerb.
  105.   if LoWord(lpici.lpVerb) = 0 then
  106.   begin
  107.     // get the handle of the window
  108.     hwnd := FindWindow ('TToDoFileForm', nil);
  109.     if hwnd <> 0 then
  110.     begin
  111.       // prepare the data to copy
  112.       cds.dwData := 0;
  113.       cds.cbData := length (fFileName);
  114.       cds.lpData := PChar (fFileName);
  115.       // activate the destination window
  116.       SetForegroundWindow (hwnd);
  117.       // send the data
  118.       SendMessage (hwnd, wm_CopyData,
  119.         lpici.hWnd, Integer (@cds));
  120.     end
  121.     else
  122.     begin
  123.       // the program should never get here
  124.       MessageBox(lpici.hWnd,
  125.         'FilesToDo Program not found',
  126.         'Error',
  127.         MB_ICONERROR or MB_OK);
  128.     end;
  129.   end;
  130. end;
  131. function TToDoMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
  132.   pszName: LPSTR; cchMax: UINT): HRESULT;
  133. begin
  134.   if (idCmd = 0) and (uType = GCS_HELPTEXT) then
  135.   begin
  136.     // return help string for menu item
  137.     strLCopy (pszName, 'Add file to the ToDoFile database', cchMax);
  138.     Result := NOERROR;
  139.   end
  140.   else
  141.     Result := E_INVALIDARG;
  142. end;
  143. { TToDoMenuFactory methods }
  144. procedure TToDoMenuFactory.UpdateRegistry(Register: Boolean);
  145. var
  146.   Reg: TRegistry;
  147. begin
  148.   inherited UpdateRegistry (Register);
  149.   Reg := TRegistry.Create;
  150.   Reg.RootKey := HKEY_CLASSES_ROOT;
  151.   try
  152.     if Register then
  153.       if Reg.OpenKey('*ShellExContextMenuHandlersToDo', True) then
  154.         Reg.WriteString('', GUIDToString(Class_ToDoMenuMenu))
  155.     else
  156.       if Reg.OpenKey('*ShellExContextMenuHandlersToDo', False) then
  157.         Reg.DeleteKey ('*ShellExContextMenuHandlersToDo');
  158.   finally
  159.     Reg.CloseKey;
  160.     Reg.Free;
  161.   end;
  162. end;
  163. initialization
  164.   TToDoMenuFactory.Create (
  165.     ComServer, TToDoMenu, Class_ToDoMenuMenu,
  166.     'ToDoMenu', 'ToDoMenu Shell Extension',
  167.     ciMultiInstance, tmApartment);
  168. end.