Subversion Repositories decoder

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
unit ShellExtMain;
2
 
3
interface
4
 
5
uses
6
  ComServ, SysUtils, ShellAPI, Windows, Registry, ActiveX, ComObj, ShlObj,
7
  Graphics, classes, inifiles;
8
 
9
const
10
  GUID_TDFKontextMenuShellExt: TGUID = '{C30DC498-38EA-4DED-8AD4-E302CE094892}';
11
 
12
type
13
  TDFKontextMenuShellExt = class(TComObject, IShellExtInit, IContextMenu)
14
    protected
15
      function IShellExtInit.Initialize = SEInitialize;
16
      function SEInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall;
17
      function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uflags: UINT): HResult; stdcall;
18
      function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
19
      function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult; stdcall;
20
  end;
21
 
22
implementation
23
 
24
var
25
  hBmp: TBitmap;
26
  handle: hwnd;
27
  vsl: tstringlist;
28
  path: string;
29
  langini: TIniFile;
30
 
31
type
32
  TDFKontextMenuShellExtFactory = class(TComObjectFactory)
33
  public
34
    procedure UpdateRegistry(Register: boolean); override;
35
  end;
36
 
37
function TDFKontextMenuShellExt.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
38
  pszName: LPSTR; cchMax: UINT): HResult;
39
begin
40
  try
41
    if (idCmd = 0) then
42
    begin
43
      if (uType = GCS_HELPTEXT) then
44
        StrCopy(pszName, pchar(langini.ReadString('ShlExt', 'openwith', '?')));
45
 
46
      Result := NOERROR;
47
    end
48
    else
49
      Result := E_INVALIDARG;
50
  except
51
    Result := E_UNEXPECTED;
52
  end;
53
end;
54
 
55
function TDFKontextMenuShellExt.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
56
var
57
  i: integer;
58
  para: string;
59
begin
60
  Result := E_FAIL;
61
  if (HiWord(Integer(lpici.lpVerb)) <> 0) then
62
    Exit;
63
 
64
  if not (LoWord(lpici.lpVerb) in [0, 1, 2]) then
65
  begin
66
    Result := E_INVALIDARG;
67
    Exit;
68
  end;
69
 
70
  if not fileexists(path+'Coder.exe') then
71
    Messagebox(handle, pchar(langini.ReadString('ShlExt', 'codermissing', '?')), pchar(langini.ReadString('ShlExt', 'error', '?')), MB_ICONERROR or MB_OK)
72
  else
73
  begin
74
    para := '';
75
    for i := 0 to vsl.count - 1 do
76
      para := para + '"'+vsl.strings[i]+'" ';
77
    para := copy(para, 0, length(para)-1);
78
 
79
    ShellExecute(handle, 'open', PChar(path+'Coder.exe'), PChar(para), pchar(path), SW_NORMAL);
80
  end;
81
 
82
  Result := NOERROR;
83
end;
84
 
85
function TDFKontextMenuShellExt.QueryContextMenu(Menu: HMENU; indexMenu,
86
  idCmdFirst, idCmdLast, uflags: UINT): HResult;
87
begin
88
  Result := 0;
89
 
90
  if ((uFlags and $0000000F) = CMF_NORMAL) or
91
      ((uFlags and CMF_EXPLORE) <> 0) or
92
      ((uFlags and CMF_VERBSONLY <> 0)) then
93
  begin
94
    InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst, pchar(langini.readstring('ShlExt', 'context', '?')));
95
 
96
    if hBmp.Handle <> 0 then
97
      SetMenuItemBitmaps(Menu, indexMenu, MF_BYPOSITION, hBmp.Handle, hBmp.Handle);
98
 
99
    Result := 1;
100
  end;
101
end;
102
 
103
function TDFKontextMenuShellExt.SEInitialize(pidlFolder: PItemIDList;
104
  lpdobj: IDataObject; hKeyProgID: HKEY): HResult;
105
var
106
  StgMedium: TStgMedium;
107
  FormatEtc: TFormatEtc;
108
  FFileName: array[0..MAX_PATH] of Char;
109
  i: Integer;
110
begin
111
  if (lpdobj = nil) then
112
  begin
113
    Result := E_INVALIDARG;
114
    Exit;
