Tools.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. //---------------------------------------------------------------------------
  2. #define NO_WIN32_LEAN_AND_MEAN
  3. #include <vcl.h>
  4. #pragma hdrstop
  5. #include <shlobj.h>
  6. #include <stdio.h>
  7. #include <Common.h>
  8. #include <TextsWin.h>
  9. #include "GUITools.h"
  10. #include "Tools.h"
  11. //---------------------------------------------------------------------------
  12. #pragma package(smart_init)
  13. //---------------------------------------------------------------------------
  14. TFontStyles __fastcall IntToFontStyles(int value)
  15. {
  16. TFontStyles Result;
  17. for (int i = fsBold; i <= fsStrikeOut; i++)
  18. {
  19. if (value & 1)
  20. {
  21. Result << (TFontStyle)i;
  22. }
  23. value >>= 1;
  24. }
  25. return Result;
  26. }
  27. //---------------------------------------------------------------------------
  28. int __fastcall FontStylesToInt(const TFontStyles value)
  29. {
  30. int Result = 0;
  31. for (int i = fsStrikeOut; i >= fsBold; i--)
  32. {
  33. Result <<= 1;
  34. if (value.Contains((TFontStyle)i))
  35. {
  36. Result |= 1;
  37. }
  38. }
  39. return Result;
  40. }
  41. //---------------------------------------------------------------------------
  42. void __fastcall CenterFormOn(TForm * Form, TControl * CenterOn)
  43. {
  44. TPoint ScreenPoint = CenterOn->ClientToScreen(TPoint(0, 0));
  45. Form->Left = ScreenPoint.x + (CenterOn->Width / 2) - (Form->Width / 2);
  46. Form->Top = ScreenPoint.y + (CenterOn->Height / 2) - (Form->Height / 2);
  47. }
  48. //---------------------------------------------------------------------------
  49. AnsiString __fastcall GetListViewStr(TListView * ListView)
  50. {
  51. AnsiString Result;
  52. for (int Index = 0; Index < ListView->Columns->Count; Index++)
  53. {
  54. if (!Result.IsEmpty())
  55. {
  56. Result += ",";
  57. }
  58. Result += IntToStr(ListView->Column[Index]->Width);
  59. }
  60. return Result;
  61. }
  62. //---------------------------------------------------------------------------
  63. void __fastcall LoadListViewStr(TListView * ListView, AnsiString LayoutStr)
  64. {
  65. int Index = 0;
  66. while (!LayoutStr.IsEmpty() && (Index < ListView->Columns->Count))
  67. {
  68. ListView->Column[Index]->Width = StrToIntDef(
  69. CutToChar(LayoutStr, ',', true), ListView->Column[Index]->Width);
  70. Index++;
  71. }
  72. }
  73. //---------------------------------------------------------------------------
  74. void __fastcall RestoreForm(AnsiString Data, TForm * Form)
  75. {
  76. assert(Form);
  77. if (!Data.IsEmpty())
  78. {
  79. TRect Bounds = Form->BoundsRect;
  80. int Left = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Left);
  81. int Top = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Top);
  82. bool Center = (Left == -1) && (Top == -1);
  83. if (!Center)
  84. {
  85. Bounds.Left = Left;
  86. Bounds.Top = Top;
  87. }
  88. else
  89. {
  90. Bounds.Left = 0;
  91. Bounds.Top = 0;
  92. }
  93. Bounds.Right = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Right);
  94. Bounds.Bottom = StrToIntDef(::CutToChar(Data, ';', true), Bounds.Bottom);
  95. TWindowState State = (TWindowState)StrToIntDef(::CutToChar(Data, ';', true), (int)wsNormal);
  96. Form->WindowState = State;
  97. if (State == wsNormal)
  98. {
  99. if (Bounds.Width() > Screen->Width) Bounds.Right -= (Bounds.Width() - Screen->Width);
  100. if (Bounds.Height() > Screen->Height) Bounds.Bottom -= (Bounds.Height() - Screen->Height);
  101. #define POS_RANGE(x, prop) (x < 0) || (x > Screen->prop)
  102. if (Center)
  103. {
  104. Form->Position = poMainFormCenter;
  105. Form->Width = Bounds.Width();
  106. Form->Height = Bounds.Height();
  107. }
  108. else if (POS_RANGE(Bounds.Left, Width - 20) ||
  109. POS_RANGE(Bounds.Top, Height - 40))
  110. {
  111. Form->Position = poDefaultPosOnly;
  112. Form->Width = Bounds.Width();
  113. Form->Height = Bounds.Height();
  114. }
  115. else
  116. {
  117. Form->Position = poDesigned;
  118. Form->BoundsRect = Bounds;
  119. }
  120. #undef POS_RANGE
  121. }
  122. }
  123. else if (Form->Position == poDesigned)
  124. {
  125. Form->Position = poDefaultPosOnly;
  126. }
  127. }
  128. //---------------------------------------------------------------------------
  129. AnsiString __fastcall StoreForm(TCustomForm * Form)
  130. {
  131. assert(Form);
  132. return FORMAT("%d;%d;%d;%d;%d", ((int)Form->BoundsRect.Left, (int)Form->BoundsRect.Top,
  133. (int)Form->BoundsRect.Right, (int)Form->BoundsRect.Bottom,
  134. (int)Form->WindowState));
  135. }
  136. //---------------------------------------------------------------------------
  137. bool __fastcall ExecuteShellAndWait(const AnsiString Path, const AnsiString Params)
  138. {
  139. return ExecuteShellAndWait(Application->Handle, Path, Params,
  140. &Application->ProcessMessages);
  141. }
  142. //---------------------------------------------------------------------------
  143. bool __fastcall ExecuteShellAndWait(const AnsiString Command)
  144. {
  145. return ExecuteShellAndWait(Application->Handle, Command,
  146. &Application->ProcessMessages);
  147. }
  148. //---------------------------------------------------------------------------
  149. void __fastcall CreateDesktopShortCut(const AnsiString &Name,
  150. const AnsiString &File, const AnsiString & Params, const AnsiString & Description,
  151. int SpecialFolder)
  152. {
  153. IShellLink* pLink;
  154. IPersistFile* pPersistFile;
  155. LPMALLOC ShellMalloc;
  156. LPITEMIDLIST DesktopPidl;
  157. char DesktopDir[MAX_PATH];
  158. if (SpecialFolder < 0)
  159. {
  160. SpecialFolder = CSIDL_DESKTOPDIRECTORY;
  161. }
  162. try
  163. {
  164. if (FAILED(SHGetMalloc(&ShellMalloc))) throw Exception("");
  165. if (FAILED(SHGetSpecialFolderLocation(NULL, SpecialFolder, &DesktopPidl)))
  166. {
  167. throw Exception("");
  168. }
  169. if (!SHGetPathFromIDList(DesktopPidl, DesktopDir))
  170. {
  171. ShellMalloc->Free(DesktopPidl);
  172. ShellMalloc->Release();
  173. throw Exception("");
  174. }
  175. ShellMalloc->Free(DesktopPidl);
  176. ShellMalloc->Release();
  177. if (SUCCEEDED(CoInitialize(NULL)))
  178. {
  179. if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  180. IID_IShellLink, (void **) &pLink)))
  181. {
  182. try
  183. {
  184. pLink->SetPath(File.c_str());
  185. pLink->SetDescription(Description.c_str());
  186. pLink->SetArguments(Params.c_str());
  187. pLink->SetShowCmd(SW_SHOW);
  188. if (SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile)))
  189. {
  190. try
  191. {
  192. WideString strShortCutLocation(DesktopDir);
  193. // Name can contain even path (e.g. to create quick launch icon)
  194. strShortCutLocation += AnsiString("\\") + Name + ".lnk";
  195. if (!SUCCEEDED(pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE)))
  196. {
  197. throw Exception("");
  198. }
  199. }
  200. __finally
  201. {
  202. pPersistFile->Release();
  203. }
  204. }
  205. }
  206. __finally
  207. {
  208. pLink->Release();
  209. }
  210. }
  211. CoUninitialize();
  212. }
  213. }
  214. catch(...)
  215. {
  216. throw Exception(CREATE_SHORTCUT_ERROR);
  217. }
  218. }
  219. //---------------------------------------------------------------------------
  220. void __fastcall ValidateMaskEdit(TComboBox * Edit)
  221. {
  222. assert(Edit != NULL);
  223. TFileMasks Masks = Edit->Text;
  224. int Start, Length;
  225. if (!Masks.IsValid(Start, Length))
  226. {
  227. SimpleErrorDialog(FMTLOAD(MASK_ERROR, (Masks.Masks.SubString(Start + 1, Length))));
  228. Edit->SetFocus();
  229. Edit->SelStart = Start;
  230. Edit->SelLength = Length;
  231. Abort();
  232. }
  233. }
  234. //---------------------------------------------------------------------------
  235. void __fastcall ValidateMaskEdit(TEdit * Edit)
  236. {
  237. assert(Edit != NULL);
  238. TFileMasks Masks = Edit->Text;
  239. int Start, Length;
  240. if (!Masks.IsValid(Start, Length))
  241. {
  242. SimpleErrorDialog(FMTLOAD(MASK_ERROR, (Masks.Masks.SubString(Start + 1, Length))));
  243. Edit->SetFocus();
  244. Edit->SelStart = Start;
  245. Edit->SelLength = Length;
  246. Abort();
  247. }
  248. }
  249. //---------------------------------------------------------------------------
  250. void __fastcall ExitActiveControl(TForm * Form)
  251. {
  252. if (Form->ActiveControl != NULL)
  253. {
  254. TNotifyEvent OnExit = ((TEdit*)Form->ActiveControl)->OnExit;
  255. if (OnExit != NULL)
  256. {
  257. OnExit(Form->ActiveControl);
  258. }
  259. }
  260. }
  261. //---------------------------------------------------------------------------
  262. void __fastcall OpenBrowser(AnsiString URL)
  263. {
  264. ShellExecute(Application->Handle, "open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
  265. }
  266. //---------------------------------------------------------------------------
  267. bool __fastcall IsFormatInClipboard(unsigned int Format)
  268. {
  269. bool Result = OpenClipboard(0);
  270. if (Result)
  271. {
  272. Result = IsClipboardFormatAvailable(Format);
  273. CloseClipboard();
  274. }
  275. return Result;
  276. }
  277. //---------------------------------------------------------------------------
  278. bool __fastcall TextFromClipboard(AnsiString & Text)
  279. {
  280. bool Result = OpenClipboard(0);
  281. if (Result)
  282. {
  283. HANDLE Handle = NULL;
  284. try
  285. {
  286. Handle = GetClipboardData(CF_TEXT);
  287. Result = (Handle != NULL);
  288. if (Result)
  289. {
  290. Text = static_cast<const char*>(GlobalLock(Handle));
  291. }
  292. }
  293. __finally
  294. {
  295. if (Handle != NULL)
  296. {
  297. GlobalUnlock(Handle);
  298. }
  299. CloseClipboard();
  300. }
  301. }
  302. return Result;
  303. }
  304. //---------------------------------------------------------------------------
  305. static bool __fastcall GetResource(
  306. const AnsiString ResName, void *& Content, unsigned long & Size)
  307. {
  308. HRSRC Resource;
  309. Resource = FindResourceEx(NULL, RT_RCDATA, ResName.c_str(),
  310. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
  311. bool Result = (Resource != NULL);
  312. if (Result)
  313. {
  314. Size = SizeofResource(NULL, Resource);
  315. if (!Size)
  316. {
  317. throw Exception(FORMAT("Cannot get size of resource %s", (ResName)));
  318. }
  319. Content = LoadResource(NULL, Resource);
  320. if (!Content)
  321. {
  322. throw Exception(FORMAT("Cannot read resource %s", (ResName)));
  323. }
  324. Content = LockResource(Content);
  325. if (!Content)
  326. {
  327. throw Exception(FORMAT("Cannot lock resource %s", (ResName)));
  328. }
  329. }
  330. return Result;
  331. }
  332. //---------------------------------------------------------------------------
  333. bool __fastcall DumpResourceToFile(const AnsiString ResName,
  334. const AnsiString FileName)
  335. {
  336. void * Content;
  337. unsigned long Size;
  338. bool Result = GetResource(ResName, Content, Size);
  339. if (Result)
  340. {
  341. FILE * f = fopen(FileName.c_str(), "wb");
  342. if (!f)
  343. {
  344. throw Exception(FORMAT("Cannot create file %s", (FileName)));
  345. }
  346. if (fwrite(Content, 1, Size, f) != Size)
  347. {
  348. throw Exception(FORMAT("Cannot write to file %s", (FileName)));
  349. }
  350. fclose(f);
  351. }
  352. return Result;
  353. }
  354. //---------------------------------------------------------------------------
  355. AnsiString __fastcall ReadResource(const AnsiString ResName)
  356. {
  357. void * Content;
  358. unsigned long Size;
  359. AnsiString Result;
  360. if (GetResource(ResName, Content, Size))
  361. {
  362. Result = AnsiString(static_cast<char*>(Content), Size);
  363. }
  364. return Result;
  365. }
  366. //---------------------------------------------------------------------------
  367. template <class T>
  368. void __fastcall BrowseForExecutableT(T * Control, AnsiString Title,
  369. AnsiString Filter, bool FileNameCommand)
  370. {
  371. AnsiString Executable, Program, Params, Dir;
  372. Executable = Control->Text;
  373. if (FileNameCommand)
  374. {
  375. ReformatFileNameCommand(Executable);
  376. }
  377. SplitCommand(Executable, Program, Params, Dir);
  378. TOpenDialog * FileDialog = new TOpenDialog(Application);
  379. try
  380. {
  381. AnsiString ExpandedProgram = ExpandEnvironmentVariables(Program);
  382. FileDialog->FileName = ExpandedProgram;
  383. FileDialog->Filter = Filter;
  384. FileDialog->Title = Title;
  385. if (FileDialog->Execute())
  386. {
  387. TNotifyEvent PrevOnChange = Control->OnChange;
  388. Control->OnChange = NULL;
  389. try
  390. {
  391. // preserve unexpanded file, if the destination has not changed actually
  392. if (!CompareFileName(ExpandedProgram, FileDialog->FileName))
  393. {
  394. Program = FileDialog->FileName;
  395. }
  396. Control->Text = FormatCommand(Program, Params);
  397. }
  398. __finally
  399. {
  400. Control->OnChange = PrevOnChange;
  401. }
  402. if (Control->OnExit != NULL)
  403. {
  404. Control->OnExit(Control);
  405. }
  406. }
  407. }
  408. __finally
  409. {
  410. delete FileDialog;
  411. }
  412. }
  413. //---------------------------------------------------------------------------
  414. void __fastcall BrowseForExecutable(TEdit * Control, AnsiString Title,
  415. AnsiString Filter, bool FileNameCommand)
  416. {
  417. BrowseForExecutableT(Control, Title, Filter, FileNameCommand);
  418. }
  419. //---------------------------------------------------------------------------
  420. void __fastcall BrowseForExecutable(TComboBox * Control, AnsiString Title,
  421. AnsiString Filter, bool FileNameCommand)
  422. {
  423. BrowseForExecutableT(Control, Title, Filter, FileNameCommand);
  424. }
  425. //---------------------------------------------------------------------------
  426. bool __fastcall IsWin64()
  427. {
  428. static int Result = -1;
  429. if (Result < 0)
  430. {
  431. typedef BOOL WINAPI (*IsWow64ProcessType)(HANDLE Process, PBOOL Wow64Process);
  432. Result = 0;
  433. HMODULE Kernel = GetModuleHandle(kernel32);
  434. if (Kernel != NULL)
  435. {
  436. IsWow64ProcessType IsWow64Process =
  437. (IsWow64ProcessType)GetProcAddress(Kernel, "IsWow64Process");
  438. if (IsWow64Process != NULL)
  439. {
  440. BOOL Wow64Process = FALSE;
  441. if (IsWow64Process(GetCurrentProcess(), &Wow64Process))
  442. {
  443. if (Wow64Process)
  444. {
  445. Result = 1;
  446. }
  447. }
  448. }
  449. }
  450. }
  451. return (Result > 0);
  452. }