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.

291 lines
6.2 KiB

  1. // File: dlgcall.cpp
  2. //
  3. // Outgoing call progress dialog
  4. #include "precomp.h"
  5. #include "resource.h"
  6. #include "call.h"
  7. #include "dlgcall.h"
  8. #include "conf.h"
  9. #include "ConfUtil.h"
  10. static int g_cDlgCall = 0; // number of outgoing call dialogs
  11. static int g_dypOffset = 0;
  12. /* C D L G C A L L */
  13. /*-------------------------------------------------------------------------
  14. %%Function: CDlgCall
  15. -------------------------------------------------------------------------*/
  16. CDlgCall::CDlgCall(CCall * pCall):
  17. RefCount(NULL),
  18. m_pCall(pCall),
  19. m_hwnd(NULL)
  20. {
  21. ASSERT(NULL != m_pCall);
  22. m_pCall->AddRef(); // Released in destructor
  23. AddRef(); // Destroyed when call goes to a completed state
  24. if(!_Module.InitControlMode())
  25. {
  26. CreateCallDlg();
  27. g_cDlgCall++;
  28. }
  29. }
  30. CDlgCall::~CDlgCall(void)
  31. {
  32. m_pCall->Release();
  33. g_cDlgCall--;
  34. if (0 == g_cDlgCall)
  35. {
  36. g_dypOffset = 0; // center new dialogs
  37. }
  38. }
  39. STDMETHODIMP_(ULONG) CDlgCall::AddRef(void)
  40. {
  41. return RefCount::AddRef();
  42. }
  43. STDMETHODIMP_(ULONG) CDlgCall::Release(void)
  44. {
  45. return RefCount::Release();
  46. }
  47. /* C R E A T E C A L L D L G */
  48. /*-------------------------------------------------------------------------
  49. %%Function: CreateCallDlg
  50. Create the outgoing call progress dialog
  51. -------------------------------------------------------------------------*/
  52. VOID CDlgCall::CreateCallDlg()
  53. {
  54. ASSERT(NULL == m_hwnd);
  55. ASSERT(NULL != m_pCall);
  56. LPCTSTR pcszName = m_pCall->GetPszName();
  57. if (NULL == pcszName)
  58. return;
  59. // determine the maximum width of the string
  60. TCHAR szMsg[MAX_PATH*2];
  61. FLoadString1(IDS_STATUS_WAITING, szMsg, (PVOID) pcszName);
  62. m_nTextWidth = DxpSz(szMsg);
  63. FLoadString1(IDS_STATUS_FINDING, szMsg, (PVOID) pcszName);
  64. int dxp = DxpSz(szMsg);
  65. if (m_nTextWidth < dxp)
  66. {
  67. m_nTextWidth = dxp;
  68. }
  69. m_hwnd = ::CreateDialogParam(::GetInstanceHandle(), MAKEINTRESOURCE(IDD_CALL_PROGRESS),
  70. ::GetMainWindow(), CDlgCall::DlgProc, (LPARAM) this);
  71. if (NULL == m_hwnd)
  72. return;
  73. ::SetDlgItemText(m_hwnd, IDC_MSG_STATIC, szMsg);
  74. RECT rc;
  75. ::GetWindowRect(m_hwnd, &rc);
  76. // Stretch the width to fit the person's name,
  77. int nWidth = RectWidth(rc) + m_nTextWidth;
  78. int nHeight = RectHeight(rc);
  79. MoveWindow(m_hwnd, 0, 0, nWidth, nHeight, FALSE);
  80. // Center it
  81. CenterWindow(m_hwnd, HWND_DESKTOP);
  82. ::GetWindowRect(m_hwnd, &rc);
  83. // Move it down
  84. OffsetRect(&rc, 0, g_dypOffset);
  85. // Show, move, make topmost
  86. HWND hwndInsertAfter = HWND_TOPMOST;
  87. #ifdef DEBUG
  88. { // Hack to allow call placement to be debugged
  89. RegEntry reDebug(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  90. if (0 == reDebug.GetNumber(REGVAL_DBG_CALLTOP, DEFAULT_DBG_CALLTOP))
  91. {
  92. hwndInsertAfter = HWND_NOTOPMOST;
  93. }
  94. }
  95. #endif
  96. ::SetWindowPos(m_hwnd, hwndInsertAfter, rc.left, rc.top, nWidth, nHeight,
  97. SWP_SHOWWINDOW | SWP_DRAWFRAME);
  98. // Adjust for next time
  99. g_dypOffset += nHeight;
  100. // Check for wrap-around
  101. RECT rcDeskTop;
  102. GetWindowRect(GetDesktopWindow(), &rcDeskTop);
  103. if ((rc.bottom + nHeight) > rcDeskTop.bottom)
  104. {
  105. g_dypOffset -= rc.top;
  106. }
  107. }
  108. /* O N I N I T D I A L O G */
  109. /*-------------------------------------------------------------------------
  110. %%Function: OnInitDialog
  111. -------------------------------------------------------------------------*/
  112. VOID CDlgCall::OnInitDialog(HWND hdlg)
  113. {
  114. HWND hwnd;
  115. RECT rc;
  116. ::SetWindowLongPtr(hdlg, DWLP_USER, (LONG_PTR) this);
  117. AddModelessDlg(hdlg);
  118. // Move the Cancel button
  119. hwnd = ::GetDlgItem(hdlg, IDCANCEL);
  120. if ((NULL != hwnd) && ::GetWindowRect(hwnd, &rc))
  121. {
  122. // Turn rc top and left into client coords:
  123. ::MapWindowPoints(NULL, hdlg, (LPPOINT) &rc, 1);
  124. ::SetWindowPos(hwnd, NULL,
  125. rc.left + m_nTextWidth, rc.top, 0, 0,
  126. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW);
  127. }
  128. // Stretch the text field:
  129. hwnd = ::GetDlgItem(hdlg, IDC_MSG_STATIC);
  130. if ((NULL != hwnd) && ::GetWindowRect(hwnd, &rc))
  131. {
  132. ::SetWindowPos(hwnd, NULL,
  133. 0, 0, m_nTextWidth, rc.bottom - rc.top,
  134. SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
  135. // and set the font
  136. ::SendMessage(hwnd, WM_SETFONT, (WPARAM) g_hfontDlg, 0);
  137. }
  138. // Start the animation
  139. hwnd = GetDlgItem(hdlg, IDC_CALL_ANIMATION);
  140. Animate_Open(hwnd, MAKEINTRESOURCE(IDA_CALL_ANIMATION));
  141. Animate_Play(hwnd, 0, -1, -1);
  142. }
  143. // Change the state of the call
  144. VOID CDlgCall::OnStateChange(void)
  145. {
  146. if (NULL == m_hwnd)
  147. return;
  148. // Assume the only state change is to "Waiting"
  149. TCHAR szMsg[MAX_PATH*2];
  150. FLoadString1(IDS_STATUS_WAITING, szMsg, (PVOID) m_pCall->GetPszName());
  151. SetWindowText(GetDlgItem(m_hwnd, IDC_MSG_STATIC), szMsg);
  152. }
  153. // Destroy the window
  154. // Can be called by OnCancel or the owner
  155. VOID CDlgCall::Destroy(void)
  156. {
  157. if (NULL != m_hwnd)
  158. {
  159. ASSERT(IsWindow(m_hwnd));
  160. DestroyWindow(m_hwnd);
  161. m_hwnd = NULL;
  162. }
  163. }
  164. // Cancel/Close the dialog
  165. VOID CDlgCall::OnCancel(void)
  166. {
  167. ASSERT(NULL != m_pCall);
  168. m_pCall->Cancel(FALSE);
  169. return;
  170. }
  171. // Handle the destruction of the dialog
  172. VOID CDlgCall::OnDestroy(void)
  173. {
  174. SetWindowLongPtr(m_hwnd, DWLP_USER, 0L);
  175. HWND hwnd = GetDlgItem(m_hwnd, IDC_CALL_ANIMATION);
  176. if (NULL != hwnd)
  177. {
  178. Animate_Stop(hwnd);
  179. Animate_Close(hwnd);
  180. }
  181. ::RemoveModelessDlg(m_hwnd);
  182. Release(); // This normally destroys the object
  183. }
  184. /* D L G P R O C */
  185. /*-------------------------------------------------------------------------
  186. %%Function: DlgProc
  187. -------------------------------------------------------------------------*/
  188. INT_PTR CALLBACK CDlgCall::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  189. {
  190. switch (uMsg)
  191. {
  192. case WM_INITDIALOG:
  193. {
  194. CDlgCall * ppm = (CDlgCall*) lParam;
  195. ASSERT(NULL != ppm);
  196. ppm->AddRef();
  197. ppm->OnInitDialog(hDlg);
  198. return TRUE;
  199. }
  200. case WM_COMMAND:
  201. {
  202. switch (GET_WM_COMMAND_ID(wParam, lParam))
  203. {
  204. case IDCANCEL:
  205. {
  206. CDlgCall * pDlg = (CDlgCall*) GetWindowLongPtr(hDlg, DWLP_USER);
  207. if (NULL != pDlg)
  208. {
  209. // OnCancel will cause this window to be destoyed
  210. // AddRef this object so that it does not go away.
  211. pDlg->AddRef();
  212. pDlg->OnCancel();
  213. pDlg->Release();
  214. }
  215. break;
  216. }
  217. default:
  218. break;
  219. }
  220. return TRUE;
  221. }
  222. case WM_DESTROY:
  223. {
  224. CDlgCall * pDlg = (CDlgCall*) GetWindowLongPtr(hDlg, DWLP_USER);
  225. if (NULL != pDlg)
  226. {
  227. pDlg->OnDestroy();
  228. pDlg->Release();
  229. }
  230. break;
  231. }
  232. default:
  233. break;
  234. }
  235. return FALSE;
  236. }