The Shell supports several search utilities that allow users to locate namespace
objects such as files or printers. You can create a custom search engine and make
it available to users by implementing and registering a search handler.
Users have two ways to select a search engine. The first way is from the Start
menu. With systems earlier than Microsoft Windows 2000, selecting the Find command
on the Start menu displays a submenu of the available search engines. With Windows
2000 and later, the Start menu's Find command is renamed Search.
Users can also launch a search from Windows Explorer. On systems earlier than
Windows 2000, they click the Find command on the Tools menu to display essentially
the same menu as the one associated with the Start menu. However, Windows Explorer
for Windows 2000 handles search engines in a very different way. Instead of
handling search engines as a submenu of the Tools menu, there is now a Search
button on the toolbar. Clicking this button opens the Explorer bar's Search pane
The following example shows how to implement Shell Search Handler using Borland
Delphi. As any Shell Extension it must be implemented as in-process Component
Object Model (COM) object. It must be assigned a globally unique identifier (GUID)
and registered using regsvr32.exe
1 library SearchHandler;
2
3 uses
4 ComServ,
5 HandlerM in 'HandlerM.pas';
6
7 {$R *.RES}
8
9 exports
10 DllGetClassObject,
11 DllCanUnloadNow,
12 DllRegisterServer,
13 DllUnregisterServer;
14
15 begin
16 end.
17
18 {*****************************************************************************
19 Name : TSearchEngine
20 Author : Perevoznyk Serhiy
21 Description : Shell Search Handler
22 *****************************************************************************}
23
24 unit HandlerM;
25
26 interface
27
28 uses
29 Windows, ActiveX, ComObj, ShlObj, Dialogs;
30
31 type
32 TSearchEngine = class(TComObject, IShellExtInit, IContextMenu)
33 protected
34 { IShellExtInit }
35 function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning
36 function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
37 hKeyProgID: HKEY): HResult; stdcall;
38 { IContextMenu }
39 function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
40 uFlags: UINT): HResult; stdcall;
41 function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
42 function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
43 pszName: LPSTR; cchMax: UINT): HResult; stdcall;
44 end;
45
46 const
47 Class_SearchEngine: TGUID = '{B8091A44-1F5E-4EFE-8F26-194ACBDE4465}';
48
49 implementation
50
51 uses ComServ, SysUtils, ShellApi, Registry;
52
53 function TSearchEngine.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
54 hKeyProgID: HKEY): HResult;
55 begin
56 Result := NOERROR;
57 end;
58
59 function TSearchEngine.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
60 idCmdLast, uFlags: UINT): HResult;
61 begin
62 Result := 0;
63 end;
64
65
66 function TSearchEngine.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
67 begin
68 //enter your code here
69 ShowMessage('Executed');
70 Result := NOERROR;
71 end;
72
73 function TSearchEngine.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
74 pszName: LPSTR; cchMax: UINT): HRESULT;
75 begin
76 if (idCmd = 0) then
77 begin
78 if (uType = GCS_HELPTEXT) then
79 // return help string for menu item
80 StrCopy(pszName, 'Find document');
81 Result := NOERROR;
82 end
83 else
84 Result := E_INVALIDARG;
85 end;
86
87 type
88 TSearchEngineFactory = class(TComObjectFactory)
89 public
90 procedure UpdateRegistry(register: Boolean); override;
91 end;
92
93
94 procedure CreateKey(const Key, ValueName, Value: string);
95 var
96 Handle: HKey;
97 Status, Disposition: Integer;
98 begin
99 Status := RegCreateKeyEx(HKEY_LOCAL_MACHINE, PChar(Key), 0, '',
100 REG_OPTION_NON_VOLATILE, KEY_READ or KEY_WRITE, nil, Handle,
101 @Disposition);
102 if Status = 0 then
103 begin
104 RegSetValueEx(Handle, PChar(ValueName), 0, REG_SZ,
105 PChar(Value), Length(Value) + 1);
106 RegCloseKey(Handle);
107 end;
108 end;
109
110
111 procedure DeleteKey(const Key: string);
112 begin
113 RegDeleteKey(HKEY_LOCAL_MACHINE, PChar(Key));
114 end;
115
116 procedure TSearchEngineFactory.UpdateRegistry(register: Boolean);
117 var
118 ClassID: string;
119 FileName: array [0..MAX_PATH] of Char;
120 begin
121 if register then
122 begin
123 inherited UpdateRegistry(register);
124 ClassID := GUIDToString(Class_SearchEngine);
125 GetModuleFileName(HInstance, FileName, SizeOf(FileName));
126
127 CreateKey('Software\Microsoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
128 SearchHandler');
129
130 CreateKey('Software\Microsoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
131 SearchHandler\0'lphi...');
132
133 CreateKey('crosoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
134 SearchHandler\0\DefaultIcon', ' ', FileName + '0');
135 end
136 else
137 begin
138
139 DeleteKey('crosoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
140 SearchHandler\0\DefaultIcon');
141
142 DeleteKey('crosoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
143 SearchHandler\0');
144
145 DeleteKey('crosoft\Windows\CurrentVersion\Explorer\FindExtensions\Static\
146 SearchHandler');
147 inherited UpdateRegistry(Register);
148 end;
149 end;
150
151 initialization
152 TSearchEngineFactory.Create(ComServer, TSearchEngine, Class_SearchEngine,
153 'Delphi Search Engine Example', ciMultiInstance,
154 tmApartment);
155 end.
|