📄 jclshell.pas
字号:
end;
function ShellLinkIcon(const FileName: string): HICON; overload;
var
Link: TShellLink;
begin
if Succeeded(ShellLinkResolve(FileName, Link)) then
begin
Result := ShellLinkIcon(Link);
ShellLinkFree(Link);
end
else
Result := 0;
end;
//=== Miscellaneous ==========================================================
function SHGetItemInfoTip(const Folder: IShellFolder; Item: PItemIdList): string;
var
QueryInfo: IQueryInfo;
InfoTip: PWideChar;
begin
Result := '';
if (Item = nil) or (Folder = nil) then
Exit;
if Succeeded(Folder.GetUIObjectOf(0, 1, Item, IQueryInfo, nil,
Pointer(QueryInfo))) then
begin
if Succeeded(QueryInfo.GetInfoTip(0, InfoTip)) then
begin
Result := WideCharToString(InfoTip);
SHFreeMem(Pointer(InfoTip));
end;
end;
end;
function SHDllGetVersion(const FileName: string; var Version: TDllVersionInfo): Boolean;
type
TDllGetVersionProc = function (var pdvi: TDllVersionInfo): HRESULT; stdcall;
var
_DllGetVersion: TDllGetVersionProc;
LibHandle: HINST;
begin
Result := False;
LibHandle := LoadLibrary(PChar(FileName));
if LibHandle <> 0 then
begin
@_DllGetVersion := GetProcAddress(LibHandle, PChar('DllGetVersion'));
if @_DllGetVersion <> nil then
begin
Version.cbSize := SizeOf(TDllVersionInfo);
Result := Succeeded(_DllGetVersion(Version));
end;
FreeLibrary(LibHandle);
end;
end;
function OverlayIcon(var Icon: HICON; Overlay: HICON; Large: Boolean): Boolean;
var
Source, Dest: HIMAGELIST;
Width, Height: Integer;
begin
Result := False;
if Large then
begin
Width := GetSystemMetrics(SM_CXICON);
Height := GetSystemMetrics(SM_CYICON);
Source := ImageList_Create(Width, Height, ILC_MASK or ILC_COLOR32, 1, 0);
end
else
begin
Width := GetSystemMetrics(SM_CXSMICON);
Height := GetSystemMetrics(SM_CYSMICON);
Source := ImageList_Create(Width, Height, ILC_MASK or ILC_COLOR32, 1, 0);
end;
if Source <> 0 then
begin
if (ImageList_AddIcon(Source, Icon) <> -1) and
(ImageList_AddIcon(Source, Overlay) <> -1) then
begin
Dest := HIMAGELIST(ImageList_Merge(Source, 0, Source, 1, 0, 0));
if Dest <> 0 then
begin
DestroyIcon(Icon);
Icon := ImageList_ExtractIcon(0, Dest, 0);
ImageList_Destroy(Dest);
Result := True;
end;
end;
ImageList_Destroy(Source);
end;
end;
function OverlayIconShortCut(var Large, Small: HICON): Boolean;
var
OvlLarge, OvlSmall: HICON;
begin
Result := False;
if ExtractIconEx(PChar('shell32.dll'), 29, OvlLarge, OvlSmall, 1) = 2 then
begin
OverlayIcon(Large, OvlLarge, True);
OverlayIcon(Small, OvlSmall, False);
end;
end;
function OverlayIconShared(var Large, Small: HICON): Boolean;
var
OvlLarge, OvlSmall: HICON;
begin
Result := False;
if ExtractIconEx(PChar('shell32.dll'), 28, OvlLarge, OvlSmall, 1) = 2 then
begin
OverlayIcon(Large, OvlLarge, True);
OverlayIcon(Small, OvlSmall, False);
end;
end;
function GetSystemIcon(IconIndex: Integer; Flags: Cardinal): HICON;
var
FileInfo: TSHFileInfo;
ImageList: HIMAGELIST;
begin
FillChar(FileInfo, SizeOf(FileInfo), #0);
if Flags = 0 then
Flags := SHGFI_SHELLICONSIZE;
ImageList := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo),
Flags or SHGFI_SYSICONINDEX);
Result := ImageList_ExtractIcon(0, ImageList, IconIndex);
end;
function ShellExecEx(const FileName: string; const Parameters: string;
const Verb: string; CmdShow: Integer): Boolean;
var
Sei: TShellExecuteInfo;
begin
FillChar(Sei, SizeOf(Sei), #0);
Sei.cbSize := SizeOf(Sei);
Sei.fMask := SEE_MASK_DOENVSUBST or SEE_MASK_FLAG_NO_UI;
Sei.lpFile := PChar(FileName);
Sei.lpParameters := PCharOrNil(Parameters);
Sei.lpVerb := PCharOrNil(Verb);
Sei.nShow := CmdShow;
Result := ShellExecuteEx(@Sei);
end;
{ TODO -cHelp : author Jeff note, ShellExecEx() above used to be ShellExec()... }
function ShellExec(Wnd: Integer; const Operation, FileName, Parameters, Directory: string; ShowCommand: Integer): Boolean;
begin
Result := ShellExecute(Wnd, PChar(Operation), PChar(FileName), PChar(Parameters),
PChar(Directory), ShowCommand) > 32;
end;
function ShellExecAndWait(const FileName: string; const Parameters: string;
const Verb: string; CmdShow: Integer): Boolean;
var
Sei: TShellExecuteInfo;
Res: LongBool;
Msg: tagMSG;
begin
FillChar(Sei, SizeOf(Sei), #0);
Sei.cbSize := SizeOf(Sei);
Sei.fMask := SEE_MASK_DOENVSUBST or SEE_MASK_FLAG_NO_UI or SEE_MASK_NOCLOSEPROCESS or
SEE_MASK_FLAG_DDEWAIT;
Sei.lpFile := PChar(FileName);
Sei.lpParameters := PCharOrNil(Parameters);
Sei.lpVerb := PCharOrNil(Verb);
Sei.nShow := CmdShow;
Result := ShellExecuteEx(@Sei);
if Result then
begin
WaitForInputIdle(Sei.hProcess, INFINITE);
while WaitForSingleObject(Sei.hProcess, 10) = WAIT_TIMEOUT do
repeat
Res := PeekMessage(Msg, Sei.Wnd, 0, 0, PM_REMOVE);
if Res then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until not Res;
CloseHandle(Sei.hProcess);
end;
end;
function ShellOpenAs(const FileName: string): Boolean;
begin
Result := ShellExecEx('rundll32', Format('shell32.dll,OpenAs_RunDLL "%s"', [FileName]), '', SW_SHOWNORMAL);
end;
{ TODO: Dynamic linking - move TRasDialDlgA to JclWin32}
type
TRasDialDlgA = function(lpszPhonebook, lpszEntry, lpszPhoneNumber: PAnsiChar; lpInfo: PRasDialDlg): BOOL; stdcall;
function ShellRasDial(const EntryName: string): Boolean;
var
Info: TRasDialDlg;
RasDlg: HModule;
RasDialDlgA: TRasDialDlgA;
begin
if IsWinNT then
begin
Result := False;
RasDlg := LoadLibrary(PChar('rasdlg.dll'));
if RasDlg <> 0 then
try
@RasDialDlgA := GetProcAddress(RasDlg, PChar('RasDialDlgA'));
if @RasDialDlgA <> nil then
begin
FillChar(Info, SizeOf(Info), 0);
Info.dwSize := SizeOf(Info);
Result := RasDialDlgA(nil, PChar(EntryName), nil, @Info);
end;
finally
FreeLibrary(RasDlg);
end;
end
else
Result := ShellExecEx('rundll32', Format('rnaui.dll,RnaDial "%s"', [EntryName]), '', SW_SHOWNORMAL);
end;
// You can pass simple name of standard system control panel (e.g. 'timedate')
// or full qualified file name (Window 95 only? doesn't work on Win2K!)
// MT: Added support for Windows 98..XP. Have no win95 anymore so I have to
// trust that the original version works on Windows 95 and Windows 95OSR2.
function ShellRunControlPanel(const NameOrFileName: string; AppletNumber: Integer): Boolean;
var
FileName: TFileName;
begin
if ExtractFilePath(NameOrFileName) = '' then
FileName := ChangeFileExt(PathAddSeparator(GetWindowsSystemFolder) + NameOrFileName, '.cpl')
else
FileName := NameOrFileName;
if FileExists(FileName) then
begin
if (IsWin95 or IsWin95OSR2) then
Result := ShellExecEx('rundll32', Format('shell32.dll,Control_RunDLL "%s", @%d',
[FileName, AppletNumber]), '', SW_SHOWNORMAL)
else
Result := ShellExecEx('rundll32', Format('shell32.dll,Control_RunDLL "%s",,%d',
[FileName, AppletNumber]), '', SW_SHOWNORMAL)
end
else
begin
Result := False;
SetLastError(ERROR_FILE_NOT_FOUND);
end;
end;
function GetFileExeType(const FileName: TFileName): TJclFileExeType;
var
FileInfo: TSHFileInfo;
R: DWORD;
begin
R := SHGetFileInfo(PChar(FileName), 0, FileInfo, SizeOf(FileInfo), SHGFI_EXETYPE);
case LoWord(R) of
IMAGE_DOS_SIGNATURE:
Result := etMsDos;
IMAGE_OS2_SIGNATURE:
Result := etWin16;
Word(IMAGE_NT_SIGNATURE):
if HiWord(R) = 0 then
Result := etWin32Con
else
Result := etWin32Gui;
else
Result := etError;
end;
end;
function ShellFindExecutable(const FileName, DefaultDir: string): string;
var
Res: HINST;
Buffer: TAnsiPath;
I: Integer;
begin
FillChar(Buffer, SizeOf(Buffer), #0);
Res := FindExecutable(PChar(FileName), PCharOrNil(DefaultDir), Buffer);
if Res > 32 then
begin
// FindExecutable replaces #32 with #0
for I := Low(Buffer) to High(Buffer) - 1 do
if Buffer[I] = #0 then
Buffer[I] := #32;
Buffer[High(Buffer)] := #0;
Result := Trim(Buffer);
end
else
Result := '';
end;
function GetFileNameIcon(const FileName: string; Flags: Cardinal = 0): HICON;
var
FileInfo: TSHFileInfo;
ImageList: HIMAGELIST;
begin
FillChar(FileInfo, SizeOf(FileInfo), #0);
if Flags = 0 then
Flags := SHGFI_SHELLICONSIZE;
ImageList := SHGetFileInfo(PChar(FileName), 0, FileInfo, SizeOf(FileInfo),
Flags or SHGFI_SYSICONINDEX);
if ImageList <> 0 then
Result := ImageList_ExtractIcon(0, ImageList, FileInfo.iIcon)
else
Result := 0;
end;
initialization
//We don't load the msi functions until the first attempt to resolve an MSI link
finalization
UnloadModule(rtdlMsiLibHandle);
// History:
// $Log: JclShell.pas,v $
// Revision 1.20 2005/02/25 07:20:16 marquardt
// add section lines
//
// Revision 1.19 2005/02/24 16:34:52 marquardt
// remove divider lines, add section lines (unfinished)
//
// Revision 1.18 2005/02/13 15:47:09 mthoma
// SHEnumFolderNext works now with Win9x.
//
// Revision 1.17 2004/12/22 11:44:22 rikbarker
// Modified ShellLinkResolve to correctly read the target from MSI style shortcuts without invoking the windows installer if the product component was set to "Install on First Use". Added dynamic links to MSI functions in msi.dll
//
// Revision 1.16 2004/12/03 15:36:04 rikbarker
// Fixed ShellLinkResolve to correctly Resolve TargetPath for MS-Office style link files.
//
// Revision 1.15 2004/10/17 21:48:07 mthoma
// Removed ShellRasDial contribution. Rewrite needed as soon as dynmic linking support in JclWin32 has been redesigned.
//
// Revision 1.14 2004/10/17 21:00:16 mthoma
// cleaning
//
// Revision 1.13 2004/07/28 18:00:54 marquardt
// various style cleanings, some minor fixes
//
// Revision 1.12 2004/06/14 11:05:53 marquardt
// symbols added to all ENDIFs and some other minor style changes like removing IFOPT
//
// Revision 1.11 2004/05/09 11:22:39 rrossmair
// Contributor list update
//
// Revision 1.10 2004/05/05 07:33:49 rrossmair
// header updated according to new policy: initial developers & contributors listed
//
// Revision 1.9 2004/04/09 20:46:30 mthoma
// Fixed 0000923 (ShellRunControlPanel). Changed $data$ to date.
//
// Revision 1.8 2004/04/06 04:55:18
// adapt compiler conditions, add log entry
//
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -