Progress.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. //---------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Common.h>
  5. #include <CoreMain.h>
  6. #include <TextsWin.h>
  7. #include <HelpWin.h>
  8. #include <WinInterface.h>
  9. #include <VCLCommon.h>
  10. #include <CustomWinConfiguration.h>
  11. #include <GUITools.h>
  12. #include <BaseUtils.hpp>
  13. #include <DateUtils.hpp>
  14. #include "Progress.h"
  15. //---------------------------------------------------------------------
  16. #pragma link "HistoryComboBox"
  17. #pragma link "PathLabel"
  18. #ifndef NO_RESOURCES
  19. #pragma resource "*.dfm"
  20. #endif
  21. //---------------------------------------------------------------------
  22. UnicodeString __fastcall TProgressForm::OperationName(TFileOperation Operation, TOperationSide Side)
  23. {
  24. static const int Captions[] = { 0, 0, PROGRESS_DELETE,
  25. PROGRESS_SETPROPERTIES, 0, PROGRESS_CUSTOM_COMAND, PROGRESS_CALCULATE_SIZE,
  26. PROGRESS_REMOTE_MOVE, PROGRESS_REMOTE_COPY, PROGRESS_GETPROPERTIES,
  27. PROGRESS_CALCULATE_CHECKSUM };
  28. assert((unsigned int)Operation >= 1 && ((unsigned int)Operation - 1) < LENOF(Captions));
  29. int Id;
  30. if ((Operation == foCopy) || (Operation == foMove))
  31. {
  32. Id = (Side == osLocal) ? PROGRESS_UPLOAD : PROGRESS_DOWNLOAD;
  33. }
  34. else
  35. {
  36. Id = Captions[(int)Operation - 1];
  37. assert(Id != 0);
  38. }
  39. return LoadStr(Id);
  40. }
  41. //---------------------------------------------------------------------
  42. __fastcall TProgressForm::TProgressForm(TComponent * AOwner, bool AllowMoveToQueue)
  43. : FData(), TForm(AOwner)
  44. {
  45. FLastOperation = foNone;
  46. FLastTotalSizeSet = false;
  47. FDataGot = false;
  48. FDataReceived = false;
  49. FAsciiTransferChanged = false;
  50. FResumeStatusChanged = false;
  51. FCancel = csContinue;
  52. FMoveToQueue = false;
  53. FMinimizedByMe = false;
  54. FUpdateCounter = 0;
  55. FDeleteToRecycleBin = false;
  56. FReadOnly = false;
  57. FShowAsModalStorage = NULL;
  58. FStarted = Now();
  59. FModalBeginHooked = false;
  60. FPrevApplicationModalBegin = NULL;
  61. FModalLevel = -1;
  62. FAllowMoveToQueue = AllowMoveToQueue;
  63. UseSystemSettings(this);
  64. ResetOnceDoneOperation();
  65. if (CustomWinConfiguration->OperationProgressOnTop)
  66. {
  67. FOperationProgress = TopProgress;
  68. FFileProgress = BottomProgress;
  69. }
  70. else
  71. {
  72. FOperationProgress = BottomProgress;
  73. FFileProgress = TopProgress;
  74. }
  75. SetGlobalMinimizeHandler(this, GlobalMinimize);
  76. if (FAllowMoveToQueue)
  77. {
  78. MenuButton(MinimizeButton);
  79. }
  80. }
  81. //---------------------------------------------------------------------------
  82. __fastcall TProgressForm::~TProgressForm()
  83. {
  84. // to prevent raising assertion (e.g. IsProgress == True)
  85. FData.Clear();
  86. ClearGlobalMinimizeHandler(GlobalMinimize);
  87. if (IsApplicationMinimized() && FMinimizedByMe)
  88. {
  89. ShowNotification(
  90. NULL, MainInstructions(LoadStr(BALLOON_OPERATION_COMPLETE)),
  91. qtInformation);
  92. }
  93. if (FModalBeginHooked)
  94. {
  95. assert(Application->OnModalBegin == ApplicationModalBegin);
  96. Application->OnModalBegin = FPrevApplicationModalBegin;
  97. FModalBeginHooked = false;
  98. }
  99. ReleaseAsModal(this, FShowAsModalStorage);
  100. }
  101. //---------------------------------------------------------------------
  102. void __fastcall TProgressForm::UpdateControls()
  103. {
  104. assert((FData.Operation >= foCopy) && (FData.Operation <= foCalculateChecksum) &&
  105. FData.Operation != foRename );
  106. CancelButton->Enabled = !FReadOnly;
  107. OnceDoneOperationCombo2->Enabled =
  108. !FReadOnly && (FData.Operation != foCalculateSize) &&
  109. (FData.Operation != foGetProperties) &&
  110. (FData.Operation != foCalculateChecksum);
  111. OnceDoneOperationLabel->Enabled = OnceDoneOperationCombo2->Enabled;
  112. bool TransferOperation =
  113. ((FData.Operation == foCopy) || (FData.Operation == foMove));
  114. if (FData.Operation != FLastOperation)
  115. {
  116. bool AVisible;
  117. // Wine does have static text "Searching" instead of actual animations
  118. if (!IsWine())
  119. {
  120. try
  121. {
  122. THandle ShellModule;
  123. AVisible = true;
  124. TProgressBarStyle Style = pbstNormal;
  125. switch (FData.Operation) {
  126. case foCopy:
  127. case foMove:
  128. case foRemoteMove:
  129. case foRemoteCopy:
  130. if (FData.Count == 1) Animate->CommonAVI = aviCopyFile;
  131. else Animate->CommonAVI = aviCopyFiles;
  132. break;
  133. case foDelete:
  134. Animate->CommonAVI = (DeleteToRecycleBin ? aviRecycleFile : aviDeleteFile);
  135. break;
  136. case foSetProperties:
  137. case foGetProperties:
  138. ShellModule = SafeLoadLibrary(L"shell32.dll");
  139. if (!ShellModule)
  140. {
  141. Abort();
  142. }
  143. // workaround, VCL is not able to set both ResId and ResHandle otherwise
  144. Animate->Active = false;
  145. Animate->ResHandle = 0;
  146. Animate->ComponentState << csLoading;
  147. Animate->ResId = 165;
  148. Animate->ResHandle = ShellModule;
  149. Animate->ComponentState >> csLoading;
  150. Animate->Active = true;
  151. break;
  152. case foCalculateSize:
  153. Animate->CommonAVI = aviNone;
  154. AVisible = false;
  155. Style = pbstMarquee;
  156. break;
  157. default:
  158. assert(FData.Operation == foCustomCommand ||
  159. FData.Operation == foCalculateChecksum);
  160. Animate->CommonAVI = aviNone;
  161. AVisible = false;
  162. }
  163. TopProgress->Style = Style;
  164. }
  165. catch (...)
  166. {
  167. AVisible = false;
  168. };
  169. }
  170. else
  171. {
  172. Animate->CommonAVI = aviNone;
  173. AVisible = false;
  174. }
  175. int Delta = 0;
  176. if (AVisible && !Animate->Visible) Delta = Animate->Height;
  177. else
  178. if (!AVisible && Animate->Visible) Delta = -Animate->Height;
  179. MainPanel->Top = MainPanel->Top + Delta;
  180. TransferPanel->Top = TransferPanel->Top + Delta;
  181. Animate->Visible = AVisible;
  182. Animate->Active = AVisible;
  183. if (TransferOperation && !TransferPanel->Visible) Delta += TransferPanel->Height;
  184. else
  185. if (!TransferOperation && TransferPanel->Visible) Delta += -TransferPanel->Height;
  186. TransferPanel->Visible = TransferOperation;
  187. // when animation is hidden for transfers (on wine) speed panel does not fit,
  188. // so we hide it (temporary solution before window redesign)
  189. SpeedPanel->Visible = TransferOperation && AVisible;
  190. ClientHeight = ClientHeight + Delta;
  191. TargetLabel->Visible = TransferOperation;
  192. TargetPathLabel->Visible = TransferOperation;
  193. TargetPathLabel->UnixPath = (FData.Side == osLocal);
  194. FileLabel->UnixPath = (FData.Side == osRemote);
  195. FLastOperation = FData.Operation;
  196. FLastTotalSizeSet = !FData.TotalSizeSet;
  197. };
  198. if (FLastTotalSizeSet != FData.TotalSizeSet)
  199. {
  200. StartTimeLabelLabel->Visible = !FData.TotalSizeSet;
  201. StartTimeLabel->Visible = !FData.TotalSizeSet;
  202. TimeLeftLabelLabel->Visible = FData.TotalSizeSet;
  203. TimeLeftLabel->Visible = FData.TotalSizeSet;
  204. FLastTotalSizeSet = FData.TotalSizeSet;
  205. }
  206. if ((FData.Side == osRemote) || !FData.Temp)
  207. {
  208. FileLabel->Caption = FData.FileName;
  209. }
  210. else
  211. {
  212. FileLabel->Caption = ExtractFileName(FData.FileName);
  213. }
  214. int OverallProgress = FData.OverallProgress();
  215. FOperationProgress->Position = OverallProgress;
  216. FOperationProgress->Hint = FORMAT(L"%d%%", (OverallProgress));
  217. Caption = FormatFormCaption(this, FORMAT(L"%d%% %s", (OverallProgress, OperationName(FData.Operation, FData.Side))));
  218. if (TransferOperation)
  219. {
  220. if ((FData.Side == osLocal) || !FData.Temp)
  221. {
  222. TargetPathLabel->Caption = FData.Directory;
  223. }
  224. else
  225. {
  226. TargetPathLabel->Caption = LoadStr(PROGRESS_TEMP_DIR);
  227. }
  228. StartTimeLabel->Caption = FData.StartTime.TimeString();
  229. if (FData.TotalSizeSet)
  230. {
  231. TimeLeftLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat,
  232. FData.TotalTimeLeft());
  233. }
  234. TimeElapsedLabel->Caption = FormatDateTimeSpan(Configuration->TimeFormat, FData.TimeElapsed());
  235. BytesTransferedLabel->Caption = FormatBytes(FData.TotalTransfered);
  236. CPSLabel->Caption = FORMAT(L"%s/s", (FormatBytes(FData.CPS())));
  237. FFileProgress->Position = FData.TransferProgress();
  238. FFileProgress->Hint = FORMAT(L"%d%%", (FFileProgress->Position));
  239. }
  240. }
  241. //---------------------------------------------------------------------
  242. static TDateTime DelayStartInterval(static_cast<double>(OneSecond/5));
  243. static TDateTime UpdateInterval(static_cast<double>(OneSecond));
  244. //---------------------------------------------------------------------
  245. bool __fastcall TProgressForm::ReceiveData(bool Force, int ModalLevelOffset)
  246. {
  247. bool Result = false;
  248. if (FDataGot && !FDataReceived)
  249. {
  250. // CPS limit is set set only once from TFileOperationProgressType::Start.
  251. // Needs to be set even when data are not accepted yet, otherwise we would
  252. // write default value to FData in TProgressForm::SetProgressData
  253. FCPSLimit = FData.CPSLimit;
  254. // Never popup over dialog that appeared later than we started
  255. // (this can happen from UpdateTimerTimer when application is
  256. // restored while overwrite confirmation dialog [or any other]
  257. // is already shown).
  258. // TODO We should probably take as-modal windows into account too
  259. // (for extreme cases like restoring while reconnecting [as-modal TAuthenticateForm]).
  260. if ((FModalLevel < 0) || (Application->ModalLevel + ModalLevelOffset <= FModalLevel))
  261. {
  262. // delay showing the progress until the application is restored,
  263. // otherwise the form popups up unminimized.
  264. if (!IsApplicationMinimized() &&
  265. (Force || ((Now() - FStarted) > DelayStartInterval)))
  266. {
  267. FDataReceived = true;
  268. SpeedCombo->Text = SetSpeedLimit(FCPSLimit);
  269. ShowAsModal(this, FShowAsModalStorage);
  270. // particularly needed for the case, when we are showing the form delayed
  271. // because application was minimized when operation started
  272. Result = true;
  273. }
  274. else if (!FModalBeginHooked && ALWAYS_TRUE(FModalLevel < 0))
  275. {
  276. // record state as of time, the window should be shown,
  277. // had not we implemented delayed show
  278. FPrevApplicationModalBegin = Application->OnModalBegin;
  279. Application->OnModalBegin = ApplicationModalBegin;
  280. FModalBeginHooked = true;
  281. FModalLevel = Application->ModalLevel;
  282. }
  283. }
  284. }
  285. return Result;
  286. }
  287. //---------------------------------------------------------------------------
  288. void __fastcall TProgressForm::ApplicationModalBegin(TObject * Sender)
  289. {
  290. // Popup before any modal dialog shows (typically overwrite confirmation,
  291. // as that popups nerly instantly, i.e. less than DelayStartInterval).
  292. // The Application->ModalLevel is already incremented, but we should treat is as
  293. // if it were not as the dialog is not created yet (so we can popup if we are not yet).
  294. ReceiveData(true, -1);
  295. if (FPrevApplicationModalBegin != NULL)
  296. {
  297. FPrevApplicationModalBegin(Sender);
  298. }
  299. }
  300. //---------------------------------------------------------------------
  301. void __fastcall TProgressForm::SetProgressData(TFileOperationProgressType & AData)
  302. {
  303. TDateTime N = Now();
  304. bool InstantUpdate = false;
  305. // workaround: to force displaing first file data immediately,
  306. // otherwise form dialog uses to be blank for first second
  307. // (until UpdateTimerTimer)
  308. if (FileLabel->Caption.IsEmpty() && !AData.FileName.IsEmpty())
  309. {
  310. InstantUpdate = true;
  311. }
  312. if (!FAsciiTransferChanged && FData.AsciiTransfer != AData.AsciiTransfer)
  313. {
  314. FAsciiTransferChanged = true;
  315. InstantUpdate = true;
  316. }
  317. if (!FResumeStatusChanged && FData.ResumeStatus != AData.ResumeStatus)
  318. {
  319. FResumeStatusChanged = true;
  320. InstantUpdate = true;
  321. }
  322. FData.AssignButKeepSuspendState(AData);
  323. FDataGot = true;
  324. if (!UpdateTimer->Enabled)
  325. {
  326. UpdateTimer->Interval = static_cast<unsigned int>(MilliSecondsBetween(TDateTime(), DelayStartInterval));
  327. UpdateTimer->Enabled = true;
  328. FSinceLastUpdate = TDateTime();
  329. }
  330. if (ReceiveData(false, 0))
  331. {
  332. InstantUpdate = true;
  333. }
  334. if (InstantUpdate)
  335. {
  336. UpdateControls();
  337. Application->ProcessMessages();
  338. }
  339. if (ProcessGUI(FUpdateCounter % 5 == 0))
  340. {
  341. FUpdateCounter = 0;
  342. }
  343. FUpdateCounter++;
  344. AData.CPSLimit = FCPSLimit;
  345. }
  346. //---------------------------------------------------------------------------
  347. void __fastcall TProgressForm::UpdateTimerTimer(TObject * /*Sender*/)
  348. {
  349. // popup the progress window at least here, if SetProgressData is
  350. // not being called (typically this happens when using custom command
  351. // that launches long-lasting external process, such as visual diff)
  352. ReceiveData(false, 0);
  353. if (FDataReceived)
  354. {
  355. FSinceLastUpdate = IncMilliSecond(FSinceLastUpdate, UpdateTimer->Interval);
  356. if (FSinceLastUpdate >= UpdateInterval)
  357. {
  358. UpdateControls();
  359. FSinceLastUpdate = TDateTime();
  360. }
  361. }
  362. }
  363. //---------------------------------------------------------------------------
  364. void __fastcall TProgressForm::FormShow(TObject * /*Sender*/)
  365. {
  366. SpeedCombo->Items = CustomWinConfiguration->History[L"SpeedLimit"];
  367. ReceiveData(false, 0);
  368. if (FDataReceived)
  369. {
  370. UpdateControls();
  371. }
  372. }
  373. //---------------------------------------------------------------------------
  374. void __fastcall TProgressForm::FormHide(TObject * /*Sender*/)
  375. {
  376. // This is to counter the "infinite" timestamp in
  377. // TTerminalManager::ApplicationShowHint.
  378. // Because if form disappears on its own, hint is not hidden.
  379. Application->CancelHint();
  380. CustomWinConfiguration->History[L"SpeedLimit"] = SpeedCombo->Items;
  381. UpdateTimer->Enabled = false;
  382. }
  383. //---------------------------------------------------------------------------
  384. void __fastcall TProgressForm::CancelButtonClick(TObject * /*Sender*/)
  385. {
  386. CancelOperation();
  387. }
  388. //---------------------------------------------------------------------------
  389. void __fastcall TProgressForm::MinimizeButtonClick(TObject * Sender)
  390. {
  391. if (FAllowMoveToQueue)
  392. {
  393. MenuPopup(MinimizeMenu, MinimizeButton);
  394. }
  395. else
  396. {
  397. Minimize(Sender);
  398. }
  399. }
  400. //---------------------------------------------------------------------------
  401. void __fastcall TProgressForm::Minimize(TObject * Sender)
  402. {
  403. CallGlobalMinimizeHandler(Sender);
  404. }
  405. //---------------------------------------------------------------------------
  406. void __fastcall TProgressForm::MinimizeMenuItemClick(TObject * Sender)
  407. {
  408. Minimize(Sender);
  409. }
  410. //---------------------------------------------------------------------------
  411. void __fastcall TProgressForm::CancelOperation()
  412. {
  413. assert(FDataReceived);
  414. if (!FData.Suspended)
  415. {
  416. // mostly useless, as suspend is called over copy of actual progress data
  417. FData.Suspend();
  418. UpdateControls();
  419. try
  420. {
  421. TCancelStatus ACancel;
  422. if (FData.TransferingFile &&
  423. (FData.TimeExpected() > GUIConfiguration->IgnoreCancelBeforeFinish))
  424. {
  425. int Result = MessageDialog(LoadStr(CANCEL_OPERATION_FATAL2), qtWarning,
  426. qaYes | qaNo | qaCancel, HELP_PROGRESS_CANCEL);
  427. switch (Result)
  428. {
  429. case qaYes:
  430. ACancel = csCancelTransfer; break;
  431. case qaNo:
  432. ACancel = csCancel; break;
  433. default:
  434. ACancel = csContinue; break;
  435. }
  436. }
  437. else
  438. {
  439. int Result = MessageDialog(LoadStr(CANCEL_OPERATION2), qtConfirmation,
  440. qaYes | qaNo, HELP_PROGRESS_CANCEL);
  441. switch (Result)
  442. {
  443. case qaYes:
  444. ACancel = csCancel; break;
  445. default:
  446. ACancel = csContinue; break;
  447. }
  448. }
  449. if (FCancel < ACancel)
  450. {
  451. FCancel = ACancel;
  452. }
  453. }
  454. __finally
  455. {
  456. FData.Resume();
  457. }
  458. }
  459. }
  460. //---------------------------------------------------------------------------
  461. void __fastcall TProgressForm::GlobalMinimize(TObject * /*Sender*/)
  462. {
  463. ApplicationMinimize();
  464. FMinimizedByMe = true;
  465. }
  466. //---------------------------------------------------------------------------
  467. void __fastcall TProgressForm::SetOnceDoneOperation(TOnceDoneOperation value)
  468. {
  469. int Index = 0;
  470. switch (value)
  471. {
  472. case odoIdle:
  473. Index = 0;
  474. break;
  475. case odoDisconnect:
  476. Index = 1;
  477. break;
  478. case odoSuspend:
  479. Index = 2;
  480. break;
  481. case odoShutDown:
  482. Index = 3;
  483. break;
  484. default:
  485. FAIL;
  486. }
  487. OnceDoneOperationCombo2->ItemIndex = Index;
  488. OnceDoneOperationCombo2Select(NULL);
  489. }
  490. //---------------------------------------------------------------------------
  491. bool __fastcall TProgressForm::GetAllowMinimize()
  492. {
  493. return MinimizeButton->Visible;
  494. }
  495. //---------------------------------------------------------------------------
  496. void __fastcall TProgressForm::SetAllowMinimize(bool value)
  497. {
  498. MinimizeButton->Visible = value;
  499. }
  500. //---------------------------------------------------------------------------
  501. void __fastcall TProgressForm::SetReadOnly(bool value)
  502. {
  503. if (FReadOnly != value)
  504. {
  505. FReadOnly = value;
  506. if (!value)
  507. {
  508. ResetOnceDoneOperation();
  509. }
  510. UpdateControls();
  511. }
  512. }
  513. //---------------------------------------------------------------------------
  514. void __fastcall TProgressForm::ApplyCPSLimit()
  515. {
  516. try
  517. {
  518. FCPSLimit = GetSpeedLimit(SpeedCombo->Text);
  519. }
  520. catch(...)
  521. {
  522. SpeedCombo->SetFocus();
  523. throw;
  524. }
  525. SpeedCombo->Text = SetSpeedLimit(FCPSLimit);
  526. // visualize application
  527. SpeedCombo->SelectAll();
  528. CancelButton->SetFocus();
  529. }
  530. //---------------------------------------------------------------------------
  531. void __fastcall TProgressForm::SpeedComboExit(TObject * /*Sender*/)
  532. {
  533. SpeedCombo->Text = SetSpeedLimit(FCPSLimit);
  534. }
  535. //---------------------------------------------------------------------------
  536. void __fastcall TProgressForm::SpeedComboSelect(TObject * /*Sender*/)
  537. {
  538. ApplyCPSLimit();
  539. }
  540. //---------------------------------------------------------------------------
  541. void __fastcall TProgressForm::SpeedComboKeyPress(TObject * /*Sender*/,
  542. wchar_t & Key)
  543. {
  544. // using OnKeyPress instead of OnKeyDown to catch "enter" prevents
  545. // system beep for unhandled key
  546. if (Key == L'\r')
  547. {
  548. Key = L'\0';
  549. ApplyCPSLimit();
  550. }
  551. }
  552. //---------------------------------------------------------------------------
  553. void __fastcall TProgressForm::ResetOnceDoneOperation()
  554. {
  555. OnceDoneOperationCombo2->ItemIndex = 0;
  556. OnceDoneOperationCombo2Select(NULL);
  557. }
  558. //---------------------------------------------------------------------------
  559. void __fastcall TProgressForm::OnceDoneOperationCombo2Select(TObject * /*Sender*/)
  560. {
  561. switch (OnceDoneOperationCombo2->ItemIndex)
  562. {
  563. case 0:
  564. FOnceDoneOperation = odoIdle;
  565. break;
  566. case 1:
  567. FOnceDoneOperation = odoDisconnect;
  568. break;
  569. case 2:
  570. FOnceDoneOperation = odoSuspend;
  571. break;
  572. case 3:
  573. FOnceDoneOperation = odoShutDown;
  574. break;
  575. default:
  576. FAIL;
  577. }
  578. }
  579. //---------------------------------------------------------------------------
  580. void __fastcall TProgressForm::OnceDoneOperationCombo2CloseUp(TObject * /*Sender*/)
  581. {
  582. CancelButton->SetFocus();
  583. }
  584. //---------------------------------------------------------------------------
  585. void __fastcall TProgressForm::Dispatch(void * AMessage)
  586. {
  587. TMessage & Message = *reinterpret_cast<TMessage *>(AMessage);
  588. if (Message.Msg == WM_CLOSE)
  589. {
  590. CancelOperation();
  591. }
  592. else
  593. {
  594. TForm::Dispatch(AMessage);
  595. }
  596. }
  597. //---------------------------------------------------------------------------
  598. void __fastcall TProgressForm::MoveToQueueMenuItemClick(TObject * /*Sender*/)
  599. {
  600. FMoveToQueue = true;
  601. }
  602. //---------------------------------------------------------------------------