Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
4.8 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1998 **/
  4. /**********************************************************************/
  5. /*
  6. busydlg.cpp
  7. base class for the busy dialog
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "busydlg.h"
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CWorkerThread
  14. CWorkerThread::CWorkerThread()
  15. {
  16. m_bAutoDelete = FALSE;
  17. m_bAbandoned = FALSE;
  18. m_hEventHandle = NULL;
  19. ::InitializeCriticalSection(&m_cs);
  20. m_hWnd = NULL;
  21. }
  22. CWorkerThread::~CWorkerThread()
  23. {
  24. ::DeleteCriticalSection(&m_cs);
  25. if (m_hEventHandle != NULL)
  26. {
  27. VERIFY(::CloseHandle(m_hEventHandle));
  28. m_hEventHandle = NULL;
  29. }
  30. }
  31. BOOL CWorkerThread::Start(HWND hWnd)
  32. {
  33. ASSERT(m_hWnd == NULL);
  34. ASSERT(::IsWindow(hWnd));
  35. m_hWnd = hWnd;
  36. ASSERT(m_hEventHandle == NULL); // cannot call start twice or reuse the same C++ object
  37. m_hEventHandle = ::CreateEvent(NULL,TRUE /*bManualReset*/,FALSE /*signalled*/, NULL);
  38. if (m_hEventHandle == NULL)
  39. return FALSE;
  40. return CreateThread();
  41. }
  42. void CWorkerThread::Abandon()
  43. {
  44. Lock();
  45. OnAbandon();
  46. m_bAutoDelete = TRUE;
  47. m_bAbandoned = TRUE;
  48. Unlock();
  49. }
  50. BOOL CWorkerThread::IsAbandoned()
  51. {
  52. Lock();
  53. BOOL b = m_bAbandoned;
  54. Unlock();
  55. return b;
  56. }
  57. BOOL CWorkerThread::PostMessageToWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
  58. {
  59. BOOL b = IsAbandoned();
  60. if (b)
  61. return TRUE; // no need to post
  62. ASSERT(::IsWindow(m_hWnd));
  63. return ::PostMessage(m_hWnd, Msg, wParam, lParam);
  64. }
  65. void CWorkerThread::WaitForExitAcknowledge()
  66. {
  67. BOOL b = IsAbandoned();
  68. if (b)
  69. return;
  70. VERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(m_hEventHandle,INFINITE));
  71. }
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CDlgWorkerThread
  74. CDlgWorkerThread::CDlgWorkerThread()
  75. {
  76. m_dwErr = 0x0;
  77. }
  78. BOOL CDlgWorkerThread::Start(CLongOperationDialog* pDlg)
  79. {
  80. ASSERT(pDlg != NULL);
  81. HWND hWnd = pDlg->GetSafeHwnd();
  82. return CWorkerThread::Start(hWnd);
  83. }
  84. BOOL CDlgWorkerThread::PostMessageToDlg()
  85. {
  86. return PostMessageToWnd(CLongOperationDialog::s_nNotificationMessage,
  87. (WPARAM)0, (LPARAM)0);
  88. }
  89. int CDlgWorkerThread::Run()
  90. {
  91. // do the stuff
  92. OnDoAction();
  93. VERIFY(PostMessageToDlg());
  94. WaitForExitAcknowledge();
  95. //TRACE(_T("exiting\n"));
  96. return 0;
  97. }
  98. /////////////////////////////////////////////////////////////////////////////
  99. // CLongOperationDialog dialog
  100. UINT CLongOperationDialog::s_nNotificationMessage = WM_USER + 100;
  101. CLongOperationDialog::CLongOperationDialog(CDlgWorkerThread* pThreadObj,
  102. UINT nAviID)
  103. : CDialog(IDD_BUSY, NULL),
  104. m_bCancel(TRUE)
  105. {
  106. ASSERT(pThreadObj != NULL);
  107. m_bAbandoned = TRUE;
  108. m_pThreadObj = pThreadObj;
  109. m_nAviID = nAviID;
  110. }
  111. CLongOperationDialog::~CLongOperationDialog()
  112. {
  113. if(m_pThreadObj != NULL)
  114. {
  115. delete m_pThreadObj;
  116. m_pThreadObj = NULL;
  117. }
  118. }
  119. BOOL CLongOperationDialog::LoadTitleString(UINT nID)
  120. {
  121. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  122. return m_strTitle.LoadString(nID);
  123. }
  124. BOOL CLongOperationDialog::LoadDescriptionString(UINT nID)
  125. {
  126. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  127. return m_strDescription.LoadString(nID);
  128. }
  129. BEGIN_MESSAGE_MAP(CLongOperationDialog, CDialog)
  130. ON_MESSAGE( CLongOperationDialog::s_nNotificationMessage, OnNotificationMessage )
  131. END_MESSAGE_MAP()
  132. afx_msg LONG CLongOperationDialog::OnNotificationMessage( WPARAM wParam, LPARAM lParam)
  133. {
  134. TRACE(_T("CLongOperationDialog::OnNotificationMessage()\n"));
  135. ASSERT(m_pThreadObj != NULL);
  136. if (m_pThreadObj != NULL)
  137. {
  138. m_pThreadObj->AcknowledgeExiting();
  139. VERIFY(WAIT_OBJECT_0 == ::WaitForSingleObject(m_pThreadObj->m_hThread,INFINITE));
  140. m_bAbandoned = FALSE;
  141. PostMessage(WM_CLOSE,0,0);
  142. }
  143. return 0;
  144. }
  145. BOOL CLongOperationDialog::OnInitDialog()
  146. {
  147. TRACE(_T("CLongOperationDialog::OnInitDialog()\n"));
  148. CDialog::OnInitDialog();
  149. if (!m_strTitle.IsEmpty())
  150. SetWindowText(m_strTitle);
  151. if (!m_strDescription.IsEmpty())
  152. GetDlgItem(IDC_STATIC_DESCRIPTION)->SetWindowText(m_strDescription);
  153. // load auto play AVI file if needed
  154. if (m_nAviID != -1)
  155. {
  156. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  157. CAnimateCtrl* pAnimate = (CAnimateCtrl*)GetDlgItem(IDC_SEARCH_ANIMATE);
  158. VERIFY(pAnimate->Open(m_nAviID));
  159. }
  160. if (!m_bCancel)
  161. {
  162. // hide the system menu
  163. DWORD dwWindowStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
  164. dwWindowStyle &= ~WS_SYSMENU;
  165. SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwWindowStyle);
  166. // hide the cancel button
  167. GetDlgItem(IDCANCEL)->ShowWindow(FALSE);
  168. }
  169. // spawn worker thread
  170. GetThreadObj()->Start(this);
  171. return TRUE;
  172. }
  173. void CLongOperationDialog::OnCancel()
  174. {
  175. TRACE(_T("CLongOperationDialog::OnCancel()\n"));
  176. if (m_bAbandoned)
  177. {
  178. m_pThreadObj->Abandon();
  179. m_pThreadObj = NULL;
  180. }
  181. CDialog::OnCancel();
  182. }