115
  end;
116
 
117
  with FormatEtc do
118
  begin
119
    cfFormat := CF_HDROP;
120
    ptd      := nil;
121
    dwAspect := DVASPECT_CONTENT;
122
    lindex   := -1;
123
    tymed    := TYMED_HGLOBAL;
124
  end;
125
 
126
  Result := lpdobj.GetData(FormatEtc, StgMedium);
127
  if Failed(Result) then
128
    Exit;
129
 
130
  vsl := tstringlist.Create;
131
 
132
  vSL.Clear;
133
  for i := 0 to DragQueryFile(StgMedium.hGlobal, $FFFFFFFF, nil, 0) - 1 do
134
  begin
135
    DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
136
    vSl.Add(FFileName);
137
  end;
138
 
139
  ReleaseStgMedium(StgMedium);
140
  Result := NOERROR;
141
end;
142
 
143
procedure TDFKontextMenuShellExtFactory.UpdateRegistry(Register: boolean);
144
var
145
  ClassID: string;
146
begin
147
  ClassID := GUIDToString(GUID_TDFKontextMenuShellExt);
148
 
149
  if Register then
150
  begin
151
    inherited UpdateRegistry(Register);
152
 
153
    CreateRegKey('Folder\shellex', '', '');
154
    CreateRegKey('Folder\shellex\ContextMenuHandlers', '', '');
155
    CreateRegKey('Folder\shellex\ContextMenuHandlers\(De)Coder', '', ClassID);
156
 
157
    CreateRegKey('*\shellex', '', '');
158
    CreateRegKey('*\shellex\ContextMenuHandlers', '', '');
159
    CreateRegKey('*\shellex\ContextMenuHandlers\(De)Coder', '', ClassID);
160
 
161
    if (Win32Platform = VER_PLATFORM_WIN32_NT) then
162
      with TRegistry.Create do
163
        try
164
          RootKey := HKEY_LOCAL_MACHINE;
165
          OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved', True);
166
          WriteString(ClassID, '(De)Coder');
167
          CloseKey;
168
        finally
169
          Free;
170
        end;
171
  end
172
  else
173
  begin
174
    DeleteRegKey('Folder\shellex\ContextMenuHandlers\(De)Coder');
175
    DeleteRegKey('Folder\shellex\ContextMenuHandlers');
176
    DeleteRegKey('Folder\shellex');
177
 
178
    DeleteRegKey('*\shellex\ContextMenuHandlers\(De)Coder');
179
    DeleteRegKey('*\shellex\ContextMenuHandlers');
180
    DeleteRegKey('*\shellex');
181
 
182
    if (Win32Platform = VER_PLATFORM_WIN32_NT) then
183
      with TRegistry.Create do
184
        try
185
          RootKey := HKEY_LOCAL_MACHINE;
186
          OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved', True);
187
          DeleteValue(ClassID);
188
          CloseKey;
189
        finally
190
          Free;
191
        end;
192
 
193
    inherited UpdateRegistry(Register);
194
  end;
195
end;
196
 
197
initialization
198
  // Initialisierung
199
  TDFKontextMenuShellExtFactory.Create(ComServer, TDFKontextMenuShellExt, GUID_TDFKontextMenuShellExt,
200
    '', '(De)Coder', ciMultiInstance, tmApartment);
201
  hBmp := TBitmap.Create;
202
  hBmp.LoadFromResourceName(hInstance, 'KONTEXTICON');
203
 
204
  path := '';
205
 
206
  // Pfad ermitteln
207
  with TRegistry.Create do
208
    try
209
      RootKey := HKEY_CURRENT_USER;
210
      OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\(De)Coder_is1');
211
      path := ReadString('InstallLocation');
212
      CloseKey;
213
      if path = '' then
214
      begin
215
        RootKey := HKEY_LOCAL_MACHINE;
216
        OpenKeyReadOnly('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\(De)Coder_is1');
217
        path := ReadString('InstallLocation');
218
        CloseKey;
219
      end;
220
    finally
221
      free;
222
    end;
223
 
224
  // Language.ini öffnen
225
  langini := TIniFile.Create(path+'Language.ini');
226
 
227
finalization
228
  hBmp.Free;
229
  langini.Free;
230
end.
231