Compile Windows Shell extension using Delphi

Source: Internet
Author: User
Tags ftp site

Compile Windows Shell extension using Delphi
Anyone familiar with operating system principles will know that a complete operating system provides a shell to facilitate common users.
Use various features provided by the operating system. Windows (here it refers to Windows 95/Windows NT4.0 or later) not only provides
It provides a user-friendly GUI and powerful shell extension functions. You may see these shell extensions in many software. For example
If WinZip is installed in the system, when you right-click a folder or file in Windows choose e, the WinZip pressure will appear in the pop-up menu.
Menu. Or the FTP site folder that appears in Windows Resource Manager in bullet FTP.
Windows supports seven types of shell extensions (handler). Their functions are described as follows:

(1) Context Menu handlers: adds context menus to specific file objects;

(2) drag-and-drop handlers is used to support Ole data transmission when users perform drag-and-drop operations on certain types of file objects;

(3) icon handlers is used to provide a unique icon to a file object. You can also specify an icon for A Class of file objects;

(4) property sheet handlers adds an attribute page to a file object (that is, right-click a file object or folder object and select a property in the pop-up menu)
The property page can be shared by the same class of file objects, or you can specify a unique property page for a file object;

(5) copy-hook handlers will be called by the system when the folder object or printer object is copied, moved, deleted, and renamed.
Added copy-hook handlers to allow or disable some operations;

(6) drop target handlers is called by the system when an object is dragged to another object;

(7) Data Object handlers will be called by the system when the file is dragged, copied, or pasted.

All Windows Shell extensions are based on the COM (Component Object Model) component model, and the shell accesses objects through interfaces.
The shell extension is designed as a 32-bit server program in the process and serves the operating system in the form of a dynamic link library. Therefore, if you want
To expand the user interface, it is necessary to have some knowledge of writing COM objects. Due to space limitations, we will not introduce com here. Readers can refer
Microsoft's msdn library or related help documentation, an interface can be seen as a special class, which contains a set of function merging procedures that can be used to operate an object.
After the shell extensions are written, they must be registered to take effect. All shell extensions must be hkey_classes_root/CLSID in the Windows registry.
. Under this key, you can find many keys named {0000002f-0000-0000-c000-000000000046}. These keys are globally unique Class Identifiers.
Guid ). Each shell extension must have a globally unique Class Identifier. Windows uses this unique Class Identifier to find the shell extension handler.
The inprocserver32 sub-key under the Class Identifier records the location of the shell extension dynamic link library in the system. The shell extension associated with a file type is registered in
Under the corresponding type of shellex primary key. If the Windows operating system is Windows NT, the shell extension must also be in
HKEY_LOCAL_MACHINE/software/Microsoft/Windows/CurrentVersion/shellextensions/approved primary key registration.
After compiling the extended dllprogram of the external shell, you can use regsvr32.exe in Windows to register the DLL server program. If you use Delphi, you can also
In the run menu, select register ActiveX Server for registration.

Next, we will first introduce a common shell extension application: Context-related menu. In Windows, right-click
Menus are called context-related menus. To dynamically Add a menu item to the context menu, you can write context menu handler. For example
The familiar software, such as WinZip and ultraedit, uses context menu handler to dynamically add food items to the menu. If you have installed
WinZip, When you right-click a file named Windows (folder), the context menu will have a menu item named add to windows.zip.
The context menu handler to be implemented in this article is similar to the context menu provided by WinZip. It adds
File Operation menu item. When you click this item, the interface program will pop up a file operation window to perform operations such as file copy and movement.
To compile context menu handler, you must implement the ishellextinit, icontextmenu, and tcomobjectfactory interfaces. Ishellextinit implementation
The icontextmenu interface object implements context-related menus, and the icomobjectfactory interface creates objects.
The following describes the specific program implementation. First, click File | new in the menu in Delphi, and select DLL in the new item window to create a DLL project file.
Click file | new in the menu, select unit in the new item window to create a unit file, and click File | new in the new item window.
Select form to create a new window. Save the project file as contextmenu. DPR, unit1 as contextmenuhandle. Pas, and form
Opwindow. Pas.
The contextmenu. DPR program list is as follows:
Library contextmenu;
Uses
Comserv,
Contextmenuhandle in 'contextmenuhandle. pa ',
Opwindow in 'opwindow. pa' {form2 };

Exports
Dllgetclassobject,
Dllcanunloadnow,
Dllregisterserver,
Dllunregisterserver;

{$ R *. TLB}

{$ R *. Res}

