BUG: DDP_PostProcessing() Catches All Exceptions

ID: Q122273

The information in this article applies to:

SYMPTOMS

While a custom property page is on display, error messages generated by ThrowError(), in SetXXXXProperty() methods, will not be displayed.

CAUSE

Error messages generated by ThrowError() are usually displayed by catching COleDispatchExceptions. The DDP_PostProcessing() function catches all types of exceptions, preventing COleDispatchExceptions from being caught by the container application. This means exceptions are caught and ignored as they are generated while setting a property by using the control's custom property page.

RESOLUTION

To work around this problem, use a custom DDP_PostProcessing() function that specifically deals with COleDispatchExceptions thrown by ThrowError(). The sample code in this article builds a sample function called DDP_PostProcessingEx() based on the original DDP_PostProcessing() function, but modified to display a message box when a COleDispatchException is caught. In addition to adding the DDP_PostProcessingEx() function to your source code, you will also need to include the AFX_DDPDATA structure definition and constructor in your source file.

To use the new DDP_PostProcessingEx() function, replace the call to DDP_PostProcessing() with a call to DDP_PostProcessingEx() in your custom property page's DoDataExchange() function.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

Sample Code

   struct AFX_DDPDATA : public CObject
   {
      AFX_DDPDATA(LPVOID lpHandler, int nCtrlId, LPVOID lpMember,
         UINT nType, LPCTSTR lpszOleName);

      LPVOID  m_lpHandler;
      int     m_nCtrlId;
      LPVOID  m_lpMember;
      UINT    m_nType;
      LPCTSTR m_lpszOleName;
   };

   AFX_DDPDATA::AFX_DDPDATA(LPVOID lpHandler, int nCtrlId,
      LPVOID lpMember, UINT nType, LPCTSTR lpszOleName ) :
         m_lpHandler(lpHandler),
         m_nCtrlId(nCtrlId),
         m_lpMember(lpMember),
         m_nType(nType),
         m_lpszOleName(lpszOleName)
   {
   }

   void AFXAPI DDP_PostProcessingEx(CDataExchange*pDX)
   {
      if ( pDX->m_bSaveAndValidate )
      {
         WORD wKey;
         CMapWordToOb &m_DDPmap =((COlePropertyPage*)pDX->m_pDlgWnd)->
                                    m_DDPmap;
         AFX_DDPDATA *pDDP = NULL;
         POSITION pos = m_DDPmap.GetStartPosition();

         while( pos )
         {
            m_DDPmap.GetNextAssoc( pos, wKey, (CObject *&)pDDP);
            TRY
            {
               switch( pDDP->m_nType )
               {
                  case    VT_I1:
                {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        char *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (char *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_UI1:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        BYTE *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (BYTE *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                      break;
                  }
                  case    VT_I2:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        short *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (short *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_UI2:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        WORD *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (WORD *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_I4:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        long *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (long *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_UI4:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        DWORD *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (DWORD *)pDDP->m_lpMember, pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_R4:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        float *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX, pDDP->m_nCtrlId,
                        (float *)pDDP->m_lpMember,pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_R8:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *, int,
                        double *, LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX,pDDP->m_nCtrlId,
                        (double *)pDDP->m_lpMember,pDDP->m_lpszOleName);
                     break;
                  }
                  case    VT_BSTR:
                  {
                     typedef void (AFXAPI *PFV)(CDataExchange *,int,
                        CString *,LPCTSTR );
                     (*(PFV)pDDP->m_lpHandler)(pDX,pDDP->m_nCtrlId,
                        (CString*)pDDP->m_lpMember,pDDP->m_lpszOleName);
                     break;
                  }
                  default:
                     // Unknown Data Type!
                     ASSERT(FALSE);
                     break;
               }
            }
            CATCH(COleDispatchException, e)
            {
               // display a message box describing caught exception
               HWND hWndActive = ::GetActiveWindow();
               char szTitle[255];
               ::GetWindowText(hWndActive, szTitle, sizeof(szTitle));
               ::MessageBox(hWndActive, (LPCSTR)e->m_strDescription,
                  szTitle, MB_ICONEXCLAMATION|MB_TASKMODAL|MB_OK);
            }
            AND_CATCH_ALL(e)
            {
               // Ignore all other exceptions
            }
            END_CATCH_ALL
            delete pDDP;
         }
         m_DDPmap.RemoveAll();
      }
   }
Keywords          : kbcode kbole kbprg kbCtrl kbMFC kbVC kbbuglist
Version           : 1.00
Issue type        : kbbug

Last Reviewed: June 30, 1997