示例代码:使用语法解决继承接口的命名冲突
|
TCCContextMenu = class(TComObject, IShellExtInit)
private
FFileList: TStringList;
FGraphic: TGraphic;
protected
{ IShellExtInit
接口 }
function IShellExtInit.Initialize = SEInitialize;
function SEInitialize(pidFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall;
public
procedure Initialize; override;
destructor Destroy; override;
|
示例代码:IShellExtInit.Initialize.
可以被任何实现IShellExtInit
的类所调用
|
function TCCContextMenu.SEInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult;
begin
Result := GetFileListFromDataObject(lpdobj, FFileList);
end;
function GetFileListFromDataObject(lpdobj: IDataObject; sl: TStringList): HResult;
var
fe: FormatEtc;
sm: StgMedium;
i, iFileCount: Integer;
FileName: array[0..MAX_PATH+1] of char;
begin
assert(lpdobj<>nil);
assert(sl<>nil);
sl.clear;
with fe do
begin
cfFormat := CF_HDROP;
ptd := nil;
dwAspect := DVASPECT_CONTENT;
lindex := -1;
tymed := TYMED_HGLOBAL;
end;
with sm do
begin
tymed := TYMED_HGLOBAL;
end;
Result := lpdobj.GetData(fe, sm);
if Failed(Result) then Exit;
iFileCount := DragQueryFile(sm.hGlobal, $ffffffff, nil, 0);
if iFileCount<=0 then
begin
ReleaseStgMedium(sm);
Result := E_INVALIDARG;
Exit;
end;
for i:=0 to iFileCount-1 do
begin
DragQueryFile(sm.hGlobal, i, FileName, sizeof(FileName));
sl.Add(FileName);
end;
ReleaseStgMedium(sm);
Result := S_OK;
end;
|
示例代码: QueryContextMenu
|
const
//
菜单类型
mfString = MF_STRING or MF_BYPOSITION;
mfOwnerDraw = MF_OWNERDRAW or MF_BYPOSITION;
mfSeparator = MF_SEPARATOR or MF_BYPOSITION;
//
菜单项
idCopyAnywhere = 0; //
复制(移动)
idRegister = 5; //
注册ActiveX
idUnregister = 6; //
取消注册ActiveX
idImagePreview = 10; //
预览图片文件
idMenuRange = 90;
//
在SDK
中是使用宏Make_HRESULT
实现的,Delphi
没有宏的概念,所以这里用函数
function Make_HResult(sev, fac, code: Word): DWord;
begin
Result := (sev shl 31) or (fac shl 16) or code;
end;
function TCCContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
var
Added: UINT;
begin
if(uFlags and CMF_DEFAULTONLY)=CMF_DEFAULTONLY then
begin
Result := Make_HResult(SEVERITY_SUCCESS, FACILITY_NULL, 0);
Exit;
end;
Added := 0;
//
加入CopyAnywhere
菜单项
InsertMenu(Menu, indexMenu, mfSeparator, 0, nil);
InsertMenu(Menu, indexMenu, mfString, idCmdFirst+idCopyAnywhere, PChar(sCopyAnywhere));
InsertMenu(Menu, indexMenu, mfSeparator, 0, nil);
Inc(Added, 3);
Result := Make_HResult(SEVERITY _SUCCESS, FACILITY_NULL, idMenuRange);
end;
|
示例代码: InvokeCommand
|
function TCCContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
begin
Result := E_INVALIDARG;
if HiWord(Integer(lpici.lpVerb))<>0 then Exit;
case LoWord(Integer(lpici.lpVerb)) of
idCopyAnywhere:
DoCopyAnywhere(lpici.hwnd, FFileList);
end;
Result := NOERROR;
end;
procedure DoCopyAnywhere(Wnd: HWND; sl: TStringList);
var
frm: TfrmCopyAnywhere;
begin
frm := TfrmCopyAnywhere.Create(Application);
try
frm.AddFiles(sl);
frm.ShowModal;
finally
frm.Free;
end;
end;
|
示例代码: GetCommandString
|
function TCCContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult;
var
strTip: String;
wstrTip: WideString;
begin
strTip := ‘‘;
Result := E_INVALIDARG;
if (uType and GCS_HELPTEXT)<> GCS_HELPTEXT then Exit;
case idCmd of
idCopyAnywhere: strTip := sCopyAnywhereTip;
end;
if strTip<>‘‘ then
begin
if (uType and GCS_UNICODE)=0 then //Anse
begin
lstrcpynA(pszName, PChar(strTip), cchMax);
end
else
begin
wstrTip := strTip;
lstrcpynW(PWideChar(pszName), PWideChar(wstrTip), cchMax);
end;
Result := S_OK;
end;
end;
|
示例代码:实现Context Menu Extension
的类工厂
|
procedure TCCContextMenuFactory.UpdateRegistry(Register: Boolean);
procedure DeleteRegValue(const Path, ValueName: String; Root: DWord=HKEY_CLASSES_ROOT);
var
reg: TRegistry;
begin
reg := TRegistry.Create;
with reg do
begin
try
RootKey := Root;
if OpenKey(Path, False) then
begin
if ValueExists(ValueName) then DeleteValue(ValueName);
CloseKey;
end;
finally
Free;
end;
end;
end;
const
RegPath = ‘*\shellex\ContextMenuHandlers\CCShellExt’;
ApprovedPath = ‘Software\Microsoft\Windows\CurrentVersion\ShellExtensions\Approved’;
var
strGUID: String;
begin
inherited;
strGUID := GUIDToString(Class_CCContextMenu);
if Register then
begin
CreateRegKey(RegPath, ‘‘, strGUID);
CreateRegKey(ApprovedPath, strGUID, ‘CC
的外壳扩展’, HKEY_LOCAL_MACHINE);
end
else
begin
DeleteRegKey(RegPath);
DeleteRegValue(ApprovedPath, strGUID, HKEY_LOCAL_MACHINE);
end;
end;
|
示例代码:
|
initialization
TCCContextMenuFactory.Create(ComServer, TCCContextMenu, Class_CCContextMenu, '', '', ciMultiInstance, tmApartment);
TTypedComObjectFactory.Create(ComServer, TCCContextMenu, Class_CCContextMenu,
ciMultiInstance, tmApartment);
|
示例代码:
实现注册/
反注册功能。4
个方法:IsActiveLib
,RegisterActiveLib
,UnregisterActiveLib
,ReportWin32Error
|
resourcestring
sCopyAnywhere = ‘
复制到... ‘;
sCopyAnywhereTip = ‘
将选定的文件复制到任何路径下’;
sRegister = ‘
注册...’;
sRegisterTip = ‘
注册ActiveX
库’;
sUnregister = ‘
取消注册...’;
sUnregisterTip = ‘
取消注册ActiveX
库’;
sImagePreview = ‘
预览图片文件’;
sImagePreviewTip = ‘
预览图片文件’;
function IsActiveLib(const FileName: String): Boolean;
var
Ext: String;
hLib: THandle;
begin
Result := False;
Ext := UpperCase(ExtractFileExt(FileName));
if (Ext<>‘.EXE’) and (Ext<>‘.DLL’) and (Ext<>‘.OCX’) then Exit;
hLib := LoadLibrary(PChar(FileName));
if hLib=0 then Exit;
if GetProcAddress(hLib, ‘DllRegisterServer’)<>nil then Result := True;
FreeLibrary(hLib);
end;
procedure RegisterActiveLib(Wnd: HWND; const FileName: String);
var
hLib: THandle;
fn : TDllRegisterServer;
hr: HResult;
begin
hLib := LoadLibrary(PChar(FileName));
if hLib=0 then
begin
ReportWin32Error(Wnd, ‘
装载文件失败’, GetLastError);
Exit;
end;
fn := TDllRegisterServer(GetProcAddress(hLib, ‘DllRegisterServer’));
if not Assigned(fn) then
begin
MessageBox(Wnd, ‘
定位函数入口点DllRegisterServer
失败’, ‘
错误’, MB_ICONEXCLAMATION);
FreeLibrary(hLib);
Exit;
end;
hr := fn();
if Failed(hr) then
begin
ReportWin32Error(Wnd, ‘
注册动态库失败’, hr);
FreeLibrary(hLib);
Exit;
end;
MessageBox(Wnd, ‘
注册成功’, ‘
成功, MB_ICONINFORMATION);
FreeLibrary(hLib);
end;
procedure UnregisterActiveLib(Wnd: HWND; const FileName: String);
var
hLib: THandle;
fn : TDllRegisterServer;
hr: HResult;
begin
hLib := LoadLibrary(PChar(FileName));
if hLib=0 then
begin
ReportWin32Error(Wnd, ‘
装载文件失败’, GetLastError);
Exit;
end;
fn := TDllUnregisterServer(GetProcAddress(hLib, ‘DllUnregisterServer’));
if not Assigned(fn) then
begin
MessageBox(Wnd, ‘
定位函数入口点DllUnregisterServer’
失败’, ‘
错误’, MB_ICONEXCLAMATION);
FreeLibrary(hLib);
Exit;
end;
hr := fn();
if Failed(hr) then
begin
ReportWin32Error(Wnd, ‘
取消注册动态库失败’, hr);
FreeLibrary(hLib);
Exit;
end;
MessageBox(Wnd, ‘
取消注册成功’, ‘
成功, MB_ICONINFORMATION);
FreeLibrary(hLib);
end;
prcedure ReportWin32Error(Wnd: HWND; const Prefix: String; dwError: DWord);
var
szError: array[0..399] of char;
str: String;
begin
FormatMessage(FROMAT_MESSAGE_FROM_SYSTEM, nil, dwError, Make_LangID(LANG_NEUTRAL, SUBLANG_DEFAULT), szError, sizeof(szError), nil);
str := Format(‘%s:%s’, [Prefix, StrPas(szError)]);
MessageBox(Wnd, PChar(str), ‘
错误’, MB_ICONEXCLAMATION);
end;
|
示例代码:IContextMenu3.HandleMenuMsg2
|
function TCCContextMenu.HandleMenuMsg2(uMsg: UINT; wParam, lParam: Integer; var lpResult: Integer): HResult;
var
pmis: PMeasureItemStruct;
pdis: PDrawItemStruct;
begin
Result := S_OK;
case uMsg of
WM_MEASUREITEM:
begin
pmis := PMeasureItemStruct(lParam);
if not Assigned(FGraphic) then
begin
pmis.itemWidth := 120;
pmis.itemHeight := 120;
Exit;
end;
//
如果图片小于120*120
,那么按照实际的显示,否则缩放到120*120
if (FGraphic.Width<=120) and (FGraphic.Height<=120) then
begin
pmis.itemWidth := 140;
pmis.itemHeight := FGraphic.Height + 40;
end
else
begin
pmis.itemWidth := 140;
pmis.itemHeight := 160;
end;
end;
WM_DRAWITEM:
begin
pdis := PDrawItemStruct(lParam);
DrawGraphic(pdis.hDC, pdis,rcItem, pdis.itemState, FGraphic);
end;
end;
end;
procedure DrawGraphic(adc: HDC; rc: TRect; State: Integer; Graphic: TGraphic);
var
rcImage, rcText, rcStretch: TRect;
Canvas: TCanvas;
nSaveDC: Integer;
x, y: Integer;
xScale, yScale, Scale: Double;
xStretch, yStretch: Integer;
begin
with rcImage do
begin
Left := rc.Left + 10;
Right := rc.Right �C 10;
Top := rc.Top + 10;
Bottom := rc.Bottom �C 30;
end;
with rcText do
begin
Left := rc.Left + 10;
Right := rc.Right �C 10;
Top := rc.Top - 20;
Bottom := rc.Bottom;
end;
Canvas := TCanvas.Create;
nSaveDC := 0;
try
nSaveDC := SaveDC(adc);
Canvas.Handle := adc;
with Canvas do
begin
if not Assigned(Graphic) then
begin
Rectangle(rcImage);
MoveTo(rcImage.Left, rcImage.Top);
LineTo(rcImage.Right, rcImage.Bottom);
MoveTo(rcImage. Right, rcImage.Top);
LineTo(rcImage. Left, rcImage.Bottom);
DrawText(Canvas.Handle, ‘
未知图像’, -1, rcImage, DT_SINGLELINE or DT_CENTER or DT_VECNTER);
end
else
begin
if (Graphic.Width<rcImage.Right-rcImage.Left) and (Graphic.Height<rcImage.Bottom-rcImage.Top) then
begin
x := rcImage.Left + (rcImage.Right - rcImage.Left - Graphic.Width) div 2;
y := rcImage. Top + (rcImage. Bottom - rcImage. Top - Graphic. Height) div 2;
Canvas.Draw(x, y, Graphic);
end
else
begin
xScale := Graphic.Width / (rcImage.Right - rcImage.Left);
yScale := Graphic.Height / (rcImage.Bottom - rcImage.Top);
Scale := Max(xScale, yScale);
xStretch := Trunc(Graphic.Width / Scale);
yStretch := Trunc(Graphic. Height / Scale);
x := rcImage.Left + (rcImage.Right - rcImage.Left - xStretch) div 2;
y := rcImage. Top + (rcImage. Bottom - rcImage. Top - yStretch) div 2;
rcStretch := Rect(x, y, x+xStretch, y+yStretch);
Canvas.StretchDraw(rcStretch, Graphic);
end;
Windows.FillRect(Canvas.Handle, GetSysColor(COLOR_MENUTEXT));
SetBkColor(Canvas. Handle, PChar(ImageInfoToStr(Graphic)), -1, rcText, DT_SINGLELINE or DT_CENTER or DT_VCENTER);
end;
end;
finally
Canvas.Handle :=0;
Canvas.Free;
RestoreDC(adc, nSaveDC);
end;
end;
function ImageInfoToStr(Graphic: TGraphic): String;
begin
Result := Format(‘%d * %d’, [Graphic.Width, Graphic.Height]);
if Graphic is TIcon then Result := Result + ‘
图标’;
if Graphic is TBitmap then
begin
case TBitmap(Graphic).PixelFormat of
pfDevice: Result := Result + ‘DDB’;
pf1bit: Result := Result + ‘2
色;
pf4bit: Result := Result + ‘16
色;
pf8bit: Result := Result + ‘256
色;
pf15bit, pf16bit: Result := Result + ‘16
位色;
pf24bit: Result := Result + ‘24
位色;
pf32bit: Result := Result + ‘32
位色;
pfCustom: Result := Result + ‘
自定义’;
end;
Result := Result + ‘
位图’;
end;
if Graphic is TMetaFile then
begin
Result := Result + Format(‘(%d*%d)
元文件’, [TMetaFile(Graphic),MMWidth div 100, TMetaFile(Graphic).MMHeight div 100])
end;
if Graphic is TJPEGImage then
begin
case TJPEGImage(Graphic).PixelFormat of
jf24Bit: Result := Result + ‘24
位色JPEG’;
jf8Bit: Result := Result + ‘8
位色JPEG’;
end;
end;
end;
|