home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / atlcon / propbrowsectl.h < prev    next >
C/C++ Source or Header  |  1998-04-03  |  11KB  |  398 lines

  1. // PropBrowseCtl.h : Property browser ActiveX Control
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #ifndef __PROPBROWSECTL_H_
  14. #define __PROPBROWSECTL_H_
  15.  
  16. #include "resource.h"       // main symbols
  17. #include "ATLControls.h"    // Common control helpers
  18. using namespace ATLControls;
  19.  
  20. class CProperty
  21. {
  22. public:
  23.     DISPID m_dispid;
  24.     VARTYPE m_vtNative;
  25.     CComVariant m_value;
  26.     CComPtr<IDispatch> m_spDisp;
  27.     CComPtr<ITypeInfo> m_spInfo;
  28.     CComBSTR m_bstrDesc;
  29.     CProperty(IDispatch* pDisp, DISPID di, VARIANT val, BSTR bstrDesc, ITypeInfo* p = NULL)
  30.     {
  31.         m_dispid = di;
  32.         m_value = val;
  33.         m_bstrDesc = bstrDesc;
  34.         m_vtNative = m_value.vt;
  35.         m_spDisp = pDisp;
  36.         m_spInfo = p;
  37.     }
  38.     bool IsCombo()
  39.     {
  40.         return ((m_spInfo != NULL) || (m_vtNative == VT_BOOL));
  41.     }
  42.     HRESULT GetStringValue(BSTR* pbstr)
  43.     {
  44.         if (m_spInfo == NULL)
  45.         {
  46.             switch(m_vtNative)
  47.             {
  48.             case VT_BOOL:
  49.                 {
  50.                     CComBSTR bstr = (m_value.boolVal == VARIANT_TRUE) ? L"True" : L"False";
  51.                     *pbstr = bstr.Detach();
  52.                 }
  53.                 break;
  54.             default:
  55.                 CComVariant v = m_value;
  56.                 v.ChangeType(VT_BSTR);
  57.                 *pbstr = v.bstrVal;
  58.                 v.bstrVal = NULL;
  59.                 break;
  60.             }
  61.         }
  62.         else
  63.         {
  64.             USES_CONVERSION;
  65.             TYPEATTR *pta=NULL;
  66.             m_spInfo->GetTypeAttr(&pta);
  67.             if(pta && pta->typekind == TKIND_ENUM)
  68.             {
  69.                 VARDESC* pvd=NULL;
  70.                 for (int i=0;i<pta->cVars;i++)
  71.                 {
  72.                     m_spInfo->GetVarDesc(i, &pvd);
  73.                     if (pvd->lpvarValue->lVal == m_value.lVal)
  74.                     {
  75.                         DISPID idMember = pvd->memid;
  76.                         CComBSTR bstrName;
  77.                         m_spInfo->GetDocumentation(idMember, &bstrName, NULL, NULL, NULL);
  78.                         TCHAR buf[256];
  79.                         wsprintf(buf, _T("%d - %s"), pvd->lpvarValue->lVal, OLE2T(bstrName));
  80.                         *pbstr = T2BSTR(buf);
  81.                     }
  82.                     m_spInfo->ReleaseVarDesc(pvd);
  83.                 }
  84.             }
  85.             if(pta)
  86.                 m_spInfo->ReleaseTypeAttr(pta);
  87.         }
  88.         return S_OK;
  89.     }
  90.     HRESULT SetValue(LPCTSTR pstr)
  91.     {
  92.         _ASSERTE(m_spInfo == NULL);
  93.         switch(m_vtNative)
  94.         {
  95.         case VT_BOOL:
  96.             m_value = (lstrcmpi(pstr, _T("True"))==0) ? true : false;
  97.             break;
  98.         default:
  99.             m_value = pstr;
  100.             m_value.ChangeType(m_vtNative);
  101.             break;
  102.         }
  103.         CComDispatchDriver dd(m_spDisp);
  104.         dd.PutProperty(m_dispid, &m_value);
  105.         return S_OK;
  106.     }
  107.     HRESULT SetValue(int nIndex)
  108.     {
  109.         if (m_spInfo == NULL)
  110.         {
  111.             switch(m_vtNative)
  112.             {
  113.             case VT_BOOL:
  114.                 m_value = (nIndex == 0) ? true : false;
  115.                 break;
  116.             default:
  117.                 break;
  118.             }
  119.         }
  120.         else
  121.         {
  122.             VARDESC* pvd=NULL;
  123.             m_spInfo->GetVarDesc(nIndex, &pvd);
  124.             m_value = pvd->lpvarValue->lVal;
  125.             m_spInfo->ReleaseVarDesc(pvd);
  126.         }
  127.         CComDispatchDriver dd(m_spDisp);
  128.         dd.PutProperty(m_dispid, &m_value);
  129.         return S_OK;
  130.     }
  131.     HRESULT AddEnumValues(HWND hwnd)
  132.     {
  133.         USES_CONVERSION;
  134.         CComboBox cb = hwnd;
  135.         cb.ResetContent();
  136.         if (m_vtNative == VT_BOOL)
  137.         {
  138.             cb.AddString(_T("True"));
  139.             cb.AddString(_T("False"));
  140.             cb.SetCurSel( (m_value.boolVal==VARIANT_TRUE) ? 0 : 1);
  141.         }
  142.         if (m_spInfo != NULL)
  143.         {
  144.             TYPEATTR *pta=NULL;
  145.             m_spInfo->GetTypeAttr(&pta);
  146.             if(pta && pta->typekind == TKIND_ENUM)
  147.             {
  148.                 VARDESC* pvd=NULL;
  149.                 for (int i=0;i<pta->cVars;i++)
  150.                 {
  151.                     m_spInfo->GetVarDesc(i, &pvd);
  152.                     DISPID idMember = pvd->memid;
  153.                     CComBSTR bstrName;
  154.                     m_spInfo->GetDocumentation(idMember, &bstrName, NULL, NULL, NULL);
  155.                     TCHAR buf[256];
  156.                     wsprintf(buf, _T("%d - %s"), pvd->lpvarValue->lVal, OLE2T(bstrName));
  157.                     cb.AddString(buf);
  158.                     if (pvd->lpvarValue->lVal == m_value.lVal)
  159.                         cb.SetCurSel(i);
  160.                     m_spInfo->ReleaseVarDesc(pvd);
  161.                 }
  162.             }
  163.             if(pta)
  164.                 m_spInfo->ReleaseTypeAttr(pta);
  165.         }
  166.         return S_OK;
  167.     }
  168. };
  169.  
  170. /////////////////////////////////////////////////////////////////////////////
  171. // CPropertyBrowseControl
  172. class ATL_NO_VTABLE CPropertyBrowseControl :
  173.     public CComObjectRootEx<CComSingleThreadModel>,
  174.     public IDispatchImpl<IATLConPropertyBrowser, &__uuidof(IATLConPropertyBrowser), &LIBID_ATLCONLib>,
  175.     public CComControl<CPropertyBrowseControl, CWindowImpl<CPropertyBrowseControl, CWindow, CWinTraitsOR<0, WS_EX_CLIENTEDGE> > >,
  176.     public IOleControlImpl<CPropertyBrowseControl>,
  177.     public IOleObjectImpl<CPropertyBrowseControl>,
  178.     public IOleInPlaceActiveObjectImpl<CPropertyBrowseControl>,
  179.     public IViewObjectExImpl<CPropertyBrowseControl>,
  180.     public IOleInPlaceObjectWindowlessImpl<CPropertyBrowseControl>,
  181.     public CComCoClass<CPropertyBrowseControl, &CLSID_NULL>
  182. {
  183. public:
  184.     CPropertyBrowseControl()
  185.     {
  186.         // Initialize control hosting support
  187.         AtlAxWinInit();
  188.         m_bWindowOnly = true;
  189.         m_bShowDesc = true;
  190.     }
  191.  
  192. DECLARE_WND_CLASS_EX(NULL, CS_DBLCLKS, COLOR_WINDOW)
  193.  
  194. BEGIN_COM_MAP(CPropertyBrowseControl)
  195.     COM_INTERFACE_ENTRY(IATLConPropertyBrowser)
  196.     COM_INTERFACE_ENTRY(IDispatch)
  197.     COM_INTERFACE_ENTRY(IViewObjectEx)
  198.     COM_INTERFACE_ENTRY(IViewObject2)
  199.     COM_INTERFACE_ENTRY(IViewObject)
  200.     COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
  201.     COM_INTERFACE_ENTRY(IOleInPlaceObject)
  202.     COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  203.     COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
  204.     COM_INTERFACE_ENTRY(IOleControl)
  205.     COM_INTERFACE_ENTRY(IOleObject)
  206. END_COM_MAP()
  207.  
  208. BEGIN_MSG_MAP(CPropertyBrowseControl)
  209.     MESSAGE_HANDLER(WM_CREATE, OnCreate)
  210.     MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  211.     MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  212.     MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
  213.     MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
  214.     MESSAGE_HANDLER(WM_SIZE, OnSize)
  215.     DEFAULT_REFLECTION_HANDLER()
  216.     ALT_MSG_MAP(1)      //ListView
  217.         MESSAGE_HANDLER(WM_DESTROY, OnListViewDestroy)
  218.         COMMAND_HANDLER(103, CBN_KILLFOCUS, OnComboKillFocus)
  219.         COMMAND_HANDLER(103, CBN_SELCHANGE, OnComboOK)
  220.     ALT_MSG_MAP(2)      //Edit control
  221.         MESSAGE_HANDLER(WM_CHAR, OnChar)
  222.         MESSAGE_HANDLER(WM_KILLFOCUS, OnEditKillFocus)
  223.     ALT_MSG_MAP(3)      //Combobox
  224.     ALT_MSG_MAP(4)      //Static control
  225. END_MSG_MAP()
  226.  
  227.     LRESULT OnEditKillFocus(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  228.     {
  229.         RECT rc = {0,0,0,0};
  230.         m_edit.MoveWindow(&rc);
  231.         bHandled = FALSE;
  232.         return 1;
  233.     }
  234.  
  235.     LRESULT OnComboKillFocus(int, int, HWND h, BOOL& bHandled)
  236.     {
  237.         RECT rc = {0,0,0,0};
  238.         m_combobox.MoveWindow(&rc);
  239.         bHandled = FALSE;
  240.         return 1;
  241.     }
  242.  
  243.     void OnComboDone()
  244.     {
  245.         RECT rc = {0,0,0,0};
  246.         m_combobox.MoveWindow(&rc);
  247.         CComBSTR bstrText;
  248.         m_combobox.GetWindowText(bstrText.m_str);
  249.         USES_CONVERSION;
  250.         m_list.SetItemText(m_nItem, m_nSubItem, OLE2T(bstrText));
  251.         m_list.SetFocus();
  252.         CProperty* pProp = (CProperty*)m_list.GetItemData(m_nItem);
  253.         pProp->SetValue(m_combobox.GetCurSel());
  254.     }
  255.  
  256.     LRESULT OnComboOK(int, int, HWND h, BOOL& bHandled)
  257.     {
  258.         OnComboDone();
  259.         return 1;
  260.     }
  261.  
  262.     LRESULT OnSize(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  263.     {
  264.         WORD cx = LOWORD(lParam);
  265.         WORD cy = HIWORD(lParam);
  266.         if (m_bShowDesc)
  267.             cy -= m_nHeightDesc;
  268.         m_list.MoveWindow(0, 0, cx, cy);
  269.         m_wndDesc.MoveWindow(0, cy, cx, cy+m_nHeightDesc);
  270.         return 999;
  271.     }
  272.  
  273.     BOOL PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
  274.     {
  275.         if(pMsg->message == WM_KEYDOWN)
  276.         {
  277.             switch(pMsg->wParam)
  278.             {
  279.             case VK_LEFT:
  280.             case VK_RIGHT:
  281.             case VK_UP:
  282.             case VK_DOWN:
  283.             case VK_HOME:
  284.             case VK_END:
  285.             case VK_NEXT:
  286.             case VK_PRIOR:
  287.                 hRet = S_FALSE;
  288.                 return TRUE;
  289.             }
  290.         }
  291.         return FALSE;
  292.     }
  293.  
  294.     LRESULT OnSetFocus(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  295.     {
  296.         BOOL b;
  297.         CComControlBase::OnSetFocus(0, 0, 0, b);
  298.         DoVerbUIActivate(&m_rcPos,  NULL);
  299.         if(!IsChild(::GetFocus()))
  300.             m_list.SetFocus();
  301.         return DefWindowProc();
  302.     }
  303.  
  304.     LRESULT OnListViewDestroy(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  305.     {
  306.         ClearListView();
  307.         bHandled = FALSE;
  308.         return 1;
  309.     }
  310.  
  311.     void ClearListView()
  312.     {
  313.         int n = m_list.GetItemCount();
  314.         for (int i=0;i<n;i++)
  315.             delete (CProperty*)m_list.GetItemData(i);
  316.         m_list.DeleteAllItems();
  317.     }
  318.  
  319.     static VARTYPE GetUserDefinedType(ITypeInfo *pTI, HREFTYPE hrt)
  320.     {
  321.         CComPtr<ITypeInfo> spTypeInfo;
  322.         VARTYPE vt = VT_USERDEFINED;
  323.         HRESULT hr = E_FAIL;
  324.         hr = pTI->GetRefTypeInfo(hrt, &spTypeInfo);
  325.         if(FAILED(hr))
  326.             return vt;
  327.         TYPEATTR *pta=NULL;
  328.  
  329.         spTypeInfo->GetTypeAttr(&pta);
  330.         if(pta && pta->typekind == TKIND_ALIAS)
  331.         {
  332.             if (pta->tdescAlias.vt == VT_USERDEFINED)
  333.                 GetUserDefinedType(spTypeInfo,pta->tdescAlias.hreftype);
  334.             else
  335.                 vt = pta->tdescAlias.vt;
  336.         }
  337.  
  338.         if(pta)
  339.             spTypeInfo->ReleaseTypeAttr(pta);
  340.         return vt;
  341.  
  342.     }
  343.     static HRESULT GetEnumTypeInfo(ITypeInfo *pTI, HREFTYPE hrt, ITypeInfo** ppEnumInfo)
  344.     {
  345.         CComPtr<ITypeInfo> spTypeInfo;
  346.         HRESULT hr = E_FAIL;
  347.         hr = pTI->GetRefTypeInfo(hrt, &spTypeInfo);
  348.         if(FAILED(hr))
  349.             return hr;
  350.         TYPEATTR *pta=NULL;
  351.  
  352.         spTypeInfo->GetTypeAttr(&pta);
  353.         if(pta != NULL)
  354.         {
  355.             if (pta->typekind == TKIND_ALIAS)
  356.             {
  357.                 if (pta->tdescAlias.vt == VT_USERDEFINED)
  358.                     return GetEnumTypeInfo(spTypeInfo,pta->tdescAlias.hreftype, ppEnumInfo);
  359.             }
  360.             else if (pta->typekind == TKIND_ENUM)
  361.                 spTypeInfo.CopyTo(ppEnumInfo);
  362.  
  363.             spTypeInfo->ReleaseTypeAttr(pta);
  364.         }
  365.         return (*ppEnumInfo != NULL) ? S_OK : E_FAIL;
  366.     }
  367.  
  368.     int m_nItem;
  369.     int m_nSubItem;
  370.     int m_nHeightDesc;
  371.     bool m_bShowDesc;
  372.  
  373.     LRESULT OnNotify(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  374.     LRESULT OnChar(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  375.  
  376.     HRESULT AddDispatch(IDispatch* pDisp);
  377.  
  378. // IViewObjectEx
  379.     DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
  380.  
  381. // IPropertyBrowseControl
  382. public:
  383.     STDMETHOD(put_Dispatch)(IDispatch* pDisp);
  384.     STDMETHOD(get_Dispatch)(IDispatch** ppDisp);
  385.     STDMETHOD(get_ShowDescription)(/*[out, retval]*/ BOOL *pVal);
  386.     STDMETHOD(put_ShowDescription)(/*[in]*/ BOOL newVal);
  387.  
  388.     CComPtr<IDispatch> m_spDispatch;
  389.  
  390.     CContainedWindowT<CListViewCtrl, CWinTraitsOR<LVS_REPORT | LVS_EX_GRIDLINES | LVS_NOSORTHEADER | LVS_SINGLESEL, 0/*WS_EX_CLIENTEDGE*/> > m_list;
  391.     CContainedWindowT<CEdit, CWinTraitsOR<WS_BORDER | ES_AUTOHSCROLL> > m_edit;
  392.     CContainedWindowT<CComboBox, CWinTraitsOR<CBS_DROPDOWNLIST> > m_combobox;
  393.     CContainedWindowT<CStatic, CWinTraits<SS_LEFT, 0> > m_wndDesc;
  394.     LRESULT OnCreate(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  395. };
  396.  
  397. #endif //__PROPBROWSECTL_H_
  398.