unit main;
interface
uses
ComServ, SysUtils, ShellAPI, Registry, Classes, Windows,
ActiveX, ComObj, ShlObj, Graphics, Dialogs;
const
GUID_Tnp2cont: TGUID = '
{44FC978E-C20B-42D2-A6BD-DD3968D43172}';
type
Tnp2cont =
class(TComObject, IShellExtInit, IContextMenu)
protected
function IShellExtInit.Initialize = SEInitialize;
function SEInitialize(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;
implementation
var
FFileName:
array[0..MAX_PATH]
of Char;
hBmp: TBitmap;
type
Tnp2contFactory =
class(TComObjectFactory)
public
procedure UpdateRegistry(
Register: boolean);
override;
end;
function Tnp2cont.SEInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
var
StgMedium: TStgMedium;
FormatEtc: TFormatEtc;
begin
if (lpdobj =
nil)
then begin
Result := E_INVALIDARG;
Exit;
end;
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;
if (DragQueryFile(StgMedium.hGlobal, $FFFFFFFF,
nil, 0) = 1)
then begin
DragQueryFile(StgMedium.hGlobal, 0, FFileName, SizeOf(FFileName));
Result := NOERROR;
end
else begin
FFileName[0] := #0;
Result := E_FAIL;
end;
ReleaseStgMedium(StgMedium);
end;
function Tnp2cont.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
InsertMenu(Menu, indexMenu, MF_STRING
or MF_BYPOSITION, idCmdFirst,
'
Mit NotePad2 bearbeiten');
Result := 1;
end;
end;
function Tnp2cont.InvokeCommand(
var lpici: TCMInvokeCommandInfo): HResult;
resourcestring
sPathError = '
Error setting current directory';
var
H: THandle;
PrevDir:
string;
begin
Result := E_FAIL;
if (HiWord(Integer(lpici.lpVerb)) <> 0)
then
begin
Exit;
end;
if (LoWord(lpici.lpVerb) <> 0)
then begin
Result := E_INVALIDARG;
Exit;
end;
PrevDir := GetCurrentDir;
try
if not SetCurrentDir(ExtractFilePath(FFileName))
then
raise Exception.CreateRes(@sPathError);
H := WinExec(PChar(Format(extractfilepath(paramstr(0))+'
notepad2.exe', [FFileName])), lpici.nShow);
if (H < 32)
then
MessageBox(lpici.hWnd, '
NotePad2 konnte nicht gestartet werden.', '
Error',
MB_ICONERROR
or MB_OK);
Result := NOERROR;
finally
SetCurrentDir(PrevDir);
end;
end;
function Tnp2cont.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult;
begin
if (idCmd = 0)
then begin
if (uType = GCS_HELPTEXT)
then
// return help string for menu item
StrCopy(pszName, '
Diese Datei mit NotePad2 bearbeiten.');
Result := NOERROR;
end
else
Result := E_INVALIDARG;
end;
procedure Tnp2contfactory.UpdateRegistry(
Register: Boolean);
var
ClassID:
string;
begin
if Register then begin
inherited UpdateRegistry(
Register);
ClassID := GUIDToString(GUID_Tnp2cont);
CreateRegKey('
*\shellex', '
', '
');
CreateRegKey('
*\shellex\ContextMenuHandlers', '
', '
');
CreateRegKey('
*\shellex\ContextMenuHandlers\DFKontextMenu', '
', ClassID);
if (Win32Platform = VER_PLATFORM_WIN32_NT)
then
with TRegistry.Create
do
try
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('
SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True);
OpenKey('
Approved', True);
WriteString(ClassID, '
NP2');
finally
Free;
end;
end
else begin
DeleteRegKey('
*\shellex\ContextMenuHandlers\DFKontextMenu');
DeleteRegKey('
*\shellex\ContextMenuHandlers');
DeleteRegKey('
*\shellex');
inherited UpdateRegistry(
Register);
end;
end;
initialization
// hier wird die Erweiterung registriert
Tnp2contFactory.Create(ComServer, Tnp2cont, GUID_Tnp2cont,
'
', '
NotePad2', ciMultiInstance, tmApartment);
hBmp := TBitmap.Create;
// Bild aus Ressourcendatei laden (der Name der Bildressource muss als 2. Parameter angegeben
// werden - auf keinen Fall den DefaultNamen belassen, den der Bildeditor vergibt!
hBmp.LoadFromResourceName(hInstance, '
NOTEPAD2');
finalization
// Bitmap wieder freigeben
hBmp.Free;
end.