我得到一个名为FontPIDL的字体文件的绝对PIDL
我使用以下代码打开它: var ShExeInfo : SHELLEXECUTEINFO;
begin
ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo));
ShExeInfo.cbSize := SizeOf(ShExeInfo);
ShExeInfo.lpVerb := 'Open';
ShExeInfo.lpIDList := FontPIDL;
ShExeInfo.nShow := SW_SHOWNORMAL;
ShExeInfo.fMask := SEE_MASK_IDLIST;
end; 获取一个错误:The parameter is incorrect
我想知道怎么解决它?我错过了什么参数吗?
更新:
如何获得字体文件绝对PIDL:
var
psfDeskTop : IShellFolder;
psfFont : IShellFolder;
pEnumList : IEnumIdList;
pidFont : PItemIdList;
pidChild : PItemIdList;
pidAbFont : PItemIdList;
FontPath : array[0..MAX_PATH - 1] of Char;
pchEaten, dwAttributes, ItemsFetched : ULONG;
begin
FillChar(FontPath, sizeof(FontPath), #0);
SHGetSpecialFolderPath(0, FontPath, CSIDL_FONTS, False);
SHGetDesktopFolder(psfDeskTop);
psfDeskTop.ParseDisplayName(0, nil, FontPath, pchEaten, pidFont,
dwAttributes);
psfDeskTop.BindToObject(pidFont, nil, IID_IShellFolder, psfFont);
psfFont.EnumObjects(0, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or
SHCONTF_INCLUDEHIDDEN, pEnumList);
ItemsFetched := 0;
while pEnumList.Next(1, pidChild, ItemsFetched) = NO_ERROR do
begin
pidAbFont := ILCombine(pidFont , pidChild);
///... do something
end;
end;发布于 2012-11-28 09:11:07
省略lpVerb分配会使代码工作:
begin
ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo));
ShExeInfo.cbSize := SizeOf(ShExeInfo);
// ShExeInfo.lpVerb := 'Open'; will be fail .
// use ShExeInfo.lpVerb := '' or ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo)); before
ShExeInfo.lpIDList := FontPIDL;
ShExeInfo.nShow := SW_SHOWNORMAL;
ShExeInfo.fMask := SEE_MASK_IDLIST;
end; 发布于 2012-11-28 19:34:04
删除ShExeInfo.lpVerb := 'Open';语句是有效的,但是没有其他人说过它工作的原因。原因是字体文件在默认情况下没有注册"Open"谓词。通过将lpVerb设置为nil,允许ShellExecuteEx()对文件类型执行实际的默认谓词,不管它是什么。根据文献资料
lpVerb 类型: LPCTSTR 指定要执行的操作的字符串,称为谓词。可用谓词集取决于特定的文件或文件夹。通常,对象的快捷菜单中可用的操作是可用的谓词。此参数可以为NULL,在这种情况下,如果可用,则使用默认谓词。如果没有,则使用“打开”动词。如果两个谓词都不可用,系统将使用注册表中列出的第一个动词。
发布于 2012-11-28 07:37:36
我给你做了个样本:
var
ShExeInfo: TShellExecuteInfo;
ExecuteFile: string;
begin
ZeroMemory(@ShExeInfo, SizeOf(ShExeInfo));
ExecuteFile:='D:\SoftWare\font\BDavat.ttf';
FillChar(ShExeInfo, SizeOf(ShExeInfo), 0) ;
ShExeInfo.cbSize := SizeOf(TShellExecuteInfo) ;
with ShExeInfo do
begin
//lpVerb := 'Open';
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Application.Handle;
lpFile := PWideChar(ExecuteFile) ;
nShow := SW_SHOWNORMAL;
end;
ShellExecuteEx(@ShExeInfo) ;
end;函数用于获取它们的路径:
uses
ShlObj, ActiveX;
const
CSIDL_FLAG_CREATE = $8000;
CSIDL_ADMINTOOLS = $0030;
CSIDL_ALTSTARTUP = $001D;
CSIDL_APPDATA = $001A;
CSIDL_BITBUCKET = $000A;
CSIDL_CDBURN_AREA = $003B;
CSIDL_COMMON_ADMINTOOLS = $002F;
CSIDL_COMMON_ALTSTARTUP = $001E;
CSIDL_COMMON_APPDATA = $0023;
CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
CSIDL_COMMON_DOCUMENTS = $002E;
CSIDL_COMMON_FAVORITES = $001F;
CSIDL_COMMON_MUSIC = $0035;
CSIDL_COMMON_PICTURES = $0036;
CSIDL_COMMON_PROGRAMS = $0017;
CSIDL_COMMON_STARTMENU = $0016;
CSIDL_COMMON_STARTUP = $0018;
CSIDL_COMMON_TEMPLATES = $002D;
CSIDL_COMMON_VIDEO = $0037;
CSIDL_CONTROLS = $0003;
CSIDL_COOKIES = $0021;
CSIDL_DESKTOP = $0000;
CSIDL_DESKTOPDIRECTORY = $0010;
CSIDL_DRIVES = $0011;
CSIDL_FAVORITES = $0006;
CSIDL_FONTS = $0014;
CSIDL_HISTORY = $0022;
CSIDL_INTERNET = $0001;
CSIDL_INTERNET_CACHE = $0020;
CSIDL_LOCAL_APPDATA = $001C;
CSIDL_MYDOCUMENTS = $000C;
CSIDL_MYMUSIC = $000D;
CSIDL_MYPICTURES = $0027;
CSIDL_MYVIDEO = $000E;
CSIDL_NETHOOD = $0013;
CSIDL_NETWORK = $0012;
CSIDL_PERSONAL = $0005;
CSIDL_PRINTERS = $0004;
CSIDL_PRINTHOOD = $001B;
CSIDL_PROFILE = $0028;
CSIDL_PROFILES = $003E;
CSIDL_PROGRAM_FILES = $0026;
CSIDL_PROGRAM_FILES_COMMON = $002B;
CSIDL_PROGRAMS = $0002;
CSIDL_RECENT = $0008;
CSIDL_SENDTO = $0009;
CSIDL_STARTMENU = $000B;
CSIDL_STARTUP = $0007;
CSIDL_SYSTEM = $0025;
CSIDL_TEMPLATES = $0015;
CSIDL_WINDOWS = $0024;
function GetShellFolder(CSIDL: integer): string;
var
pidl : PItemIdList;
FolderPath : string;
SystemFolder : Integer;
Malloc : IMalloc;
begin
Malloc := nil;
FolderPath := '';
SHGetMalloc(Malloc);
if Malloc = nil then
begin
Result := FolderPath;
Exit;
end;
try
SystemFolder := CSIDL;
if SUCCEEDED(SHGetSpecialFolderLocation(0, SystemFolder, pidl)) then
begin
SetLength(FolderPath, max_path);
if SHGetPathFromIDList(pidl, PChar(FolderPath)) then
begin
SetLength(FolderPath, length(PChar(FolderPath)));
end;
end;
Result := FolderPath;
finally
Malloc.Free(pidl);
end;
end;如何使用:
ShowMessage(GetShellFolder(CSIDL_FONTS));测试一下,我希望能帮到你.
https://stackoverflow.com/questions/13599532
复制相似问题