home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / OCCDLG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-17  |  15.0 KB  |  615 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_OCC_SEG
  15. #pragma code_seg(AFX_OCC_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.  
  27. #define CH_SYSMENU ' '
  28.  
  29. #define WS_TYPEMASK 0xC0000000
  30. #define BS_TYPEMASK 0x0000000F
  31.  
  32. inline DWORD TestStyle(CWnd* pWnd, DWORD dwStyle)
  33.     { return GetWindowLong(pWnd->m_hWnd, GWL_STYLE) & dwStyle; }
  34.  
  35. inline DWORD TestExStyle(CWnd* pWnd, DWORD dwExStyle)
  36.     { return GetWindowLong(pWnd->m_hWnd, GWL_EXSTYLE) & dwExStyle; }
  37.  
  38. inline BOOL HasChildStyle(CWnd* pWnd)
  39.     { return TestStyle(pWnd, WS_TYPEMASK) == WS_CHILD; }
  40.  
  41. inline BOOL IsControlParent(CWnd* pWnd)
  42.     { return TestExStyle(pWnd, WS_EX_CONTROLPARENT); }
  43.  
  44. static DWORD GetDlgCode(CWnd* pWnd, LPMSG lpMsg=NULL)
  45. {
  46.     if (pWnd == NULL)
  47.         return 0;
  48.  
  49.     WPARAM wParam = (lpMsg == NULL) ? 0 : lpMsg->wParam;
  50.  
  51.     return (DWORD)SendMessage(pWnd->m_hWnd, WM_GETDLGCODE,
  52.         wParam, (LPARAM)(LPMSG)lpMsg);
  53. }
  54.  
  55. static void AFX_CDECL DlgSetFocus(CWnd* pWnd)
  56. {
  57.     // Select all text in an edit control.
  58.     if (GetDlgCode(pWnd) & DLGC_HASSETSEL)
  59.         pWnd->SendMessage(EM_SETSEL, 0, MAKELPARAM(0, 0xFFFE));
  60.  
  61.     // Set focus as normal.
  62.     pWnd->SetFocus();
  63. }
  64.  
  65. static CWnd* AFX_CDECL GetChildControl(CWnd* pWndRoot, CWnd* pWndChild)
  66. {
  67.     CWnd* pWndControl = NULL;
  68.  
  69.     while ((pWndChild != NULL) && HasChildStyle(pWndChild) &&
  70.         (pWndChild != pWndRoot))
  71.     {
  72.         pWndControl = pWndChild;
  73.         pWndChild = pWndChild->GetParent();
  74.  
  75.         if (IsControlParent(pWndChild))
  76.             break;
  77.     }
  78.  
  79.     return pWndControl;
  80. }
  81.  
  82. static CWnd* AFX_CDECL NextControl(CWnd* pWndRoot, CWnd* pWndStart, UINT uFlags)
  83. {
  84.     // if pWndStart is already equal to pWndRoot, this confuses this function
  85.     // badly.
  86.     ASSERT(pWndRoot != pWndStart);
  87.  
  88.     if (pWndStart == NULL)
  89.     {
  90. FirstChild:
  91.         pWndStart = pWndRoot->GetTopWindow();
  92.         if (pWndStart == NULL)
  93.             return pWndRoot;
  94.  
  95.         goto Found;
  96.     }
  97.     else
  98.     {
  99.         // Are we at the last control within some parent?  If so, pop back up.
  100.         while (pWndStart->GetNextWindow() == NULL)
  101.         {
  102.             // Popup to previous real ancestor.  pWndStart will be NULL,
  103.             // pWndRoot, or the child of a recursive dialog.
  104.             pWndStart = GetChildControl(pWndRoot, pWndStart->GetParent());
  105.             if ((pWndStart == NULL) || (pWndStart == pWndRoot))
  106.             {
  107.                 goto FirstChild;
  108.             }
  109.         }
  110.  
  111.         ASSERT(pWndStart != NULL);
  112.         pWndStart = pWndStart->GetNextWindow();
  113.     }
  114.  
  115. Found:
  116.     if (IsControlParent(pWndStart))
  117.     {
  118.         if (((uFlags & CWP_SKIPINVISIBLE) && !pWndStart->IsWindowVisible()) ||
  119.             ((uFlags & CWP_SKIPDISABLED) && !pWndStart->IsWindowEnabled()))
  120.             pWndStart = NextControl(pWndRoot, pWndStart, uFlags);
  121.         else
  122.             pWndStart = NextControl(pWndStart, NULL, uFlags);
  123.     }
  124.  
  125.     return pWndStart;
  126. }
  127.  
  128. BOOL AFX_CDECL COccManager::IsMatchingMnemonic(CWnd* pWnd, LPMSG lpMsg)
  129. {
  130.     return (pWnd->m_pCtrlSite != NULL) &&
  131.         pWnd->m_pCtrlSite->IsMatchingMnemonic(lpMsg);
  132. }
  133.  
  134. static CWnd* AFX_CDECL FindNextMnem(CWnd* pWndDlg, CWnd* pWnd, LPMSG lpMsg)
  135. {
  136.     CWnd* pWndStart;
  137.     CWnd* pWndT;
  138.     int i = 0;
  139.  
  140.     // Check if we are in a group box so we can find local mnemonics.
  141.     pWndStart = GetChildControl(pWndDlg, pWnd);
  142.  
  143.     while ((pWndT = pWndDlg->GetNextDlgGroupItem(pWndStart)) != NULL)
  144.     {
  145.         i++;
  146.  
  147.         // Avoid infinite looping.
  148.         if (pWndT == pWnd || i > 60)
  149.             break;
  150.  
  151.         pWndStart = pWndT;
  152.  
  153.         if (COccManager::IsMatchingMnemonic(pWndT, lpMsg))
  154.             return pWndT;
  155.     }
  156.  
  157.     pWnd = pWndStart = GetChildControl(pWndDlg, pWnd);
  158.  
  159.     while (TRUE)
  160.     {
  161.         pWnd = NextControl(pWndDlg, pWnd, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
  162.  
  163.         if (COccManager::IsMatchingMnemonic(pWnd, lpMsg))
  164.             break;
  165.  
  166.         if (pWnd == pWndStart)
  167.             return NULL;
  168.     }
  169.  
  170.     return pWnd;
  171. }
  172.  
  173. BOOL AFX_CDECL COccManager::IsLabelControl(CWnd* pWnd)
  174. {
  175.     return pWnd->IsWindowEnabled() && (pWnd->m_pCtrlSite != NULL) &&
  176.         pWnd->m_pCtrlSite->m_dwMiscStatus & OLEMISC_ACTSLIKELABEL;
  177. }
  178.  
  179. static CWnd* AFX_CDECL GetNextMnem(CWnd* pWndDlg, CWnd* pWnd, LPMSG lpMsg)
  180. {
  181.     CWnd* pWndFirstFound = NULL;
  182.  
  183.     // Loop for a long time but not long enough so we hang...
  184.     for (int count = 0; count < 256*2; count++)
  185.     {
  186.         // If the dialog box doesn't has the mnemonic specified, return NULL.
  187.         if ((pWnd = FindNextMnem(pWndDlg, pWnd, lpMsg)) == NULL)
  188.             return NULL;
  189.  
  190.         // If a non-disabled static item, then jump ahead to nearest tabstop.
  191.         if (COccManager::IsLabelControl(pWnd))
  192.         {
  193.             pWnd = pWndDlg->GetNextDlgTabItem(pWnd);
  194.             if (pWnd == NULL)
  195.                 return NULL;
  196.         }
  197.  
  198.         if (pWnd->IsWindowEnabled())
  199.             return pWnd;
  200.  
  201.         // Stop if we've looped back to the first item we checked
  202.         if (pWnd == pWndFirstFound)
  203.             return NULL;
  204.  
  205.         if (pWndFirstFound == NULL)
  206.             pWndFirstFound = pWnd;
  207.     }
  208.  
  209.     return NULL;
  210. }
  211.  
  212. void AFX_CDECL COccManager::UIActivateControl(CWnd* pWndNewFocus)
  213. {
  214.     if (pWndNewFocus == NULL)
  215.         return;
  216.  
  217.     // Find the nearest control in the window parent chain.
  218.     CWnd* pWndCtrl = pWndNewFocus;
  219.     COleControlContainer* pCtrlCont = NULL;
  220.     COleControlSite* pCtrlSite = NULL;
  221.     while ((pWndCtrl != NULL) &&
  222.         ((pCtrlCont = pWndCtrl->m_pCtrlCont) == NULL) &&
  223.         ((pCtrlSite = pWndCtrl->m_pCtrlSite) == NULL))
  224.     {
  225.         pWndCtrl = pWndCtrl->GetParent();
  226.     }
  227.  
  228.     if ((pWndCtrl == NULL) || (pCtrlCont != NULL))
  229.         return;
  230.  
  231.     // This will UI Activate the control.
  232.     pCtrlSite->SetFocus();
  233.  
  234.     // Make sure focus gets set to correct child of control, if any.
  235.     if (CWnd::GetFocus() != pWndNewFocus)
  236.         pWndNewFocus->SetFocus();
  237. }
  238.  
  239. void AFX_CDECL COccManager::UIDeactivateIfNecessary(CWnd* pWndOldFocus,
  240.     CWnd* pWndNewFocus)
  241. {
  242.     if (pWndOldFocus == NULL || !::IsWindow(pWndOldFocus->m_hWnd))
  243.         return;
  244.  
  245.     // Find the nearest control container in the window parent chain.
  246.     CWnd* pWndCtrlCont = pWndOldFocus->GetParent();
  247.     COleControlContainer* pCtrlCont = NULL;
  248.  
  249.     while ((pWndCtrlCont != NULL) &&
  250.         ((pCtrlCont = pWndCtrlCont->m_pCtrlCont) == NULL))
  251.     {
  252.         pWndCtrlCont = pWndCtrlCont->GetParent();
  253.     }
  254.  
  255.     if (pCtrlCont == NULL)
  256.         return;
  257.  
  258.     // Get the current UI Active control (if any).
  259.     CWnd* pWndUIActive = NULL;
  260.     COleControlSite* pSite = NULL;
  261.  
  262.     if ((pCtrlCont != NULL) &&
  263.         ((pSite = pCtrlCont->m_pSiteUIActive) != NULL))
  264.     {
  265.         pWndUIActive = CWnd::FromHandle(pSite->m_hWnd);
  266.     }
  267.  
  268.     // Ignore if no control is UI Active.
  269.     if (pWndUIActive == NULL)
  270.         return;
  271.  
  272.     // Ignore if the control getting the focus is the same control.
  273.     if ((pWndNewFocus == pWndUIActive) ||
  274.         ((pWndNewFocus != NULL) && pWndUIActive->IsChild(pWndNewFocus)))
  275.         return;
  276.  
  277.     // Tell the container to UI Deactivate the UI Active control.
  278.     pCtrlCont->OnUIActivate(NULL);
  279. }
  280.  
  281. CWnd* AFX_CDECL FindDlgItem(CWnd* pWndParent, DWORD id)
  282. {
  283.     CWnd* pWndChild;
  284.     CWnd* pWndOrig;
  285.  
  286.     // QUICK TRY:
  287.     pWndChild = pWndParent->GetDlgItem(id);
  288.     if (pWndChild != NULL)
  289.         return pWndChild;
  290.  
  291.     pWndOrig = NextControl(pWndParent, NULL, CWP_SKIPINVISIBLE);
  292.     if (pWndOrig == pWndParent)
  293.         return NULL;
  294.  
  295.     pWndChild = pWndOrig;
  296.  
  297.     do
  298.     {
  299.         if ((DWORD)pWndChild->GetDlgCtrlID() == id)
  300.             return(pWndChild);
  301.  
  302.         pWndChild = NextControl(pWndParent, pWndChild, CWP_SKIPINVISIBLE);
  303.     }
  304.     while ((pWndChild != NULL) && (pWndChild != pWndOrig));
  305.  
  306.     return NULL;
  307. }
  308.  
  309. void COccManager::SetDefaultButton(CWnd* pWnd, BOOL bDefault)
  310. {
  311.     if (pWnd->m_pCtrlSite != NULL)
  312.     {
  313.         pWnd->m_pCtrlSite->SetDefaultButton(bDefault);
  314.     }
  315.     else
  316.     {
  317.         DWORD code = GetDlgCode(pWnd);
  318.         if (code & (bDefault ? DLGC_UNDEFPUSHBUTTON : DLGC_DEFPUSHBUTTON))
  319.             pWnd->SendMessage(BM_SETSTYLE,
  320.                 (WPARAM)(bDefault ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON),
  321.                 (LPARAM)(DWORD)TRUE);
  322.     }
  323. }
  324.  
  325. DWORD AFX_CDECL COccManager::GetDefBtnCode(CWnd* pWnd)
  326. {
  327.     if (pWnd == NULL)
  328.         return 0;
  329.  
  330.     if (pWnd->m_pCtrlSite != NULL)
  331.         return pWnd->m_pCtrlSite->GetDefBtnCode();
  332.  
  333.     return GetDlgCode(pWnd) & (DLGC_UNDEFPUSHBUTTON | DLGC_DEFPUSHBUTTON);
  334. }
  335.  
  336. static void AFX_CDECL RemoveDefaultButton(CWnd* pWndRoot, CWnd* pWndStart)
  337. {
  338.     if ((pWndStart == NULL) || IsControlParent(pWndStart))
  339.         pWndStart = NextControl(pWndRoot, NULL, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED);
  340.     else
  341.         pWndStart = GetChildControl(pWndRoot, pWndStart);
  342.  
  343.     if (pWndStart == NULL)
  344.         return;
  345.  
  346.     CWnd* pWnd = pWndStart;
  347.     CWnd* pWndNext;
  348.  
  349.     do
  350.     {
  351.         COccManager::SetDefaultButton(pWnd, FALSE);
  352.         pWndNext = NextControl(pWndRoot, pWnd, 0);
  353.         pWnd = pWndNext;
  354.     }
  355.     while ((pWnd != NULL) && (pWnd != pWndStart));
  356. }
  357.  
  358. static int AFX_CDECL OriginalDefButton(CWnd* pWndRoot)
  359. {
  360.     LRESULT lResult = pWndRoot->SendMessage(DM_GETDEFID, 0, 0L);
  361.     return HIWORD(lResult) == DC_HASDEFID ? LOWORD(lResult) : IDOK;
  362. }
  363.  
  364. static void AFX_CDECL CheckDefPushButton(CWnd* pWndRoot, CWnd* pWndOldFocus,
  365.     CWnd* pWndNewFocus)
  366. {
  367.     DWORD code = 0;
  368.     CWnd* pWndT;
  369.  
  370.     // If the focus has gone to a totally separate window, bail out.
  371.     if (!pWndRoot->IsChild(pWndNewFocus))
  372.         return;
  373.  
  374.     if (pWndNewFocus != NULL)
  375.     {
  376.         // Do nothing if clicking on dialog background or recursive dialog
  377.         // background.
  378.         if (IsControlParent(pWndNewFocus))
  379.             return;
  380.  
  381.         code = COccManager::GetDefBtnCode(pWndNewFocus);
  382.     }
  383.  
  384.     if (pWndOldFocus == pWndNewFocus)
  385.     {
  386.         // Check the default ID and see if is the same as pwndOldFocus' ID.
  387.         // If not, find it and use it as pwndOldFocus
  388.         if (code & DLGC_UNDEFPUSHBUTTON)
  389.         {
  390.             if (pWndOldFocus != NULL)
  391.             {
  392.                 pWndOldFocus = FindDlgItem(pWndRoot, OriginalDefButton(pWndRoot));
  393.                 if ((pWndOldFocus != NULL) && (pWndOldFocus != pWndNewFocus))
  394.                 {
  395.                     if (COccManager::GetDefBtnCode(pWndOldFocus) & DLGC_DEFPUSHBUTTON)
  396.                     {
  397.                         RemoveDefaultButton(pWndRoot, pWndOldFocus);
  398.                         goto SetNewDefault;
  399.                     }
  400.                 }
  401.             }
  402.  
  403.             COccManager::SetDefaultButton(pWndNewFocus, TRUE);
  404.         }
  405.         return;
  406.     }
  407.  
  408.     // If the focus is changing to or from a pushbutton, then remove the
  409.     // default style from the current default button
  410.     if (((pWndOldFocus != NULL) && (COccManager::GetDefBtnCode(pWndOldFocus) != 0)) ||
  411.         ((pWndNewFocus != NULL) && (code != 0)))
  412.     {
  413.         RemoveDefaultButton(pWndRoot, pWndNewFocus);
  414.     }
  415.  
  416. SetNewDefault:
  417.     // If moving to a button, make that button the default.
  418.     if (code & (DLGC_UNDEFPUSHBUTTON | DLGC_DEFPUSHBUTTON))
  419.     {
  420.         COccManager::SetDefaultButton(pWndNewFocus, TRUE);
  421.     }
  422.     else
  423.     {
  424.         // Otherwise, make sure the original default button is default
  425.  
  426.         // Get the original default button
  427.         pWndT = FindDlgItem(pWndRoot, OriginalDefButton(pWndRoot));
  428.  
  429.         if ((COccManager::GetDefBtnCode(pWndT) & DLGC_UNDEFPUSHBUTTON) &&
  430.             pWndT->IsWindowEnabled())
  431.         {
  432.             COccManager::SetDefaultButton(pWndT, TRUE);
  433.         }
  434.     }
  435. }
  436.  
  437. BOOL COccManager::IsDialogMessage(CWnd* pWndDlg, LPMSG lpMsg)
  438. {
  439.     // If an OLE Control has the focus, then give it the first crack at key
  440.     // and mouse messages.
  441.  
  442.     CWnd* pWndFocus = CWnd::GetFocus();
  443.     HWND hWndFocus = pWndFocus->GetSafeHwnd();
  444.     UINT uMsg = lpMsg->message;
  445.  
  446.     if (((uMsg >= WM_KEYFIRST) && (uMsg <= WM_KEYLAST)) ||
  447.         ((uMsg >= WM_MOUSEFIRST) && (uMsg <= WM_MOUSELAST)))
  448.     {
  449.         CWnd* pWndCtrl = pWndFocus;
  450.  
  451.         // Walk up the parent chain, until we find an OLE control.
  452.         while ((pWndCtrl != NULL) && (pWndCtrl->m_pCtrlSite == NULL) &&
  453.             (pWndCtrl->GetParent() != pWndDlg))
  454.         {
  455.             pWndCtrl = pWndCtrl->GetParent();
  456.         }
  457.  
  458.         if ((pWndCtrl != NULL) && (pWndCtrl->m_pCtrlSite != NULL) &&
  459.             (pWndCtrl->m_pCtrlSite->m_pActiveObject != NULL) &&
  460.             (pWndCtrl->m_pCtrlSite->m_pActiveObject->TranslateAccelerator(
  461.                 lpMsg) == S_OK))
  462.         {
  463.             return TRUE;
  464.         }
  465.     }
  466.  
  467.     BOOL bResult = FALSE;
  468.     CWnd* pWndMsg = CWnd::FromHandle(lpMsg->hwnd);
  469.     CWnd* pWndNext = NULL;
  470.     DWORD code;
  471.     BOOL bBack = FALSE;
  472.     int iOK = IDCANCEL;
  473.  
  474.     switch (uMsg)
  475.     {
  476.     case WM_SYSCHAR:
  477.         // If no control has focus, and Alt not down, then ignore.
  478.         if ((pWndFocus == NULL) && (GetKeyState(VK_MENU) >= 0))
  479.             break;
  480.  
  481.         // If alt+menuchar, process as menu.
  482.         if (LOWORD(lpMsg->wParam) == CH_SYSMENU)
  483.             break;
  484.         // FALL THRU
  485.  
  486.     case WM_CHAR:
  487.         // Ignore chars sent to the dialog box (rather than the control).
  488.         if (pWndMsg == pWndDlg)
  489.             return TRUE;
  490.  
  491.         code = GetDlgCode(pWndMsg, lpMsg);
  492.  
  493.         // If the control wants to process the message, then don't check
  494.         // for possible mnemonic key.
  495.         if ((lpMsg->message == WM_CHAR) &&
  496.                 (code & (DLGC_WANTCHARS | DLGC_WANTMESSAGE)))
  497.             break;
  498.  
  499.         // If the control wants tabs, then don't let tab fall thru here
  500.         if ((LOWORD(lpMsg->wParam) == VK_TAB) && (code & DLGC_WANTTAB))
  501.             break;
  502.  
  503.         // Don't handle space as a mnemonic
  504.         if (LOWORD(lpMsg->wParam) == VK_SPACE)
  505.             return TRUE;
  506.  
  507.         if ((pWndNext = GetNextMnem(pWndDlg, pWndMsg, lpMsg)) != NULL)
  508.         {
  509.             if (pWndNext->m_pCtrlSite != NULL)
  510.             {
  511.                 // UI Activate new control, and send the mnemonic to it.
  512.                 pWndNext->m_pCtrlSite->SendMnemonic(lpMsg);
  513.                 bResult = TRUE;
  514.             }
  515.         }
  516.         break;
  517.  
  518.     case WM_KEYDOWN:
  519.         code = GetDlgCode(pWndMsg, lpMsg);
  520.         switch (LOWORD(lpMsg->wParam))
  521.         {
  522.         case VK_TAB:
  523.             if (code & DLGC_WANTTAB)    // If control wants tabs, bail out.
  524.                 break;
  525.  
  526.             pWndNext = pWndDlg->GetNextDlgTabItem(pWndMsg,
  527.                 (GetKeyState(VK_SHIFT) < 0));
  528.  
  529.             if (pWndNext != NULL)
  530.             {
  531.                 DlgSetFocus(pWndNext);
  532.                 UIDeactivateIfNecessary(pWndFocus, pWndNext);
  533.             }
  534.  
  535.             bResult = TRUE;
  536.             break;
  537.  
  538.         case VK_LEFT:
  539.         case VK_UP:
  540.             bBack = TRUE;
  541.             // FALL THRU
  542.  
  543.         case VK_RIGHT:
  544.         case VK_DOWN:
  545.             if (GetDlgCode(pWndFocus, lpMsg) & DLGC_WANTARROWS)
  546.                 break;
  547.  
  548.             pWndNext = pWndDlg->GetNextDlgGroupItem(pWndFocus, bBack);
  549.             if ((pWndNext != NULL) && (pWndNext->m_pCtrlSite != NULL))
  550.             {
  551.                 DlgSetFocus(pWndNext);
  552.                 bResult = TRUE;
  553.             }
  554.             break;
  555.  
  556.         case VK_EXECUTE:
  557.         case VK_RETURN:
  558.             // Return was pressed. Find default button and click it.
  559.             if (GetDefBtnCode(pWndFocus) & DLGC_DEFPUSHBUTTON)
  560.             {
  561.                 pWndNext = pWndFocus;
  562.                 iOK = (DWORD)pWndNext->GetDlgCtrlID();
  563.             }
  564.             else
  565.             {
  566.                 iOK = OriginalDefButton(pWndDlg);
  567.             }
  568.             // FALL THRU
  569.  
  570.         case VK_ESCAPE:
  571.         case VK_CANCEL:
  572.             if (pWndNext == NULL)
  573.                 pWndNext = FindDlgItem(pWndDlg, iOK);
  574.  
  575.             // Make sure button is not disabled.
  576.             if ((pWndNext != NULL) && !pWndNext->IsWindowEnabled())
  577.             {
  578.                 MessageBeep(0);
  579.             }
  580.             else
  581.             {
  582.                 if ((pWndNext != NULL) && (pWndNext->m_pCtrlSite != NULL))
  583.                 {
  584.                     TRY
  585.                     {
  586.                         pWndNext->InvokeHelper(DISPID_DOCLICK, DISPATCH_METHOD,
  587.                             VT_EMPTY, NULL, VTS_NONE);
  588.                     }
  589.                     END_TRY
  590.  
  591.                     bResult = TRUE;
  592.                 }
  593.             }
  594.             break;
  595.         }
  596.         break;
  597.     }
  598.  
  599.     // As a last resort, delegate to the Windows implementation
  600.     if (!bResult)
  601.     {
  602.         bResult = ::IsDialogMessage(pWndDlg->m_hWnd, lpMsg);
  603.         if (bResult && (CWnd::GetFocus() != pWndFocus))
  604.             UIActivateControl(CWnd::GetFocus());
  605.     }
  606.  
  607.     if (::IsWindow(hWndFocus))
  608.     {
  609.         UIDeactivateIfNecessary(pWndFocus, CWnd::GetFocus());
  610.         CheckDefPushButton(pWndDlg, pWndFocus, CWnd::GetFocus());
  611.     }
  612.  
  613.     return bResult;
  614. }
  615.