winshell.pas 21 KB

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