DynDialogEx.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. // DynDialogItemEx.cpp: implementation of the CDynDialogItemEx class.
  2. //
  3. // Written by Marcel Scherpenisse
  4. // mailto:Marcel_Scherpenisse@insad.nl
  5. //
  6. // This code may be used in compiled form in any way you desire. This
  7. // file may be redistributed unmodified by any means PROVIDING it is
  8. // not sold for profit without the authors written consent, and
  9. // providing that this notice and the authors name and all copyright
  10. // notices remains intact. If the source code in this file is used in
  11. // any commercial application then a statement along the lines of
  12. // "Portions copyright (c) Marcel Scherpenisse, 2002" must be included in
  13. // the startup banner, "About" box or printed documentation. An email
  14. // letting me know that you are using it would be nice as well.
  15. //
  16. // This file is provided "as is" with no expressed or implied warranty.
  17. // The author accepts no liability for any damage/loss of business that
  18. // this product may cause.
  19. //
  20. // Expect bugs!
  21. //////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "DynDialogEx.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CDynDialogEx dialog
  31. CDynDialogEx::CDynDialogEx(CWnd* pParent /*=NULL*/)
  32. : CDialog()
  33. {
  34. //{{AFX_DATA_INIT(CDynDialogEx)
  35. // NOTE: the ClassWizard will add member initialization here
  36. //}}AFX_DATA_INIT
  37. m_DialogTemplate.style = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_SETFONT;
  38. m_DialogTemplate.dwExtendedStyle = WS_EX_DLGMODALFRAME;
  39. m_DialogTemplate.x = 0;
  40. m_DialogTemplate.y = 0;
  41. m_DialogTemplate.cx = 0; // 4 horizontal units are the width of one character
  42. m_DialogTemplate.cy = 0; // 8 vertical units are the height of one character
  43. m_DialogTemplate.cdit = 0; // nr of dialog items in the dialog
  44. m_pParentWnd = pParent;
  45. m_strCaption = _T("");
  46. m_pFont = NULL;
  47. m_wFontSize = 0;
  48. m_nCurRow = FIRSTROW1;
  49. m_bAddSystemButtons = TRUE;
  50. m_bIsFontCreated = FALSE;
  51. m_bModelessDlg = FALSE;
  52. }
  53. CDynDialogEx::~CDynDialogEx()
  54. {
  55. CDynDialogItemEx *pDynDialogItemEx = NULL;
  56. for (INT_PTR i = m_arrDlgItemPtr.GetSize() - 1; i >= 0; i--) {
  57. pDynDialogItemEx = m_arrDlgItemPtr[i];
  58. if (pDynDialogItemEx != NULL) {
  59. delete pDynDialogItemEx;
  60. pDynDialogItemEx = NULL;
  61. }
  62. }
  63. if (m_bIsFontCreated) {
  64. delete m_pFont;
  65. }
  66. }
  67. CWnd *CDynDialogEx::GetParent()
  68. {
  69. return m_pParentWnd;
  70. }
  71. void CDynDialogEx::AddStyles(DWORD dwStyles)
  72. {
  73. m_DialogTemplate.style |= dwStyles;
  74. }
  75. void CDynDialogEx::RemoveStyles(DWORD dwStyles)
  76. {
  77. m_DialogTemplate.style &= (~dwStyles);
  78. }
  79. void CDynDialogEx::DoDataExchange(CDataExchange* pDX)
  80. {
  81. CDialog::DoDataExchange(pDX);
  82. //{{AFX_DATA_MAP(CDynDialogEx)
  83. // NOTE: the ClassWizard will add DDX and DDV calls here
  84. //}}AFX_DATA_MAP
  85. CDynDialogItemEx *pDynDialogItemEx = NULL;
  86. for (INT_PTR i = m_arrDlgItemPtr.GetSize() - 1; i >= 0; i--) {
  87. pDynDialogItemEx = m_arrDlgItemPtr[i];
  88. if (pDynDialogItemEx != NULL) {
  89. pDynDialogItemEx->DoDataExchange(pDX);
  90. }
  91. }
  92. }
  93. BEGIN_MESSAGE_MAP(CDynDialogEx, CDialog)
  94. //{{AFX_MSG_MAP(CDynDialogEx)
  95. ON_WM_CREATE()
  96. //}}AFX_MSG_MAP
  97. ON_MESSAGE(WM_HELP, OnHelpMsg)
  98. ON_WM_MEASUREITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
  99. ON_WM_DRAWITEM() // TMB! 06-12-2001 Adjusted.. was wrongly an ON_MESSAGE()!!
  100. END_MESSAGE_MAP()
  101. /////////////////////////////////////////////////////////////////////////////
  102. // CDynDialogEx message handlers
  103. int CDynDialogEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
  104. {
  105. if (CDialog::OnCreate(lpCreateStruct) == -1)
  106. return -1;
  107. //if we have no font, create one here
  108. if (m_pFont == NULL) {
  109. LOGFONT LogFont;
  110. // Can do better???
  111. memset(&LogFont, 0x00, sizeof(LogFont));
  112. strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
  113. LogFont.lfHeight = 8;
  114. m_pFont = new CFont;
  115. m_pFont->CreateFontIndirect(&LogFont);
  116. SetFont(m_pFont);
  117. m_bIsFontCreated = TRUE;
  118. }
  119. //Create all the controls on the dialog
  120. CDynDialogItemEx *pDynDialogItemEx = NULL;
  121. for (int i = 0; i < m_arrDlgItemPtr.GetSize(); i++) {
  122. pDynDialogItemEx = m_arrDlgItemPtr[i];
  123. if (pDynDialogItemEx != NULL) {
  124. if (!pDynDialogItemEx->IsDlgItemSubclassed()) {
  125. if (!pDynDialogItemEx->CreateEx(this)) {
  126. AfxMessageBox(_T("Failed to create DlgItem."));
  127. }
  128. else if (pDynDialogItemEx->GetSafeHwnd() != NULL) {
  129. pDynDialogItemEx->SetFont(m_pFont, FALSE);
  130. }
  131. }
  132. }
  133. }
  134. return 0;
  135. }
  136. BOOL CDynDialogEx::OnInitDialog()
  137. {
  138. //Reposition all the controls on the dialog...
  139. CDynDialogItemEx *pDynDialogItemEx = NULL;
  140. for (int i = 0; i < m_arrDlgItemPtr.GetSize(); i++) {
  141. pDynDialogItemEx = m_arrDlgItemPtr[i];
  142. if (pDynDialogItemEx != NULL) {
  143. if (!pDynDialogItemEx->IsDlgItemSubclassed() && !pDynDialogItemEx->SetWindowPos(this)) {
  144. CString strMessage;
  145. strMessage.Format(_T("Failed SetWindowPos for control %s."), pDynDialogItemEx->GetClassName());
  146. AfxMessageBox(strMessage);
  147. }
  148. }
  149. }
  150. CDialog::OnInitDialog();
  151. CenterWindow();
  152. return TRUE; // return TRUE unless you set the focus to a control
  153. // EXCEPTION: OCX Property Pages should return FALSE
  154. }
  155. int CDynDialogEx::DoModal()
  156. {
  157. //Do we need OK and Cancel buttons??
  158. if (m_bAddSystemButtons) {
  159. AddSystemButtons();
  160. }
  161. //
  162. // Get font info from mainwindow of the application
  163. //
  164. CFont* pParentFont = m_pFont;
  165. if (pParentFont == NULL && m_pParentWnd != NULL) {
  166. pParentFont = m_pParentWnd->GetFont();
  167. }
  168. if (pParentFont == NULL && AfxGetApp()->m_pActiveWnd != NULL) {
  169. pParentFont = AfxGetApp()->m_pActiveWnd->GetFont();
  170. }
  171. LOGFONT LogFont;
  172. memset(&LogFont, 0x00, sizeof(LogFont));
  173. if (pParentFont != NULL) {
  174. pParentFont->GetLogFont(&LogFont);
  175. }
  176. else {
  177. // Can do better???
  178. strncpy(LogFont.lfFaceName, _T("MS Sans Serif"), LF_FACESIZE);
  179. LogFont.lfHeight = 8;
  180. }
  181. //Prework for setting font in dialog...
  182. int cWC = MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, NULL, 0);
  183. int nFontNameLen = cWC + 1;
  184. WCHAR *szFontName = new WCHAR[nFontNameLen];
  185. // Copy the string
  186. MultiByteToWideChar(CP_ACP, 0, LogFont.lfFaceName, -1, (LPWSTR) szFontName, cWC);
  187. szFontName[cWC] = 0;
  188. nFontNameLen = (cWC) * sizeof(WCHAR);
  189. if (m_wFontSize == 0) {
  190. m_wFontSize = (unsigned short)LogFont.lfHeight;
  191. }
  192. //Prework for setting caption in dialog...
  193. cWC = MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, NULL, 0);
  194. int szBoxLen = cWC + 1;
  195. WCHAR *szBoxCaption = new WCHAR[szBoxLen];
  196. // Copy the string
  197. MultiByteToWideChar(CP_ACP, 0, m_strCaption, -1, (LPWSTR) szBoxCaption, cWC);
  198. szBoxCaption[cWC] = 0;
  199. szBoxLen = (cWC) * sizeof(WCHAR);
  200. INT_PTR iRet = -1;
  201. //Here 's the stuff to build the dialog template in memory
  202. //without the controls being in the template
  203. //(Our first try, was this same template with some additional code
  204. //for each control placed on it, that's why this class is cold Ex :)
  205. //This gave some problems on WIN9x systems, where EDIT boxes
  206. //were not shown with 3D-look, but as flat controls)
  207. int nBufferSize = sizeof(DLGTEMPLATE) + (2 * sizeof(WORD)) /*menu and class*/ + szBoxLen /*size of caption*/
  208. + sizeof(WORD) /*fontsize*/ + nFontNameLen /*size of fontname*/;
  209. //Are there any subclassed controls...
  210. if (m_DialogTemplate.cdit > 0) {
  211. nBufferSize = (nBufferSize + 3) & ~3; // adjust size to make first control DWORD aligned
  212. CDynDialogItemEx *pDynDialogItemEx = NULL;
  213. for (int i = 0; i < m_arrDlgItemPtr.GetSize(); i++) {
  214. pDynDialogItemEx = m_arrDlgItemPtr[i];
  215. if (pDynDialogItemEx != NULL) {
  216. if (pDynDialogItemEx->IsDlgItemSubclassed()) {
  217. int nItemLength = sizeof(DLGITEMTEMPLATE) + 3 * sizeof(WORD);
  218. nItemLength += (pDynDialogItemEx->GetCaptionLength() + 1) * sizeof(WCHAR);
  219. if (i != m_DialogTemplate.cdit - 1) { // the last control does not need extra bytes
  220. nItemLength = (nItemLength + 3) & ~3; // take into account gap so next control is DWORD aligned
  221. }
  222. nBufferSize += nItemLength;
  223. }
  224. }
  225. }
  226. }
  227. HLOCAL hLocal = LocalAlloc(LHND, nBufferSize);
  228. if (hLocal != NULL) {
  229. BYTE* pBuffer = (BYTE*)LocalLock(hLocal);
  230. if (pBuffer == NULL) {
  231. LocalFree(hLocal);
  232. AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalLock Failed"));
  233. }
  234. BYTE *pdest = pBuffer;
  235. // transfer DLGTEMPLATE structure to the buffer
  236. memcpy(pdest, &m_DialogTemplate, sizeof(DLGTEMPLATE)); // DLGTemplate
  237. pdest += sizeof(DLGTEMPLATE);
  238. *(WORD*)pdest = 0; // no menu -- WORD to say it is 0 bytes
  239. pdest += sizeof(WORD); // Increment
  240. *(WORD*)(pdest + 1) = 0; // use default window class -- WORD to say it is 0 bytes
  241. pdest += sizeof(WORD); // Increment
  242. memcpy(pdest, szBoxCaption, szBoxLen); // Caption
  243. pdest += szBoxLen;
  244. *(WORD*)pdest = m_wFontSize; // font size
  245. pdest += sizeof(WORD);
  246. memcpy(pdest, szFontName, nFontNameLen); // font name
  247. pdest += nFontNameLen;
  248. // will now transfer the information for each one of subclassed controls...
  249. if (m_DialogTemplate.cdit > 0) {
  250. CDynDialogItemEx *pDynDialogItemEx = NULL;
  251. for (int i = 0; i < m_arrDlgItemPtr.GetSize(); i++) {
  252. pDynDialogItemEx = m_arrDlgItemPtr[i];
  253. if (pDynDialogItemEx != NULL) {
  254. if (pDynDialogItemEx->IsDlgItemSubclassed()) {
  255. pdest = pDynDialogItemEx->FillBufferWithItemTemplate(pdest);
  256. }
  257. }
  258. }
  259. }
  260. ASSERT(pdest - pBuffer == nBufferSize); // just make sure we did not overrun the heap
  261. //Next lines to make sure that MFC makes no ASSERTION when PREVIOUS/NEXT is pressed:)
  262. if (m_lpDialogTemplate != NULL) {
  263. m_lpDialogTemplate = NULL;
  264. }
  265. //These are the MFC functions, which do the job...
  266. if (m_bModelessDlg) {
  267. iRet = CreateIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
  268. }
  269. else {
  270. InitModalIndirect((LPDLGTEMPLATE)pBuffer, m_pParentWnd);
  271. iRet = CDialog::DoModal();
  272. }
  273. LocalUnlock(hLocal);
  274. LocalFree(hLocal);
  275. delete [] szBoxCaption;
  276. delete [] szFontName;
  277. return iRet;
  278. }
  279. else {
  280. AfxMessageBox(_T("CDynDialogEx::DoModal() : LocalAllock Failed"));
  281. return -1;
  282. }
  283. }
  284. void CDynDialogEx::SetFont(CFont *pFont)
  285. {
  286. m_pFont = pFont;
  287. }
  288. CFont *CDynDialogEx::GetFont()
  289. {
  290. return m_pFont;
  291. }
  292. void CDynDialogEx::SetFontSize(WORD wSize)
  293. {
  294. m_wFontSize = wSize;
  295. }
  296. WORD CDynDialogEx::GetFontSize()
  297. {
  298. return m_wFontSize;
  299. }
  300. void CDynDialogEx::SetUseSystemButtons(BOOL bUse /*= TRUE*/)
  301. {
  302. m_bAddSystemButtons = bUse;
  303. }
  304. void CDynDialogEx::GetDlgRect(LPRECT lpRect)
  305. {
  306. ASSERT(lpRect);
  307. lpRect->left = m_DialogTemplate.x;
  308. lpRect->top = m_DialogTemplate.y;
  309. lpRect->right = lpRect->left + m_DialogTemplate.cx;
  310. lpRect->bottom = lpRect->top + m_DialogTemplate.cy;
  311. }
  312. void CDynDialogEx::SetDlgRect(LPRECT lpRect)
  313. {
  314. ASSERT(lpRect);
  315. //#pragma warning(disable : 4244)
  316. m_DialogTemplate.cx = (short)(lpRect->right - lpRect->left);
  317. m_DialogTemplate.cy = (short)(lpRect->bottom - lpRect->top);
  318. m_DialogTemplate.x = (short)(lpRect->left);
  319. m_DialogTemplate.y = (short)(lpRect->top);
  320. //#pragma warning(default : 4244)
  321. }
  322. void CDynDialogEx::SetDlgRectangle(LPRECT pRect)
  323. {
  324. RECT rect;
  325. GetDlgRect(&rect);
  326. if (rect.left > pRect->left) {
  327. rect.left = pRect->left;
  328. }
  329. if (rect.right < pRect->right) {
  330. rect.right = pRect->right + 5;
  331. }
  332. if (rect.top > pRect->top) {
  333. rect.top = pRect->top;
  334. }
  335. if (rect.bottom < pRect->bottom) {
  336. rect.bottom = pRect->bottom + 5;
  337. }
  338. SetDlgRect(&rect);
  339. }
  340. UINT CDynDialogEx::AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl,
  341. LPCTSTR lpszCaption,
  342. DWORD dwStyle,
  343. DWORD dwExtendedStyle,
  344. LPRECT pRect /*= NULL*/,
  345. void *pData /*= NULL*/,
  346. UINT nID /*= 0*/)
  347. {
  348. UINT nRet = 0;
  349. //In case no rectangle given create our own...
  350. CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
  351. //if no rectangle given use our own...
  352. if (pRect == NULL) {
  353. pRect = &Rect;
  354. }
  355. // else {
  356. // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
  357. // }
  358. m_nCurRow += (ROWSTEPSIZE);
  359. //Update dialogtemplate boundaries
  360. SetDlgRectangle(pRect);
  361. //Create control and add to array of controls
  362. CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
  363. if (pDynDialogItemEx != NULL) {
  364. nRet = pDynDialogItemEx->InitDialogItem(TypeControl, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
  365. m_arrDlgItemPtr.Add(pDynDialogItemEx);
  366. }
  367. //Return ID of Control we created.
  368. return nRet;
  369. }
  370. UINT CDynDialogEx::AddDlgControl(LPCSTR lpszClassName,
  371. LPCTSTR lpszCaption,
  372. DWORD dwStyle,
  373. DWORD dwExtendedStyle,
  374. LPRECT pRect /*= NULL*/,
  375. void *pData /*= NULL*/,
  376. UINT nID /*= 0*/)
  377. {
  378. UINT nRet = 0;
  379. //In case no rectangle given create our own...
  380. CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
  381. //if no rectangle given use our own...
  382. if (pRect == NULL) {
  383. pRect = &Rect;
  384. Rect.right += INPUTCOL;
  385. }
  386. // else {
  387. // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
  388. // }
  389. m_nCurRow += (ROWSTEPSIZE);
  390. //Update dialogtemplate boundaries
  391. SetDlgRectangle(pRect);
  392. //Create control and add to array of controls
  393. CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
  394. if (pDynDialogItemEx != NULL) {
  395. nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData);
  396. m_arrDlgItemPtr.Add(pDynDialogItemEx);
  397. }
  398. //Return ID of Control we created.
  399. return nRet;
  400. }
  401. UINT CDynDialogEx::AddSubclassedDlgControl(LPCSTR lpszClassName,
  402. LPCTSTR lpszCaption,
  403. DWORD dwStyle,
  404. DWORD dwExtendedStyle,
  405. LPRECT pRect /*= NULL*/,
  406. UINT nID /*= 0*/)
  407. {
  408. UINT nRet = 0;
  409. //In case no rectangle given create our own...
  410. CRect Rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2, m_nCurRow + ROWSTEPSIZE);
  411. //if no rectangle given use our own...
  412. if (pRect == NULL) {
  413. pRect = &Rect;
  414. Rect.right += INPUTCOL;
  415. }
  416. // else {
  417. // m_nCurRow = max(m_nCurRow, pRect->bottom) - m_nCurRow;
  418. // }
  419. m_nCurRow += (ROWSTEPSIZE);
  420. //Update dialogtemplate boundaries
  421. SetDlgRectangle(pRect);
  422. //Create control and add to array of controls
  423. CDynDialogItemEx *pDynDialogItemEx = new CDynDialogItemEx;
  424. if (pDynDialogItemEx != NULL) {
  425. nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, TRUE);
  426. m_arrDlgItemPtr.Add(pDynDialogItemEx);
  427. m_DialogTemplate.cdit++;
  428. }
  429. //Return ID of Control we created.
  430. return nRet;
  431. }
  432. void CDynDialogEx::AddSystemButtons()
  433. {
  434. m_nCurRow += 6; // Leave some room!
  435. CRect rect(FIXEDCOL1, m_nCurRow, FIXEDCOL2 - 60, m_nCurRow + (long)(ROWSTEPSIZE * 1.2));
  436. AddDlgControl(BUTTON, _T("OK"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDOK);
  437. // This has to be revised later.
  438. rect.left += 55;
  439. rect.right += 55;
  440. AddDlgControl(BUTTON, _T("Annuleren"), STYLE_BUTTON, EXSTYLE_BUTTON, &rect, NULL, IDCANCEL);
  441. }
  442. void CDynDialogEx::SetWindowTitle(LPCSTR lpszCaption)
  443. {
  444. m_strCaption = lpszCaption;
  445. }
  446. void CDynDialogEx::SetUseModeless(BOOL bModelessDlg /*= TRUE*/)
  447. {
  448. m_bModelessDlg = bModelessDlg;
  449. }
  450. void CDynDialogEx::OnCancel()
  451. {
  452. if (m_bModelessDlg) {
  453. DestroyWindow();
  454. }
  455. else {
  456. CDialog::OnCancel();
  457. }
  458. }
  459. void CDynDialogEx::OnOK()
  460. {
  461. if (m_bModelessDlg) {
  462. DestroyWindow();
  463. }
  464. else {
  465. CDialog::OnOK();
  466. }
  467. }
  468. BOOL CDynDialogEx::OnCommand(WPARAM wParam, LPARAM lParam)
  469. {
  470. //wParam
  471. //The low-order word of wParam identifies the command ID of the menu item, control, or accelerator.
  472. //The high-order word of wParam specifies the notification message if the message is from a control.
  473. //If the message is from an accelerator, the high-order word is 1.
  474. //If the message is from a menu, the high-order word is 0.
  475. //lParam
  476. //Identifies the control that sends the message if the message is from a control. Otherwise, lParam is 0.
  477. WORD wControlID = LOWORD(wParam);
  478. WORD wMessageID = HIWORD(wParam);
  479. if (wControlID != 0) {
  480. switch (wControlID) {
  481. case IDOK:
  482. OnOK();
  483. return TRUE;
  484. break;
  485. case IDCANCEL:
  486. OnCancel();
  487. return TRUE;
  488. break;
  489. default:
  490. //if we have a parent send the message to the parent, so we can handle the message over there.
  491. if (m_pParentWnd != NULL) {
  492. ::SendMessage(m_pParentWnd->GetSafeHwnd(), WM_COMMAND, wParam, lParam);
  493. }
  494. break;
  495. }
  496. }
  497. return CDialog::OnCommand(wParam, lParam);
  498. }
  499. // Hellup!
  500. afx_msg LRESULT CDynDialogEx::OnHelpMsg(WPARAM wParam, LPARAM lParam)
  501. {
  502. //lParam <<-- Contains: (LPHELPINFO)lParam
  503. // >> typedef struct tagHELPINFO {
  504. // UINT cbSize;
  505. // int iContextType
  506. // int iCtrlId;
  507. // HANDLE hItemHandle;
  508. // DWORD dwContextId;
  509. // POINT MousePos;
  510. // } HELPINFO, FAR *LPHELPINFO;
  511. //
  512. // User pressed F1 in dialog, call the OnHelp() function, this can be overridden...
  513. //
  514. OnHelp();
  515. return TRUE;
  516. }
  517. // Default implementation of the OnHelp()
  518. // This one is to be overridden by a caller ;)
  519. void CDynDialogEx::OnHelp()
  520. {
  521. CDialog::OnHelp();
  522. }