2
0

winshell.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. { Shell helper routines to create Start Menu and Desktop shortcuts. }
  2. { (C) Copyright 2001, Tramontana Co. Released into the public domain. }
  3. { 2003.01.27: renamed WinShell to remember that it is windows specific by Pierre Muller }
  4. { 2003.01.28: IShellLinkDataList support added by Pierre Muller }
  5. unit WinShell;
  6. interface
  7. uses
  8. Windows;
  9. const
  10. { GetCurrentPlatform constants }
  11. pfAll = %11111111;
  12. pfWin31 = %00000001;
  13. pfWin95 = %00000010;
  14. pfWin98 = %00000100;
  15. pfWinME = %00001000;
  16. pfWin9x = pfWin95 or pfWin98 or pfWinME;
  17. pfWinNT3 = %00010000;
  18. pfWinNT4 = %00100000;
  19. pfWin2000 = %01000000;
  20. pfWinNTx = pfWinNT3 or pfWinNT4 or pfWin2000;
  21. pfWin16 = pfWin31;
  22. pfWin32 = pfWin9x or pfWinNTx;
  23. { Execution context constants }
  24. CLSCTX_INPROC_SERVER = 1;
  25. CLSCTX_INPROC_HANDLER = 2;
  26. CLSCTX_LOCAL_SERVER = 4;
  27. CLSCTX_INPROC_SERVER16 = 8;
  28. CLSCTX_REMOTE_SERVER = 16;
  29. CLSCTX_SERVER = CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER or CLSCTX_REMOTE_SERVER;
  30. CLSCTX_ALL = CLSCTX_INPROC_HANDLER or CLSCTX_SERVER;
  31. { SHGetSpecialFolder... constants }
  32. CSIDL_PROGRAMS = $0002;
  33. CSIDL_DESKTOPDIRECTORY = $0010;
  34. CSIDL_COMMON_PROGRAMS = $0017;
  35. CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
  36. { Various GUIDs/CLSIDs }
  37. CLSID_ShellDesktop : GUID = (Data1 : $00021400; Data2 : 0; Data3 : 0;
  38. Data4 : ($C0, 0, 0, 0, 0, 0, 0, $46));
  39. CLSID_ShellLink : GUID = (Data1 : $00021401; Data2 : 0; Data3 : 0;
  40. Data4 : ($C0, 0, 0, 0, 0, 0, 0, $46));
  41. IID_IShellLink : GUID = (Data1 : $000214EE; Data2 : 0; Data3 : 0;
  42. Data4 : ($C0, 0, 0, 0, 0, 0, 0, $46));
  43. IID_IShellLinkDataList : GUID = (Data1 : $45E2B4AE; Data2 : $B1C3; Data3 : $11D0;
  44. Data4 : ($B9, $2f, 0, $A0, $C9, $03, $12, $E1));
  45. IID_IPersistFile : GUID = (Data1 : $0000010B; Data2 : 0; Data3 : 0;
  46. Data4 : ($C0, 0, 0, 0, 0, 0, 0, $46));
  47. type
  48. {$PACKRECORDS 1}
  49. { COM interfaces -- without explicit compiler support, also runs with FPC 1.0x }
  50. { Note that the original Ole2.pp coming with the compiler is not working, this is how IUnknown should look like: }
  51. { IUnknown }
  52. PIUnknown = ^IUnknown;
  53. IUnknown = packed record
  54. vtbl : ^IUnknownVtbl;
  55. end;
  56. IUnknownVtbl = packed record
  57. QueryInterface : function (const this : PIUnknown; const iid: TIID; var obj): HResult; stdcall;
  58. AddRef : function (const this : PIUnknown) : longint; stdcall;
  59. Release : function (const this : PIUnknown) : longint; stdcall;
  60. end;
  61. { IMalloc }
  62. PPIMalloc = ^PIMalloc;
  63. PIMalloc = ^IMalloc;
  64. IMalloc = packed record
  65. vtbl : ^IMallocVtbl;
  66. end;
  67. IMallocVtbl = packed record
  68. QueryInterface : function (const this : PIMalloc; const iid: TIID; var obj): HResult; stdcall;
  69. AddRef : function (const this : PIMalloc) : ULONG; stdcall;
  70. Release : function (const this : PIMalloc) : ULONG; stdcall;
  71. Alloc : function (const this : PIMalloc; cb : ULONG) : pointer; stdcall;
  72. Realloc : function (const this : PIMalloc; var pv; cb : ULONG) : pointer; stdcall;
  73. Free : procedure (const this : PIMalloc; pv : pointer); stdcall;
  74. GetSize : function (const this : PIMalloc; pv : pointer) : ULONG; stdcall;
  75. DidAlloc : function (const this : PIMalloc; pv : pointer) : INT; stdcall;
  76. HeapMinimize : procedure (const this : PIMalloc); stdcall;
  77. end;
  78. { IShellLink }
  79. PIShellLink = ^IShellLink;
  80. IShellLink = packed record
  81. vtbl : ^IShellLinkVtbl;
  82. end;
  83. IShellLinkVtbl = packed record
  84. QueryInterface : function (const this : PIShellLink; const iid: TIID; var obj): HResult; stdcall;
  85. AddRef : function (const this : PIShellLink) : ULONG; stdcall;
  86. Release : function (const this : PIShellLink) : ULONG; stdcall;
  87. GetPath : function (const this : PIShellLink; pszFile : LPSTR; cchMaxPAth : INT; var fd : WIN32_FIND_DATA; Flags : DWORD) : hResult; stdcall;
  88. GetIDList : function (const this : PIShellLink; var pidl : LPITEMIDLIST) : hResult; stdcall;
  89. SetIDList : function (const this : PIShellLink; pidl : LPITEMIDLIST) : hResult; stdcall;
  90. GetDescription : function (const this : PIShellLink; pszName : LPSTR; cchMaxName : INT) : hResult; stdcall;
  91. SetDescription : function (const this : PIShellLink; pszName : LPSTR) : hResult; stdcall;
  92. GetWorkingDirectory : function (const this : PIShellLink; pszDir : LPSTR; cchMaxName : INT) : hResult; stdcall;
  93. SetWorkingDirectory : function (const this : PIShellLink; pszDir : LPSTR) : hResult; stdcall;
  94. GetArguments : function (const this : PIShellLink; pszArgs : LPSTR; cchMaxName : INT) : hResult; stdcall;
  95. SetArguments : function (const this : PIShellLink; pszArgs : LPSTR) : hResult; stdcall;
  96. GetHotkey : function (const this : PIShellLink; var wHotKey : WORD) : hResult; stdcall;
  97. SetHotkey : function (const this : PIShellLink; wHotKey : WORD) : hResult; stdcall;
  98. GetShowCmd : function (const this : PIShellLink; var iShowCmd : INT) : hResult; stdcall;
  99. SetShowCmd : function (const this : PIShellLink; iShowCmd : INT) : hResult; stdcall;
  100. GetIconLocation : function (const this : PIShellLink; pszIconPath : LPSTR; cchIconPath : INT; var iIcon : INT) : hResult; stdcall;
  101. SetIconLocation : function (const this : PIShellLink; pszIconPath : LPSTR; iIcon : INT) : hResult; stdcall;
  102. SetRelativePath : function (const this : PIShellLink; pszPathRel : LPSTR; wReserved : DWORD) : hResult; stdcall;
  103. Resolve : function (const this : PIShellLink; hwnd : HWND; fFlags : DWORD) : hResult; stdcall;
  104. SetPath : function (const this : PIShellLink; pszFile : LPSTR) : hResult; stdcall;
  105. end;
  106. { IPersistFile }
  107. PIPersistFile = ^IPersistFile;
  108. IPersistFile = packed record
  109. vtbl : ^IPersistFileVtbl;
  110. end;
  111. IPersistFileVtbl = packed record
  112. QueryInterface : function (const this : PIPersistFile; const iid: TIID; var obj): HResult; stdcall;
  113. AddRef : function (const this : PIPersistFile) : ULONG; stdcall;
  114. Release : function (const this : PIPersistFile) : ULONG; stdcall;
  115. GetClassID : function (const this : PIPersistFile; ClassID : TCLSID) : hResult; stdcall;
  116. IsDirty : function (const this : PIPersistFile) : hResult; stdcall;
  117. Load : function (const this : PIPersistFile; plszFilename : LPWSTR; dwMode : DWORD) : hResult; stdcall;
  118. Save : function (const this : PIPersistFile; plszFilename : LPWSTR; fRemember : BOOL) : hResult; stdcall;
  119. SaveCompleted : function (const this : PIPersistFile; plszFilename : LPWSTR) : hResult; stdcall;
  120. GetCurFile : function (const this : PIPersistFile; var plszFilename : LPWSTR) : hResult; stdcall;
  121. end;
  122. { IShellLinkDataList }
  123. { inplemented in shell32.dll version 4.71 or later }
  124. {Data block structureDescription}
  125. const
  126. EXP_DARWIN_ID_SIG = $A0000006; // The link's Microsoft© Windows© Installer identifier (ID).
  127. EXP_LOGO3_ID_SIG = $A0000007;
  128. EXP_SPECIAL_FOLDER_SIG = $A0000005; // Special folder information.
  129. EXP_SZ_LINK_SIG = $A0000001; // The target name.
  130. EXP_SZ_ICON_SIG = $A0000007; // The icon name.
  131. NT_CONSOLE_PROPS_SIG = $A0000002; // Console properties.
  132. NT_FE_CONSOLE_PROPS_SIG = $A0000004; // The console's code page.
  133. SLDF_HAS_ID_LIST = $00000001; // The link has ID list.
  134. SLDF_HAS_LINK_INFO = $00000002; // The link has LinkInfo.
  135. SLDF_HAS_NAME = $00000004; // The link has a name.
  136. SLDF_HAS_RELPATH = $00000008; // The link has a relative path.
  137. SLDF_HAS_WORKINGDIR = $00000010; // The link has a working directory.
  138. SLDF_HAS_ARGS = $00000020; // The link has arguments.
  139. SLDF_HAS_ICONLOCATION = $00000040; // The link has an icon location.
  140. SLDF_UNICODE = $00000080; // The strings are unicode.
  141. SLDF_FORCE_NO_LINKINFO = $00000100; // Do not create link information. Distributed tracking will be disabled.
  142. SLDF_HAS_EXP_SZ = $00000200; // The link contains expandable environment strings.
  143. SLDF_RUN_IN_SEPARATE = $00000400; // Run the 16-bit target exe in a separate VDM/WOW.
  144. SLDF_HAS_LOGO3ID = $00000800; // The link is a special Logo3/MSICD link.
  145. SLDF_HAS_DARWINID = $00001000; // The link is a special Darwin link.
  146. SLDF_RUNAS_USER = $00002000; // Run the link as a different user.
  147. SLDF_HAS_EXP_ICON_SZ = $00004000; // The link contains expandable env string for icon path.
  148. SLDF_NO_PIDL_ALIAS = $00008000; // Don't ever resolve to a logical location.
  149. SLDF_FORCE_UNCNAME = $00010000; // Make GetPath() prefer the UNC name to the local name.
  150. SLDF_RUN_WITH_SHIMLAYER = $00020000; // Launch the target of this link w/ shim layer active.
  151. SLDF_RESERVED = $80000000; // Reserved-- so we can use the low word as an index value in the future
  152. Type
  153. DATABLOCK_HEADER = packed record
  154. cbSize,
  155. dwSignature : DWORD;
  156. end;
  157. EXP_DARWIN_LINK = packed record
  158. dbh : DATABLOCK_HEADER;
  159. szDarwinID : array [0..MAX_PATH-1] of char;
  160. szwDarwinID : array [0..MAX_PATH-1] of word;
  161. end;
  162. EXP_SPECIAL_FOLDER = packed record
  163. dbh : DATABLOCK_HEADER;
  164. idSpecialFolder,
  165. cbOffset : DWORD;
  166. end;
  167. EXP_SZ_LINK = packed record
  168. dbh : DATABLOCK_HEADER;
  169. szTarget : array [0..MAX_PATH-1] of char;
  170. szwTarget : array [0..MAX_PATH-1] of word;
  171. end;
  172. NT_CONSOLE_PROPS = packed record
  173. dbh : DATABLOCK_HEADER;
  174. wFillAttribute : WORD;
  175. wPopupFillAttribute : WORD;
  176. dwScreenBufferSize : COORD;
  177. dwWindowSize : COORD;
  178. dwWindowOrigin : COORD;
  179. nFont : DWORD;
  180. nInputBufferSize : DWORD;
  181. dwFontSize : COORD;
  182. uFontFamily : UINT;
  183. uFontWeight : UINT;
  184. FaceName : array [0..LF_FACESIZE-1] of word;
  185. uCursorSize : UINT;
  186. bFullScreen : BOOL;
  187. bQuickEdit : BOOL;
  188. bInsertMode : BOOL;
  189. bAutoPosition : BOOL;
  190. uHistoryBufferSize : UINT;
  191. uNumberOfHistoryBuffers : UINT;
  192. bHistoryNoDup : BOOL;
  193. ColorTable : array [0..16-1] of COLORREF;
  194. end;
  195. NT_FE_CONSOLE_PROPS = packed record
  196. dbh : DATABLOCK_HEADER;
  197. uCodePage : UINT;
  198. end;
  199. { IShellLinkDataList }
  200. PIShellLinkDataList = ^IShellLinkDataList;
  201. IShellLinkDataList = packed record
  202. vtbl : ^IShellLinkDataListVtbl;
  203. end;
  204. IShellLinkDataListVtbl = packed record
  205. QueryInterface : function (const this : PIShellLinkDataList; const iid: TIID; var obj): HResult; stdcall;
  206. AddRef : function (const this : PIShellLinkDataList) : ULONG; stdcall;
  207. Release : function (const this : PIShellLinkDataList) : ULONG; stdcall;
  208. // AddDataBlock Adds a data block to a link.
  209. AddDataBlock : function (const this : PIShellLinkDataList;PDataBlock : pointer) : ULONG; stdcall;
  210. // CopyDataBlock Retrieves a copy of a link's data block.
  211. CopyDataBlock : function (const this : PIShellLinkDataList;dwSig : ULONG;var pDataBlock : pointer) : ULONG; stdcall;
  212. // pDataBlock must be freed with LocalFree
  213. // RemoveDataBlock Removes a data block from a link.
  214. RemoveDataBlock : function (const this : PIShellLinkDataList;dwSig : DWORD) : HResult; stdcall;
  215. // GetFlags Retrieves the current option settings.
  216. GetFlags : function (const this : PIShellLinkDataList;var dwFlags : DWORD) : HResult; stdcall;
  217. // SetFlags Specifies the current option settings.
  218. SetFlags : function (const this : PIShellLinkDataList;dwFlags : DWORD) : HResult; stdcall;
  219. end;
  220. { GetCurrentPlatform -- determines the version of Windows
  221. RETURNS
  222. a pfXXXX constant }
  223. function GetCurrentPlatform : cardinal;
  224. { CreateShortcut -- creates a shortcut (.lnk) file with the specified parameters
  225. INPUT
  226. pszLinkFile = path of the shortcut (.lnk) file
  227. pszPathName = the path of the file the shortcut references to
  228. pszArgs = optional arguments for the referenced file
  229. pszWorkingDir = path to working directory
  230. pszDesc = shortcut description (menu entry in Start Menu)
  231. pszIconPath = path to a file containing an icon resource (.EXE, .DLL, .RES, .ICO)
  232. nIconIndex = zero based index number of the icon in the pszIconPath file
  233. RETURNS
  234. S_OK = shortcut succesfully created
  235. E_FAIL or anything else = creation failed }
  236. function CreateShortcut (pszLinkFile, pszPathName, pszArgs, pszWorkingDir, pszDesc, pszIconPath : LPSTR; nIconIndex : INT) : hResult;
  237. { GetDesktopFolder -- returns the folder of the Desktop
  238. INPUT
  239. ForThisUser = on multi-user systems (NT/2000): TRUE queries the desktop of the current user, FALSE that of all users;
  240. on other systems (95/98/ME): its value is not important
  241. OUTPUT
  242. szPath = the string the folder name will be assigned to, must be at least MAX_PATH long }
  243. procedure GetDesktopFolder (ForThisUser : Boolean; szPath : LPSTR);
  244. { GetStartMenuFolder -- returns the folder of the Start Menu
  245. INPUT
  246. ForThisUser = on multi-user systems (NT/2000): TRUE queries the Start Menu of the current user, FALSE that of all users;
  247. on other systems (95/98/ME): its value is not important
  248. OUTPUT
  249. szPath = the string the folder name will be assigned to, must be at least MAX_PATH long }
  250. procedure GetStartMenuFolder (ForThisUser : Boolean; szPath : LPSTR);
  251. function SHGetMalloc (ppMalloc : PPIMalloc) : hResult; external 'SHELL32' name 'SHGetMalloc';
  252. function CoCreateInstance (rclsid : TCLSID; pUnkOuter : PIUnknown; dwClsContext : longint; riid : TIID; var ppv) : hResult; external 'OLE32' name 'CoCreateInstance';
  253. function CoInitialize (pvReserved : pointer) : hResult; external 'OLE32' name 'CoInitialize';
  254. procedure CoUninitialize; external 'OLE32' name 'CoUninitialize';
  255. implementation
  256. var
  257. CurrentPlatform : cardinal;
  258. function GetCurrentPlatform : cardinal;
  259. var
  260. VersionInfo : OSVERSIONINFO;
  261. begin
  262. VersionInfo.dwOSVersionInfoSize := sizeof (OSVERSIONINFO);
  263. GetVersionEx (VersionInfo);
  264. case VersionInfo.dwPlatformId of
  265. VER_PLATFORM_WIN32s:
  266. GetCurrentPlatform := pfWin31;
  267. VER_PLATFORM_WIN32_WINDOWS:
  268. case VersionInfo.dwMinorVersion of
  269. 0: GetCurrentPlatform := pfWin95;
  270. 1: GetCurrentPlatform := pfWin98;
  271. else GetCurrentPlatform := pfWinME;
  272. end;
  273. VER_PLATFORM_WIN32_NT:
  274. case VersionInfo.dwMajorVersion of
  275. 3: GetCurrentPlatform := pfWinNT3;
  276. 4: GetCurrentPlatform := pfWinNT4;
  277. 5: GetCurrentPlatform := pfWin2000;
  278. end;
  279. else GetCurrentPlatform := 0;
  280. end;
  281. end; { GetCurrentPlatform }
  282. function CreateShortcut (pszLinkFile, pszPathName, pszArgs, pszWorkingDir, pszDesc, pszIconPath : LPSTR; nIconIndex : INT) : hResult;
  283. var
  284. hres : hResult;
  285. link : PIShellLink;
  286. f : PIPersistFile;
  287. DL : PIShellLinkDataList;
  288. lszPath : array [0..MAX_PATH] of WCHAR;
  289. ConsoleProps : NT_CONSOLE_PROPS;
  290. p : ^NT_CONSOLE_PROPS;
  291. CodePage : NT_FE_CONSOLE_PROPS;
  292. pfe :^NT_FE_CONSOLE_PROPS;
  293. flags : DWORD;
  294. begin
  295. hres := E_FAIL;
  296. CoInitialize (nil);
  297. if CoCreateInstance (CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IID_IShellLink, link) = S_OK then
  298. begin
  299. link^.vtbl^.SetPath (link, pszPathName);
  300. if pszArgs <> nil then link^.vtbl^.SetArguments (link, pszArgs);
  301. link^.vtbl^.SetDescription (link, pszDesc);
  302. link^.vtbl^.SetIconLocation (link, pszIconPath, nIconIndex);
  303. link^.vtbl^.SetWorkingDirectory (link, pszWorkingDir);
  304. if link^.vtbl^.QueryInterface (link, IID_IPersistFile, f) = S_OK then
  305. begin
  306. MultiByteToWideChar (CP_ACP, 0, pszLinkFile, -1, lszPath, MAX_PATH);
  307. hres := f^.vtbl^.Save (f, lszPath, true);
  308. f^.vtbl^.Release (f);
  309. end;
  310. if link^.vtbl^.QueryInterface (link, IID_IShellLinkDataList, DL) = S_OK then
  311. begin
  312. flags:=-1;
  313. if DL^.vtbl^.GetFlags(DL,flags)=S_OK then
  314. begin
  315. writeln('Link flag is ',hexstr(flags,8));
  316. // flags:=flags or SLDF_RUNAS_USER;
  317. if DL^.vtbl^.SetFlags(DL,flags)=S_OK then
  318. Writeln('Flags changed');
  319. flags:=0;
  320. DL^.vtbl^.GetFlags(DL,flags);
  321. writeln('Link flag after is ',hexstr(flags,8));
  322. end;
  323. if DL^.vtbl^.CopyDataBlock(DL,NT_CONSOLE_PROPS_SIG,p)=S_OK then
  324. begin
  325. ConsoleProps:=p^;
  326. Writeln('Has NT_CONSOLE_PROPS');
  327. ConsoleProps.bQuickEdit:=false;
  328. ConsoleProps.bInsertMode:=false;
  329. ConsoleProps.bFullScreen:=true;
  330. LocalFree(longint(p));
  331. end
  332. else
  333. begin
  334. FillChar(ConsoleProps,sizeof(ConsoleProps),#0);
  335. ConsoleProps.dbh.cbSize:=sizeof(ConsoleProps);
  336. ConsoleProps.dbh.dwSignature:=NT_CONSOLE_PROPS_SIG;
  337. ConsoleProps.wFillAttribute := $07;
  338. ConsoleProps.wPopupFillAttribute := $5f;
  339. ConsoleProps.dwScreenBufferSize.X :=80;
  340. ConsoleProps.dwScreenBufferSize.Y :=500;
  341. ConsoleProps.dwWindowSize.X:= 70;
  342. ConsoleProps.dwWindowSize.Y:= 40;
  343. //ConsoleProps.dwWindowOrigin : COORD;
  344. //ConsoleProps.nFont : DWORD;
  345. ConsoleProps.nInputBufferSize:=100;
  346. ConsoleProps.dwFontSize.X := 8;
  347. ConsoleProps.dwFontSize.Y := 12;
  348. //ConsoleProps.uFontFamily : UINT;
  349. //ConsoleProps.uFontWeight : UINT;
  350. //ConsoleProps.FaceName : array [0..LF_FACESIZE-1] of word;
  351. //ConsoleProps.uCursorSize : UINT;
  352. ConsoleProps.bFullScreen := false;
  353. ConsoleProps.bQuickEdit := false;
  354. ConsoleProps.bInsertMode := false;
  355. ConsoleProps.bAutoPosition := false;
  356. ConsoleProps.uHistoryBufferSize :=350;
  357. ConsoleProps.uNumberOfHistoryBuffers := 5;
  358. ConsoleProps.bHistoryNoDup := true;
  359. ConsoleProps.ColorTable[0]:=RGB(0,0,0);
  360. ConsoleProps.ColorTable[1]:=RGB(0,0,128);
  361. ConsoleProps.ColorTable[2]:=RGB(0,128,0);
  362. ConsoleProps.ColorTable[3]:=RGB(0,128,128);
  363. ConsoleProps.ColorTable[4]:=RGB(128,0,0);
  364. ConsoleProps.ColorTable[5]:=RGB(128,0,128);
  365. ConsoleProps.ColorTable[6]:=RGB(128,128,0);
  366. ConsoleProps.ColorTable[7]:=RGB(192,192,192);
  367. ConsoleProps.ColorTable[8]:=RGB(128,128,128);
  368. ConsoleProps.ColorTable[9]:=RGB(0,0,255);
  369. ConsoleProps.ColorTable[10]:=RGB(0,255,0);
  370. ConsoleProps.ColorTable[11]:=RGB(0,255,255);
  371. ConsoleProps.ColorTable[12]:=RGB(255,0,0);
  372. ConsoleProps.ColorTable[13]:=RGB(255,0,255);
  373. ConsoleProps.ColorTable[14]:=RGB(255,255,0);
  374. ConsoleProps.ColorTable[15]:=RGB(255,255,255);
  375. //ConsoleProps.ColorTable : array [0..16-1] of COLORREF;
  376. end;
  377. if DL^.vtbl^.AddDataBlock(DL,@ConsoleProps)=S_OK then
  378. begin
  379. Writeln('Insert mode successfully changed');
  380. end;
  381. if DL^.vtbl^.CopyDataBlock(DL,NT_CONSOLE_PROPS_SIG,p)=S_OK then
  382. begin
  383. Writeln('bQuickEdit=',p^.bQuickEdit);
  384. Writeln('bInsertMode=',p^.bInsertMode);
  385. Writeln('bFullScreen=',p^.bFullScreen);
  386. LocalFree(longint(p));
  387. end;
  388. if DL^.vtbl^.CopyDataBlock(DL,NT_FE_CONSOLE_PROPS_SIG,pfe)=S_OK then
  389. begin
  390. Writeln('Console code page=',pfe^.uCodePage);
  391. LocalFree(longint(pfe));
  392. end
  393. else
  394. begin
  395. CodePage.dbh.cbSize:=sizeof(CodePage);
  396. CodePage.dbh.dwSignature:=NT_FE_CONSOLE_PROPS_SIG;
  397. CodePage.uCodePage:=437;
  398. DL^.vtbl^.AddDataBlock(DL,@CodePage);
  399. if DL^.vtbl^.CopyDataBlock(DL,NT_FE_CONSOLE_PROPS_SIG,pfe)=S_OK then
  400. begin
  401. Writeln('Console code page after=',pfe^.uCodePage);
  402. LocalFree(longint(pfe));
  403. end;
  404. end;
  405. DL^.vtbl^.Release (DL);
  406. end;
  407. if link^.vtbl^.QueryInterface (link, IID_IPersistFile, f) = S_OK then
  408. begin
  409. MultiByteToWideChar (CP_ACP, 0, pszLinkFile, -1, lszPath, MAX_PATH);
  410. hres := f^.vtbl^.Save (f, lszPath, true);
  411. f^.vtbl^.Release (f);
  412. end;
  413. link^.vtbl^.Release (link);
  414. end;
  415. CoUninitialize;
  416. CreateShortcut := hres;
  417. end; { CreateShortcut }
  418. (* The reason for using SHGetSpecialFolderLocation instead of SHGetSpecialFolderPath is that the second is only
  419. available from the version 4.71 (Internet Explorer 4) of the Shell32.dll while the first is present on all systems
  420. starting with NT 4 and Win 95. *)
  421. procedure GetDesktopFolder (ForThisUser : Boolean; szPath : LPSTR);
  422. var
  423. Memory : PIMalloc;
  424. pidl : LPITEMIDLIST;
  425. begin
  426. Memory := nil;
  427. pidl := nil;
  428. if SHGetMalloc (@Memory) = NOERROR then
  429. begin
  430. if not ForThisUser and ((CurrentPlatform and pfWinNTx) > 0) then
  431. SHGetSpecialFolderLocation (0, CSIDL_COMMON_DESKTOPDIRECTORY, pidl)
  432. else
  433. SHGetSpecialFolderLocation (0, CSIDL_DESKTOPDIRECTORY, pidl);
  434. SHGetPathFromIDList (pidl, szPath);
  435. end;
  436. if (pidl <> nil) and (Memory <> nil) then Memory^.vtbl^.Free (Memory, pidl);
  437. if (Memory <> nil) then Memory^.vtbl^.Release (Memory);
  438. end; { GetDesktopFolder }
  439. procedure GetStartMenuFolder (ForThisUser : Boolean; szPath : LPSTR);
  440. var
  441. Memory : PIMalloc;
  442. pidl : LPITEMIDLIST;
  443. begin
  444. Memory := nil;
  445. pidl := nil;
  446. if SHGetMalloc (@Memory) = NOERROR then
  447. begin
  448. if not ForThisUser and ((CurrentPlatform and pfWinNTx) > 0) then
  449. SHGetSpecialFolderLocation (0, CSIDL_COMMON_PROGRAMS, pidl)
  450. else
  451. SHGetSpecialFolderLocation (0, CSIDL_PROGRAMS, pidl);
  452. SHGetPathFromIDList (pidl, szPath);
  453. end;
  454. if (pidl <> nil) and (Memory <> nil) then Memory^.vtbl^.Free (Memory, pidl);
  455. if (Memory <> nil) then Memory^.vtbl^.Release (Memory);
  456. end; { GetStartMenuFolder }
  457. begin
  458. CurrentPlatform := GetCurrentPlatform;
  459. end.