IEUtils.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. (*******************************
  2. * IEUTILS 1.4 (Oct. 16 2001) *
  3. *******************************)
  4. unit IEUtils;
  5. interface
  6. uses
  7. Variants,
  8. IEConst, dialogs,Inifiles, Registry, Sysutils, ShellApi, Windows, Activex, Shlobj;
  9. function IE5_Installed: Boolean;
  10. //function GetIEVersion: string;
  11. function StringToVarArray(const S: string): Variant;
  12. function VarArrayToString(const V: Variant): string;
  13. function Encode(const S: string): string;
  14. function IsFolder(ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  15. function IsFolderEx(ChannelShortcut: String; ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  16. function IsChannel(ChannelShortcut: String; ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  17. function GetDisplayName(Folder: IShellFolder; pidl: PItemIDList): string;
  18. function GetImageIndex(pidl: PItemIDList): integer;
  19. function ExtractUrl(ShellFolder: IShellFolder; pidl: PItemIDList): string;
  20. function ResolveChannel(pFolder: IShellFolder; pidl: PItemIDList; var lpszURL: string): HRESULT;
  21. function ResolveLink(const path: string): string;
  22. function GetFileName(Folder: IShellFolder; pidl: PItemIDList): string;
  23. function ResolveUrlIni(Filename: string): string;
  24. function ResolveUrlIntShCut(Filename: string): string;
  25. procedure DisposePIDL(ID: PItemIDList);
  26. function CopyITEMID(Malloc: IMalloc; ID: PItemIDList): PItemIDList;
  27. function NextPIDL(IDList: PItemIDList): PItemIDList;
  28. function GetPIDLSize(IDList: PItemIDList): Integer;
  29. procedure StripLastID(IDList: PItemIDList);
  30. function CreatePIDL(Size: Integer): PItemIDList;
  31. function CopyPIDL(IDList: PItemIDList): PItemIDList;
  32. function ConcatPIDLs(IDList1, IDList2: PItemIDList): PItemIDList;
  33. implementation
  34. uses comobj;
  35. function StringToVarArray(const S: string): Variant;
  36. begin
  37. Result := Unassigned;
  38. if S <> '' then
  39. begin
  40. Result := VarArrayCreate([0, Length(S) - 1], varByte);
  41. Move(Pointer(S)^, VarArrayLock(Result)^, Length(S));
  42. VarArrayUnlock(Result);
  43. end;
  44. end;
  45. function VarArrayToString(const V: Variant): string;
  46. var
  47. i, j: Integer;
  48. begin
  49. if VarIsArray(V) then
  50. for I := 0 to VarArrayHighBound(V, 1) do
  51. begin
  52. j := V[i];
  53. result := result + chr(j);
  54. end;
  55. end;
  56. function Encode(const S: string): string;
  57. var
  58. I: Integer;
  59. Hex: string;
  60. begin
  61. for I := 1 to Length(S) do
  62. case S[i] of
  63. ' ': result := Result + '+';
  64. 'A'..'Z', 'a'..'z', '*', '@', '.', '_', '-',
  65. '0'..'9', '$', '!', '''', '(', ')':
  66. result := Result + s[i];
  67. else
  68. begin
  69. Hex := IntToHex(ord(S[i]), 2);
  70. if Length(Hex) = 2 then Result := Result + '%' + Hex else
  71. Result := Result + '%0' + hex;
  72. end;
  73. end;
  74. end;
  75. function IE5_Installed: Boolean;
  76. var
  77. Reg: TRegistry;
  78. S: string;
  79. begin
  80. Reg := TRegistry.Create;
  81. with Reg do begin
  82. RootKey := HKEY_LOCAL_MACHINE;
  83. OpenKey('Software\Microsoft\Internet Explorer', False);
  84. if ValueExists('Version') then S := ReadString('Version')
  85. else S := '0';
  86. CloseKey;
  87. Free;
  88. end;
  89. Result := (StrToInt(S[1]) > 4);
  90. end;
  91. {
  92. function GetIEVersion: string;
  93. var
  94. SysDir: PChar;
  95. Info: Pointer;
  96. InfoData: Pointer;
  97. InfoSize: LongInt;
  98. Len: DWORD;
  99. FName: Pchar;
  100. SystemDir, Infotype: string;
  101. LangPtr: Pointer;
  102. begin
  103. Len := MAX_PATH + 1;
  104. GetMem(SysDir, Len);
  105. try
  106. if Windows.GetSystemDirectory(SysDir, Len) <> 0 then
  107. SystemDir := SysDir;
  108. finally
  109. FreeMem(SysDir);
  110. end;
  111. result := '';
  112. InfoType := 'FileVersion';
  113. FName := Pchar(SystemDir + '\shdocvw.dll');
  114. InfoSize := GetFileVersionInfoSize(Fname, Len);
  115. if (InfoSize > 0) then
  116. begin
  117. GetMem(Info, InfoSize);
  118. try
  119. if GetFileVersionInfo(FName, Len, InfoSize, Info) then
  120. begin
  121. Len := 255;
  122. if VerQueryValue(Info, '\VarFileInfo\Translation', LangPtr, Len) then
  123. InfoType := Format('\StringFileInfo\%0.4x%0.4x\%s'#0, [LoWord(LongInt(LangPtr^)),
  124. HiWord(LongInt(LangPtr^)), InfoType]);
  125. if VerQueryValue(Info, Pchar(InfoType), InfoData, len) then
  126. Result := strPas(InfoData);
  127. end;
  128. finally
  129. FreeMem(Info, InfoSize);
  130. end;
  131. end;
  132. end; }
  133. function ResolveUrlIni(Filename: string): string;
  134. var
  135. ini: TiniFile;
  136. begin
  137. result := '';
  138. ini := TIniFile.create(fileName);
  139. try
  140. result := ini.ReadString('InternetShortcut', 'URL', '');
  141. finally
  142. ini.free;
  143. end;
  144. end;
  145. function ResolveUrlIntShCut(Filename: string): string;
  146. var
  147. IURL: IUniformResourceLocator;
  148. PersistFile: IPersistfile;
  149. FName: array[0..MAX_PATH] of WideChar;
  150. p: Pchar;
  151. begin
  152. if Succeeded(CoCreateInstance(CLSID_InternetShortcut, nil, CLSCTX_INPROC_SERVER,
  153. IID_IUniformResourceLocator, IURL))
  154. then begin
  155. Persistfile := IUrl as IPersistFile;
  156. StringToWideChar(FileName, FName, MAX_PATH);
  157. PersistFile.Load(Fname, STGM_READ);
  158. IUrl.geturl(@P);
  159. Result := P;
  160. end;
  161. end;
  162. function ResolveChannel(pFolder: IShellFolder; pidl: PItemIDList; var lpszURL: string): HRESULT;
  163. var
  164. pidlChannel: PItemIDList;
  165. psfDesktop: IShellFolder;
  166. pShellLink: IShellLink;
  167. begin
  168. Result := S_FALSE;
  169. if Succeeded(pFolder.GetUIObjectOf(0, 1, pidl, IShellLink, nil, Pointer(pShellLink)))
  170. then
  171. if Succeeded(pShellLink.GetIDList(pidlChannel)) then
  172. if Succeeded(SHGetDesktopFolder(psfDesktop))
  173. then
  174. begin
  175. lpszURL := getDisplayName(psfDesktop, PidlChannel);
  176. Result := S_OK;
  177. end;
  178. DisposePidl(PidlChannel);
  179. end;
  180. function ResolveLink(const path: string): string;
  181. var
  182. link: IShellLink;
  183. storage: IPersistFile;
  184. filedata: TWin32FindData;
  185. buf: array[0..MAX_PATH] of Char;
  186. widepath: WideString;
  187. begin
  188. OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, link));
  189. OleCheck(link.QueryInterface(IPersistFile, storage));
  190. widepath := path;
  191. Result := '';
  192. if Succeeded(storage.Load(@widepath[1], STGM_READ)) then
  193. if Succeeded(link.Resolve(GetActiveWindow, SLR_NOUPDATE)) then
  194. if Succeeded(link.GetPath(buf, sizeof(buf), filedata, SLGP_UNCPRIORITY)) then
  195. Result := buf;
  196. storage := nil;
  197. link := nil;
  198. end;
  199. function ExtractUrl(ShellFolder: IShellFolder; pidl: PItemIDList): string;
  200. var
  201. Handle: THandle;
  202. Info: IQueryInfo;
  203. W: PWideChar;
  204. begin
  205. Handle := 0;
  206. Info := nil;
  207. ShellFolder.GetUIObjectOf(Handle, 1, pidl, IID_IQUERYINFO, nil, Pointer(Info));
  208. if assigned(Info) then
  209. begin
  210. Info.GetInfoTip(0, w);
  211. Result := W;
  212. end else result := '';
  213. Result := Trim(Copy(Result, Pos(#10, Result) + 1, length(Result)));
  214. end;
  215. function IsFolder(ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  216. var
  217. Flags: UINT;
  218. begin
  219. Flags := SFGAO_FOLDER;
  220. ShellFolder.GetAttributesOf(1, ID, Flags);
  221. Result := SFGAO_FOLDER and Flags <> 0;
  222. end;
  223. function IsChannel(ChannelShortcut: String; ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  224. var
  225. FileInfo: TShFileInfo;
  226. begin
  227. SHGetFileInfo(Pchar(ID), 0, FileInfo, SizeOf(TSHFileInfo), SHGFI_PIDL or SHGFI_TYPENAME);
  228. Result:=BOOL(fileinfo.szTypeName = ChannelShortcut);
  229. end;
  230. function IsFolderEx(ChannelShortcut: String; ShellFolder: IShellFolder; ID: PItemIDList): Boolean;
  231. var
  232. Flags: UINT;
  233. begin
  234. Flags := SFGAO_FOLDER;
  235. ShellFolder.GetAttributesOf(1, ID, Flags);
  236. If SFGAO_FOLDER and Flags <> 0 then
  237. result:=not isChannel(ChannelShortcut, Shellfolder, id)
  238. else Result:=False;
  239. end;
  240. function GetImageIndex(pidl: PItemIDList): integer;
  241. var
  242. Flags: UINT;
  243. FileInfo: TSHFileInfo;
  244. begin
  245. Flags := SHGFI_PIDL or SHGFI_SYSICONINDEX or SHGFI_ICON or SHGFI_SMALLICON;
  246. if SHGetFileInfo(PChar(pidl), 0, FileInfo, SizeOf(TSHFileInfo), Flags) = 0 then
  247. Result := -1
  248. else
  249. Result := FileInfo.iIcon;
  250. end;
  251. function GetDisplayName(Folder: IShellFolder; pidl: PItemIDList): string;
  252. var
  253. StrRet: TStrRet;
  254. begin
  255. Folder.GetDisplayNameOf(pidl, SHGDN_NORMAL, StrRet);
  256. case StrRet.uType of
  257. STRRET_CSTR:
  258. SetString(Result, StrRet.cStr, lStrLenA(StrRet.cStr));
  259. STRRET_OFFSET:
  260. Result := Pchar(@pidl.mkid.abID[StrRet.uOffset - SizeOf(pidl.mkid.cb)]);
  261. STRRET_WSTR:
  262. Result := StrRet.pOleStr;
  263. end;
  264. end;
  265. function GetFileName(Folder: IShellFolder; pidl: PItemIDList): string;
  266. var
  267. StrRet: TStrRet;
  268. begin
  269. Folder.GetDisplayNameOf(pidl, SHGDN_FORPARSING, StrRet);
  270. case StrRet.uType of
  271. STRRET_CSTR:
  272. SetString(Result, StrRet.cStr, lStrLenA(StrRet.cStr));
  273. STRRET_OFFSET:
  274. Result:= Pchar(@pidl.mkid.abID[StrRet.uOffset - SizeOf(pidl.mkid.cb)]);
  275. STRRET_WSTR:
  276. Result := StrRet.pOleStr;
  277. end;
  278. end;
  279. procedure DisposePIDL(ID: PItemIDList);
  280. var
  281. Malloc: IMalloc;
  282. begin
  283. if ID = nil then Exit;
  284. OLECheck(SHGetMalloc(Malloc));
  285. Malloc.Free(ID);
  286. end;
  287. function CopyITEMID(Malloc: IMalloc; ID: PItemIDList): PItemIDList;
  288. begin
  289. Result := Malloc.Alloc(ID^.mkid.cb + SizeOf(ID^.mkid.cb));
  290. CopyMemory(Result, ID, ID^.mkid.cb + SizeOf(ID^.mkid.cb));
  291. end;
  292. function NextPIDL(IDList: PItemIDList): PItemIDList;
  293. begin
  294. Result := IDList;
  295. Inc(PChar(Result), IDList^.mkid.cb);
  296. end;
  297. function GetPIDLSize(IDList: PItemIDList): Integer;
  298. begin
  299. Result := 0;
  300. if Assigned(IDList) then
  301. begin
  302. Result := SizeOf(IDList^.mkid.cb);
  303. while IDList^.mkid.cb <> 0 do
  304. begin
  305. Result := Result + IDList^.mkid.cb;
  306. IDList := NextPIDL(IDList);
  307. end;
  308. end;
  309. end;
  310. procedure StripLastID(IDList: PItemIDList);
  311. var
  312. MarkerID: PItemIDList;
  313. begin
  314. MarkerID := IDList;
  315. if Assigned(IDList) then
  316. begin
  317. while IDList.mkid.cb <> 0 do
  318. begin
  319. MarkerID := IDList;
  320. IDList := NextPIDL(IDList);
  321. end;
  322. MarkerID.mkid.cb := 0;
  323. end;
  324. end;
  325. function CreatePIDL(Size: Integer): PItemIDList;
  326. var
  327. Malloc: IMalloc;
  328. HR: HResult;
  329. begin
  330. Result := nil;
  331. HR := SHGetMalloc(Malloc);
  332. if Failed(HR) then
  333. Exit;
  334. try
  335. Result := Malloc.Alloc(Size);
  336. if Assigned(Result) then
  337. FillChar(Result^, Size, 0);
  338. finally
  339. end;
  340. end;
  341. function CopyPIDL(IDList: PItemIDList): PItemIDList;
  342. var
  343. Size: Integer;
  344. begin
  345. Size := GetPIDLSize(IDList);
  346. Result := CreatePIDL(Size);
  347. if Assigned(Result) then
  348. CopyMemory(Result, IDList, Size);
  349. end;
  350. function ConcatPIDLs(IDList1, IDList2: PItemIDList): PItemIDList;
  351. var
  352. cb1, cb2: Integer;
  353. begin
  354. if Assigned(IDList1) then
  355. cb1 := GetPIDLSize(IDList1) - SizeOf(IDList1^.mkid.cb)
  356. else
  357. cb1 := 0;
  358. cb2 := GetPIDLSize(IDList2);
  359. Result := CreatePIDL(cb1 + cb2);
  360. if Assigned(Result) then
  361. begin
  362. if Assigned(IDList1) then
  363. CopyMemory(Result, IDList1, cb1);
  364. CopyMemory(PChar(Result) + cb1, IDList2, cb2);
  365. end;
  366. end;
  367. end.