[BROWSEUI] CISFBand: Handle DBID_SETWINDOWTHEME. CORE-14176
[reactos.git] / dll / win32 / browseui / shellbars / CISFBand.cpp
index 85f4431..8d538c2 100644 (file)
@@ -7,28 +7,20 @@
  */
 
 #include "shellbars.h"
-#include <commoncontrols.h>
-#include <strsafe.h>
 
-#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
-#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+#include <commoncontrols.h>
+#include <shellapi.h>
+#include <wingdi.h>
+#include <uxtheme.h>
 
-// ***Extras***
-/*++
-* @name _ILIsDesktop
-*
-* Checks whether the given PIDL is of Desktop folder or not.
-*
-* @param pidl
-*        PIDL to be checked.
-*
-* @return True if PIDL is of Desktop, otherwise false.
-*
-*--*/
-static BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
-{
-    return (pidl == NULL || pidl->mkid.cb == 0);
-}
+/*
+TODO:
+    ** drag and drop support
+    ** tooltips
+    ** handle change notifications
+    ** Fix position of the items context menu
+    ** Implement responding to theme change
+*/
 
 //*****************************************************************************************
 // *** CISFBand *** 
@@ -37,7 +29,8 @@ CISFBand::CISFBand() :
     m_BandID(0),    
     m_pidl(NULL),
     m_textFlag(true),
-    m_iconFlag(true)
+    m_iconFlag(true),
+    m_QLaunch(false)
 {
 }
 
@@ -70,6 +63,9 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
     if (m_hWnd == NULL)
         return E_FAIL;      
 
+    if (!m_textFlag)
+        SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
+
     // Set the image list.
     HIMAGELIST* piml;
     HRESULT hr = SHGetImageList(SHIL_SMALL, IID_IImageList, (void**)&piml); 
@@ -84,7 +80,7 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
     CComPtr<IEnumIDList> pEndl;    
     LPITEMIDLIST pidl;
     STRRET stret;     
-    hr = m_pISF->EnumObjects(0, SHCONTF_FOLDERS, &pEndl);
+    hr = m_pISF->EnumObjects(0, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS, &pEndl);
     if (FAILED_UNEXPECTEDLY(hr)) 
     {
         DestroyWindow();
@@ -242,7 +238,10 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
 
             if (pdbi->dwMask & DBIM_MINSIZE)
             {
-                pdbi->ptMinSize.x = -1;
+                if (m_QLaunch)
+                    pdbi->ptMinSize.x = idealSize.x;
+                else
+                    pdbi->ptMinSize.x = -1;
                 pdbi->ptMinSize.y = idealSize.y;
             }
             if (pdbi->dwMask & DBIM_MAXSIZE)
@@ -258,10 +257,19 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
                 pdbi->ptActual = actualSize;
             }
             if (pdbi->dwMask & DBIM_TITLE)
-                wcscpy(pdbi->wszTitle, L"Quick Launch");                
+            {
+                if (m_QLaunch || !ILGetDisplayNameEx(NULL, m_pidl, pdbi->wszTitle, ILGDN_INFOLDER))
+                {
+                    pdbi->dwMask &= ~DBIM_TITLE;
+                }
+            }
             if (pdbi->dwMask & DBIM_MODEFLAGS)
             {
-                pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT | DBIMF_USECHEVRON | DBIMF_NOMARGINS | DBIMF_BKCOLOR | DBIMF_ADDTOFRONT;
+                pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT | DBIMF_USECHEVRON | DBIMF_NOMARGINS | DBIMF_BKCOLOR;
+                if (m_QLaunch)
+                {
+                    pdbi->dwModeFlags |= DBIMF_ADDTOFRONT;
+                }
             }
             if (pdbi->dwMask & DBIM_BKCOLOR)
                 pdbi->dwMask &= ~DBIM_BKCOLOR;
@@ -425,6 +433,13 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
 
         if (IsEqualIID(*pguidCmdGroup, IID_IDeskBand))
         {
+            if (nCmdID == DBID_SETWINDOWTHEME)
+            {
+                if (pvaIn && V_VT(pvaIn) == VT_BSTR && V_BSTR(pvaIn))
+                {
+                    SetWindowTheme(m_hWnd, V_BSTR(pvaIn), NULL);
+                }
+            }
             return S_OK;
         }
         
