Write a Windows shell with Delphi
Friends who are more understanding for operating system principles will know that a complete operating system provides a shell to facilitate normal users to use the various functions provided by the operating system. The housing of Windows (here is the operating system of Windows 95 / Windows NT4.0 or more) not only provides a convenient and beautiful GUI graphical interface, but also provides powerful enclosure extension, and everyone may see in many software. These housings are expanded. For example: If you have Winzip installed in your system, when you right click on a folder or file, you will appear in the pop-up menu. Windows supports seven types of housing extensions (called Handler), and their corresponding role is as follows: (1) Context Menu Handlers: Add a context-related menu to a specific type of file object; (2) Drag-and-drop handlers: Used to support OLE data transmission when a user is dragging and dropping a certain type of file object; (3) icon handlers: Used to provide a unique icon to a file object, or give a certain type of file object specified Icon; (4) Property Sheet Handlers: Add a property page to the file object (just right click on the file object or folder object, the dialog box that appears after the Properties item in the pop-up menu), the property page can be used for the same class object You can also give a file object to specify a unique property page; (5) Copy-Hook Handlers: When the folder object or printer object is copied, move, delete, and rename it, it will be called by the system, by adding COPY for Windows. -Hook Handlers, can be allowed or disabled; (6) DROP TARGET HANDERS: When an object is dragged and dropped to another object, it will be called by the system; (7) Data Object handlers: in the file Drag and drop, copy or paste, will be called by the system. All housing extensions of Windows are based on COM (Component Object Model) component model, and the housing is accessible through the interface (interface). The outer casing extension is designed into a 32-bit process server program, and is provided in the form of a dynamic link library to serve the operating system. Therefore, if you want to expand the Windows user interface, some knowledge of writing COM objects is necessary. After writing the enclosure extension, they must register them to take effect. All housing extensions must be registered under the HKEY_CLASSES_ROOT / CLSID key of the Windows registry. Below the key, you can find a key like {0000002F-0000-0000-C000-000000000046}, which is the global unique class identifier (GUID). Each housing extension must have a global unique class identifier, and Windows is using this unique class identifier to find the housing extension handler. The location of the housing extension dynamic link library in the system is recorded under the INPROCSERVER32 sub-key under the class identifier. The housing extension associated with some file type is registered under the corresponding type of Shellex primary key. If the Windows operating system is Windows NT, the outer casing must also be registered under the HKEY-local-machine / currentversion / shellextensions / approved primary key in the registry.
After compiling the DLL programs that have been extended in the case, you can use the regsvr32.exe provided by Windows itself to register the DLL server program. If you use Delphi, you can also select Register ActiveX Server to register in the RUN menu. Let's first introduce a relatively common case extension application: context-related menus, in Windows, right-click the menu that pops up when you pop up with files or folders is called context-related menus. To dynamically add menu items to the context-related menu, you can implement it by writing the Context Menu Handler. For example, Winzip and UltraEdit, which are familiar to, are dynamically add menu items to the menu by writing the Context Menu Handler. This article wants to add a file operation menu item to the context-related menu of any type file object. When you click this item, the interface program pops up a file operation window, performs file copy, movement, etc. Write the Context Menu Handler must implement three interfaces of Ishellextinit, IconTextMenu, and TcomobjectFactory. ISHELLEXTINIT implementation interface initialization, IContextMenu interface object implements context-related menus, the IComObjectFactory interface implements the creation of objects. The following is a specific program implementation. First click on the File | New item of the menu in Delphi, select DLL to create a DLL project file in the New Item window. Then click on the File | New item of the menu. Select Unit to create a Unit file in the New Item window, click the File | New item to click on the menu, select Form to create a new window in the New Item window. The engineering file will be saved as contextMenu.dpr, saved Unit1 as ContextMenuHandle.PAS, saved Form as Opwindow.PAS.
Listing Contextmenu.dpr follows: library contextmenu; uses ComServ, contextmenuhandle in 'contextmenuhandle.pas', opwindow in 'opwindow.pas' {Form2}; exports DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnregisterServer; {$ R * .TLB} { . $ R * .RES} begin end Contextmenuhandle program list is as follows: unit ContextMenuHandle; interface uses Windows, ActiveX, ComObj, ShlObj, Classes; type TContextMenu = class (TComObject, IShellExtInit, IContextMenu) private FFileName: array [0..MAX_PATH ] of Char; protected function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning function SEIInitialize (pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall; function QueryContextMenu (Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult; stdcall; function InvokeCommand (var lpici: TCMInvokeCommandInfo): HResult; stdcall; function GetCommandString (idCmd, uType: UINT; pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult; stdcall; end;Const class_contextmenu: tguid = '{19741013-C829-11D1-8233-0020AF3E97A0}'; {Global Unique Identifier (GUID) is a 16-byte (128) value, which uniquely identifies an interface (Interface)} var FileList: TStringList; implementation uses ComServ, SysUtils, ShellApi, Registry, UnitForm; function TContextMenu.SEIInitialize (pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; var StgMedium: TStgMedium; FormatEtc: TFormatEtc; FileNumber, i: Integer BEGIN / / If LPDOBJ is equal to NIL, this call is failed if (lpdobj = nil) thr; = e_invalidarg; exit; End; // First initialize and empty filelist: = tstringlist.create; filelist.clear ;
// Initialization clipboard format with FormatEtc do begin cfFormat: = CF_HDROP; ptd: = nil; dwAspect: = DVASPECT_CONTENT; lindex: = -1; tymed: = TYMED_HGLOBAL; end; Result: = lpdobj.GetData (FormatEtc, StgMedium) If FAILED THEN EXIT; / / First Query the number of files in the user selected file filenumber: = DragQueryFile (STGMEDIUM.HGLOBAL, $ FFFFFFFFFF, NIL, 0); // Location, save all users selected files in the FileList for i: = 0 to FileNumber-1 do begin DragQueryFile (StgMedium.hGlobal, i, FFileName, SizeOf (FFileName)); FileList.Add (FFileName); Result: = NOERROR; end; ReleaseStgMedium (StgMedium); end ; function TContextMenu.QueryContextMenu (Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult; begin Result: = 0; if ((uFlags and $ 0000000F) = CMF-NORMAL) or ((uFlags and CMF_EXPLORE) < > 0) THEN Begin // Add a menu item to the Context Menu, the title of the menu item is to view bitmap file INSERTMENU (Menu, IndexMenu, MF_String OR MF_BYPOSITION, IDCMDFIRST, PCHAR ('file operation')); // Return to increase The number of menu items Result: = 1; end; end; function tcontextMenu.invokecommand (var lpici: tcminvokecommandinfo): hres Ult; var frmop: tform1; begin // First, determine that the process is the system instead of being called IF (HiWord (Integer (Integer (Integer (Integer (Integer (Integer (Integer (Integer (Integer (Integer (Integer)) ",", ".") the beginning: = E_FAIL; EXIT; // Determine the validity IF (Loword (LPICI.LPVERB) <> 0) The Begin Result: = E_INVALIDARG; EXIT; END; // Established File Operation Window FRMOP: = TFORM1.CREATE (NIL); // Add all file lists to the list of FRMOP.ListBox1.Items: = filelist; result: = noError; end; function; pwreserved: puint; pside; pwante; cchmax: UINT): HRESULT; begin if (idcmd = 0) THEN BEGIN if (utype = gcs_helptext) THEN {returned to the help information of the menu item,
This help information will appear on the status bar when the user moves the mouse to the menu item.
} StrCopy (pszName, PChar ( 'click on the menu item to perform file operations')); Result: = NOERROR; end else Result: = E_INVALIDARG; end; type TContext Menu Factory = class (TCom Object Factory) public procedure UpdateRegistry (Register : Boolean); override; end; procedure TContextMenuFactory.UpdateRegistry (Register: Boolean); var ClassID: string; begin if Register then begin inherited UpdateRegistry (Register); ClassID: = GUIDToString (Class-ContextMenu); // if registration extensions When the file is added, the library is added to the registry CreateRegKey ('* / shellex', '', '); CreateRegKey (' * / shellex / contextMenuHandlers', ',' '); CreateRegKey (' * / shellex / contextMenuHandlers / Fileopreation ',' ', classid; // If the operating system is Windows NT if (Win32Platform = Ver-Platform-Win32-NT) TreGistry.create Do Try Rootkey: = HKEY-local-machine; OpenKey (' Software / Microsoft / Windows / CurrentVersion / Shell Extensions ', True); OpenKey (' Approved ', True); WriteString (ClassID,' Context Menu Shell Extension '); finally Free; end; end else begin DeleteRegKey (' * / shellex / ContextMenuHand lers / FileOpreation '); inherited UpdateRegistry (Register); end; end; initialization TContext Menu Factory.Create (Com Server, TContextMenu, Class-ContextMenu,' ',' Context Menu Shell Extension ', ciMultiInstance, tmApartment); end on. opWindow window to add a TListBox control and two TButton controls, OpWindows.pas program list is as follows: unit opwindow; interface uses Windows, Messages, SysUtils, Classes, Graphics, controls, Forms, Dialogs, ExtCtrls, StdCtrls, shlobj, shellapi, ActiveX; Type TFORM1 = Class (TFORM) Listbox1: TListBox;
Button1: TButton; Button2: TButton; procedure FormCreate (Sender: TObject); procedure FormClose (Sender: TObject; var Action: TCloseAction); procedure Button1Click (Sender: TObject); procedure Button2Click (Sender: TObject); private {Private declarations} public FileList: TStringList; {public declarations} end; var Form1: TForm1; implementation {$ R * .DFM} procedure TForm1.FormCreate (Sender: TObject); begin FileList: = TStringList.Create; Button1.Caption: = 'files replication '; Button2.Caption: =' moving file '; Self.Show; end; procedure TForm1.FormClose (Sender: TObject; var Action: TCloseAction); begin FileList.Free; end; procedure TForm1.Button1Click (Sender: TObject); VAR Spath: string; fstemp: shfileopstruct; i: integer; begin spath: = inputbox ('file operation', 'input copy path', 'c: / windows'); if spath <> '' Then Begin fStemp.Wnd: = Self.Handle; // Set file operation type fStemp.wfunc: = fo_copy; // Allow undo operation fStemp.fflags: = fof-allowundo; for i: = 0 to listbox1.items.count-1 do begin // Source file full path name fSTEMP.PFROM: = PC HAR (ListBox1.Items.Strings [i]); // To copy the path fstemp.pto: = pchar (spath); fstemp.lpszprogressTitle: = 'copy file'; if shfileOperation (fstemp) <> 0 Then ShowMessage 'File copy failed'); end; end; end; procedure tform1.button2click (sender: Tobject); var spath: string; fstemp: shfileopstruct; i: integer; begin spath: = inputbox ('file operation', 'input mobile Path ',' C: / Windows'); if Spath <> '' Then Begin fstemp.wnd: = self.handle; fstemp.wfunc: = fo_move; fstemp.fflags: = fof_allowundo; for i: = 0 to ListBox1. Items.count-1 do begin fstemp.pfrom: =