Figure 2   IPerPropertyBrowsing Interface


 typedef struct tagCALPOLESTR {
             ULONG cElems;
             OLECHAR ** pElems;
 } CALPOLESTR;
 
 typedef struct tagCADWORD {
             ULONG cElems;
             DWORD * pElems;
 } CADWORD;
 
 interface IPerPropertyBrowsing : IUnknown
 {
   HRESULT GetDisplayString(DISPID dispid, BSTR * lpbstr);
   HRESULT MapPropertyToPage(DISPID dispid, CLSID *lpclsid);
   HRESULT GetPredefinedStrings(DISPID dispid, CALPOLESTR *lpcasz, 
                                CADWORD *lpcadw);
   HRESULT GetPredefinedValue(DISPID dispid, DWORD dwCookie,
                              VARIANT *lpvarOut);
 }


Figure 4   OnGetPredefinedStrings


 LPCTSTR g_szBobs[] = { 
   _T("Bob"), _T("Bobby"), _T("Robert") 
 };
 BOOL 
 CBobCtrl::OnGetPredefinedStrings(DISPID dispid, 
                                  CStringArray* pStringArray,
                                  CDWordArray * pCookieArray)
 {
   BOOL result = FALSE; 
   switch (dispid)
   {
   case dispidFirstName:
 //  update string and cookie arrays 
 //  and indicate that we have done it
     pStringArray->Add(g_szBobs[0]);
     pCookieArray->Add(0);
     pStringArray->Add(g_szBobs[1]);
     pCookieArray->Add(1);
     pStringArray->Add(g_szBobs[2]);
     pCookieArray->Add(2);
     result = TRUE;
     break;
   default:
 //  allow base class to perform 
 //  default mappings (usually none)
     result = COleControl::OnGetPredefinedStrings (dispid, 
                                                   pStringArray,
                                                   pCookieArray);
   }
   return result;
 }


Figure 5   Standard OnGetPredefinedValue


 BOOL 
 CBobCtrl::OnGetPredefinedValue(DISPID dispid, 
                                DWORD dwCookie, 
                                VARIANT * lpvarOut)
 {
   USES_CONVERSION;
   BOOL result = FALSE; 
   switch (dispid)
   {
   case dispidFirstName:
 // map dwCookie to the name and indicate 
 // that we did it
     VariantInit(lpvarOut);
     lpvarOut->vt = VT_BSTR;
     assert(dwCookie < 3);
     lpvarOut->bstrVal = SysAllocString(T2COLE(
                             g_szBobs[dwCookie]));
     result = TRUE;
     break;
   default:
 // allow base class to perform mappings
    result = COleControl::OnGetPredefinedValue(dispid, 
                                               dwCookie, 
                                               lpvarOut);
   }
   return result;
}


Figure 6   Custom OnGetPredefinedValue


 BOOL 
 CBobCtrl::OnGetPredefinedValue(DISPID dispid,
                                DWORD dwCookie, 
                                VARIANT * lpvarOut)
 {
   BOOL result = FALSE; 
   switch (dispid)
   {
   case dispidFirstName:
     VariantInit(lpvarOut);
     lpvarOut->vt = VT_I2;
     lpvarOut->iVal = short(dwCookie);
     result = TRUE;
     break line
   default:
     result = COleControl::OnGetPredefinedValue(dispid,
                                                dwCookie,
                                                lpvarOut);
   }
   return result;
}


Figure 7   OnGetDisplayString


 BOOL 
 CBobCtrl::OnGetDisplayString(DISPID dispid, 
                              CString& strValue)
 {
   BOOL result = FALSE; 
   switch (dispid)
   {
   case dispidFirstName:
 //  update display string and indicate that 
 //  we did it
     strValue = g_szBobs[m_firstName];
     result = TRUE;
     break;
   default:
 //  allow base class to perform mappings
     result = COleControl::OnGetDisplayString(dispid, 
                                              strValue);
   }
   return result;
 }


Figure 9   OnMapPropertyToPage


 BOOL 
 CBobCtrl::OnMapPropertyToPage(DISPID dispid, 
                               CLSID *lpclsid, 
                               BOOL* pbPageOptional)
 {
   BOOL result = FALSE; 
   switch (dispid)
   {
   case dispidLastName:
 //  map dispid to a CLSID and indicate 
 //  that we did it
     *lpclsid = CLastNamePropPage::guid;
     *pbPageOptional = TRUE;
     result = TRUE;
     break;
   default:
 //  allow base class to perform mappings
     result = COleControl::OnMapPropertyToPage(dispid, 
                                               lpclsid, 
                                               pbPageOptional);
   }
   return result;
}