Begin

End.

The 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, id1_first, 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 }';

{A globally unique identifier (guid) is a 16-byte value (128) that uniquely identifies an 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
File: // If lpdobj is equal to nil, this call fails.
If (lpdobj = nil) then begin
Result: = e_invalidarg;
Exit;
End;

File: // first initialize and clear filelist to add a file
Filelist: = tstringlist. Create;
Filelist. Clear;
File: // initialize the clipboard Format File
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 (result) Then exit;

File: // first query the number of files selected by the user
Filenumber: = dragqueryfile (stgmedium. hglobal, $ ffffffff, nil, 0 );
File: // read the file cyclically. save all the files selected by the user to filelist.
For I: = 0 to a 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, id1_first,
Idcmdlast, uflags: uint): hresult;
Begin
Result: = 0;
If (uflags and $ 0000000f) = cmf_normal) or
(Uflags and cmf_0000e) <> 0) then begin
// Add a menu item to the context menu. The title of the menu item is to view the bitmap file.
Insertmenu (menu, indexmenu, mf_string or mf_byposition, id1_first,
Pchar ('file operation '));
// Return the number of added menu items
Result: = 1;
End;
End;

Function tcontextmenu. invokecommand (VAR lpici: tcminvokecommandinfo): hresult;
VaR
Frmop: tform1;
Begin
// First, make sure that the process is called by the system rather than by a program.
If (hiword (INTEGER (lpici. lpverb) <> 0) then
Begin
Result: = e_fail;
Exit;
End;
// Determine the validity of the passed Parameter
If (loword (lpici. lpverb) <> 0) then begin
Result: = e_invalidarg;
Exit;
End;

File: // create a file operation window
Frmop: = tform1.create (NiL );
File: // Add the list of all files to the list in the file operation window.
Frmop. listbox1.items: = filelist;
Result: = noerror;
End;

Function tcontextmenu. getcommandstring (idcmd, utype: uint; pwreserved: puint;
Pszname: lpstr; cchmax: uint): hresult;
Begin
If (idcmd = 0) then begin
If (utype = gcs_helptext) then
{Return the help information for this menu item.
It appears on the status bar when you move to this menu item .}
Strcopy (pszname, pchar ('click this menu item to perform file operation '));
Result: = noerror;
End
Else
Result: = e_invalidarg;
End;

Type
Tcontextmenufactory = Class (tcomobjectfactory)
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 );
File: // when registering an extension library file, add the Library to the Registry.
Createregkey ('*/shellex ','','');
Createregkey ('*/shellex/contextmenuhandlers ','','');
Createregkey ('*/shellex/contextmenuhandlers/fileopreation', '', classid );

File: // If the operating system is Windows NT
If (win32platform = ver_platform_win32_nt) then
With Tregistry. Create do
Try
Rootkey: = HKEY_LOCAL_MACHINE;
Openkey ('Software/Microsoft/Windows/CurrentVersion/Shell extension', true );
Openkey ('apache', true );
Writestring (classid, 'Context menu shell extension ');
Finally
Free;
End;
End
Else begin
Deleteregkey ('*/shellex/contextmenuhandlers/fileopreation ');
Inherited updateregistry (Register );
End;
End;

 

Initialization
Tcontextmenufactory. Create (comserver, tcontextmenu, class_contextmenu,
'', 'Context menu shell extension', cimultiinstance, tmapartment );

End.

Add a tlistbox control and two tbutton controls to the opwindow window. The program list of opwindows. PAS 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: = 'Copy file ';
Button2.caption: = 'move 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;
File: // set the File Operation Type
Fstemp. wfunc: = fo_copy;
File: // allows the Undo operation
Fstemp. fflags: = fof_allowundo;
For I: = 0 to listbox1.items. Count-1 do begin
File: // full path name of the source file
Fstemp. pfrom: = pchar (listbox1.items. Strings [I]);
File: // path to be copied
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: = pchar (listbox1.items. Strings [I]);
Fstemp. PTO: = pchar (Spath );
Fstemp. lpszprogresstitle: = 'move file ';
If shfileoperation (fstemp) <> 0 then
Showmessage ('file copy failed ');
End;
End;
End;

End.

Click project | build contextmenu, and Delphi will create the contextmenu. dll file. This is the context-related menu program.
Use regsvr32.exe to register the program, and then right-click any or several files in Windows's example E. In the context menu
Click one more menu item for file operations. In the displayed window, the names of all selected files are listed. You can select the copy file button or
Move the file button to perform file operations.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.