@@ -437,20 +452,60 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
 // *** IShellFolderBand ***
     STDMETHODIMP CISFBand::GetBandInfoSFB(PBANDINFOSFB pbi)
     {
+        if (pbi->dwMask == ISFB_MASK_IDLIST)
+        {
+            pbi->pidl = ILClone(m_pidl);
+            if (!pbi->pidl)
+                return E_OUTOFMEMORY;
+            return S_OK;
+        }
+
         return E_NOTIMPL;
     }
 
     STDMETHODIMP CISFBand::InitializeSFB(IShellFolder *psf, PCIDLIST_ABSOLUTE pidl)
     {
-        if (_ILIsDesktop(pidl))
+        HRESULT hr;
+
+        if (!psf && !pidl)
+            return E_INVALIDARG;
+
+        if (psf && pidl)
+            return E_INVALIDARG;
+
+        if (pidl != NULL)
         {
-            m_pISF = psf;
+            CComPtr<IShellFolder> psfDesktop;
+            hr = SHGetDesktopFolder(&psfDesktop);
+            if (FAILED_UNEXPECTEDLY(hr))
+                return hr;
+
+            if (_ILIsDesktop(pidl))
+            {
+                m_pISF = psfDesktop;
+            }
+            else
+            {
+                hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &m_pISF));
+                if (FAILED_UNEXPECTEDLY(hr))
+                    return hr;
+            }
+
             m_pidl = ILClone(pidl);
         }
-        else 
+
+        if (psf != NULL)
         {
-            psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &m_pISF));
-            m_pidl = ILClone(pidl);
+            CComPtr<IPersistFolder2> ppf2;
+            hr = psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
+            if (FAILED_UNEXPECTEDLY(hr))
+                return hr;
+
+            hr = ppf2->GetCurFolder(&m_pidl);
+            if (FAILED_UNEXPECTEDLY(hr))
+                return hr;
+
+            m_pISF = psf;
         }
                
         return S_OK;
@@ -458,6 +513,16 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
 
     STDMETHODIMP CISFBand::SetBandInfoSFB( PBANDINFOSFB pbi)
     {
+        if ((pbi->dwMask & ISFB_MASK_STATE) && 
+            (pbi->dwState & ISFB_STATE_QLINKSMODE) &&
+            (pbi->dwStateMask & ISFB_STATE_QLINKSMODE))
+        {
+            m_QLaunch = true;
+            m_textFlag = false;
+            if (m_hWnd)
+                SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);    
+        }
+
         return E_NOTIMPL;
     }
 
@@ -524,6 +589,23 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
                     if (FAILED_UNEXPECTEDLY(hr)) return hr;
                     break;
                 }
+                case IDM_OPEN_FOLDER:
+                {
+                    SHELLEXECUTEINFO shexinfo;
+
+                    memset(&shexinfo, 0x0, sizeof(shexinfo));
+
+                    shexinfo.cbSize = sizeof(shexinfo);
+                    shexinfo.fMask = SEE_MASK_IDLIST;
+                    shexinfo.lpVerb = _T("open");
+                    shexinfo.lpIDList = m_pidl;
+                    shexinfo.nShow = SW_SHOW;
+
+                    if (!ShellExecuteEx(&shexinfo))
+                        return E_FAIL;
+
+                    break;
+                }
                 case IDM_SHOW_TEXT:
                 {                    
                     if (m_textFlag)
@@ -570,6 +652,9 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
             CheckMenuItem(qMenu, IDM_SMALL_ICONS, MF_UNCHECKED);
         }
 
+        if (_ILIsDesktop(m_pidl))
+            DeleteMenu(qMenu, IDM_OPEN_FOLDER, MF_BYCOMMAND);
+
         UINT idMax = Shell_MergeMenus(hmenu, GetSubMenu(qMenu, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
         DestroyMenu(qMenu);
         return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(idMax - idCmdFirst +1));         
@@ -578,7 +663,7 @@ HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
 /*****************************************************************************/
 // C Constructor
     extern "C"
-    HRESULT WINAPI CISFBand_CreateInstance(REFIID riid, void** ppv)
+    HRESULT WINAPI RSHELL_CISFBand_CreateInstance(REFIID riid, void** ppv)
     {
         return ShellObjectCreator<CISFBand>(riid, ppv);
     }