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.

1325 lines
35 KiB

  1. //******************************************************************
  2. // trapdlg.cpp
  3. //
  4. // This is the source file for eventrap's main dialog.
  5. //
  6. // Author: Larry A. French
  7. //
  8. // History:
  9. // December-1995 SEA - Wrote it
  10. // SEA - wrote it.
  11. //
  12. // 20-Febuary-1996 Larry A. French
  13. // Totally rewrote it to fix the spagetti code and huge
  14. // methods. The original author seemed to have little or
  15. // no ability to form meaningful abstractions.
  16. //
  17. //
  18. // Copyright (C) 1995, 1996 Microsoft Corporation. All rights reserved.
  19. //******************************************************************
  20. #include "stdafx.h"
  21. #include "Eventrap.h"
  22. #include "trapdlg.h"
  23. #include "evntprop.h"
  24. #include "settings.h"
  25. #include "busy.h"
  26. #include "trapreg.h"
  27. #include "globals.h"
  28. #include "evntfind.h"
  29. #include "export.h"
  30. #include "dlgsavep.h"
  31. //#include "smsalloc.h"
  32. #ifdef _DEBUG
  33. #undef THIS_FILE
  34. static char BASED_CODE THIS_FILE[] = __FILE__;
  35. #endif
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CAboutDlg dialog used for App About
  38. class CAboutDlg : public CDialog
  39. {
  40. public:
  41. CAboutDlg();
  42. // Dialog Data
  43. //{{AFX_DATA(CAboutDlg)
  44. enum { IDD = IDD_ABOUTBOX };
  45. //}}AFX_DATA
  46. // Implementation
  47. protected:
  48. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  49. //{{AFX_MSG(CAboutDlg)
  50. virtual BOOL OnInitDialog();
  51. //}}AFX_MSG
  52. DECLARE_MESSAGE_MAP()
  53. };
  54. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  55. {
  56. //{{AFX_DATA_INIT(CAboutDlg)
  57. //}}AFX_DATA_INIT
  58. }
  59. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  60. {
  61. CDialog::DoDataExchange(pDX);
  62. //{{AFX_DATA_MAP(CAboutDlg)
  63. //}}AFX_DATA_MAP
  64. }
  65. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  66. //{{AFX_MSG_MAP(CAboutDlg)
  67. // No message handlers
  68. //}}AFX_MSG_MAP
  69. END_MESSAGE_MAP()
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CAboutDlg message handlers
  72. BOOL CAboutDlg::OnInitDialog()
  73. {
  74. CDialog::OnInitDialog();
  75. CenterWindow();
  76. // TODO: Add extra about dlg initialization here
  77. return TRUE; // return TRUE unless you set the focus to a control
  78. }
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CEventTrapDlg dialog
  81. CEventTrapDlg::CEventTrapDlg(CWnd* pParent /*=NULL*/)
  82. : CDialog(CEventTrapDlg::IDD, pParent)
  83. {
  84. //{{AFX_DATA_INIT(CEventTrapDlg)
  85. //}}AFX_DATA_INIT
  86. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINICON);
  87. m_source.Create(this);
  88. m_bExtendedView = FALSE;
  89. m_bSaveInProgress = FALSE;
  90. }
  91. CEventTrapDlg::~CEventTrapDlg()
  92. {
  93. PostQuitMessage(0);
  94. }
  95. void CEventTrapDlg::DoDataExchange(CDataExchange* pDX)
  96. {
  97. CDialog::DoDataExchange(pDX);
  98. //{{AFX_DATA_MAP(CEventTrapDlg)
  99. DDX_Control(pDX, IDC_APPLY, m_btnApply);
  100. DDX_Control(pDX, ID_BUTTON_EXPORT, m_btnExport);
  101. DDX_Control(pDX, IDC_EVENTLIST, m_lcEvents);
  102. DDX_Control(pDX, IDC_TV_SOURCES, m_tcSource);
  103. DDX_Control(pDX, IDC_STAT_LABEL0, m_statLabel0);
  104. DDX_Control(pDX, IDC_STAT_LABEL1, m_statLabel1);
  105. DDX_Control(pDX, IDC_STAT_LABEL2, m_statLabel2);
  106. DDX_Control(pDX, IDC_LV_SOURCES, m_lcSource);
  107. DDX_Control(pDX, IDOK, m_btnOK);
  108. DDX_Control(pDX, IDCANCEL, m_btnCancel);
  109. DDX_Control(pDX, ID_SETTINGS, m_btnSettings);
  110. DDX_Control(pDX, ID_PROPERTIES, m_btnProps);
  111. DDX_Control(pDX, ID_VIEW, m_btnView);
  112. DDX_Control(pDX, ID_REMOVE, m_btnRemove);
  113. DDX_Control(pDX, ID_ADD, m_btnAdd);
  114. DDX_Control(pDX, ID_FIND, m_btnFind);
  115. DDX_Control(pDX, IDC_STAT_GRP_CONFIG_TYPE, m_btnConfigTypeBox);
  116. DDX_Control(pDX, IDC_RADIO_CUSTOM, m_btnConfigTypeCustom);
  117. DDX_Control(pDX, IDC_RADIO_DEFAULT, m_btnConfigTypeDefault);
  118. //}}AFX_DATA_MAP
  119. }
  120. BEGIN_MESSAGE_MAP(CEventTrapDlg, CDialog)
  121. //{{AFX_MSG_MAP(CEventTrapDlg)
  122. ON_WM_SYSCOMMAND()
  123. ON_WM_DESTROY()
  124. ON_WM_PAINT()
  125. ON_WM_QUERYDRAGICON()
  126. ON_BN_CLICKED(ID_ADD, OnAdd)
  127. ON_BN_CLICKED(ID_PROPERTIES, OnProperties)
  128. ON_BN_CLICKED(ID_SETTINGS, OnSettings)
  129. ON_NOTIFY(NM_DBLCLK, IDC_EVENTLIST, OnDblclkEventlist)
  130. ON_NOTIFY(LVN_COLUMNCLICK, IDC_EVENTLIST, OnColumnclickEventlist)
  131. ON_WM_SIZE()
  132. ON_BN_CLICKED(ID_VIEW, OnView)
  133. ON_BN_CLICKED(ID_REMOVE, OnRemove)
  134. ON_BN_CLICKED(ID_FIND, OnFind)
  135. ON_NOTIFY(TVN_SELCHANGED, IDC_TV_SOURCES, OnSelchangedTvSources)
  136. ON_NOTIFY(LVN_COLUMNCLICK, IDC_LV_SOURCES, OnColumnclickLvSources)
  137. ON_NOTIFY(NM_DBLCLK, IDC_LV_SOURCES, OnDblclkLvSources)
  138. ON_BN_CLICKED(ID_BUTTON_EXPORT, OnButtonExport)
  139. ON_NOTIFY(LVN_KEYDOWN, IDC_EVENTLIST, OnKeydownEventlist)
  140. ON_NOTIFY(LVN_ITEMCHANGED, IDC_EVENTLIST, OnItemchangedEventlist)
  141. ON_NOTIFY(LVN_ITEMCHANGED, IDC_LV_SOURCES, OnItemchangedLvSources)
  142. ON_BN_CLICKED(IDC_RADIO_CUSTOM, OnRadioCustom)
  143. ON_BN_CLICKED(IDC_RADIO_DEFAULT, OnRadioDefault)
  144. ON_WM_DRAWITEM()
  145. ON_COMMAND(ID_HELP, OnHelp)
  146. ON_WM_HELPINFO()
  147. ON_WM_CONTEXTMENU()
  148. ON_BN_CLICKED(IDC_APPLY, OnApply)
  149. ON_BN_CLICKED(IDC_DEFAULT, OnDefault)
  150. ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TV_SOURCES, OnTvSourcesExpanded)
  151. //}}AFX_MSG_MAP
  152. END_MESSAGE_MAP()
  153. /////////////////////////////////////////////////////////////////////////////
  154. // CEventTrapDlg message handlers
  155. void CEventTrapDlg::OnSysCommand(UINT nID, LPARAM lParam)
  156. {
  157. /*
  158. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  159. {
  160. CAboutDlg dlgAbout;
  161. dlgAbout.DoModal();
  162. }
  163. else
  164. {
  165. CDialog::OnSysCommand(nID, lParam);
  166. }
  167. */
  168. CDialog::OnSysCommand(nID, lParam);
  169. m_lcEvents.SetFocus();
  170. }
  171. void CEventTrapDlg::OnDestroy()
  172. {
  173. CDialog::OnDestroy();
  174. }
  175. // If you add a minimize button to your dialog, you will need the code below
  176. // to draw the icon. For MFC applications using the document/view model,
  177. // this is automatically done for you by the framework.
  178. void CEventTrapDlg::OnPaint()
  179. {
  180. if (IsIconic())
  181. {
  182. CPaintDC dc(this); // device context for painting
  183. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  184. // Center icon in client rectangle
  185. int cxIcon = GetSystemMetrics(SM_CXICON);
  186. int cyIcon = GetSystemMetrics(SM_CYICON);
  187. CRect rect;
  188. GetClientRect(&rect);
  189. int x = (rect.Width() - cxIcon + 1) / 2;
  190. int y = (rect.Height() - cyIcon + 1) / 2;
  191. // Draw the icon
  192. dc.DrawIcon(x, y, m_hIcon);
  193. }
  194. else
  195. {
  196. CDialog::OnPaint();
  197. }
  198. }
  199. // The system calls this to obtain the cursor to display while the user drags
  200. // the minimized window.
  201. HCURSOR CEventTrapDlg::OnQueryDragIcon()
  202. {
  203. return (HCURSOR) m_hIcon;
  204. }
  205. //*************************************************************************
  206. // CEventTrapDlg::OnInitDialog
  207. //
  208. // Initialize the dialog.
  209. //
  210. // Parameters:
  211. // None.
  212. //
  213. // Returns:
  214. // BOOL
  215. // TRUE if Windows should set the focus to the first control
  216. // in the dialog box. FALSE if the focus has already been set
  217. // and Windows should leave it alone.
  218. //
  219. //*************************************************************************
  220. BOOL CEventTrapDlg::OnInitDialog()
  221. {
  222. CBusy busy;
  223. CDialog::OnInitDialog();
  224. CenterWindow();
  225. // VERIFY(m_lcSource.SubclassDlgItem(IDC_LV_SOURCES, this));
  226. SetIcon(m_hIcon, TRUE);
  227. SetIcon(m_hIcon, FALSE);
  228. m_layout.Initialize(this);
  229. // Layout the dialog view for the small (non-extended) view
  230. m_bExtendedView = FALSE;
  231. m_layout.LayoutView(FALSE);
  232. // The registry class is keeping a pointer to the 'Apply' pointer in order to
  233. // enable disable it according to the 'dirty' state.
  234. g_reg.SetApplyButton(&m_btnApply);
  235. // Step the progress indicator for loading the configuration.
  236. // Note that if you add more steps here, you must modify
  237. // CTrapReg::CTrapReg to account for these extra steps.
  238. //=========================================================
  239. g_reg.m_pdlgLoadProgress->StepProgress();
  240. ++g_reg.m_nLoadSteps;
  241. CString sText;
  242. sText.LoadString(IDS_TITLE_EDIT_BUTTON);
  243. m_btnView.SetWindowText(sText);
  244. // Notify the message source container and the events list control
  245. // that this dialog has been initialized so that they can initialize
  246. // their windows and so on. Note that this must be called after the
  247. // g_reg.m_aEventLogs is deserialized because information contained therein
  248. // will be displayed
  249. m_source.CreateWindowEpilogue();
  250. g_reg.m_pdlgLoadProgress->StepProgress();
  251. ++g_reg.m_nLoadSteps;
  252. m_lcEvents.CreateWindowEpilogue();
  253. g_reg.m_pdlgLoadProgress->StepProgress();
  254. ++g_reg.m_nLoadSteps;
  255. m_lcEvents.AddEvents(m_source, g_reg.m_aEventLogs);
  256. g_reg.m_pdlgLoadProgress->StepProgress();
  257. ++g_reg.m_nLoadSteps;
  258. m_sExportTitle.LoadString(IDS_EXPORT_DEFAULT_FILENAME);
  259. CheckEventlistSelection();
  260. m_btnAdd.EnableWindow(FALSE);
  261. if ((g_reg.GetConfigType() == CONFIG_TYPE_CUSTOM)) {
  262. CheckRadioButton(IDC_RADIO_CUSTOM, IDC_RADIO_DEFAULT, IDC_RADIO_CUSTOM);
  263. }
  264. else {
  265. CheckRadioButton(IDC_RADIO_CUSTOM, IDC_RADIO_DEFAULT, IDC_RADIO_DEFAULT);
  266. }
  267. if ((g_reg.GetConfigType() == CONFIG_TYPE_CUSTOM) && !g_reg.m_bRegIsReadOnly) {
  268. m_btnView.EnableWindow(TRUE);
  269. }
  270. else {
  271. m_btnView.EnableWindow(FALSE);
  272. }
  273. // If eventrap will be used without the SMS Admin UI, then we want to hide the
  274. // configuration type group box because it it meaningless if SMS will not be
  275. // distributing jobs containing the default configuration.
  276. if (!g_reg.m_bShowConfigTypeBox) {
  277. m_btnConfigTypeBox.ShowWindow(SW_HIDE);
  278. m_btnConfigTypeCustom.ShowWindow(SW_HIDE);
  279. m_btnConfigTypeDefault.ShowWindow(SW_HIDE);
  280. }
  281. // Now that we know what the configuration type is, we can update the
  282. // dialog's title. But first we will save the default dialog title so
  283. // that we can use it as the base that will be extended with an optional
  284. // machine name and configuration type.
  285. GetWindowText(m_sBaseDialogCaption);
  286. UpdateDialogTitle();
  287. delete g_reg.m_pdlgLoadProgress;
  288. g_reg.m_pdlgLoadProgress = NULL;
  289. // initially, once the registry gets loaded, the dirty state is 'false'
  290. g_reg.SetDirty(FALSE);
  291. return TRUE; // return TRUE unless you set the focus to a control
  292. // EXCEPTION: OCX Property Pages should return FALSE
  293. }
  294. //*************************************************************************
  295. // CEventTrapDlg::OnAdd
  296. //
  297. // Add the messages that are currently selected in the message source list
  298. // to the event list.
  299. //
  300. // The event list is the list control in the upper part of the dialog box.
  301. // The message source list is the list control in the lower-right side of
  302. // the dialog box.
  303. //
  304. // Parameters:
  305. // None.
  306. //
  307. // Returns:
  308. // Nothing.
  309. //
  310. //*************************************************************************
  311. void CEventTrapDlg::OnAdd()
  312. {
  313. CBusy busy;
  314. // Get an array containing the selected messages
  315. CXMessageArray aMessages;
  316. m_source.GetSelectedMessages(aMessages);
  317. if (aMessages.GetSize() == 0) {
  318. AfxMessageBox(IDS_WARNING_NO_MESSAGE_SELECTED);
  319. m_lcEvents.SetFocus();
  320. return;
  321. }
  322. // Create a set of events corresponding to the messages.
  323. CXEventArray aEvents;
  324. CXEventArray aEventsAlreadyTrapped;
  325. LONG nMessages = aMessages.GetSize();
  326. m_lcEvents.UpdateWindow();
  327. aEvents.RemoveAll();
  328. for (LONG iMessage = 0; iMessage < nMessages; ++iMessage) {
  329. CXMessage* pMessage = aMessages[iMessage];
  330. CXEvent* pEvent;
  331. pEvent = pMessage->m_pEventSource->FindEvent(pMessage->m_dwId);
  332. if (pEvent == NULL) {
  333. CXEvent* pEvent = new CXEvent(pMessage);
  334. aEvents.Add(pEvent);
  335. }
  336. else {
  337. aEventsAlreadyTrapped.Add(pEvent);
  338. }
  339. }
  340. if (aEvents.GetSize() > 0) {
  341. // Now we need to ask the user for the "settings" for these events.
  342. CEventPropertiesDlg dlg;
  343. if (!dlg.EditEventProperties(aEvents)) {
  344. aEvents.DeleteAll();
  345. m_lcEvents.SetFocus();
  346. return;
  347. }
  348. m_lcEvents.AddEvents(m_source, aEvents);
  349. aEvents.RemoveAll();
  350. g_reg.SetDirty(TRUE);
  351. }
  352. if (aEventsAlreadyTrapped.GetSize() > 0) {
  353. m_lcEvents.SelectEvents(aEventsAlreadyTrapped);
  354. aEventsAlreadyTrapped.RemoveAll();
  355. if (nMessages == aEventsAlreadyTrapped.GetSize()) {
  356. AfxMessageBox(IDS_ALREADYTRAPPING);
  357. }
  358. else {
  359. AfxMessageBox(IDS_SOMETRAPPING);
  360. }
  361. }
  362. m_lcEvents.SetFocus();
  363. }
  364. //*************************************************************************
  365. // CEventTrapDlg::OnProperties
  366. //
  367. // Edit the properties of the selected events in the event-list.
  368. //
  369. // Parameters:
  370. // None.
  371. //
  372. // Returns:
  373. // Nothing.
  374. //
  375. //*************************************************************************
  376. void CEventTrapDlg::OnProperties()
  377. {
  378. CXEventArray aEvents;
  379. m_lcEvents.GetSelectedEvents(aEvents);
  380. // Nothing selected.
  381. if (aEvents.GetSize() == 0)
  382. {
  383. CString sMsg;
  384. sMsg.LoadString(IDS_MSG_SELECTEVENT);
  385. MessageBox(sMsg, NULL, MB_ICONEXCLAMATION);
  386. }
  387. else {
  388. // Put up the dialog to edit the event properties.
  389. CEventPropertiesDlg dlg;
  390. if (dlg.EditEventProperties(aEvents)) {
  391. m_lcEvents.RefreshEvents(aEvents);
  392. }
  393. }
  394. m_lcEvents.SetFocus();
  395. }
  396. //*************************************************************************
  397. // CEventTrapDlg::OnSettings
  398. //
  399. // Edit the global settings.
  400. //
  401. // Parameters:
  402. // None.
  403. //
  404. // Returns:
  405. // Nothing.
  406. //
  407. //*************************************************************************
  408. void CEventTrapDlg::OnSettings()
  409. {
  410. // Setup and load the dialog.
  411. CTrapSettingsDlg dlg(this);
  412. dlg.EditSettings();
  413. m_lcEvents.SetFocus();
  414. }
  415. //*************************************************************************
  416. // CEventTrapDlg::OnRemove
  417. //
  418. // Remove the events currently selected in the CLcEvents list control.
  419. //
  420. // Parameters:
  421. // None.
  422. //
  423. // Returns:
  424. // Nothing.
  425. //
  426. //*************************************************************************
  427. void CEventTrapDlg::OnRemove()
  428. {
  429. // If nothing was selected, warn the user.
  430. CString sText;
  431. if (!m_lcEvents.HasSelection()) {
  432. sText.LoadString(IDS_MSG_SELECTEVENT);
  433. MessageBox(sText, NULL, MB_ICONEXCLAMATION);
  434. return; // Nothing to do.
  435. }
  436. // Make sure the user wants to delete these items.
  437. sText.LoadString(IDS_MSG_DELETEEVENT);
  438. if (MessageBox(sText, NULL, MB_ICONQUESTION | MB_OKCANCEL) != IDOK)
  439. return;
  440. // We must notify the source control that the events are deleted
  441. // so that the trapping flag can be updated.
  442. CBusy busy;
  443. m_lcEvents.DeleteSelectedEvents(m_source);
  444. g_reg.SetDirty(TRUE);
  445. // All of the selected events were removed, so now there is no selection
  446. // and the export and properties buttons should be disabled.
  447. m_btnProps.EnableWindow(FALSE);
  448. m_btnExport.EnableWindow(FALSE);
  449. m_btnRemove.EnableWindow(FALSE);
  450. m_lcEvents.SetFocus();
  451. }
  452. //*********************************************************************
  453. // CEventTrapDlg::OnOK
  454. //
  455. // This method is called when the "OK" button is clicked. All we
  456. // have to do is save the current configuration.
  457. //
  458. // Parameters:
  459. // None.
  460. //
  461. // Returns:
  462. // Nothing.
  463. //
  464. //********************************************************************
  465. void CEventTrapDlg::OnOK()
  466. {
  467. CBusy busy;
  468. // Set the save in progress flag so that we aren't interrupted in the
  469. // middle of writing to the registry.
  470. m_bSaveInProgress = TRUE;
  471. // Clear the "lost connection" flag so that the user can attempt to save
  472. // again.
  473. SCODE sc = g_reg.Serialize();
  474. if ((sc == S_SAVE_CANCELED) || FAILED(sc)) {
  475. // Control comes here if the user elected to cancel the save. We clear
  476. // the m_bSaveInProgress dialog so that the user can cancel out of this
  477. // application altogether if he or she chooses to do so.
  478. m_bSaveInProgress = FALSE;
  479. return;
  480. }
  481. CDialog::OnOK();
  482. delete this;
  483. }
  484. //*********************************************************************
  485. // CEventTrapDlg::OnApply
  486. //
  487. // This method is called when the "Apply" button is clicked. All we
  488. // have to do is save the current configuration.
  489. //
  490. // Parameters:
  491. // None.
  492. //
  493. // Returns:
  494. // Nothing.
  495. //
  496. //********************************************************************
  497. void CEventTrapDlg::OnApply()
  498. {
  499. CBusy busy;
  500. // Set the save in progress flag so that we aren't interrupted in the
  501. // middle of writing to the registry.
  502. m_bSaveInProgress = TRUE;
  503. // Clear the "lost connection" flag so that the user can attempt to save
  504. // again.
  505. SCODE sc = g_reg.Serialize();
  506. // Control comes here if the user elected to cancel the save. We clear
  507. // the m_bSaveInProgress dialog so that the user can cancel out of this
  508. // application altogether if he or she chooses to do so.
  509. m_bSaveInProgress = FALSE;
  510. }
  511. //********************************************************************
  512. // CEventTrapDlg::OnDblclkEventlist
  513. //
  514. // This method is called when the user double clicks an item within
  515. // the event-list. This is equivallent to clicking the "Properties"
  516. // button.
  517. //
  518. // Parameters:
  519. // NMHDR* pNMHDR
  520. //
  521. // LRESULT* pResult
  522. //
  523. // Returns:
  524. // Nothing.
  525. //******************************************************************
  526. void CEventTrapDlg::OnDblclkEventlist(NMHDR* pNMHDR, LRESULT* pResult)
  527. {
  528. OnProperties();
  529. *pResult = 0;
  530. }
  531. //************************************************************************
  532. // CEventTrapDlg::OnColumnclickEventlist
  533. //
  534. // This method is called when the user click a column header in the
  535. // eventlist. When this occurs, the event list must be resorted
  536. // according to the criteria for that column.
  537. //
  538. // Ideally, this method would be a member of the CLcEvents class, but the
  539. // class wizard and MFC wouldn't let me do it (MFC4.0 and VC++4.0 do let
  540. // you do it).
  541. //
  542. // Parameters:
  543. // See the MFC documentation.
  544. //
  545. // Returns:
  546. // Nothing.
  547. //
  548. //***********************************************************************
  549. void CEventTrapDlg::OnColumnclickEventlist(NMHDR* pNMHDR, LRESULT* pResult)
  550. {
  551. CBusy busy;
  552. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  553. ASSERT(pNMListView->iSubItem < ICOL_LcEvents_MAX);
  554. // First flip the sort order for the column and then do the sort.
  555. g_abLcEventsSortAscending[pNMListView->iSubItem] = ! g_abLcEventsSortAscending[pNMListView->iSubItem];
  556. m_lcEvents.SortItems(pNMListView->iSubItem);
  557. *pResult = 0;
  558. }
  559. //************************************************************************
  560. // CEventTrapDlg::OnSize
  561. //
  562. // This method is called when the trap dialog changes sizes. When this
  563. // occurs, the dialog layout must be recalculated because the dialog is
  564. // laid out dynamically.
  565. //
  566. // Parameters:
  567. // See the MFC documentation.
  568. //
  569. // Returns:
  570. // Nothing.
  571. //
  572. //************************************************************************
  573. void CEventTrapDlg::OnSize(UINT nType, int cx, int cy)
  574. {
  575. CDialog::OnSize(nType, cx, cy);
  576. if (!::IsWindow(m_btnOK.m_hWnd)) {
  577. return;
  578. }
  579. m_layout.LayoutAndRedraw(m_bExtendedView, cx, cy);
  580. }
  581. //*********************************************************************
  582. // CEventTrapDlg::OnView
  583. //
  584. // This method is called when the user clicks the View/Edit button.
  585. //
  586. // Parameters:
  587. // None.
  588. //
  589. // Returns:
  590. // Nothing.
  591. //
  592. //*********************************************************************
  593. void CEventTrapDlg::OnView()
  594. {
  595. // Flip the normal/extended view type and redo the dialog layout
  596. // to reflect the change.
  597. m_bExtendedView = !m_bExtendedView;
  598. m_layout.LayoutView(m_bExtendedView);
  599. // Flip the title of the View/Edit button to the other state.
  600. CString sText;
  601. sText.LoadString(m_bExtendedView ? IDS_TITLE_VIEW_BUTTON : IDS_TITLE_EDIT_BUTTON);
  602. m_btnView.SetWindowText(sText);
  603. if (m_bExtendedView)
  604. m_tcSource.SetFocus();
  605. else
  606. m_lcEvents.SetFocus();
  607. }
  608. //********************************************************************
  609. // CEventTrapDlg::OnFind
  610. //
  611. // This method is called when the user clicks the "Find" button. Pass
  612. // the notification onto the CSource object.
  613. //
  614. // Parameters:
  615. // None.
  616. //
  617. // Returns:
  618. // Nothing.
  619. //
  620. //********************************************************************
  621. void CEventTrapDlg::OnFind()
  622. {
  623. m_source.OnFind(this);
  624. }
  625. //********************************************************************
  626. // CEventTrapDlg::OnSelchangedTvSources
  627. //
  628. // This method is changed when the message source treeview selection
  629. // changes. Ideally, this method would be part of the CTcSource class,
  630. // but MFC3.0 doesn't allow this (or at least you can't do it through
  631. // the VC++ class wizard). So, the message needs to be passed along
  632. // to the CTcSource class.
  633. //
  634. // Parameters:
  635. // See the MFC documentation.
  636. //
  637. // Returns:
  638. // Nothing.
  639. //
  640. //********************************************************************
  641. void CEventTrapDlg::OnSelchangedTvSources(NMHDR* pNMHDR, LRESULT* pResult)
  642. {
  643. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  644. // We update the window so that the old selection will be unhighlighted
  645. // immediately. This is useful if it takes a long time to complete
  646. // the selection change. Without the update, the user may get the impression
  647. // that there is a multiple selection.
  648. m_tcSource.UpdateWindow();
  649. m_tcSource.SelChanged();
  650. *pResult = 0;
  651. }
  652. //*******************************************************************
  653. // CEventTrapDlg::OnColumnclickLvSources
  654. //
  655. // This method is called when a column is clicked in the message source
  656. // listview. When this occurs, the messages must be resorted according
  657. // to the sorting criteria for the clicked column.
  658. //
  659. // Parameters:
  660. // See the MFC documentation.
  661. //
  662. // Returns:
  663. // Nothing.
  664. //
  665. //******************************************************************
  666. void CEventTrapDlg::OnColumnclickLvSources(NMHDR* pNMHDR, LRESULT* pResult)
  667. {
  668. CBusy busy;
  669. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  670. ASSERT(pNMListView->iSubItem < ICOL_LcSource_MAX);
  671. // First flip the sort order for the column and then do the sort.
  672. g_abLcSourceSortAscending[pNMListView->iSubItem] = ! g_abLcSourceSortAscending[pNMListView->iSubItem];
  673. m_lcSource.SortItems(pNMListView->iSubItem);
  674. *pResult = 0;
  675. }
  676. //*******************************************************************
  677. // CEventTrapDlg::OnDblclkLvSources
  678. //
  679. // This method is called when the user double clicks a message in the
  680. // source list. This is equivallent to clicking the "Add" button.
  681. //
  682. // Parameters:
  683. // See the MFC documentation.
  684. //
  685. // Returns:
  686. // Nothing.
  687. //
  688. //*******************************************************************
  689. void CEventTrapDlg::OnDblclkLvSources(NMHDR* pNMHDR, LRESULT* pResult)
  690. {
  691. OnAdd();
  692. *pResult = 0;
  693. }
  694. //********************************************************************
  695. // CEventTrapDlg::OnButtonExport
  696. //
  697. // This method is called when the "Export" button is clicked. This is
  698. // where events can be exported by writing a trap-text or trap tool
  699. // files corresponding to the selected events.
  700. //
  701. // Parameters:
  702. // None.
  703. //
  704. // Returns:
  705. // Nothing.
  706. //
  707. //********************************************************************
  708. void CEventTrapDlg::OnButtonExport()
  709. {
  710. CXEventArray aEvents;
  711. m_lcEvents.GetSelectedEvents(aEvents);
  712. // Nothing selected.
  713. if (aEvents.GetSize() == 0)
  714. {
  715. AfxMessageBox(IDS_MSG_SELECTEVENT, MB_ICONEXCLAMATION);
  716. }
  717. else {
  718. m_dlgExport.DoModal(aEvents);
  719. }
  720. m_lcEvents.SetFocus();
  721. }
  722. //*******************************************************************
  723. // CEventTrapDlg::OnCancel
  724. //
  725. // This method is called when the cancel button is clicked.
  726. //
  727. // Parameters:
  728. // None.
  729. //
  730. // Returns:
  731. // Nothing.
  732. //
  733. //*******************************************************************
  734. void CEventTrapDlg::OnCancel()
  735. {
  736. if (m_bSaveInProgress) {
  737. return;
  738. }
  739. CDialog::OnCancel();
  740. delete this;
  741. }
  742. //********************************************************************
  743. // CEventTrapDlg::CheckEventlistSelection
  744. //
  745. // Check to see if any events are currently selected in the event
  746. // list. If no events are selected, then the buttons that operate on
  747. // events are disabled. If at least one event is selected then the
  748. // buttons that operate on events are enabled.
  749. //
  750. // Parameters:
  751. // None.
  752. //
  753. // Returns:
  754. // Nothing.
  755. //
  756. //*******************************************************************
  757. void CEventTrapDlg::CheckEventlistSelection()
  758. {
  759. LONG nSelected = m_lcEvents.GetSelectedCount();
  760. if (nSelected > 0) {
  761. m_btnProps.EnableWindow(TRUE);
  762. m_btnExport.EnableWindow(TRUE);
  763. m_btnRemove.EnableWindow(TRUE);
  764. }
  765. else {
  766. m_btnProps.EnableWindow(FALSE);
  767. m_btnExport.EnableWindow(FALSE);
  768. m_btnRemove.EnableWindow(FALSE);
  769. }
  770. }
  771. //********************************************************************
  772. // CEventTrapDlg::CheckSourcelistSelection
  773. //
  774. // Check to see if any messages are currently selected in the message
  775. // source list. If no messages are selected, then the "Add" button needs
  776. // to be disabled. If one or more messages are selected, then the "Add"
  777. // button is enabled, allowing the user to add the message to the event
  778. // list.
  779. //
  780. // Parameters:
  781. // None.
  782. //
  783. // Returns:
  784. // Nothing.
  785. //
  786. //*******************************************************************
  787. void CEventTrapDlg::CheckSourcelistSelection()
  788. {
  789. LONG nSelected = m_lcSource.GetSelectedCount();
  790. if (nSelected > 0) {
  791. m_btnAdd.EnableWindow(TRUE);
  792. }
  793. else {
  794. m_btnAdd.EnableWindow(FALSE);
  795. }
  796. }
  797. //********************************************************************
  798. // CEventTrapDlg::OnKeydownEventlist
  799. //
  800. // This method is called when a keydown message is sent to the
  801. // event list. There are reasons why we monitor keydown events here:
  802. //
  803. // 1. To delete the selected event when the user hits the delete key.
  804. //
  805. // Parameters:
  806. // See the MFC documentation.
  807. //
  808. // Returns:
  809. // Nothing.
  810. //
  811. //********************************************************************
  812. void CEventTrapDlg::OnKeydownEventlist(NMHDR* pNMHDR, LRESULT* pResult)
  813. {
  814. #define VKEY_DELETE 46
  815. LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
  816. // Check to see if the delete key was entered. If so, delete the
  817. // selected event. Note that events can be deleted only if this
  818. // is a "Custom" configuration.
  819. if (pLVKeyDow->wVKey == VKEY_DELETE) {
  820. if (g_reg.GetConfigType() == CONFIG_TYPE_CUSTOM) {
  821. if (pLVKeyDow->wVKey == VKEY_DELETE) {
  822. OnRemove();
  823. }
  824. *pResult = 0;
  825. } else {
  826. MessageBeep(MB_ICONQUESTION);
  827. }
  828. }
  829. }
  830. //***************************************************************************
  831. // CEventTrapDlg::OnItemchangedEventlist
  832. //
  833. // This method is called when an item changes in the event list. When this
  834. // occurs, various buttons may have to be enabled or disabled depending on
  835. // whether or not anything is selected.
  836. //
  837. // Parameters:
  838. // Please see the MFC documentation.
  839. //
  840. // Returns:
  841. // Nothing.
  842. //
  843. //**************************************************************************
  844. void CEventTrapDlg::OnItemchangedEventlist(NMHDR* pNMHDR, LRESULT* pResult)
  845. {
  846. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  847. // TODO: Add your control notification handler code here
  848. CheckEventlistSelection();
  849. *pResult = 0;
  850. }
  851. //***********************************************************************
  852. // CEventTrapDlg::OnItemchangedLvSources
  853. //
  854. // This method is called when an item in the message source list changes.
  855. // When this occurs, buttons such as "Add" and "Remove" may have to
  856. // be enabled or disabled depending on whether or not anything is selected
  857. // in the list.
  858. //
  859. // Parameters:
  860. // NMHDR* pNMHDR
  861. //
  862. // LRESULT* pResult
  863. //
  864. // Returns:
  865. // Nothing.
  866. //
  867. //***********************************************************************
  868. void CEventTrapDlg::OnItemchangedLvSources(NMHDR* pNMHDR, LRESULT* pResult)
  869. {
  870. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  871. CheckSourcelistSelection();
  872. *pResult = 0;
  873. }
  874. //*********************************************************************
  875. // CEventTrapDlg::NotifySourceSelChanged
  876. //
  877. // This method is called when the selection changes in the message source
  878. // list. When this occurs, buttons such as "Add" and "Remove" may have
  879. // to be enabled or disabled depending on whether or not anything is
  880. // selected in the list.
  881. //
  882. // Parameters:
  883. // None.
  884. //
  885. // Returns:
  886. // Nothing.
  887. //
  888. //*********************************************************************
  889. void CEventTrapDlg::NotifySourceSelChanged()
  890. {
  891. CheckSourcelistSelection();
  892. }
  893. //*********************************************************************
  894. // CEventTrapDlg::OnRadioCustom
  895. //
  896. // This method is called when the "Custom" radio button in the
  897. // "Configuration Type" groupbox is clicked. When the user selects
  898. // the custom configuration type, he or she is allowed to edit the
  899. // current configuration. Also the registry will be marked so that
  900. // the next time SMS distributes an "Event to Trap" configuration job,
  901. // the current configuration will not be replaced with the default configuration.
  902. //
  903. // There are three possible configuration states: custom, default, and
  904. // default pending.
  905. //
  906. // Parameters:
  907. // None.
  908. //
  909. // Returns:
  910. // Nothing.
  911. //
  912. //**********************************************************************
  913. void CEventTrapDlg::OnRadioCustom()
  914. {
  915. CheckRadioButton(IDC_RADIO_CUSTOM, IDC_RADIO_DEFAULT, IDC_RADIO_CUSTOM);
  916. if (!g_reg.m_bRegIsReadOnly) {
  917. m_btnView.EnableWindow(TRUE);
  918. }
  919. g_reg.SetConfigType(CONFIG_TYPE_CUSTOM);
  920. UpdateDialogTitle();
  921. }
  922. //*********************************************************************
  923. // CEventTrapDlg::OnRadioDefault
  924. //
  925. // This method is called when the "Default" radio button in the
  926. // "Configuration Type" groupbox is clicked. When the user selects
  927. // the default configuration, he or she is prevented from editing the
  928. // current configuration. Also the registry will be marked so that
  929. // the next time SMS distributes an "Event to Trap" configuration job,
  930. // the current configuration will be replaced with the default configuration.
  931. //
  932. // There are three possible configuration states: custom, default, and
  933. // default pending.
  934. //
  935. // Parameters:
  936. // None.
  937. //
  938. // Returns:
  939. // Nothing.
  940. //
  941. //**********************************************************************
  942. void CEventTrapDlg::OnRadioDefault()
  943. {
  944. CheckRadioButton(IDC_RADIO_CUSTOM, IDC_RADIO_DEFAULT, IDC_RADIO_DEFAULT);
  945. // When the "Default" configuration is slected, the user is not allowed
  946. // to edit the event list, so if the extended dialog view is currently
  947. // being displayed, it is flipped back to the non-extended state and
  948. // the edit button is disabled.
  949. if (m_bExtendedView) {
  950. OnView();
  951. }
  952. m_btnView.EnableWindow(FALSE);
  953. // Mark the registry with the current config type so that when the
  954. // SMS event to trap job comes, it knows that it can overwrite the
  955. // current settings.
  956. g_reg.SetConfigType(CONFIG_TYPE_DEFAULT);
  957. // Update the dialog title to indicate the configuration state.
  958. UpdateDialogTitle();
  959. }
  960. //**********************************************************************
  961. // CEventTrapDlg::UpdateDialogTitle
  962. //
  963. // This method updates the dialog's title. The format of the title is
  964. //
  965. // Event to Trap Translator - Machine Name - [configuration type]
  966. //
  967. // If the registry of the local machine is being edited, then the
  968. // machine name is omitted.
  969. //
  970. // Parameters:
  971. // None.
  972. //
  973. // Returns:
  974. // Nothing.
  975. //
  976. //**********************************************************************
  977. void CEventTrapDlg::UpdateDialogTitle()
  978. {
  979. // Map the configuration type to a string-table resource id.
  980. LONG idsConfigType;
  981. switch(g_reg.GetConfigType()) {
  982. case CONFIG_TYPE_CUSTOM:
  983. idsConfigType = IDS_CONFIGTYPE_CUSTOM;
  984. break;
  985. case CONFIG_TYPE_DEFAULT:
  986. idsConfigType = IDS_CONFIGTYPE_DEFAULT;
  987. break;
  988. case CONFIG_TYPE_DEFAULT_PENDING:
  989. idsConfigType = IDS_CONFIGTYPE_DEFAULT_PENDING;
  990. break;
  991. default:
  992. ASSERT(FALSE);
  993. break;
  994. }
  995. CString sConfigType;
  996. sConfigType.LoadString(idsConfigType);
  997. CString sCaption = m_sBaseDialogCaption;
  998. if (!g_reg.m_sComputerName.IsEmpty()) {
  999. sCaption = sCaption + _T(" - ") + g_reg.m_sComputerName;
  1000. }
  1001. sCaption = sCaption + _T(" - [") + sConfigType + _T(']');
  1002. SetWindowText(sCaption);
  1003. }
  1004. void CEventTrapDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
  1005. {
  1006. // TODO: Add your message handler code here and/or call default
  1007. CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
  1008. }
  1009. BOOL CEventTrapDlg::OnHelpInfo(HELPINFO* pHelpInfo)
  1010. {
  1011. if (pHelpInfo->iContextType == HELPINFO_WINDOW)
  1012. {
  1013. ::WinHelp ((HWND)pHelpInfo->hItemHandle,
  1014. AfxGetApp()->m_pszHelpFilePath,
  1015. HELP_WM_HELP,
  1016. (ULONG_PTR)g_aHelpIDs_IDD_EVNTTRAPDLG);
  1017. }
  1018. return TRUE;
  1019. }
  1020. void CEventTrapDlg::OnContextMenu(CWnd* pWnd, CPoint point)
  1021. {
  1022. CMenu contextMenus;
  1023. if (this == pWnd)
  1024. return;
  1025. contextMenus.LoadMenu(IDR_CTXMENUS);
  1026. if (pWnd->m_hWnd == m_lcEvents.m_hWnd)
  1027. {
  1028. CMenu * pMenuLcEvents;
  1029. pMenuLcEvents = contextMenus.GetSubMenu(0);
  1030. if (pMenuLcEvents != NULL)
  1031. {
  1032. if (!m_lcEvents.HasSelection())
  1033. {
  1034. pMenuLcEvents->EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);
  1035. pMenuLcEvents->EnableMenuItem(3, MF_GRAYED | MF_BYPOSITION);
  1036. pMenuLcEvents->EnableMenuItem(5, MF_GRAYED | MF_BYPOSITION);
  1037. }
  1038. pMenuLcEvents->TrackPopupMenu(
  1039. TPM_LEFTALIGN | TPM_LEFTBUTTON,
  1040. point.x,
  1041. point.y,
  1042. this,
  1043. NULL);
  1044. }
  1045. }
  1046. else if (pWnd->m_hWnd == m_lcSource.m_hWnd)
  1047. {
  1048. CMenu *pMenuLcSource;
  1049. pMenuLcSource = contextMenus.GetSubMenu(1);
  1050. if (pMenuLcSource != NULL)
  1051. {
  1052. if (m_lcSource.GetNextItem(-1, LVNI_SELECTED) == -1)
  1053. {
  1054. pMenuLcSource->EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);
  1055. }
  1056. pMenuLcSource->TrackPopupMenu(
  1057. TPM_LEFTALIGN | TPM_LEFTBUTTON,
  1058. point.x,
  1059. point.y,
  1060. this,
  1061. NULL);
  1062. }
  1063. }
  1064. else
  1065. {
  1066. ::WinHelp (pWnd->m_hWnd,
  1067. AfxGetApp()->m_pszHelpFilePath,
  1068. HELP_CONTEXTMENU,
  1069. (ULONG_PTR)g_aHelpIDs_IDD_EVNTTRAPDLG);
  1070. }
  1071. }
  1072. void CEventTrapDlg::OnDefault()
  1073. {
  1074. HTREEITEM hti;
  1075. DWORD ctrlID = GetFocus()->GetDlgCtrlID();
  1076. switch(ctrlID)
  1077. {
  1078. case IDC_EVENTLIST:
  1079. if (m_lcEvents.HasSelection())
  1080. OnProperties();
  1081. else
  1082. OnSettings();
  1083. break;
  1084. case IDC_TV_SOURCES:
  1085. hti = m_tcSource.GetSelectedItem();
  1086. if (hti != NULL)
  1087. m_tcSource.Expand(hti, TVE_TOGGLE);
  1088. break;
  1089. case IDC_LV_SOURCES:
  1090. OnAdd();
  1091. m_lcSource.SetFocus();
  1092. break;
  1093. case IDC_RADIO_CUSTOM:
  1094. OnRadioDefault();
  1095. m_btnConfigTypeDefault.SetFocus();
  1096. break;
  1097. case IDC_RADIO_DEFAULT:
  1098. OnRadioCustom();
  1099. m_btnConfigTypeCustom.SetFocus();
  1100. break;
  1101. default:
  1102. OnOK();
  1103. }
  1104. }
  1105. void CEventTrapDlg::OnTvSourcesExpanded(NMHDR* pNMHDR, LRESULT* pResult)
  1106. {
  1107. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  1108. INT nImage = (pNMTreeView->itemNew.state & TVIS_EXPANDED) ?
  1109. 1 : // node is expanded -> 'open' folder icon is the second in the list
  1110. 0 ; // node is contracted -> 'close' folder icon is the first in the list
  1111. // TODO: Add your control notification handler code here
  1112. m_tcSource.SetItemImage(pNMTreeView->itemNew.hItem, nImage, nImage);
  1113. *pResult = 0;
  1114. }
  1115.