Icontextmenu i Ikoną
ziom213
Oto Gotowy skrypt na IcontextMenu windowsa
library ContMenu;
uses
ComServ,
ContextM in 'ContextM.pas';
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;
begin
end.
unit ContextM;
interface
uses
Windows, ActiveX, ComObj, ShlObj, Dialogs;
type
TContextMenu = class(TComObject, IShellExtInit, IContextMenu)
private
FFileName: array[0..MAX_PATH] of Char;
protected
{ IShellExtInit }
function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning
function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult; stdcall;
{ IContextMenu }
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 = '{EBDF1F20-C829-11D1-8233-0020AF3E97A9}';
implementation
uses ComServ, SysUtils, ShellApi, Registry,Graphics;
function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult;
var
StgMedium: TStgMedium;
FormatEtc: TFormatEtc;
begin
// Fail the call if lpdobj is Nil.
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;
// Render the data referenced by the IDataObject pointer to an HGLOBAL
// storage medium in CF_HDROP format.
Result := lpdobj.GetData(FormatEtc, StgMedium);
if Failed(Result) then
Exit;
// If only one file is selected, retrieve the file name and store it in
// FFileName. Otherwise fail the call.
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 TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
idCmdLast, uFlags: UINT): HResult;
var
bmp : tpicture;
begin
Result := 0; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 0);
if ((uFlags and $0000000F) = CMF_NORMAL) or
((uFlags and CMF_EXPLORE) <> 0) then begin
// Add one menu item to context menu
InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst,
'text opcji');
bmp:=tpicture.create;
bmp.LoadFromFile('c:\ikonka.bmp');
SetMenuItemBitmaps(Menu,indexMenu,MF_BYPOSITION,bmp.Bitmap.handle,bmp.bitmap.handle);
// Return number of menu items added
Result := 1; // or use MakeResult(SEVERITY_SUCCESS, FACILITY_NULL, 1)
end;
end;
// Returns string containing path to Delphi command line compiler
function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
resourcestring
sPathError = 'Error setting current directory';
var
H: THandle;
PrevDir: string;
begin
Result := E_FAIL;
// Make sure we are not being called by an application
if (HiWord(Integer(lpici.lpVerb)) <> 0) then
begin
Exit;
end;
// Make sure we aren't being passed an invalid argument number
if (LoWord(lpici.lpVerb) <> 0) then begin
Result := E_INVALIDARG;
Exit;
end;
// Execute the command specified by lpici.lpVerb
// by invoking the Delphi command line compiler.
PrevDir := GetCurrentDir;
try
if not SetCurrentDir(ExtractFilePath(FFileName)) then
raise Exception.CreateRes(@sPathError);
H := WinExec(PChar(Format('program.exe', [FFileName])), lpici.nShow);
if (H < 32) then
MessageBox(lpici.hWnd, 'błąd uruchomienia.', 'Error',
MB_ICONERROR or MB_OK);
Result := NOERROR;
finally
SetCurrentDir(PrevDir);
end;
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 help string for menu item
StrCopy(pszName, 'opis opcji');
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);
CreateRegKey('*\shellex', '', '');
CreateRegKey('*\shellex\ContextMenuHandlers', '', '');
CreateRegKey('*\shellex\ContextMenuHandlers\ContMenu', '', ClassID);
CreateRegKey('Drive\shellex', '', '');
CreateRegKey('Drive\shellex\ContextMenuHandlers', '', '');
CreateRegKey('Drive\shellex\ContextMenuHandlers\ContMenu', '', ClassID);
CreateRegKey('Directory\shellex', '', '');
CreateRegKey('Directory\shellex\ContextMenuHandlers', '', '');
CreateRegKey('Directory\shellex\ContextMenuHandlers\ContMenu', '', 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, 'Context Menu Shell nazwa programu np. delphi');
finally
Free;
end;
end
else begin
DeleteRegKey('*\shellex\ContextMenuHandlers\ContMenu');
DeleteRegKey('*\shellex\ContextMenuHandlers');
DeleteRegKey('*\shellex');
DeleteRegKey('Drive\shellex\ContextMenuHandlers\ContMenu');
DeleteRegKey('Drive\shellex\ContextMenuHandlers');
DeleteRegKey('Drive\shellex');
DeleteRegKey('Directory\shellex\ContextMenuHandlers\ContMenu');
DeleteRegKey('Directory\shellex\ContextMenuHandlers');
DeleteRegKey('Directory\shellex');
inherited UpdateRegistry(Register);
end;
end;
initialization
TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
'', 'Context Menu Shell nazwa programu', ciMultiInstance,
tmApartment);
end.
To
bmp:=tpicture.create;
bmp.LoadFromFile('c:\ikonka.bmp');
SetMenuItemBitmaps(Menu,indexMenu,MF_BYPOSITION,bmp.Bitmap.handle,bmp.bitmap.handle);
zabija system, wyciek pamieci !!! Bitmapa tworzona i nikt jej nie zwalnia !
W elementach powloki to strasznie powazny problem bo konec koncow to explorer przepelni pamiec !!
Bitmapa powinna być utworzona na poczatku i zniszona na koncu zycia obiektu.
Arta mozna dodac do zbiorczego o powloce windows