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.

707 lines
18 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: StatusDlg.cpp
  4. //
  5. // Module: CMMON32.EXE
  6. //
  7. // Synopsis: Implement status/count-down dialog class CStatusDlg
  8. //
  9. // Copyright (c) 1998-1999 Microsoft Corporation
  10. //
  11. // Author: ????? Created 02/20/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include "cmmaster.h"
  15. #include "StatusDlg.h"
  16. #include "Connection.h"
  17. #include "resource.h"
  18. #include "Monitor.h"
  19. #include "cmmgr32.h" // help IDs
  20. #include "cm_misc.h"
  21. #include "resource.h"
  22. //
  23. // Map of control id to help id
  24. //
  25. const DWORD CStatusDlg::m_dwHelp[] = {IDOK, IDH_OK_CONNECTED,
  26. IDC_DISCONNECT, IDH_STATUS_DISCONNECT,
  27. IDC_DETAILS, IDH_DETAILS,
  28. 0,0};
  29. //+----------------------------------------------------------------------------
  30. //
  31. // Function: CStatusDlg::CStatusDlg
  32. //
  33. // Synopsis: Constructor
  34. //
  35. // Arguments: CCmConnection* pConnection - The connection to notify event
  36. //
  37. // Returns: Nothing
  38. //
  39. // History: Created Header 2/20/98
  40. //
  41. //+----------------------------------------------------------------------------
  42. CStatusDlg::CStatusDlg(CCmConnection* pConnection):CModelessDlg(m_dwHelp)
  43. {
  44. m_pConnection = pConnection;
  45. m_fDisplayStatus = FALSE;
  46. m_fStatusWindowVisible = FALSE;
  47. }
  48. //+----------------------------------------------------------------------------
  49. //
  50. // Function: CStatusDlg::Create
  51. //
  52. // Synopsis: Create a modeless status dialog
  53. //
  54. // Arguments: HINSTANCE hInstance - Instance of the resource
  55. // HWND hWndParent - Parent window
  56. // LPCTSTR lpszTitle - Dialog window title
  57. // HICON hIcon - Dialog icon
  58. //
  59. // Returns: HWND - The dialog window handle
  60. //
  61. // History: Created Header 2/20/98
  62. //
  63. //+----------------------------------------------------------------------------
  64. HWND CStatusDlg::Create(HINSTANCE hInstance, HWND hWndParent,
  65. LPCTSTR lpszTitle, HICON hIcon)
  66. {
  67. MYDBGASSERT(lpszTitle);
  68. MYDBGASSERT(hIcon);
  69. DWORD dwStatusDlgId = OS_NT4 ? IDD_CONNSTATNT4 : IDD_CONNSTAT;
  70. if (!CModelessDlg::Create(hInstance, dwStatusDlgId, hWndParent))
  71. {
  72. MYDBGASSERT(FALSE);
  73. return NULL;
  74. }
  75. EnableWindow(m_hWnd, FALSE);
  76. UpdateFont(m_hWnd);
  77. SetWindowTextU(m_hWnd,lpszTitle);
  78. SendDlgItemMessageA(m_hWnd,IDC_CONNSTAT_ICON,STM_SETIMAGE,
  79. IMAGE_ICON,(LPARAM) hIcon);
  80. MakeBold(GetDlgItem(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY), FALSE);
  81. m_uiHwndMsgTaskBar = RegisterWindowMessageA("TaskbarCreated");
  82. return m_hWnd;
  83. }
  84. //+----------------------------------------------------------------------------
  85. //
  86. // Function: CStatusDlg::OnInitDialog
  87. //
  88. // Synopsis: Called when dialog is intialized and WM_INITDIALOG is received.
  89. //
  90. // Arguments: None
  91. //
  92. // Returns: BOOL - FALSE is focus was assigned to a control.
  93. //
  94. // History: nickball 03/22/00 Created
  95. //
  96. //+----------------------------------------------------------------------------
  97. BOOL CStatusDlg::OnInitDialog()
  98. {
  99. SetForegroundWindow(m_hWnd);
  100. return FALSE;
  101. }
  102. //+----------------------------------------------------------------------------
  103. //
  104. // Function: CStatusDlg::OnOtherCommand
  105. //
  106. // Synopsis: Process WM_COMMAND other than IDOK and IDCANCEL
  107. //
  108. // Arguments: WPARAM wParam - wParam of the message
  109. // LPARAM -
  110. //
  111. // Returns: DWORD - Return value of the message
  112. //
  113. // History: fengsun Created Header 2/20/98
  114. //
  115. //+----------------------------------------------------------------------------
  116. DWORD CStatusDlg::OnOtherCommand(WPARAM wParam, LPARAM)
  117. {
  118. switch (LOWORD(wParam))
  119. {
  120. case IDC_DISCONNECT:
  121. KillRasMonitorWindow();
  122. //
  123. // The thread message loop will handle thread message
  124. //
  125. PostThreadMessageU(GetCurrentThreadId(), CCmConnection::WM_CONN_EVENT,
  126. CCmConnection::EVENT_USER_DISCONNECT, 0);
  127. break;
  128. case IDC_DETAILS:
  129. m_pConnection->OnStatusDetails();
  130. break;
  131. case IDMC_TRAY_STATUS:
  132. //
  133. // Don't show the UI if we are at Winlogon unless we are on NT4
  134. //
  135. if (!IsLogonAsSystem() || OS_NT4)
  136. {
  137. BringToTop();
  138. }
  139. break;
  140. case WM_DESTROY:
  141. ReleaseBold(GetDlgItem(m_hWnd, IDC_CONNSTAT_DISCONNECT_DISPLAY));
  142. break;
  143. default:
  144. //
  145. // Should be message comes from additional tray icon menu item
  146. //
  147. if (LOWORD(wParam) >= CCmConnection::IDM_TRAYMENU &&
  148. LOWORD(wParam) <= (CCmConnection::IDM_TRAYMENU + 100))
  149. {
  150. m_pConnection->OnAdditionalTrayMenu(LOWORD(wParam));
  151. }
  152. break;
  153. }
  154. return FALSE;
  155. }
  156. //+----------------------------------------------------------------------------
  157. //
  158. // Function: CStatusDlg::OnOtherMessage
  159. //
  160. // Synopsis: Process message other than WM_COMMAND and WM_INITDIALOG
  161. //
  162. // Arguments: UINT uMsg - the message
  163. // WPARAM wParam - wParam of the message
  164. // LPARAM lParam - lParam of the message
  165. //
  166. // Returns: DWORD - return value of the message
  167. //
  168. // History: Created Header 2/20/98
  169. //
  170. //+----------------------------------------------------------------------------
  171. DWORD CStatusDlg::OnOtherMessage(UINT uMsg, WPARAM wParam, LPARAM lParam )
  172. {
  173. switch (uMsg)
  174. {
  175. case CCmConnection::WM_TRAYICON:
  176. return m_pConnection->OnTrayIcon(wParam, lParam);
  177. case WM_TIMER:
  178. // CMMON does not use WM_TIMER
  179. MYDBGASSERT(0);
  180. return 0;
  181. case WM_SHOWWINDOW:
  182. if (wParam) //fShow == TRUE
  183. {
  184. //
  185. // Statistics is not updated if window is invisible.
  186. // Force a update of statistics now.
  187. //
  188. m_pConnection->StateConnectedOnTimer();
  189. }
  190. break;
  191. default:
  192. if (uMsg == m_uiHwndMsgTaskBar && !m_pConnection->IsTrayIconHidden())
  193. {
  194. //
  195. // we need to re-add the trayicon
  196. //
  197. m_pConnection->ReInstateTrayIcon();
  198. }
  199. break;
  200. }
  201. return FALSE;
  202. }
  203. //+----------------------------------------------------------------------------
  204. //
  205. // Function: CStatusDlg::OnCancel
  206. //
  207. // Synopsis: Virtual function. Process WM_COMMAND IDCANCEL
  208. //
  209. // Arguments: None
  210. //
  211. // Returns: Nothing
  212. //
  213. // History: fengsun Created Header 2/20/98
  214. //
  215. //+----------------------------------------------------------------------------
  216. void CStatusDlg::OnCancel()
  217. {
  218. //
  219. // Even through, the status dialog does not have a cancel button, this message
  220. // is send when user click Esc, or close from system menu
  221. //
  222. //
  223. // As if OK/StayOnLine is clicked
  224. //
  225. OnOK();
  226. }
  227. //+----------------------------------------------------------------------------
  228. //
  229. // Function: CStatusDlg::OnOK
  230. //
  231. // Synopsis: Virtual function. Process WM_COMMAND IDOK
  232. //
  233. // Arguments: None
  234. //
  235. // Returns: Nothing
  236. //
  237. // History: fengsun Created Header 2/20/98
  238. //
  239. //+----------------------------------------------------------------------------
  240. void CStatusDlg::OnOK()
  241. {
  242. if (m_fDisplayStatus)
  243. {
  244. ShowWindow(m_hWnd, SW_HIDE);
  245. EnableWindow(m_hWnd, FALSE);
  246. }
  247. else // in count-down state
  248. {
  249. m_pConnection->OnStayOnLine();
  250. //
  251. // If window is was up previously and a countdown is being
  252. // terminated leave the window active. Otherwise restore
  253. // window to previous hidden state.
  254. //
  255. if (!m_fStatusWindowVisible)
  256. {
  257. ShowWindow(m_hWnd,SW_HIDE);
  258. EnableWindow(m_hWnd, FALSE);
  259. }
  260. }
  261. if (!IsWindowVisible(m_hWnd))
  262. {
  263. //
  264. // Minimize the working set after hide the window.
  265. //
  266. CMonitor::MinimizeWorkingSet();
  267. }
  268. }
  269. //+----------------------------------------------------------------------------
  270. //
  271. // Function: CStatusDlg::ChangeToCountDown
  272. //
  273. // Synopsis: Change the status dialog to count-down dialog
  274. //
  275. // Arguments: None
  276. //
  277. // Returns: Nothing
  278. //
  279. // History: fengsun Created Header 2/20/98
  280. //
  281. //+----------------------------------------------------------------------------
  282. void CStatusDlg::ChangeToCountDown()
  283. {
  284. MYDBGASSERT(m_fDisplayStatus); // is status;
  285. m_fDisplayStatus = FALSE;
  286. //
  287. // After user clicked "Stay Online", we need to restore the visible state
  288. // Convert is to real boolean
  289. //
  290. m_fStatusWindowVisible = IsWindowVisible(m_hWnd) != FALSE;
  291. KillRasMonitorWindow();
  292. //
  293. // Change OK to Stay Online
  294. //
  295. LPTSTR pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_STAYONLINE);
  296. SetDlgItemTextU(m_hWnd,IDOK,pszTmp);
  297. CmFree(pszTmp);
  298. //
  299. // Change Disconnect to Disconnect Now
  300. //
  301. pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_DISCNOW);
  302. SetDlgItemTextU(m_hWnd,IDC_DISCONNECT,pszTmp);
  303. CmFree(pszTmp);
  304. // Hide/Show the windows for countdown mode
  305. if (!OS_NT4)
  306. {
  307. //
  308. // Hide 9X statistics control
  309. //
  310. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SPEED_DISPLAY),SW_HIDE);
  311. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_RECEIVED_DISPLAY),SW_HIDE);
  312. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SENT_DISPLAY),SW_HIDE);
  313. }
  314. ShowWindow(GetDlgItem(m_hWnd,IDC_AUTODISC),SW_SHOW);
  315. SetForegroundWindow(m_hWnd);
  316. //
  317. // Make sure we're flashing and topmost for countdown
  318. //
  319. SetWindowPos(m_hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
  320. Flash();
  321. }
  322. //+----------------------------------------------------------------------------
  323. //
  324. // Function: CStatusDlg::ChangeToStatus
  325. //
  326. // Synopsis: Change the count-down dialog to status dialog
  327. //
  328. // Arguments: None
  329. //
  330. // Returns: Nothing
  331. //
  332. // History: fengsun Created Header 2/20/98
  333. //
  334. //+----------------------------------------------------------------------------
  335. void CStatusDlg::ChangeToStatus()
  336. {
  337. MYDBGASSERT(!m_fDisplayStatus); // is count down
  338. m_fDisplayStatus = TRUE;
  339. // Set text for buttons and static to standard mode
  340. SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY,TEXT(""));
  341. //
  342. // Change back to OK
  343. //
  344. LPTSTR pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_OK);
  345. SetDlgItemTextU(m_hWnd,IDOK,pszTmp);
  346. CmFree(pszTmp);
  347. //
  348. // Change back to Disconnect
  349. //
  350. pszTmp = CmLoadString(CMonitor::GetInstance(),IDMSG_CONNDISC_DISCONNECT);
  351. SetDlgItemTextU(m_hWnd,IDC_DISCONNECT,pszTmp);
  352. CmFree(pszTmp);
  353. // Hide/Show the windows for standard mode
  354. ShowWindow(GetDlgItem(m_hWnd,IDC_AUTODISC),SW_HIDE);
  355. if (!OS_NT4)
  356. {
  357. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SPEED_DISPLAY),SW_SHOW);
  358. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_RECEIVED_DISPLAY),SW_SHOW);
  359. ShowWindow(GetDlgItem(m_hWnd,IDC_CONNSTAT_SENT_DISPLAY),SW_SHOW);
  360. }
  361. //
  362. // Make sure we're not top-most, just on top, when we switch to status
  363. //
  364. SetWindowPos(m_hWnd, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
  365. }
  366. //+----------------------------------------------------------------------------
  367. //
  368. // Function: CStatusDlg::UpdateCountDown
  369. //
  370. // Synopsis: Update the "xx seconds until disconnect" of the count-down dialog
  371. //
  372. // Arguments: DWORD dwDuration: connection duration
  373. // DWORD dwSeconds - seconds remain to disconnect
  374. //
  375. // Returns: Nothing
  376. //
  377. // History: fengsun Created Header 2/20/98
  378. //
  379. //+----------------------------------------------------------------------------
  380. void CStatusDlg::UpdateCountDown(DWORD dwDuration, DWORD dwSeconds)
  381. {
  382. MYDBGASSERT(!m_fDisplayStatus);
  383. MYDBGASSERT(dwSeconds < 0xFFFF);
  384. UpdateDuration(dwDuration);
  385. LPTSTR pszTmp = CmFmtMsg(CMonitor::GetInstance(), IDMSG_CONNDISCONNECT, dwSeconds);
  386. SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DISCONNECT_DISPLAY,pszTmp);
  387. CmFree(pszTmp);
  388. }
  389. //+----------------------------------------------------------------------------
  390. //
  391. // Function: CStatusDlg::UpdateDuration
  392. //
  393. // Synopsis: Update the connection duration
  394. //
  395. // Arguments: DWORD dwSeconds - connected duration
  396. //
  397. // Returns: Nothing
  398. //
  399. // History: fengsun Created Header 2/20/98
  400. //
  401. //+----------------------------------------------------------------------------
  402. void CStatusDlg::UpdateDuration(DWORD dwSeconds)
  403. {
  404. if (!IsWindowVisible(m_hWnd))
  405. {
  406. return;
  407. }
  408. LPTSTR pszMsg;
  409. // Connect Duration
  410. pszMsg = CmFmtMsg(CMonitor::GetInstance(),
  411. IDMSG_CONNDUR,
  412. (WORD)((dwSeconds/60)/60),
  413. (WORD)((dwSeconds/60)%60),
  414. (WORD)(dwSeconds%60));
  415. SetDlgItemTextU(m_hWnd,IDC_CONNSTAT_DURATION_DISPLAY,pszMsg);
  416. CmFree(pszMsg);
  417. }
  418. //+----------------------------------------------------------------------------
  419. //
  420. // Function: CStatusDlg::UpdateStats
  421. //
  422. // Synopsis: Update the status dialog for Win9X
  423. //
  424. // Arguments: DWORD dwBaudRate - Baud rate
  425. // DWORD dwBytesRead - Total Bytes read
  426. // DWORD dwBytesWrite - Total bytes written
  427. // DWORD dwBytesReadPerSec - Byte read last second
  428. // DWORD dwBytesWritePerSec - Byte written last second
  429. //
  430. // Returns: Nothing
  431. //
  432. // History: fengsun Created Header 2/20/98
  433. //
  434. //+----------------------------------------------------------------------------
  435. void CStatusDlg::UpdateStats(DWORD dwBaudRate, DWORD dwBytesRead, DWORD dwBytesWrite,
  436. DWORD dwBytesReadPerSec, DWORD dwBytesWritePerSec)
  437. {
  438. //
  439. // Received
  440. //
  441. CHAR szFmtNum1[MAX_PATH];
  442. CHAR szFmtNum2[MAX_PATH];
  443. LPSTR pszMsg;
  444. FmtNum(dwBytesRead, szFmtNum1, sizeof(szFmtNum1));
  445. if (dwBytesReadPerSec)
  446. {
  447. FmtNum(dwBytesReadPerSec, szFmtNum2, sizeof(szFmtNum2));
  448. pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNTRATE, szFmtNum1, szFmtNum2);
  449. }
  450. else
  451. {
  452. pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNT, szFmtNum1);
  453. }
  454. SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_RECEIVED_DISPLAY, pszMsg);
  455. CmFree(pszMsg);
  456. //
  457. // Sent
  458. //
  459. FmtNum(dwBytesWrite, szFmtNum1, sizeof(szFmtNum1));
  460. if (dwBytesWritePerSec)
  461. {
  462. FmtNum(dwBytesWritePerSec, szFmtNum2, sizeof(szFmtNum2));
  463. pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNTRATE, szFmtNum1, szFmtNum2);
  464. }
  465. else
  466. {
  467. pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNCNT, szFmtNum1);
  468. }
  469. SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_SENT_DISPLAY, pszMsg);
  470. CmFree(pszMsg);
  471. if (dwBaudRate)
  472. {
  473. FmtNum(dwBaudRate, szFmtNum1, sizeof(szFmtNum1));
  474. pszMsg = CmFmtMsgA(CMonitor::GetInstance(), IDMSG_CONNSPEED, szFmtNum1);
  475. SetDlgItemTextA(m_hWnd, IDC_CONNSTAT_SPEED_DISPLAY, pszMsg);
  476. CmFree(pszMsg);
  477. }
  478. }
  479. //+----------------------------------------------------------------------------
  480. //
  481. // Function: CStatusDlg::GetRasMonitorWindow
  482. //
  483. // Synopsis: Find the RasMonitor window on NT, if present
  484. // The Status window is the owner of the RasMonitor
  485. //
  486. // Arguments: none
  487. //
  488. // Returns: HWND - The RasMonitor window handle or NULL
  489. //
  490. // History: fengsun Created Header 2/12/98
  491. //
  492. //+----------------------------------------------------------------------------
  493. HWND CStatusDlg::GetRasMonitorWindow()
  494. {
  495. //
  496. // RasMonitor window only exists on NT
  497. //
  498. if (!OS_NT4)
  499. {
  500. return NULL;
  501. }
  502. //
  503. // The RasMonitor window is the child window of desktop
  504. // however, the owner window is the status window
  505. //
  506. HWND hwnd = NULL;
  507. while (hwnd = FindWindowExU(NULL, hwnd, WC_DIALOG, NULL))
  508. {
  509. if (GetParent(hwnd) == m_hWnd)
  510. {
  511. return hwnd;
  512. }
  513. }
  514. return NULL;
  515. }
  516. //+----------------------------------------------------------------------------
  517. //
  518. // Function: CStatusDlg::KillRasMonitorWindow
  519. //
  520. // Synopsis: Close the RasMonitorDlg and any child dialog it might have
  521. //
  522. // Arguments: None
  523. //
  524. // Returns: Nothing
  525. //
  526. // History: fengsun Created Header 4/28/98
  527. //
  528. //+----------------------------------------------------------------------------
  529. void CStatusDlg::KillRasMonitorWindow()
  530. {
  531. HWND hwndRasMonitor = GetRasMonitorWindow();
  532. if (hwndRasMonitor)
  533. {
  534. //
  535. // The current thread is the connection thread
  536. //
  537. MYDBGASSERT(GetWindowThreadProcessId(m_hWnd, NULL) == GetCurrentThreadId());
  538. //
  539. // The RasMonitorDlg can pop up aother dialog, such as details.
  540. // Kill all the dialog in the RasMonitor thread
  541. //
  542. DWORD dwRasMonitorThread = GetWindowThreadProcessId(hwndRasMonitor, NULL);
  543. MYDBGASSERT(dwRasMonitorThread);
  544. MYDBGASSERT(dwRasMonitorThread != GetCurrentThreadId());
  545. EnumThreadWindows(dwRasMonitorThread, KillRasMonitorWndProc, (LPARAM)this);
  546. }
  547. }
  548. //+----------------------------------------------------------------------------
  549. //
  550. // Function: CStatusDlg::KillRasMonitorWndProc
  551. //
  552. // Synopsis: Kill all the window in the RasMonitorThread
  553. //
  554. // Arguments: HWND hwnd - Window handle belong to the RasMonitorThread
  555. // LPARAM lParam - pointer to CStatusDlg
  556. //
  557. // Returns: BOOL - TRUE to continue enumeration
  558. //
  559. // History: fengsun Created Header 4/28/98
  560. //
  561. //+----------------------------------------------------------------------------
  562. BOOL CALLBACK CStatusDlg::KillRasMonitorWndProc(HWND hwnd, LPARAM lParam)
  563. {
  564. //
  565. // SendMessage will block until the message returns, because we do not
  566. // want to exit the connection thread before RasMinotor thread ended.
  567. // CM sends a message from Connection thread to RasMonitor thread.
  568. // Be careful about possible deadlock situation
  569. // Cause Bug 166787
  570. //
  571. SendMessageA(hwnd, WM_CLOSE, (WPARAM)0, (LPARAM)0);
  572. return TRUE;
  573. }
  574. //+----------------------------------------------------------------------------
  575. //
  576. // Function: CStatusDlg::DismissStatusDlg
  577. //
  578. // Synopsis: Dismisses the status dialog.
  579. //
  580. // Arguments: None
  581. //
  582. // Returns: Nothing
  583. //
  584. // History: quintinb Created Header 4/28/98
  585. //
  586. //+----------------------------------------------------------------------------
  587. void CStatusDlg::DismissStatusDlg()
  588. {
  589. //
  590. // Since OnOK is protected and virtual we will just add a member function
  591. // to call it. We really just want to dismiss the dialog so it will be
  592. // hidden again.
  593. //
  594. OnOK();
  595. }
  596. #ifdef DEBUG
  597. //+----------------------------------------------------------------------------
  598. //
  599. // Function: CStatusDlg::AssertValid
  600. //
  601. // Synopsis: For debug purpose only, assert the object is valid
  602. //
  603. // Arguments: None
  604. //
  605. // Returns: Nothing
  606. //
  607. // History: Created Header 2/12/98
  608. //
  609. //+----------------------------------------------------------------------------
  610. void CStatusDlg::AssertValid() const
  611. {
  612. MYDBGASSERT(m_fDisplayStatus == TRUE || m_fDisplayStatus == FALSE);
  613. MYDBGASSERT(m_fStatusWindowVisible == TRUE || m_fStatusWindowVisible == FALSE);
  614. MYDBGASSERT(m_pConnection != NULL);
  615. }
  616. #endif