function SlashDirName(ADir: String): string;
var s: string;
RootDir: Boolean;
begin
if ADir <> '' then
begin
s := ADir;
RootDir := ((Length(s) = 3) and (S[2] = ':')) or (s = '\');
if not RootDir then
if s[Length(s)] <> '\' then s := s + '\';
Result := s;
end;
end;
function SHGetIDListFromPath(Path: TFileName; var ShellFolder: IShellFolder): pItemIDList;
var TempPath, NextDir: TFileName;
SlashPos: Integer;
Folder, subFolder: IShellFolder;
PIDL, PIDLbase: PItemIDList;
ParseStruct: TStrRet;
ParseNAme: string;
EList: IEnumIDList;
DidGet: integer;
ScanParam: integer;
begin
SHGetDesktopFolder(Folder);
SHGetSpecialFolderLocation(0, CSIDL_DRIVES, PIDLbase);
{ Enumerate the path one directory at a time }
while Length(TempPath)>0 do
begin
SlashPos := Pos('\', TempPath);
if SlashPos > 0 then
begin
if Pos(':', TempPath) > 0 then NextDir := Copy(TempPath, 1, 3)
else NextDir := SlashDirName(NextDir) + Copy(TempPath, 1, SlashPos - 1);
TempPath := Copy(TempPath, SlashPos + 1, Length(TempPath));
end else begin
if NextDir = '' then NextDir:=TempPath
else NextDir := SlashDirName(NextDir) + TempPath;
TempPath := '';
end;
Pidl := PidlBase;
ScanParam := SHCONTF_FOLDERS or SHCONTF_INCLUDEHIDDEN;
if (NextDir = Path) and (not DirectoryExists(Path)) then
ScanParam := ScanParam or SHCONTF_NONFOLDERS;
if S_OK = SubFolder.EnumObjects(0, ScanParam, EList) then
while S_OK = EList.Next(1, pidl, ULong(DidGet)) do
begin
OLECheck(SubFolder.GetDisplayNameOf(PIDL, SHGDN_FORPARSING, ParseStruct));
case ParseStruct.uType of
STRRET_CSTR: ParseName := ParseStruct.cStr;
STRRET_WSTR: ParseName := WideCharToString(ParseStruct.pOleStr);
STRRET_OFFSET: Parsename := PChar(DWORD(Pidl)+ParseStruct.uOffset);
end;
if UpperCase(Parsename) = UpperCase(NextDir) then Break;
end else begin
Folder:=nil;
Result:=nil;
Exit;
end;
if DidGet=0 then
begin
Folder := nil;
Result := nil;
Exit;
end;
PIDLBase := Pidl;
Folder := subFolder;
{ As best as we can, determine whether or not this is a file. }
{ If so then we cannot bind it to the ShellFolder (hence "folder".) }
if not FileExists(NextDir) then
OLECheck(Folder.BindToObject(Pidl, nil, IID_IShellFolder, Pointer(SubFolder)));
end;
ShellFolder := Folder;
if ShellFolder = nil then Result := nil
else Result := Pidl;
end;
procedure ContextMenuForFile(hWndMain:DWord;Folder: IShellFolder; Pidl: pItemIDList);
var aContextMenu: IContextMenu;
aPrgOut: Pointer;
aPopup: hMenu;
aCmd: Integer;
aCmdInfo: TCMInvokeCommandInfo;
MenuInfo: TMenuItemInfo;
t, ItemCount: integer;
buf: array[0..80] of Char;
Where: TPoint;
begin
GetCursorPos(Where);
OLECheck(Folder.GetUIObjectOf(hWndMain, 1, Pidl, IID_IContextMenu,
aPrgOut, Pointer(aContextMenu)));
aPopup := CreatePopUpMenu;
if aPopup = 0 then exit;
try
OLECheck(aContextMenu.QueryContextMenu(aPopup, 0, 1, $7FFF, CMF_NORMAL));
AppendMenu(aPopup, MF_SEPARATOR, 0, '');
if s_NowFile <> '' then //显示保存文件菜单
Appendmenu(aPopup,MF_STRING,SC_MenuSave,'Save');
if s_NowURL <> '' then //显示复制URL菜单
Appendmenu(aPopup,MF_STRING,SC_MenuCopyURL,'Copy URL');
if s_NowPath <> '' then //显示输出文件菜单
Appendmenu(aPopup,MF_STRING,SC_MenuExportPath,'Export Files');
aCmd := Integer(TrackPopupMenuEx(aPopup, TPM_LEFTALIGN or TPM_RETURNCMD or
TPM_RIGHTBUTTON or TPM_HORIZONTAL or TPM_VERTICAL, Where.X, Where.Y,
hWndMain, nil));
if aCmd <> 0 then
begin
if aCmd = SC_MenuSave then //用户选择保存
begin
MessageBox(0,PChar(s_NowFile),'Save',0);
end
else if aCmd = SC_MenuCopyURL then //用户选择CopyURL
begin
CopyURLToClp(s_NowURL);
// MessageBox(0,PChar(s_NowURL),'Copy URL',0);
end
else if aCmd = SC_MenuExportPath then //选择输出
begin
form1.ExportCache;
end
else
begin
Fillchar(aCmdInfo, Sizeof(aCmdInfo), 0);
with aCmdInfo do
begin
cbSize := SizeOf(TCMInvokeCommandInfo);
hwnd := hWndMain;
lpVerb := MakeIntResource(aCmd - 1);
nShow := SW_SHOWNORMAL;
end;
try
aContextMenu.InvokeCommand(aCmdInfo);
except
raise Exception.Create('The system menu for this file could not be created.');
end;
bFileIsEx := FileExists(s_NowFile); //返回文件是否存在
bDirIsEx := DirectoryExists(s_NowPath); //返回目录是否存在
end;
end;
finally
DestroyMenu(aPopup);
end;
end;
procedure DisplayContextMenuForFile(hWnd:DWord;FileName: string);
var ShellFolder: IShellFolder;
Pidl: pItemIDList;
begin
Pidl := SHGetIDListFromPath(FileName, ShellFolder);
if Assigned(Pidl) then
ContextMenuForFile(hWnd,ShellFolder, Pidl);
end;