dlgcore.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #include "occimpl.h"
  12. #ifdef AFX_CORE1_SEG
  13. #pragma code_seg(AFX_CORE1_SEG)
  14. #endif
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. #define new DEBUG_NEW
  20. /////////////////////////////////////////////////////////////////////////////
  21. // AfxDlgProc - does nothing since all messages are handled via AfxWndProc
  22. BOOL CALLBACK AfxDlgProc(HWND hWnd, UINT message, WPARAM, LPARAM)
  23. {
  24. if (message == WM_INITDIALOG)
  25. {
  26. // special case for WM_INITDIALOG
  27. CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, CWnd::FromHandlePermanent(hWnd));
  28. if (pDlg != NULL)
  29. return pDlg->OnInitDialog();
  30. else
  31. return 1;
  32. }
  33. return 0;
  34. }
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CDialog - Modeless and Modal
  37. BEGIN_MESSAGE_MAP(CDialog, CWnd)
  38. #ifndef _AFX_NO_GRAYDLG_SUPPORT
  39. ON_WM_CTLCOLOR()
  40. #endif
  41. //{{AFX_MSG_MAP(CDialog)
  42. ON_COMMAND(IDOK, OnOK)
  43. ON_COMMAND(IDCANCEL, OnCancel)
  44. ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
  45. ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
  46. ON_MESSAGE(WM_INITDIALOG, HandleInitDialog)
  47. ON_MESSAGE(WM_SETFONT, HandleSetFont)
  48. //}}AFX_MSG_MAP
  49. #ifndef _AFX_NO_CTL3D_SUPPORT
  50. ON_MESSAGE(WM_QUERY3DCONTROLS, OnQuery3dControls)
  51. #endif
  52. END_MESSAGE_MAP()
  53. BOOL CDialog::PreTranslateMessage(MSG* pMsg)
  54. {
  55. // for modeless processing (or modal)
  56. ASSERT(m_hWnd != NULL);
  57. // allow tooltip messages to be filtered
  58. if (CWnd::PreTranslateMessage(pMsg))
  59. return TRUE;
  60. // don't translate dialog messages when in Shift+F1 help mode
  61. CFrameWnd* pFrameWnd = GetTopLevelFrame();
  62. if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
  63. return FALSE;
  64. // fix around for VK_ESCAPE in a multiline Edit that is on a Dialog
  65. // that doesn't have a cancel or the cancel is disabled.
  66. if (pMsg->message == WM_KEYDOWN &&
  67. (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_CANCEL) &&
  68. (::GetWindowLong(pMsg->hwnd, GWL_STYLE) & ES_MULTILINE) &&
  69. _AfxCompareClassName(pMsg->hwnd, _T("Edit")))
  70. {
  71. HWND hItem = ::GetDlgItem(m_hWnd, IDCANCEL);
  72. if (hItem == NULL || ::IsWindowEnabled(hItem))
  73. {
  74. SendMessage(WM_COMMAND, IDCANCEL, 0);
  75. return TRUE;
  76. }
  77. }
  78. // filter both messages to dialog and from children
  79. return PreTranslateInput(pMsg);
  80. }
  81. BOOL CDialog::OnCmdMsg(UINT nID, int nCode, void* pExtra,
  82. AFX_CMDHANDLERINFO* pHandlerInfo)
  83. {
  84. if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  85. return TRUE;
  86. if ((nCode != CN_COMMAND && nCode != CN_UPDATE_COMMAND_UI) ||
  87. !IS_COMMAND_ID(nID) || nID >= 0xf000)
  88. {
  89. // control notification or non-command button or system command
  90. return FALSE; // not routed any further
  91. }
  92. // if we have an owner window, give it second crack
  93. CWnd* pOwner = GetParent();
  94. if (pOwner != NULL)
  95. {
  96. #ifdef _DEBUG
  97. if (afxTraceFlags & traceCmdRouting)
  98. TRACE1("Routing command id 0x%04X to owner window.\n", nID);
  99. #endif
  100. ASSERT(pOwner != this);
  101. if (pOwner->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  102. return TRUE;
  103. }
  104. // last crack goes to the current CWinThread object
  105. CWinThread* pThread = AfxGetThread();
  106. if (pThread != NULL)
  107. {
  108. #ifdef _DEBUG
  109. if (afxTraceFlags & traceCmdRouting)
  110. TRACE1("Routing command id 0x%04X to app.\n", nID);
  111. #endif
  112. if (pThread->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  113. return TRUE;
  114. }
  115. #ifdef _DEBUG
  116. if (afxTraceFlags & traceCmdRouting)
  117. {
  118. TRACE2("IGNORING command id 0x%04X sent to %hs dialog.\n", nID,
  119. GetRuntimeClass()->m_lpszClassName);
  120. }
  121. #endif
  122. return FALSE;
  123. }
  124. /////////////////////////////////////////////////////////////////////////////
  125. // Modeless Dialogs have 2-phase construction
  126. CDialog::CDialog()
  127. {
  128. ASSERT(m_hWnd == NULL);
  129. AFX_ZERO_INIT_OBJECT(CWnd);
  130. }
  131. CDialog::~CDialog()
  132. {
  133. if (m_hWnd != NULL)
  134. {
  135. TRACE0("Warning: calling DestroyWindow in CDialog::~CDialog --\n");
  136. TRACE0("\tOnDestroy or PostNcDestroy in derived class will not be called.\n");
  137. DestroyWindow();
  138. }
  139. }
  140. BOOL CDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
  141. {
  142. ASSERT(HIWORD(lpszTemplateName) == 0 ||
  143. AfxIsValidString(lpszTemplateName));
  144. m_lpszTemplateName = lpszTemplateName; // used for help
  145. if (HIWORD(m_lpszTemplateName) == 0 && m_nIDHelp == 0)
  146. m_nIDHelp = LOWORD((DWORD)m_lpszTemplateName);
  147. #ifdef _DEBUG
  148. if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE))
  149. {
  150. ASSERT(FALSE); // invalid dialog template name
  151. PostNcDestroy(); // cleanup if Create fails too soon
  152. return FALSE;
  153. }
  154. #endif //_DEBUG
  155. HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);
  156. HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);
  157. HGLOBAL hTemplate = LoadResource(hInst, hResource);
  158. BOOL bResult = CreateIndirect(hTemplate, pParentWnd, hInst);
  159. FreeResource(hTemplate);
  160. return bResult;
  161. }
  162. // for backward compatibility
  163. BOOL CDialog::CreateIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd)
  164. {
  165. return CreateIndirect(hDialogTemplate, pParentWnd, NULL);
  166. }
  167. BOOL CDialog::CreateIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd,
  168. HINSTANCE hInst)
  169. {
  170. ASSERT(hDialogTemplate != NULL);
  171. LPCDLGTEMPLATE lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
  172. BOOL bResult = CreateIndirect(lpDialogTemplate, pParentWnd, NULL, hInst);
  173. UnlockResource(hDialogTemplate);
  174. return bResult;
  175. }
  176. // for backward compatibility
  177. BOOL CDialog::CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd,
  178. void* lpDialogInit)
  179. {
  180. return CreateIndirect(lpDialogTemplate, pParentWnd, lpDialogInit, NULL);
  181. }
  182. BOOL CDialog::CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd,
  183. void* lpDialogInit, HINSTANCE hInst)
  184. {
  185. ASSERT(lpDialogTemplate != NULL);
  186. if (pParentWnd == NULL)
  187. pParentWnd = AfxGetMainWnd();
  188. m_lpDialogInit = lpDialogInit;
  189. return CreateDlgIndirect(lpDialogTemplate, pParentWnd, hInst);
  190. }
  191. BOOL CWnd::CreateDlg(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
  192. {
  193. // load resource
  194. LPCDLGTEMPLATE lpDialogTemplate = NULL;
  195. HGLOBAL hDialogTemplate = NULL;
  196. HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG);
  197. HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);
  198. hDialogTemplate = LoadResource(hInst, hResource);
  199. if (hDialogTemplate != NULL)
  200. lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
  201. ASSERT(lpDialogTemplate != NULL);
  202. // create a modeless dialog
  203. BOOL bSuccess = CreateDlgIndirect(lpDialogTemplate, pParentWnd, hInst);
  204. // free resource
  205. UnlockResource(hDialogTemplate);
  206. FreeResource(hDialogTemplate);
  207. return bSuccess;
  208. }
  209. // for backward compatibility
  210. BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd)
  211. {
  212. return CreateDlgIndirect(lpDialogTemplate, pParentWnd, NULL);
  213. }
  214. BOOL CWnd::CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate,
  215. CWnd* pParentWnd, HINSTANCE hInst)
  216. {
  217. ASSERT(lpDialogTemplate != NULL);
  218. if (pParentWnd != NULL)
  219. ASSERT_VALID(pParentWnd);
  220. if (hInst == NULL)
  221. hInst = AfxGetInstanceHandle();
  222. #ifndef _AFX_NO_OCC_SUPPORT
  223. _AFX_OCC_DIALOG_INFO occDialogInfo;
  224. COccManager* pOccManager = afxOccManager;
  225. #endif
  226. HGLOBAL hTemplate = NULL;
  227. HWND hWnd = NULL;
  228. #ifdef _DEBUG
  229. DWORD dwError = 0;
  230. #endif
  231. TRY
  232. {
  233. VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));
  234. AfxDeferRegisterClass(AFX_WNDCOMMCTLSNEW_REG);
  235. #ifndef _AFX_NO_OCC_SUPPORT
  236. // separately create OLE controls in the dialog template
  237. if (pOccManager != NULL)
  238. {
  239. if (!SetOccDialogInfo(&occDialogInfo))
  240. return FALSE;
  241. lpDialogTemplate = pOccManager->PreCreateDialog(&occDialogInfo,
  242. lpDialogTemplate);
  243. }
  244. if (lpDialogTemplate == NULL)
  245. return FALSE;
  246. #endif //!_AFX_NO_OCC_SUPPORT
  247. // If no font specified, set the system font.
  248. CString strFace;
  249. WORD wSize = 0;
  250. BOOL bSetSysFont = !CDialogTemplate::GetFont(lpDialogTemplate, strFace,
  251. wSize);
  252. // On DBCS systems, also change "MS Sans Serif" or "Helv" to system font.
  253. if ((!bSetSysFont) && GetSystemMetrics(SM_DBCSENABLED))
  254. {
  255. bSetSysFont = (strFace == _T("MS Shell Dlg") ||
  256. strFace == _T("MS Sans Serif") || strFace == _T("Helv"));
  257. if (bSetSysFont && (wSize == 8))
  258. wSize = 0;
  259. }
  260. if (bSetSysFont)
  261. {
  262. CDialogTemplate dlgTemp(lpDialogTemplate);
  263. dlgTemp.SetSystemFont(wSize);
  264. hTemplate = dlgTemp.Detach();
  265. }
  266. if (hTemplate != NULL)
  267. lpDialogTemplate = (DLGTEMPLATE*)GlobalLock(hTemplate);
  268. // setup for modal loop and creation
  269. m_nModalResult = -1;
  270. m_nFlags |= WF_CONTINUEMODAL;
  271. // create modeless dialog
  272. AfxHookWindowCreate(this);
  273. hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
  274. pParentWnd->GetSafeHwnd(), AfxDlgProc);
  275. #ifdef _DEBUG
  276. dwError = ::GetLastError();
  277. #endif
  278. }
  279. CATCH_ALL(e)
  280. {
  281. DELETE_EXCEPTION(e);
  282. m_nModalResult = -1;
  283. }
  284. END_CATCH_ALL
  285. #ifndef _AFX_NO_OCC_SUPPORT
  286. if (pOccManager != NULL)
  287. {
  288. pOccManager->PostCreateDialog(&occDialogInfo);
  289. if (hWnd != NULL)
  290. SetOccDialogInfo(NULL);
  291. }
  292. #endif //!_AFX_NO_OCC_SUPPORT
  293. if (!AfxUnhookWindowCreate())
  294. PostNcDestroy(); // cleanup if Create fails too soon
  295. // handle EndDialog calls during OnInitDialog
  296. if (hWnd != NULL && !(m_nFlags & WF_CONTINUEMODAL))
  297. {
  298. ::DestroyWindow(hWnd);
  299. hWnd = NULL;
  300. }
  301. if (hTemplate != NULL)
  302. {
  303. GlobalUnlock(hTemplate);
  304. GlobalFree(hTemplate);
  305. }
  306. // help with error diagnosis (only if WM_INITDIALOG didn't EndDialog())
  307. if (hWnd == NULL && (m_nFlags & WF_CONTINUEMODAL))
  308. {
  309. #ifdef _DEBUG
  310. #ifndef _AFX_NO_OCC_SUPPORT
  311. if (afxOccManager == NULL)
  312. {
  313. TRACE0(">>> If this dialog has OLE controls:\n");
  314. TRACE0(">>> AfxEnableControlContainer has not been called yet.\n");
  315. TRACE0(">>> You should call it in your app's InitInstance function.\n");
  316. }
  317. else if (dwError != 0)
  318. {
  319. TRACE1("Warning: Dialog creation failed! GetLastError returns 0x%8.8X\n", dwError);
  320. }
  321. #endif //!_AFX_NO_OCC_SUPPORT
  322. #endif //_DEBUG
  323. return FALSE;
  324. }
  325. ASSERT(hWnd == m_hWnd);
  326. return TRUE;
  327. }
  328. #ifndef _AFX_NO_OCC_SUPPORT
  329. BOOL CDialog::SetOccDialogInfo(_AFX_OCC_DIALOG_INFO* pOccDialogInfo)
  330. {
  331. m_pOccDialogInfo = pOccDialogInfo;
  332. return TRUE;
  333. }
  334. #endif
  335. /////////////////////////////////////////////////////////////////////////////
  336. // Modal Dialogs
  337. // Modal Constructors just save parameters
  338. CDialog::CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
  339. {
  340. ASSERT(HIWORD(lpszTemplateName) == 0 ||
  341. AfxIsValidString(lpszTemplateName));
  342. AFX_ZERO_INIT_OBJECT(CWnd);
  343. m_pParentWnd = pParentWnd;
  344. m_lpszTemplateName = lpszTemplateName;
  345. if (HIWORD(m_lpszTemplateName) == 0)
  346. m_nIDHelp = LOWORD((DWORD)m_lpszTemplateName);
  347. }
  348. CDialog::CDialog(UINT nIDTemplate, CWnd* pParentWnd)
  349. {
  350. AFX_ZERO_INIT_OBJECT(CWnd);
  351. m_pParentWnd = pParentWnd;
  352. m_lpszTemplateName = MAKEINTRESOURCE(nIDTemplate);
  353. m_nIDHelp = nIDTemplate;
  354. }
  355. BOOL CDialog::InitModalIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd)
  356. {
  357. // must be called on an empty constructed CDialog
  358. ASSERT(m_lpszTemplateName == NULL);
  359. ASSERT(m_hDialogTemplate == NULL);
  360. ASSERT(hDialogTemplate != NULL);
  361. if (m_pParentWnd == NULL)
  362. m_pParentWnd = pParentWnd;
  363. m_hDialogTemplate = hDialogTemplate;
  364. return TRUE; // always ok (DoModal actually brings up dialog)
  365. }
  366. BOOL CDialog::InitModalIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd,
  367. void* lpDialogInit)
  368. {
  369. // must be called on an empty constructed CDialog
  370. ASSERT(m_lpszTemplateName == NULL);
  371. ASSERT(m_lpDialogTemplate == NULL);
  372. ASSERT(lpDialogTemplate != NULL);
  373. if (m_pParentWnd == NULL)
  374. m_pParentWnd = pParentWnd;
  375. m_lpDialogTemplate = lpDialogTemplate;
  376. m_lpDialogInit = lpDialogInit;
  377. return TRUE; // always ok (DoModal actually brings up dialog)
  378. }
  379. HWND CDialog::PreModal()
  380. {
  381. // cannot call DoModal on a dialog already constructed as modeless
  382. ASSERT(m_hWnd == NULL);
  383. // allow OLE servers to disable themselves
  384. CWinApp* pApp = AfxGetApp();
  385. if (pApp != NULL)
  386. pApp->EnableModeless(FALSE);
  387. // find parent HWND
  388. HWND hWnd = CWnd::GetSafeOwner_(m_pParentWnd->GetSafeHwnd(), &m_hWndTop);
  389. // hook for creation of dialog
  390. AfxHookWindowCreate(this);
  391. // return window to use as parent for dialog
  392. return hWnd;
  393. }
  394. void CDialog::PostModal()
  395. {
  396. AfxUnhookWindowCreate(); // just in case
  397. Detach(); // just in case
  398. // re-enable windows
  399. if (::IsWindow(m_hWndTop))
  400. ::EnableWindow(m_hWndTop, TRUE);
  401. m_hWndTop = NULL;
  402. CWinApp* pApp = AfxGetApp();
  403. if (pApp != NULL)
  404. pApp->EnableModeless(TRUE);
  405. }
  406. int CDialog::DoModal()
  407. {
  408. // can be constructed with a resource template or InitModalIndirect
  409. ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL ||
  410. m_lpDialogTemplate != NULL);
  411. // load resource as necessary
  412. LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
  413. HGLOBAL hDialogTemplate = m_hDialogTemplate;
  414. HINSTANCE hInst = AfxGetResourceHandle();
  415. if (m_lpszTemplateName != NULL)
  416. {
  417. hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
  418. HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
  419. hDialogTemplate = LoadResource(hInst, hResource);
  420. }
  421. if (hDialogTemplate != NULL)
  422. lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
  423. // return -1 in case of failure to load the dialog template resource
  424. if (lpDialogTemplate == NULL)
  425. return -1;
  426. // disable parent (before creating dialog)
  427. HWND hWndParent = PreModal();
  428. AfxUnhookWindowCreate();
  429. BOOL bEnableParent = FALSE;
  430. if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
  431. {
  432. ::EnableWindow(hWndParent, FALSE);
  433. bEnableParent = TRUE;
  434. }
  435. TRY
  436. {
  437. // create modeless dialog
  438. AfxHookWindowCreate(this);
  439. if (CreateDlgIndirect(lpDialogTemplate,
  440. CWnd::FromHandle(hWndParent), hInst))
  441. {
  442. if (m_nFlags & WF_CONTINUEMODAL)
  443. {
  444. // enter modal loop
  445. DWORD dwFlags = MLF_SHOWONIDLE;
  446. if (GetStyle() & DS_NOIDLEMSG)
  447. dwFlags |= MLF_NOIDLEMSG;
  448. VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
  449. }
  450. // hide the window before enabling the parent, etc.
  451. if (m_hWnd != NULL)
  452. SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
  453. SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
  454. }
  455. }
  456. CATCH_ALL(e)
  457. {
  458. DELETE_EXCEPTION(e);
  459. m_nModalResult = -1;
  460. }
  461. END_CATCH_ALL
  462. if (bEnableParent)
  463. ::EnableWindow(hWndParent, TRUE);
  464. if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
  465. ::SetActiveWindow(hWndParent);
  466. // destroy modal window
  467. DestroyWindow();
  468. PostModal();
  469. // unlock/free resources as necessary
  470. if (m_lpszTemplateName != NULL || m_hDialogTemplate != NULL)
  471. UnlockResource(hDialogTemplate);
  472. if (m_lpszTemplateName != NULL)
  473. FreeResource(hDialogTemplate);
  474. return m_nModalResult;
  475. }
  476. void CDialog::EndDialog(int nResult)
  477. {
  478. ASSERT(::IsWindow(m_hWnd));
  479. if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL))
  480. EndModalLoop(nResult);
  481. ::EndDialog(m_hWnd, nResult);
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. // Standard CDialog implementation
  485. LRESULT CDialog::HandleSetFont(WPARAM wParam, LPARAM)
  486. {
  487. OnSetFont(CFont::FromHandle((HFONT)wParam));
  488. return Default();
  489. }
  490. void CDialog::PreInitDialog()
  491. {
  492. // ignore it
  493. }
  494. LRESULT CDialog::HandleInitDialog(WPARAM, LPARAM)
  495. {
  496. PreInitDialog();
  497. #ifndef _AFX_NO_OCC_SUPPORT
  498. // create OLE controls
  499. COccManager* pOccManager = afxOccManager;
  500. if ((pOccManager != NULL) && (m_pOccDialogInfo != NULL))
  501. {
  502. BOOL bDlgInit;
  503. if (m_lpDialogInit != NULL)
  504. bDlgInit = pOccManager->CreateDlgControls(this, m_lpDialogInit,
  505. m_pOccDialogInfo);
  506. else
  507. bDlgInit = pOccManager->CreateDlgControls(this, m_lpszTemplateName,
  508. m_pOccDialogInfo);
  509. if (!bDlgInit)
  510. {
  511. TRACE0("Warning: CreateDlgControls failed during dialog init.\n");
  512. EndDialog(-1);
  513. return FALSE;
  514. }
  515. }
  516. #endif
  517. // Default will call the dialog proc, and thus OnInitDialog
  518. BOOL bResult = Default();
  519. #ifndef _AFX_NO_OCC_SUPPORT
  520. if (bResult && (m_nFlags & WF_OLECTLCONTAINER))
  521. {
  522. CWnd* pWndNext = GetNextDlgTabItem(NULL);
  523. if (pWndNext != NULL)
  524. {
  525. pWndNext->SetFocus(); // UI Activate OLE control
  526. bResult = FALSE;
  527. }
  528. }
  529. #endif
  530. return bResult;
  531. }
  532. BOOL AFXAPI AfxHelpEnabled()
  533. {
  534. if (AfxGetApp() == NULL)
  535. return FALSE;
  536. // help is enabled if the app has a handler for ID_HELP
  537. AFX_CMDHANDLERINFO info;
  538. // check main window first
  539. CWnd* pWnd = AfxGetMainWnd();
  540. if (pWnd != NULL && pWnd->OnCmdMsg(ID_HELP, CN_COMMAND, NULL, &info))
  541. return TRUE;
  542. // check app last
  543. return AfxGetApp()->OnCmdMsg(ID_HELP, CN_COMMAND, NULL, &info);
  544. }
  545. void CDialog::OnSetFont(CFont*)
  546. {
  547. // ignore it
  548. }
  549. BOOL CDialog::OnInitDialog()
  550. {
  551. // execute dialog RT_DLGINIT resource
  552. BOOL bDlgInit;
  553. if (m_lpDialogInit != NULL)
  554. bDlgInit = ExecuteDlgInit(m_lpDialogInit);
  555. else
  556. bDlgInit = ExecuteDlgInit(m_lpszTemplateName);
  557. if (!bDlgInit)
  558. {
  559. TRACE0("Warning: ExecuteDlgInit failed during dialog init.\n");
  560. EndDialog(-1);
  561. return FALSE;
  562. }
  563. // transfer data into the dialog from member variables
  564. if (!UpdateData(FALSE))
  565. {
  566. TRACE0("Warning: UpdateData failed during dialog init.\n");
  567. EndDialog(-1);
  568. return FALSE;
  569. }
  570. // enable/disable help button automatically
  571. CWnd* pHelpButton = GetDlgItem(ID_HELP);
  572. if (pHelpButton != NULL)
  573. pHelpButton->ShowWindow(AfxHelpEnabled() ? SW_SHOW : SW_HIDE);
  574. return TRUE; // set focus to first one
  575. }
  576. void CDialog::OnOK()
  577. {
  578. if (!UpdateData(TRUE))
  579. {
  580. TRACE0("UpdateData failed during dialog termination.\n");
  581. // the UpdateData routine will set focus to correct item
  582. return;
  583. }
  584. EndDialog(IDOK);
  585. }
  586. void CDialog::OnCancel()
  587. {
  588. EndDialog(IDCANCEL);
  589. }
  590. BOOL CDialog::CheckAutoCenter()
  591. {
  592. // load resource as necessary
  593. LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
  594. HGLOBAL hDialogTemplate = m_hDialogTemplate;
  595. if (m_lpszTemplateName != NULL)
  596. {
  597. HINSTANCE hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
  598. HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
  599. hDialogTemplate = LoadResource(hInst, hResource);
  600. }
  601. if (hDialogTemplate != NULL)
  602. lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
  603. // determine if dialog should be centered
  604. BOOL bResult = TRUE;
  605. if (lpDialogTemplate != NULL)
  606. {
  607. DWORD dwStyle = lpDialogTemplate->style;
  608. short x;
  609. short y;
  610. if (((DLGTEMPLATEEX*)lpDialogTemplate)->signature == 0xFFFF)
  611. {
  612. // it's a DIALOGEX resource
  613. dwStyle = ((DLGTEMPLATEEX*)lpDialogTemplate)->style;
  614. x = ((DLGTEMPLATEEX*)lpDialogTemplate)->x;
  615. y = ((DLGTEMPLATEEX*)lpDialogTemplate)->y;
  616. }
  617. else
  618. {
  619. // it's a DIALOG resource
  620. x = lpDialogTemplate->x;
  621. y = lpDialogTemplate->y;
  622. }
  623. bResult = !(dwStyle & (DS_CENTER|DS_CENTERMOUSE|DS_ABSALIGN)) &&
  624. x == 0 && y == 0;
  625. }
  626. // unlock/free resources as necessary
  627. if (m_lpszTemplateName != NULL || m_hDialogTemplate != NULL)
  628. UnlockResource(hDialogTemplate);
  629. if (m_lpszTemplateName != NULL)
  630. FreeResource(hDialogTemplate);
  631. return bResult; // TRUE if auto-center is ok
  632. }
  633. /////////////////////////////////////////////////////////////////////////////
  634. // Gray background support
  635. #ifndef _AFX_NO_GRAYDLG_SUPPORT
  636. HBRUSH CDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  637. {
  638. // use helper in CWnd
  639. return OnGrayCtlColor(pDC, pWnd, nCtlColor);
  640. }
  641. #endif //!_AFX_NO_GRAYDLG_SUPPORT
  642. /////////////////////////////////////////////////////////////////////////////
  643. // CDialog support for context sensitive help.
  644. LRESULT CDialog::OnCommandHelp(WPARAM, LPARAM lParam)
  645. {
  646. if (lParam == 0 && m_nIDHelp != 0)
  647. lParam = HID_BASE_RESOURCE + m_nIDHelp;
  648. if (lParam != 0)
  649. {
  650. CWinApp* pApp = AfxGetApp();
  651. if (pApp != NULL)
  652. pApp->WinHelp(lParam);
  653. return TRUE;
  654. }
  655. return FALSE;
  656. }
  657. LRESULT CDialog::OnHelpHitTest(WPARAM, LPARAM)
  658. {
  659. if (m_nIDHelp != 0)
  660. return HID_BASE_RESOURCE + m_nIDHelp;
  661. return 0;
  662. }
  663. /////////////////////////////////////////////////////////////////////////////
  664. // CDialog Diagnostics
  665. #ifdef _DEBUG
  666. void CDialog::AssertValid() const
  667. {
  668. CWnd::AssertValid();
  669. }
  670. void CDialog::Dump(CDumpContext& dc) const
  671. {
  672. CWnd::Dump(dc);
  673. dc << "m_lpszTemplateName = ";
  674. if (HIWORD(m_lpszTemplateName) == 0)
  675. dc << (int)LOWORD((DWORD)m_lpszTemplateName);
  676. else
  677. dc << m_lpszTemplateName;
  678. dc << "\nm_hDialogTemplate = " << (UINT)m_hDialogTemplate;
  679. dc << "\nm_lpDialogTemplate = " << (UINT)m_lpDialogTemplate;
  680. dc << "\nm_pParentWnd = " << (void*)m_pParentWnd;
  681. dc << "\nm_nIDHelp = " << m_nIDHelp;
  682. dc << "\n";
  683. }
  684. // diagnostic routine to check for and decode dialog templates
  685. // return FALSE if a program error occurs (i.e. bad resource ID or
  686. // bad dialog styles).
  687. BOOL AFXAPI _AfxCheckDialogTemplate(LPCTSTR lpszResource, BOOL bInvisibleChild)
  688. {
  689. ASSERT(lpszResource != NULL);
  690. HINSTANCE hInst = AfxFindResourceHandle(lpszResource, RT_DIALOG);
  691. HRSRC hResource = ::FindResource(hInst, lpszResource, RT_DIALOG);
  692. if (hResource == NULL)
  693. {
  694. if (HIWORD(lpszResource) != 0)
  695. TRACE1("ERROR: Cannot find dialog template named '%s'.\n",
  696. lpszResource);
  697. else
  698. TRACE1("ERROR: Cannot find dialog template with IDD 0x%04X.\n",
  699. LOWORD((DWORD)lpszResource));
  700. return FALSE;
  701. }
  702. if (!bInvisibleChild)
  703. return TRUE; // that's all we need to check
  704. // we must check that the dialog template is for an invisible child
  705. // window that can be used for a form-view or dialog-bar
  706. HGLOBAL hTemplate = LoadResource(hInst, hResource);
  707. if (hTemplate == NULL)
  708. {
  709. TRACE0("Warning: LoadResource failed for dialog template.\n");
  710. // this is only a warning, the real call to CreateDialog will fail
  711. return TRUE; // not a program error - just out of memory
  712. }
  713. DLGTEMPLATEEX* pTemplate = (DLGTEMPLATEEX*)LockResource(hTemplate);
  714. DWORD dwStyle;
  715. if (pTemplate->signature == 0xFFFF)
  716. dwStyle = pTemplate->style;
  717. else
  718. dwStyle = ((DLGTEMPLATE*)pTemplate)->style;
  719. UnlockResource(hTemplate);
  720. FreeResource(hTemplate);
  721. if (dwStyle & WS_VISIBLE)
  722. {
  723. if (HIWORD(lpszResource) != 0)
  724. TRACE1("ERROR: Dialog named '%s' must be invisible.\n",
  725. lpszResource);
  726. else
  727. TRACE1("ERROR: Dialog with IDD 0x%04X must be invisible.\n",
  728. LOWORD((DWORD)lpszResource));
  729. return FALSE;
  730. }
  731. if (!(dwStyle & WS_CHILD))
  732. {
  733. if (HIWORD(lpszResource) != 0)
  734. TRACE1("ERROR: Dialog named '%s' must have the child style.\n",
  735. lpszResource);
  736. else
  737. TRACE1("ERROR: Dialog with IDD 0x%04X must have the child style.\n",
  738. LOWORD((DWORD)lpszResource));
  739. return FALSE;
  740. }
  741. return TRUE;
  742. }
  743. #endif //_DEBUG
  744. #ifdef AFX_INIT_SEG
  745. #pragma code_seg(AFX_INIT_SEG)
  746. #endif
  747. IMPLEMENT_DYNAMIC(CDialog, CWnd)
  748. /////////////////////////////////////////////////////////////////////////////