home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / DLGCORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-18  |  23.0 KB  |  899 lines

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