combooc.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 14k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "shellprv.h"
  2. #include "combooc.h"
  3. #include "unicppsdspatch.h"
  4. #define DROPDOWN_DEFAULTSIZE    300 // in pixels
  5. CComboBoxExOC::CComboBoxExOC(LPCTSTR pszRegKey, int csidlDefaultPidl)
  6. {
  7.     INITCOMMONCONTROLSEX icex;
  8.     DllAddRef();
  9.     // This allocator should have zero inited the memory, so assert the member variables are empty.
  10.     ASSERT(!_hwndComboBox);
  11.     ASSERT(!_hwndEdit);
  12.     ASSERT(!_pszInitialString);
  13.     ASSERT(!_pszPersistString);
  14.     ASSERT(!_fInRecursion);
  15.     _fEnabled = VARIANT_TRUE;        // Default to enabled.
  16.     _pszRegKey = pszRegKey;
  17.     _csidlDefaultPidl = csidlDefaultPidl;
  18.     // We do this so comctl32.dll won't fail to create the ComboBoxEx
  19.     // control.
  20.     icex.dwSize = sizeof(icex);
  21.     icex.dwICC = ICC_USEREX_CLASSES;
  22.     InitCommonControlsEx(&icex);
  23.     _dwDropDownSize = DROPDOWN_DEFAULTSIZE;
  24. }
  25. CComboBoxExOC::~CComboBoxExOC()
  26. {
  27.     if (_hwndComboBox)
  28.         ::DestroyWindow(_hwndComboBox);
  29.     Str_SetPtrA((LPSTR *)&_pszInitialString, NULL);
  30.     Str_SetPtr((LPTSTR *)&_pszPersistString, NULL);
  31.     ASSERT(!_fInRecursion);     // We are in a bad state.
  32.     DllRelease();
  33. }
  34. LRESULT CComboBoxExOC::cb_ForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  35. {
  36. #ifdef UNICODE
  37.     LRESULT lResult = ::SendMessageW(_hwndComboBox, uMsg, wParam, lParam);
  38. #else // UNICODE
  39.     LRESULT lResult = ::SendMessageA(_hwndComboBox, uMsg, wParam, lParam);
  40. #endif // UNICODE
  41.     //TraceMsg(TF_CUSTOM1, "in CComboBoxExOC::_ForwardMessage() forward msg=%d to real window. (lParam=%d, wParam=%d)", uMsg, lParam, wParam);
  42.     bHandled = (lResult ? TRUE : FALSE);
  43.     return lResult;
  44. }
  45. LRESULT CComboBoxExOC::cb_OnDropDownMessage(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  46. {
  47.     HCURSOR hCursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  48.     // DOH! The user wants to see the full combo contents.
  49.     // Better go fill it in now.
  50.     _Populate();
  51.     SetCursor(hCursorOld);
  52.    //TraceMsg(TF_CUSTOM1, "in CComboBoxExOC::_ForwardMessage() forward msg=%d to real window. (lParam=%d, wParam=%d)", uMsg, lParam, wParam);
  53.     bHandled = FALSE;
  54.     return 1;
  55. }
  56. #define STYLE_EX_MASK (CBES_EX_NOSIZELIMIT | CBES_EX_CASESENSITIVE | CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT | CBES_EX_PATHWORDBREAKPROC)
  57. HWND CComboBoxExOC::_CreateComboBoxEx(IOleClientSite * pClientSite, HWND hWnd, HWND hWndParent, RECT& rcPos, LPCTSTR pszWindowName, DWORD dwStyle, DWORD dwExStyle, UINT_PTR nID)
  58. {
  59.     HWND hwndParent = NULL;
  60.     HRESULT hr = S_OK;
  61.     CComQIPtr<IOleWindow, &IID_IOleWindow> spOleWindow(pClientSite);
  62.     if (EVAL(spOleWindow))
  63.         spOleWindow.p->GetWindow(&hwndParent);
  64.     // Please call BryanSt if this happens.
  65.     ASSERT(hwndParent);     // If this happens we need to reparent our selves later.
  66.     if (!hWnd)
  67.     {
  68.         DWORD dwStyle = (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN);
  69.         DWORD dwWindowStyle = _GetWindowStyles();
  70.         UINT_PTR nID = (UINT_PTR)this;
  71.         if (!_fEnableEdit)
  72.             dwWindowStyle |= CBS_DROPDOWNLIST;  // Disable editing in the editbox.
  73.         rcPos.bottom += _dwDropDownSize;
  74.         // This is the wrapper hwnd because ATL doesn't allow the normal winproc to get messages this
  75.         // control doesn't handle.
  76.         hWnd = _Create(hWndParent, rcPos, pszWindowName, dwStyle, dwExStyle, nID);
  77.         if (EVAL(hWnd))
  78.         {   
  79.             _hwndComboBox = CreateWindowEx(0, WC_COMBOBOXEX, TEXT("Shell Name Space ComboBoxEx"), dwWindowStyle,
  80.                 0, 0, (rcPos.right - rcPos.left), (rcPos.bottom - rcPos.top), hWnd, (HMENU) FCIDM_VIEWADDRESS, HINST_THISDLL, NULL);
  81.             if (EVAL(_hwndComboBox))
  82.             {
  83.                 ::EnableWindow(_hwndComboBox, ((VARIANT_TRUE == _fEnabled) ? TRUE : FALSE));     // Set the gray property in case we needed to cache it until the window was created.
  84.                 // Initial combobox parameters.
  85.                 ::SendMessage(_hwndComboBox, CBEM_SETEXTENDEDSTYLE,
  86.                         CBES_EX_NOEDITIMAGE |
  87.                         CBES_EX_NOSIZELIMIT | CBES_EX_CASESENSITIVE,
  88.                         CBES_EX_NOSIZELIMIT | CBES_EX_CASESENSITIVE);
  89.                 // _hwndEdit will be NULL if we are a rooted explorer and we
  90.                 // turned off the edit attribute of the ComboBox by
  91.                 // setting the CBS_DROPDOWNLIST flag when creating the window
  92.                 // at the top of this function.
  93.                 _hwndEdit = (HWND)::SendMessage(_hwndComboBox, CBEM_GETEDITCONTROL, 0, 0L);
  94.                 if (_pszInitialString)
  95.                     ::SetWindowTextA(_hwndComboBox, _pszInitialString);
  96.                 // TODO: Add AutoComplete here if we want it.
  97.                 ::ShowWindow(_hwndComboBox, SW_SHOW);
  98.                 HIMAGELIST  hil = _GetSystemImageListSmallIcons() ;
  99.                 ASSERT( hil ) ;
  100.  
  101.                 ::SendMessage(_hwndComboBox, CBEM_SETIMAGELIST, 0, (LPARAM)hil);
  102.                 ::SendMessage(_hwndComboBox, CBEM_SETEXSTYLE, 0, 0);
  103.                 _PopulateTopItem();
  104.             }
  105.         }
  106.         else
  107.             hr = HRESULT_FROM_WIN32(GetLastError());
  108.         TraceMsg(TF_CUSTOM1, "in CComboBoxExOC::_CreateComboBoxEx() new window created.");
  109.     }
  110.     else
  111.         TraceMsg(TF_CUSTOM1, "in CComboBoxExOC::_CreateComboBoxEx() window already exists.");
  112.     return hWnd;
  113. }
  114. HRESULT CComboBoxExOC::_AddCsidlIcon(LPCTSTR pszDisplayName, LPVOID pvData, int nCsidlIcon, INT_PTR nPos, int iIndent)
  115. {
  116.     CBXITEM item ;
  117.     HRESULT hr = _MakeCsidlIconCbxItem( &item, pszDisplayName, pvData, nCsidlIcon, nPos, iIndent ) ;
  118.     if( SUCCEEDED( hr ) )
  119.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  120.     return hr;
  121. }
  122. HRESULT CComboBoxExOC::_AddFileType(LPCTSTR pszDisplayName, LPCTSTR pszExt, LPCITEMIDLIST pidlIcon, INT_PTR nPos, int iIndent)
  123. {
  124.     HRESULT hr = S_OK;
  125.     CBXITEM item ;
  126.     if( SUCCEEDED( (hr = _MakeFileTypeCbxItem( &item, pszDisplayName, pszExt, pidlIcon, nPos, iIndent )) ) )
  127.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  128.     return hr;
  129. }
  130. HRESULT CComboBoxExOC::_AddResourceAndCsidlStr(UINT idString, int nCsidlItem, int nCsidlIcon, INT_PTR nPos, int iIndent)
  131. {
  132.     CBXITEM item ;
  133.     HRESULT hr = _MakeResourceAndCsidlStrCbxItem( &item, idString, nCsidlItem, nCsidlIcon, nPos, iIndent ) ;
  134.     if( SUCCEEDED( hr ) )
  135.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  136.     return hr ;
  137. }
  138. HRESULT CComboBoxExOC::_AddResourceItem(int idString, DWORD dwData, int nCsidlIcon, INT_PTR nPos, int iIndent)
  139. {
  140.     CBXITEM item ;
  141.     HRESULT hr = _MakeResourceCbxItem( &item, idString, dwData, nCsidlIcon, nPos, iIndent ) ;
  142.     if( SUCCEEDED( hr ) )
  143.     {
  144.         hr = _CustomizeName( idString, item.szText, ARRAYSIZE(item.szText) ) ;
  145.         if( SUCCEEDED( hr ) )
  146.             hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  147.     }
  148.     return hr;
  149. }
  150. HRESULT CComboBoxExOC::_AddCsidlItemStr(int nCsidlItem, int nCsidlIcon, INT_PTR nPos, int iIndent)
  151. {
  152.     CBXITEM item ;
  153.     HRESULT hr = _MakeCsidlItemStrCbxItem( &item, nCsidlItem, nCsidlIcon, nPos, iIndent ) ;
  154.     if( SUCCEEDED( hr ) )
  155.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  156.     return hr;
  157. }
  158. HRESULT CComboBoxExOC::_AddCsidlItem(int nCsidlItem, int nCsidlIcon, INT_PTR nPos, int iIndent)
  159. {
  160.     CBXITEM item ;
  161.     HRESULT hr = _MakeCsidlCbxItem( &item, nCsidlItem, nCsidlIcon, nPos, iIndent ) ;
  162.     if( SUCCEEDED( hr ) )
  163.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  164.     return hr;
  165. }
  166. HRESULT CComboBoxExOC::_AddPidl(LPITEMIDLIST pidl, LPITEMIDLIST pidlIcon, INT_PTR nPos, int iIndent)
  167. {
  168.     CBXITEM item ;
  169.     HRESULT hr = _MakePidlCbxItem( &item, pidl, pidlIcon, nPos, iIndent ) ;
  170.     if( SUCCEEDED( hr ) )
  171.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, NULL ) ;
  172.     return hr ;
  173. }
  174. HRESULT CComboBoxExOC::_AddToComboBox(LPCTSTR pszDisplayName, LPVOID pvData, LPCITEMIDLIST pidlIcon, INT_PTR nPos, int iIndent,
  175.                                       INT_PTR *pnPosAdded)
  176. {
  177.     HRESULT hr ;
  178.     CBXITEM item ;
  179.     if( SUCCEEDED( (hr = _MakeCbxItem( &item, pszDisplayName, pvData, pidlIcon, nPos, iIndent )) ) )
  180.     {
  181.         hr = _AddCbxItemToComboBox( _hwndComboBox, &item, pnPosAdded ) ;
  182.     }
  183.     return hr ;
  184. }
  185. HRESULT CComboBoxExOC::_AddToComboBoxKnownImage(LPCTSTR pszDisplayName, LPVOID pvData, int iImage, int iSelectedImage, INT_PTR nPos, int iIndent, INT_PTR *pnPosAdded)
  186. {
  187.     CBXITEM item ;
  188.     HRESULT hr ;
  189.     if( SUCCEEDED( (hr = _MakeCbxItemKnownImage( &item, pszDisplayName, pvData, iImage, iSelectedImage, nPos, iIndent )) ) )
  190.         return _AddCbxItemToComboBox( _hwndComboBox, &item, pnPosAdded ) ;
  191.     return hr ;
  192. }
  193. HRESULT CComboBoxExOC::_LoadAndConvertString(UINT idString, LPTSTR pszDisplayName, DWORD chSize)
  194. {
  195.     // After loading the string, we may need to make a conversion on it.
  196.     if (EVAL(LoadString(HINST_THISDLL, idString, pszDisplayName, chSize)))
  197.         return _CustomizeName(idString, pszDisplayName, chSize);
  198.     return E_FAIL;
  199. }
  200. HRESULT CComboBoxExOC::_Load(IPropertyBag * pPropBag, IErrorLog * pErrorLog)
  201. {
  202.     HRESULT hr = S_FALSE;
  203.     VARIANT var;
  204.     TraceMsg(TF_CUSTOM1, "in CUpDownOC::_Load()");
  205.     var.vt = VT_BSTR;
  206.     var.bstrVal = NULL;
  207.     hr = pPropBag->Read(L"Initial String", &var, NULL);
  208.     if (SUCCEEDED(hr) && var.vt==VT_BSTR)
  209.     {
  210.         CHAR szString[MAX_URL_STRING];
  211.         SHUnicodeToAnsi(var.bstrVal, szString, ARRAYSIZE(szString));
  212.         Str_SetPtrA((LPSTR *)&_pszInitialString, szString);
  213.     }
  214.     var.vt = VT_BSTR;
  215.     var.bstrVal = NULL;
  216.     hr = pPropBag->Read(L"Persist String", &var, NULL);
  217.     if (SUCCEEDED(hr) && var.vt==VT_BSTR)
  218.     {
  219.         TCHAR szString[MAX_URL_STRING];
  220.         SHUnicodeToTChar(var.bstrVal, szString, ARRAYSIZE(szString));
  221.         Str_SetPtr((LPTSTR *)&_pszPersistString, szString);
  222.     }
  223.     var.vt = VT_UI4;
  224.     var.ulVal = NULL;
  225.     hr = pPropBag->Read(L"Drop Down Height", &var, NULL);
  226.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  227.         _dwDropDownSize = var.ulVal;
  228.     var.vt = VT_UI4;
  229.     var.ulVal = NULL;
  230.     hr = pPropBag->Read(L"Enable Edit", &var, NULL);
  231.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  232.         _fEnableEdit = var.ulVal;
  233.     var.vt = VT_UI4;
  234.     var.ulVal = NULL;
  235.     hr = pPropBag->Read(L"Enabled", &var, NULL);
  236.     if (SUCCEEDED(hr) && (var.vt==VT_UI4) && (!var.ulVal))
  237.         _fEnabled = VARIANT_FALSE;
  238.     return S_OK;
  239. }
  240. HRESULT CComboBoxExOC::TranslateAcceleratorInternal(MSG *pMsg, IOleClientSite * pocs)
  241. {
  242.     HRESULT hr = E_NOTIMPL;
  243.     if (WM_KEYDOWN == pMsg->message)
  244.     {
  245.         switch (pMsg->wParam)
  246.         {
  247.         case VK_RETURN:
  248.             if (TranslateMessage(pMsg))
  249.             {
  250.                 DispatchMessage(pMsg);
  251.                 Fire_EnterPressed();
  252.                 hr = S_OK;
  253.             }
  254.             break;
  255.         default:
  256.             break;
  257.         }
  258.     }
  259.     return hr;
  260. }
  261. /****************************************************
  262.     FUNCTION: _PopulateTopItem
  263.     DESCRIPTION:
  264.         This function is optimizing for perf.  Since
  265.     enumerating the drop down includes hitting the disk
  266.     a bit, we want to optimize for the default case of
  267.     "My Computer" being selected.
  268. ****************************************************/
  269. HRESULT CComboBoxExOC::_PopulateTopItem(void)
  270. {
  271.     TCHAR szLastSelection[MAX_URL_STRING];
  272.     DWORD cbSize = SIZEOF(szLastSelection);
  273.     BOOL fIsSecure = _IsSecure();
  274.     szLastSelection[0] = 0;
  275.     // Will we allow the page to use persistence.
  276.     if (TRUE == fIsSecure)
  277.         SHGetValue(HKEY_CURRENT_USER, _pszRegKey, (_pszPersistString ? _pszPersistString : SZ_REGVALUE_LAST_SELECTION), NULL, (LPVOID)szLastSelection, &cbSize);
  278.     // We will use the default item if either:
  279.     // 1. We are not secure so we can't read the registery - or -
  280.     // 2. We read the registery and it's blank or equal to the default value.
  281.     if (!fIsSecure ||
  282.         (!szLastSelection[0] || _IsDefaultSelection(szLastSelection)))
  283.     {
  284.         // Yes
  285.         _AddDefaultItem();
  286.     }
  287.     // Also give the subclass a way to handle it directly himself...
  288.     else if (_RestoreIfUserInputValue(szLastSelection) != S_OK)
  289.     {
  290.         TCHAR szRegValue[MAX_PATH];
  291.         TCHAR szLastPath[MAX_URL_STRING];
  292.         szLastPath[0] = 0;
  293.         cbSize = SIZEOF(szLastPath);
  294.         wnsprintf(szRegValue, ARRAYSIZE(szRegValue), TEXT("%s_Path"), (_pszPersistString ? _pszPersistString : SZ_REGVALUE_LAST_SELECTION));
  295.         SHGetValue(HKEY_CURRENT_USER, _pszRegKey, szRegValue, NULL, (LPVOID)szLastPath, &cbSize);
  296.         // No, so take the hit now.
  297.         _Populate();
  298.         if (szLastSelection[0] && szLastPath[0])
  299.             _SetSelect(szLastSelection, szLastPath);
  300.     }
  301.     return S_OK;
  302. }
  303. HRESULT CComboBoxExOC::_SetSelect(LPCTSTR pszDisplay, LPCTSTR pszReplace)
  304. {
  305.     HRESULT hr = E_FAIL;
  306.     LRESULT nIndex = ::SendMessage(_hwndComboBox, CB_FINDSTRINGEXACT, (WPARAM)0, (LPARAM) pszDisplay);
  307.     if (CB_ERR == nIndex)
  308.     {
  309.         // Not in the name space, meaning it's probably custom.
  310.         ::SetWindowText(_hwndComboBox, pszReplace);
  311.     }
  312.     else
  313.         ::SendMessage(_hwndComboBox, CB_SETCURSEL, (WPARAM)nIndex, 0);
  314.     return hr;
  315. }
  316. HRESULT CComboBoxExOC::_putString(LPCSTR pszString)
  317. {
  318.     Str_SetPtrA((LPSTR *)&_pszInitialString, pszString);
  319.     if (_hwndComboBox)
  320.         ::SetWindowTextA(_hwndComboBox, _pszInitialString);
  321.     return S_OK;
  322. }
  323. HRESULT CComboBoxExOC::get_Enabled(OUT VARIANT_BOOL * pfEnabled)
  324. {
  325.     if (!EVAL(pfEnabled))
  326.         return S_FALSE;
  327.     *pfEnabled = _fEnabled;
  328.     return S_OK;
  329. }
  330. HRESULT CComboBoxExOC::put_Enabled(IN VARIANT_BOOL fEnabled)
  331. {    
  332.     if (_hwndComboBox)
  333.     {
  334.         _fEnabled = fEnabled;
  335.         ::EnableWindow(_hwndComboBox, ((VARIANT_TRUE == _fEnabled) ? TRUE : FALSE));
  336.     }
  337.     else
  338.         _fEnabled = fEnabled;
  339.     return S_OK;
  340. }