Leaked source code of windows server 2003
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.

1080 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: statdlg.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // StatDlg.cpp : implementation file
  11. //
  12. #include "stdafx.h"
  13. #include "ScAlert.h"
  14. #include "miscdef.h"
  15. #include "statmon.h"
  16. #include "StatDlg.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. ////////////////////////////////////////////////////////////////////////////
  23. #ifdef __cplusplus
  24. extern "C" { // Assume C declarations for C++
  25. #endif // __cplusplus
  26. #ifdef __cplusplus
  27. }
  28. #endif /* __cplusplus */
  29. /////////////////////////////////////////////////////////////////////////////////////
  30. //
  31. // CSCStatusDlgThrd
  32. //
  33. IMPLEMENT_DYNCREATE(CSCStatusDlgThrd, CWinThread)
  34. /*++
  35. InitInstance
  36. Must override init instance to perform UI thread initialization
  37. Arguments:
  38. Return Value:
  39. TRUE on build start message loop. FALSE otherwise
  40. Author:
  41. Chris Dudley 2/27/1997
  42. --*/
  43. BOOL CSCStatusDlgThrd::InitInstance( void )
  44. {
  45. INT_PTR nResult = -1; // error creating dialog
  46. LONG lReturn = SCARD_S_SUCCESS;
  47. SCARDCONTEXT hSCardContext = NULL;
  48. // Acquire context with resource manager
  49. lReturn = SCardEstablishContext( SCARD_SCOPE_USER,
  50. NULL,
  51. NULL,
  52. &hSCardContext);
  53. if (lReturn != SCARD_S_SUCCESS)
  54. {
  55. nResult = IDCANCEL;
  56. }
  57. else
  58. {
  59. m_StatusDlg.SetContext(hSCardContext);
  60. // Run the dialog as Modal
  61. m_fStatusDlgUp = TRUE;
  62. nResult = m_StatusDlg.DoModal();// if the dialog is shut down by a
  63. // cancellation of the SCARDCONTEXT,
  64. // it will return IDCANCEL
  65. m_fStatusDlgUp = FALSE;
  66. }
  67. // Release context
  68. if (NULL != hSCardContext)
  69. {
  70. SCardReleaseContext(hSCardContext);
  71. }
  72. // Post message that the thread is exiting, based on return...
  73. if (NULL != m_hCallbackWnd)
  74. {
  75. ::PostMessage( m_hCallbackWnd,
  76. WM_SCARD_STATUS_DLG_EXITED, // CANCELLATION (0), or ERROR (1)
  77. 0, 0);
  78. }
  79. AfxEndThread(0);
  80. return TRUE; // to make compiler happy
  81. }
  82. /*++
  83. void ShowDialog:
  84. Brings dialog to front if already open
  85. Arguments:
  86. None.
  87. Return Value:
  88. None.
  89. Author:
  90. Chris Dudley 7/30/1997
  91. Note:
  92. --*/
  93. void CSCStatusDlgThrd::ShowDialog( int nCmdShow, CStringArray* paIdleList )
  94. {
  95. if (m_fStatusDlgUp)
  96. {
  97. m_StatusDlg.ShowWindow(nCmdShow);
  98. m_StatusDlg.SetIdleList(paIdleList);
  99. }
  100. }
  101. /*++
  102. void UpdateStatus:
  103. If the dialog is up, updates idle list and status text
  104. Arguments:
  105. None.
  106. Return Value:
  107. None.
  108. Author:
  109. Chris Dudley 7/30/1997
  110. Note:
  111. --*/
  112. void CSCStatusDlgThrd::UpdateStatus( CStringArray* paIdleList )
  113. {
  114. if (m_fStatusDlgUp)
  115. {
  116. m_StatusDlg.UpdateLogonLockInfo();
  117. m_StatusDlg.SetIdleList(paIdleList);
  118. m_StatusDlg.UpdateStatusText();
  119. }
  120. }
  121. /*++
  122. void UpdateStatusText:
  123. If the dialog is up, updates Status Text and
  124. Arguments:
  125. None.
  126. Return Value:
  127. None.
  128. Author:
  129. Chris Dudley 7/30/1997
  130. Note:
  131. --*/
  132. void CSCStatusDlgThrd::UpdateStatusText( void )
  133. {
  134. if (m_fStatusDlgUp)
  135. {
  136. m_StatusDlg.UpdateStatusText();
  137. }
  138. }
  139. /*++
  140. void Close:
  141. Closes modal dialog if already open
  142. Arguments:
  143. None.
  144. Return Value:
  145. None.
  146. Author:
  147. Chris Dudley 7/30/1997
  148. Note:
  149. --*/
  150. void CSCStatusDlgThrd::Close( void )
  151. {
  152. // Setup for close
  153. if (m_fStatusDlgUp)
  154. {
  155. m_StatusDlg.EndDialog(IDOK);
  156. }
  157. m_fStatusDlgUp = FALSE;
  158. }
  159. /*++
  160. void Update:
  161. This routine updates the UI.
  162. Arguments:
  163. None.
  164. Return Value:
  165. None.
  166. Author:
  167. Chris Dudley 7/30/1997
  168. Note:
  169. --*/
  170. void CSCStatusDlgThrd::Update( void )
  171. {
  172. // Tell the dialog to update its statmonitor, if it's up.
  173. if (m_fStatusDlgUp)
  174. {
  175. m_StatusDlg.RestartMonitor();
  176. }
  177. // Do other updating
  178. UpdateStatusText();
  179. }
  180. /////////////////////////////////////////////////////////////////////////////
  181. //
  182. // CSCStatusDlg dialog
  183. //
  184. CSCStatusDlg::CSCStatusDlg(CWnd* pParent /*=NULL*/)
  185. : CDialog(CSCStatusDlg::IDD, pParent)
  186. {
  187. //{{AFX_DATA_INIT(CSCStatusDlg)
  188. // NOTE: the ClassWizard will add member initialization here
  189. //}}AFX_DATA_INIT
  190. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  191. m_hIcon = AfxGetApp()->LoadIcon(IDI_SC_READERLOADED_V2);
  192. // Other initialization
  193. m_fEventsGood = FALSE;
  194. m_hSCardContext = NULL;
  195. m_aIdleList.RemoveAll();
  196. UpdateLogonLockInfo();
  197. }
  198. void CSCStatusDlg::UpdateLogonLockInfo(void)
  199. {
  200. m_pstrLogonReader = &(((CSCStatusApp*)AfxGetApp())->m_strLogonReader);
  201. m_pstrRemovalText = &(((CSCStatusApp*)AfxGetApp())->m_strRemovalText);
  202. m_fLogonLock = (!(m_pstrLogonReader->IsEmpty()));
  203. }
  204. void CSCStatusDlg::DoDataExchange(CDataExchange* pDX)
  205. {
  206. CDialog::DoDataExchange(pDX);
  207. //{{AFX_DATA_MAP(CSCStatusDlg)
  208. DDX_Control(pDX, IDC_SCARD_LIST, m_SCardList);
  209. DDX_Control(pDX, IDC_ALERT, m_btnAlert);
  210. DDX_Control(pDX, IDC_INFO, m_ediInfo);
  211. //}}AFX_DATA_MAP
  212. }
  213. BEGIN_MESSAGE_MAP(CSCStatusDlg, CDialog)
  214. //{{AFX_MSG_MAP(CSCStatusDlg)
  215. ON_WM_PAINT()
  216. ON_WM_QUERYDRAGICON()
  217. ON_WM_CLOSE()
  218. ON_MESSAGE( WM_READERSTATUSCHANGE, OnReaderStatusChange )
  219. ON_WM_DESTROY()
  220. ON_BN_CLICKED(IDC_ALERT, OnAlertOptions)
  221. //}}AFX_MSG_MAP
  222. END_MESSAGE_MAP()
  223. /////////////////////////////////////////////////////////////////////////////
  224. //
  225. // CSCStatusDlg Implementation
  226. /*++
  227. BOOL SetContext:
  228. Sets the Context with the resource manager
  229. Arguments:
  230. SCardContext - the context
  231. Return Value:
  232. None.
  233. Author:
  234. Chris Dudley 3/6/1997
  235. Revision History:
  236. Chris Dudley 5/13/1997
  237. --*/
  238. void CSCStatusDlg::SetContext(SCARDCONTEXT hSCardContext)
  239. {
  240. m_hSCardContext = hSCardContext;
  241. }
  242. /*++
  243. void CleanUp:
  244. Routine cleans up for exit
  245. Arguments:
  246. None.
  247. Return Value:
  248. None.
  249. Author:
  250. Chris Dudley 3/11/1997
  251. Revision History:
  252. Chris Dudley 5/13/1997
  253. --*/
  254. void CSCStatusDlg::CleanUp ( void )
  255. {
  256. m_monitor.Stop();
  257. m_SCardList.DeleteAllItems();
  258. }
  259. /*++
  260. void SetIdleList:
  261. Make a local copy of the app's list of readers with idle cards.
  262. Notes:
  263. --*/
  264. void CSCStatusDlg::SetIdleList(CStringArray* paIdleList)
  265. {
  266. m_aIdleList.Copy(*paIdleList);
  267. long lResult = UpdateSCardListCtrl();
  268. }
  269. /*++
  270. void UpdateStatusText:
  271. Reflect card usage status in text. (alert message, howto, etc.)
  272. Notes:
  273. Not localization friendly. Move strings to resources.
  274. --*/
  275. void CSCStatusDlg::UpdateStatusText( void )
  276. {
  277. CString str;
  278. if (k_State_CardIdle == ((CSCStatusApp*)AfxGetApp())->m_dwState)
  279. {
  280. str = _T("A smart card has been left idle. You may safely remove it now.");
  281. }
  282. else
  283. {
  284. str = _T("Click the button on the left to change your alert options.");
  285. }
  286. m_ediInfo.SetWindowText(str);
  287. }
  288. /*++
  289. void InitSCardListCtrl:
  290. This routine sets up the CListCtrl properly for display
  291. Arguments:
  292. None.
  293. Return Value:
  294. None.
  295. Author:
  296. Chris Dudley 3/6/1997
  297. Revision History:
  298. Chris Dudley 5/13/1997
  299. --*/
  300. void CSCStatusDlg::InitSCardListCtrl( void )
  301. {
  302. CString strHeader;
  303. CImageList imageList;
  304. HICON hicon;
  305. // Create columns in list control
  306. strHeader.LoadString(IDS_SC_READER);
  307. m_SCardList.InsertColumn(READER_COLUMN,
  308. strHeader,
  309. LVCFMT_LEFT,
  310. 100,
  311. -1);
  312. strHeader.LoadString(IDS_SC_CARDSTATUS);
  313. m_SCardList.InsertColumn(STATUS_COLUMN,
  314. strHeader,
  315. LVCFMT_LEFT,
  316. 600,
  317. -1);
  318. strHeader.LoadString(IDS_SC_CARD);
  319. m_SCardList.InsertColumn(CARD_COLUMN,
  320. strHeader,
  321. LVCFMT_LEFT,
  322. 100,
  323. -1);
  324. // Create the image list & give it to the list control
  325. imageList.Create ( IMAGE_WIDTH,
  326. IMAGE_HEIGHT,
  327. TRUE, // list does not include masks
  328. NUMBER_IMAGES,
  329. 0); // list won't grow
  330. // Build the list
  331. for (int ix = 0; ix < NUMBER_IMAGES; ix++ )
  332. {
  333. // Load icon and add it to image list
  334. hicon = ::LoadIcon(AfxGetInstanceHandle(),
  335. MAKEINTRESOURCE(IMAGE_LIST_IDS[ix]) );
  336. imageList.Add(hicon);
  337. }
  338. // Be sure that all the small icons were added.
  339. _ASSERTE(imageList.GetImageCount() == NUMBER_IMAGES);
  340. m_SCardList.SetImageList(&imageList, (int) LVSIL_SMALL);
  341. imageList.Detach(); // leave the images intact when we go out of scope
  342. }
  343. /*++
  344. LONG UpdateSCardListCtrl:
  345. This routine updates the list box display.
  346. Arguments:
  347. None.
  348. Return Value:
  349. A LONG value indicating the status of the requested action. Please
  350. see the Smartcard header files for additional information.
  351. Author:
  352. Chris Dudley 3/7/1997
  353. Revision History:
  354. Chris Dudley 5/13/1997
  355. Notes:
  356. 1. Strings need to be converted from type stored in the smartcard
  357. thread help classes to this dialog's build type (i.e. UNICODE/ANSI)!!!!
  358. --*/
  359. LONG CSCStatusDlg::UpdateSCardListCtrl( void )
  360. {
  361. LONG lReturn = SCARD_S_SUCCESS;
  362. LONG lMoreReaders = SCARD_S_SUCCESS;
  363. CSCardReaderState* pReader;
  364. int nImage = 0;
  365. LV_ITEM lv_item;
  366. CString strCardStatus, strCardName;
  367. //
  368. // If the status monitor is not running,
  369. // Don't bother to update SCardListCtrl
  370. // If there used to be readers, display an error and shut down dialog
  371. //
  372. if (CScStatusMonitor::running != m_monitor.GetStatus())
  373. {
  374. m_SCardList.EnableWindow(FALSE);
  375. DoErrorMessage();
  376. return lReturn;
  377. }
  378. // Setup LV_ITEM struct
  379. lv_item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  380. // Remove old items from list if required
  381. m_SCardList.DeleteAllItems();
  382. //
  383. // Update the reader information
  384. //
  385. m_monitor.GetReaderStatus(m_aReaderState);
  386. //
  387. // Recreate the items in the reader list (UI)
  388. //
  389. int nNumReaders = (int)m_aReaderState.GetSize();
  390. for(int nIndex = 0; nIndex < nNumReaders; nIndex++)
  391. {
  392. // Setup struct for system reader list
  393. pReader = m_aReaderState[nIndex];
  394. lv_item.state = 0;
  395. lv_item.stateMask = 0;
  396. lv_item.iItem = nIndex;
  397. lv_item.iSubItem = 0;
  398. lv_item.pszText = _T("");
  399. lv_item.cchTextMax = MAX_ITEMLEN;
  400. lv_item.iImage = (int)READEREMPTY;
  401. if (NULL != pReader)
  402. {
  403. lv_item.pszText = (LPTSTR)(LPCTSTR)((m_aReaderState[nIndex])->strReader);
  404. // Get the card status: image
  405. DWORD dwState = (m_aReaderState[nIndex])->dwState;
  406. if (dwState == SC_STATUS_NO_CARD)
  407. {
  408. lv_item.iImage = (int)READEREMPTY;
  409. }
  410. else if (dwState == SC_STATUS_ERROR)
  411. {
  412. lv_item.iImage = (int)READERERROR;
  413. }
  414. else
  415. {
  416. // normally, this would be a "card loaded"...
  417. lv_item.iImage = (int)READERLOADED;
  418. // ...unless the card is the logon/locked card or idle
  419. if (m_fLogonLock &&
  420. (0 == m_pstrLogonReader->Compare((m_aReaderState[nIndex])->strReader)))
  421. {
  422. lv_item.iImage = (int)READERLOCK;
  423. }
  424. else
  425. {
  426. for (int n1=(int)m_aIdleList.GetUpperBound(); n1>=0; n1--)
  427. {
  428. if (m_aIdleList[n1] == (m_aReaderState[nIndex])->strReader)
  429. {
  430. lv_item.iImage = (int)READERINFO;
  431. break;
  432. }
  433. }
  434. }
  435. }
  436. // Add Reader Item
  437. m_SCardList.InsertItem(&lv_item);
  438. // Add Card Name sub item
  439. if (dwState != SC_STATUS_NO_CARD && dwState != SC_STATUS_ERROR)
  440. {
  441. // Set card name if not available
  442. strCardName = (LPCTSTR)(m_aReaderState[nIndex])->strCard;
  443. if (strCardName.IsEmpty())
  444. {
  445. strCardName.LoadString(IDS_SC_NAME_UNKNOWN);
  446. }
  447. m_SCardList.SetItemText(nIndex,
  448. CARD_COLUMN,
  449. strCardName);
  450. }
  451. // Add Card Status sub item
  452. ASSERT(dwState >= SC_STATUS_FIRST && dwState <= SC_STATUS_LAST);
  453. strCardStatus.LoadString(CARD_STATUS_IDS[dwState]);
  454. if (m_fLogonLock &&
  455. (0 == m_pstrLogonReader->Compare((m_aReaderState[nIndex])->strReader)))
  456. {
  457. CString strTemp = *m_pstrRemovalText + strCardStatus;
  458. strCardStatus = strTemp;
  459. }
  460. m_SCardList.SetItemText(nIndex,
  461. STATUS_COLUMN,
  462. strCardStatus);
  463. strCardStatus.Empty();
  464. strCardName.Empty();
  465. }
  466. }
  467. // If we got this far, things are OK. Make sure the window is enabled.
  468. m_SCardList.EnableWindow(TRUE);
  469. return lReturn;
  470. }
  471. /*++
  472. void RestartMonitor:
  473. This routine forces the monitor to refresh its list of readers.
  474. Arguments:
  475. None.
  476. Return Value:
  477. None.
  478. Author:
  479. Amanda Matlosz 11/04/1998
  480. Notes:
  481. --*/
  482. void CSCStatusDlg::RestartMonitor( void )
  483. {
  484. m_monitor.Start(m_hWnd, WM_READERSTATUSCHANGE);
  485. }
  486. /////////////////////////////////////////////////////////////////////////////
  487. //
  488. // CSCStatusDlg message handlers
  489. //
  490. /*++
  491. void OnInitDialog:
  492. Performs dialog initialization.
  493. Arguments:
  494. None.
  495. Return Value:
  496. TRUE if successful and dialog should be displayed. FALSE otherwise.
  497. Author:
  498. Chris Dudley 7/30/1997
  499. Note:
  500. --*/
  501. BOOL CSCStatusDlg::OnInitDialog()
  502. {
  503. LONG lReturn = SCARD_S_SUCCESS;
  504. CDialog::OnInitDialog();
  505. //
  506. // Initialize the CScStatusMonitor
  507. //
  508. m_monitor.Start(m_hWnd, WM_READERSTATUSCHANGE);
  509. //
  510. // Initialize the list control -- whether or not the monitor has started!
  511. //
  512. InitSCardListCtrl();
  513. lReturn = UpdateSCardListCtrl();
  514. //
  515. // Show the dialog IFF the above succeeded
  516. //
  517. if (SCARD_S_SUCCESS == lReturn)
  518. {
  519. // Set the status text
  520. UpdateStatusText();
  521. // Set the icon for this dialog. The framework does this automatically
  522. // when the application's main window is not a dialog
  523. SetIcon(m_hIcon, TRUE); // Set big icon
  524. SetIcon(m_hIcon, FALSE); // Set small icon
  525. // set icon for Alerts button
  526. HICON hIcon = AfxGetApp()->LoadIcon(IDI_SC_INFO);
  527. SendDlgItemMessage(IDC_ALERT, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
  528. // Center the dialog and bring it to top
  529. CenterWindow();
  530. SetWindowPos( &wndTop,
  531. 0,0,0,0,
  532. SWP_NOMOVE | SWP_NOSIZE);
  533. SetActiveWindow();
  534. // Set Parent to desktop
  535. SetParent(NULL);
  536. }
  537. else
  538. {
  539. //
  540. // If any of the initialization depending on the resource manager failed,
  541. // give up and report a death-due-to-some-error to the caller
  542. //
  543. PostMessage(WM_CLOSE, 0, 0); // need to CANCEL, instead of close...
  544. TRACE_CATCH_UNKNOWN(_T("OnInitDialog"));
  545. }
  546. return TRUE; // return TRUE unless you set the focus to a control
  547. }
  548. /*++
  549. void OnPaint:
  550. Used to paint dialog. In this case, used to draw the icon for the dialog
  551. while minimized/maximized.
  552. Arguments:
  553. None.
  554. Return Value:
  555. None.
  556. Author:
  557. Chris Dudley 7/30/1997
  558. Note:
  559. --*/
  560. void CSCStatusDlg::OnPaint()
  561. {
  562. if (IsIconic())
  563. {
  564. CPaintDC dc(this); // device context for painting
  565. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  566. // Center icon in client rectangle
  567. int cxIcon = GetSystemMetrics(SM_CXICON);
  568. int cyIcon = GetSystemMetrics(SM_CYICON);
  569. CRect rect;
  570. GetClientRect(&rect);
  571. int x = (rect.Width() - cxIcon + 1) / 2;
  572. int y = (rect.Height() - cyIcon + 1) / 2;
  573. // Draw the icon
  574. dc.DrawIcon(x, y, m_hIcon);
  575. }
  576. else
  577. {
  578. CDialog::OnPaint();
  579. }
  580. }
  581. /*++
  582. void OnQueryDragIcon:
  583. The system calls this to obtain the cursor to display while the user drags
  584. the minimized window.
  585. Arguments:
  586. None.
  587. Return Value:
  588. HCURSOR handle to cursor to display
  589. Author:
  590. Chris Dudley 7/30/1997
  591. Note:
  592. --*/
  593. HCURSOR CSCStatusDlg::OnQueryDragIcon()
  594. {
  595. return (HCURSOR) m_hIcon;
  596. }
  597. /*++
  598. void DestroyWindow:
  599. This is called by MFC whenever the dialog is closed, whether that is
  600. through WM_CLOSE (sysmenu "X") or EndDialog(IDOK/IDCANCEL)...
  601. Arguments:
  602. None.
  603. Return Value:
  604. Base class version of DestroyWindow.
  605. Author:
  606. Amanda Matlosz 4/29/98
  607. Note:
  608. --*/
  609. BOOL CSCStatusDlg::DestroyWindow()
  610. {
  611. CleanUp();
  612. return CDialog::DestroyWindow();
  613. }
  614. /*++
  615. void OnReaderStatusChange:
  616. This message handler is called by the status thread when smartcard status
  617. has changed.
  618. Arguments:
  619. None.
  620. Return Value:
  621. None
  622. Author:
  623. Chris Dudley 3/9/1997
  624. Revision History:
  625. Chris Dudley 5/13/1997
  626. Note:
  627. 1. No formal parameters are declared. These are not used and
  628. will stop compiler warnings from being generated.
  629. --*/
  630. LONG CSCStatusDlg::OnReaderStatusChange( UINT , LONG )
  631. {
  632. // Update the display
  633. UpdateSCardListCtrl();
  634. return 0;
  635. }
  636. /*++
  637. allow user to set alert options (sound, pop-up, neither)
  638. --*/
  639. void CSCStatusDlg::OnAlertOptions()
  640. {
  641. COptionsDlg dlg;
  642. dlg.DoModal();
  643. }
  644. /*++
  645. void DoErrorMessage:
  646. This is a helper routine to keep the UI stuff in one place and make sure
  647. the same error messages are handled consistently throughout.
  648. Arguments:
  649. None.
  650. Return Value:
  651. None
  652. Author:
  653. Amanda Matlosz 5/21/98
  654. Revision History:
  655. Note:
  656. 1. Consider taking an error code as well as m_monitor.GetStatus()
  657. --*/
  658. void CSCStatusDlg::DoErrorMessage( void )
  659. {
  660. CString strMsg;
  661. BOOL fShutDownDlg = FALSE;
  662. switch(m_monitor.GetStatus())
  663. {
  664. case CScStatusMonitor::no_service:
  665. fShutDownDlg = TRUE;
  666. strMsg.LoadString(IDS_NO_SYSTEM_STATUS);
  667. break;
  668. case CScStatusMonitor::no_readers:
  669. // for now, do nothing!
  670. break;
  671. case CScStatusMonitor::stopped:
  672. // do nothing! This is a clean stop on the way to shutting down.
  673. break;
  674. case CScStatusMonitor::uninitialized:
  675. case CScStatusMonitor::unknown:
  676. case CScStatusMonitor::running:
  677. fShutDownDlg = TRUE;
  678. strMsg.LoadString(IDS_UNKNOWN_ERROR);
  679. }
  680. if (!strMsg.IsEmpty())
  681. {
  682. CString strTitle;
  683. strTitle.LoadString(IDS_TITLE_ERROR);
  684. MessageBox(strMsg, strTitle, MB_OK | MB_ICONINFORMATION);
  685. }
  686. if (fShutDownDlg)
  687. {
  688. PostMessage(WM_CLOSE, 0, 0);
  689. }
  690. }
  691. /////////////////////////////////////////////////////////////////////////////
  692. // COptionsDlg dialog
  693. COptionsDlg::COptionsDlg(CWnd* pParent /*=NULL*/)
  694. : CDialog(COptionsDlg::IDD, pParent)
  695. {
  696. BOOL fSound = FALSE;
  697. BOOL fDlg = FALSE;
  698. switch(((CSCStatusApp*)AfxGetApp())->m_dwAlertOption)
  699. {
  700. case k_AlertOption_IconSound:
  701. fSound = TRUE;
  702. break;
  703. case k_AlertOption_IconSoundMsg:
  704. fSound = TRUE;
  705. case k_AlertOption_IconMsg:
  706. fDlg = TRUE;
  707. break;
  708. }
  709. //{{AFX_DATA_INIT(COptionsDlg)
  710. m_fDlg = fDlg;
  711. m_fSound = fSound;
  712. //}}AFX_DATA_INIT
  713. }
  714. void COptionsDlg::DoDataExchange(CDataExchange* pDX)
  715. {
  716. CDialog::DoDataExchange(pDX);
  717. //{{AFX_DATA_MAP(COptionsDlg)
  718. DDX_Check(pDX, IDC_DIALOG, m_fDlg);
  719. DDX_Check(pDX, IDC_SOUND, m_fSound);
  720. //}}AFX_DATA_MAP
  721. }
  722. BEGIN_MESSAGE_MAP(COptionsDlg, CDialog)
  723. //{{AFX_MSG_MAP(COptionsDlg)
  724. //}}AFX_MSG_MAP
  725. END_MESSAGE_MAP()
  726. /////////////////////////////////////////////////////////////////////////////
  727. // COptionsDlg message handlers
  728. void COptionsDlg::OnOK()
  729. {
  730. // use status of check boxes to set alert options state for app
  731. UpdateData(TRUE);
  732. if (TRUE == m_fSound)
  733. {
  734. if (TRUE == m_fDlg)
  735. {
  736. ((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconSoundMsg;
  737. }
  738. else
  739. {
  740. ((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconSound;
  741. }
  742. }
  743. else if (TRUE == m_fDlg)
  744. {
  745. ((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconMsg;
  746. }
  747. else
  748. {
  749. ((CSCStatusApp*)AfxGetApp())->m_dwAlertOption = k_AlertOption_IconOnly;
  750. }
  751. CDialog::OnOK();
  752. }