https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7a3865f1dff4793fea05c…
commit 7a3865f1dff4793fea05ce8d6b07b9bfbaf6f9c3
Author: Shriraj Sawant <sr.official(a)hotmail.com>
AuthorDate: Mon Oct 16 16:38:39 2017 +0300
[QCKLNCH] Implement the quick launch shell extension including the CISFBand
---
dll/shellext/CMakeLists.txt | 1 +
dll/shellext/qcklnch/CISFBand.cpp | 587 ++++++++++++++++++++++++++++++
dll/shellext/qcklnch/CISFBand.h | 196 ++++++++++
dll/shellext/qcklnch/CMakeLists.txt | 43 +++
dll/shellext/qcklnch/CQuickLaunchBand.cpp | 361 ++++++++++++++++++
dll/shellext/qcklnch/CQuickLaunchBand.h | 174 +++++++++
dll/shellext/qcklnch/lang/en-US.rc | 19 +
dll/shellext/qcklnch/precomp.h | 41 +++
dll/shellext/qcklnch/qcklnch.cpp | 70 ++++
dll/shellext/qcklnch/qcklnch.rc | 15 +
dll/shellext/qcklnch/qcklnch.spec | 4 +
dll/shellext/qcklnch/resource.h | 11 +
dll/shellext/qcklnch/rgs/qcklnch.rgs | 13 +
13 files changed, 1535 insertions(+)
diff --git a/dll/shellext/CMakeLists.txt b/dll/shellext/CMakeLists.txt
index 56fabe1299..2b5b3c6c65 100644
--- a/dll/shellext/CMakeLists.txt
+++ b/dll/shellext/CMakeLists.txt
@@ -6,5 +6,6 @@ add_subdirectory(devcpux)
add_subdirectory(fontext)
add_subdirectory(netshell)
add_subdirectory(ntobjshex)
+add_subdirectory(qcklnch)
add_subdirectory(shellbtrfs)
add_subdirectory(stobject)
diff --git a/dll/shellext/qcklnch/CISFBand.cpp b/dll/shellext/qcklnch/CISFBand.cpp
new file mode 100644
index 0000000000..34192b45d3
--- /dev/null
+++ b/dll/shellext/qcklnch/CISFBand.cpp
@@ -0,0 +1,587 @@
+/*
+ * PROJECT: ReactOS shell extensions
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/shellext/qcklnch/CISFBand.cpp
+ * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
+ * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official(a)hotmail.com>
+ */
+
+#include "precomp.h"
+#include <commoncontrols.h>
+
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
+
+WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
+
+// ***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.
+*
+*--*/
+BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
+{
+ return (pidl == NULL || pidl->mkid.cb == 0);
+}
+
+//*****************************************************************************************
+// *** CISFBand ***
+
+CISFBand::CISFBand() :
+ m_BandID(0),
+ m_pidl(NULL),
+ m_textFlag(true),
+ m_iconFlag(true)
+{
+}
+
+CISFBand::~CISFBand()
+{
+ CloseDW(0);
+}
+
+// Toolbar
+/*++
+* @name CreateSimpleToolbar
+*
+* Creates a toolbar and fills it up with buttons for enumerated objects.
+*
+* @param hWndParent
+* Handle to the parent window, which receives the appropriate messages from child
toolbar.
+*
+* @return The error code.
+*
+*--*/
+HRESULT CISFBand::CreateSimpleToolbar(HWND hWndParent)
+{
+ // Declare and initialize local constants.
+ const DWORD buttonStyles = BTNS_AUTOSIZE;
+
+ // Create the toolbar.
+ m_hWnd = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
+ WS_CHILD | TBSTYLE_FLAT | TBSTYLE_LIST | CCS_NORESIZE | CCS_NODIVIDER,
CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
+ hWndParent, NULL, 0, NULL);
+ if (m_hWnd == NULL)
+ return E_FAIL;
+
+ // Set the image list.
+ HIMAGELIST* piml;
+ HRESULT hr = SHGetImageList(SHIL_SMALL, IID_IImageList, (void**)&piml);
+ if (FAILED_UNEXPECTEDLY(hr))
+ {
+ DestroyWindow();
+ return hr;
+ }
+ SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
+
+ // Enumerate objects
+ CComPtr<IEnumIDList> pEndl;
+ LPITEMIDLIST pidl;
+ STRRET stret;
+ hr = m_pISF->EnumObjects(0, SHCONTF_FOLDERS, &pEndl);
+ if (FAILED_UNEXPECTEDLY(hr))
+ {
+ DestroyWindow();
+ return hr;
+ }
+
+ for (int i=0; pEndl->Next(1, &pidl, NULL) != S_FALSE; i++)
+ {
+ WCHAR sz[MAX_PATH];
+ int index = SHMapPIDLToSystemImageListIndex(m_pISF, pidl, NULL);
+ hr = m_pISF->GetDisplayNameOf(pidl, SHGDN_NORMAL, &stret);
+ if (FAILED_UNEXPECTEDLY(hr))
+ {
+ strcpyW(sz, L"<Unknown-Name>");
+ }
+ else
+ StrRetToBuf(&stret, pidl, sz, _countof(sz));
+
+ TBBUTTON tb = { MAKELONG(index, 0), i, TBSTATE_ENABLED, buttonStyles,{ 0 },
(DWORD_PTR)pidl, (INT_PTR)sz };
+ SendMessage(m_hWnd, TB_INSERTBUTTONW, i, (LPARAM)&tb);
+ }
+
+ // Resize the toolbar, and then show it.
+ SendMessage(m_hWnd, TB_AUTOSIZE, 0, 0);
+
+ return hr;
+}
+
+/*****************************************************************************/
+
+// *** IObjectWithSite ***
+ STDMETHODIMP CISFBand::SetSite(IUnknown *pUnkSite)
+ {
+ HRESULT hr;
+ HWND hwndParent;
+
+ TRACE("CISFBand::SetSite(0x%p)\n", pUnkSite);
+
+ hr = IUnknown_GetWindow(pUnkSite, &hwndParent);
+ if (FAILED(hr))
+ {
+ TRACE("Querying site window failed: 0x%x\n", hr);
+ return hr;
+ }
+ m_Site = pUnkSite;
+
+ hr = CreateSimpleToolbar(hwndParent);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::GetSite(IN REFIID riid, OUT VOID **ppvSite)
+ {
+ TRACE("CISFBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
+
+ HRESULT hr;
+ if (m_Site != NULL)
+ {
+ hr = m_Site->QueryInterface(riid, ppvSite);
+ if (FAILED(hr)) return hr;
+ }
+
+ *ppvSite = NULL;
+ return E_FAIL;
+ }
+
+/*****************************************************************************/
+// *** IDeskBand ***
+ STDMETHODIMP CISFBand::GetWindow(OUT HWND *phwnd)
+ {
+ if (!m_hWnd)
+ return E_FAIL;
+ if (!phwnd)
+ return E_POINTER;
+ *phwnd = m_hWnd;
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::ContextSensitiveHelp(IN BOOL fEnterMode)
+ {
+ /* FIXME: Implement */
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CISFBand::ShowDW(IN BOOL bShow)
+ {
+ if (m_hWnd)
+ {
+ ShowWindow(bShow ? SW_SHOW : SW_HIDE);
+ return S_OK;
+ }
+
+ return E_FAIL;
+ }
+
+ STDMETHODIMP CISFBand::CloseDW(IN DWORD dwReserved)
+ {
+ if (m_hWnd)
+ {
+ ShowWindow(SW_HIDE);
+
+ TBBUTTON tb;
+ for (int i = 0; SendMessage(m_hWnd, TB_GETBUTTON, i, (LPARAM)&tb); i++)
+ {
+ CoTaskMemFree((LPITEMIDLIST)tb.dwData);
+ }
+
+ DestroyWindow();
+ m_hWnd = NULL;
+ return S_OK;
+ }
+
+ return E_FAIL;
+ }
+
+ STDMETHODIMP CISFBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite,
BOOL fReserved)
+ {
+ /* No need to implement this method */
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CISFBand::GetBandInfo(IN DWORD dwBandID, IN DWORD dwViewMode, IN OUT
DESKBANDINFO *pdbi)
+ {
+ TRACE("CTaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID,
dwViewMode, pdbi, m_hWnd);
+
+ if (m_hWnd && pdbi)
+ {
+ m_BandID = dwBandID;
+
+ RECT actualRect;
+ POINTL actualSize;
+ POINTL idealSize;
+ POINTL maxSize;
+ POINTL itemSize;
+
+ GetWindowRect(&actualRect);
+ actualSize.x = actualRect.right - actualRect.left;
+ actualSize.y = actualRect.bottom - actualRect.top;
+
+ // Obtain the ideal size, to be used as min and max
+ SendMessageW(m_hWnd, TB_AUTOSIZE, 0, 0);
+ SendMessageW(m_hWnd, TB_GETMAXSIZE, 0,
reinterpret_cast<LPARAM>(&maxSize));
+
+ idealSize = maxSize;
+ SendMessageW(m_hWnd, TB_GETIDEALSIZE, FALSE,
reinterpret_cast<LPARAM>(&idealSize));
+
+ // Obtain the button size, to be used as the integral size
+ DWORD size = SendMessageW(m_hWnd, TB_GETBUTTONSIZE, 0, 0);
+ itemSize.x = GET_X_LPARAM(size);
+ itemSize.y = GET_Y_LPARAM(size);
+
+ if (pdbi->dwMask & DBIM_MINSIZE)
+ {
+ pdbi->ptMinSize.x = -1;
+ pdbi->ptMinSize.y = idealSize.y;
+ }
+ if (pdbi->dwMask & DBIM_MAXSIZE)
+ {
+ pdbi->ptMaxSize = maxSize;
+ }
+ if (pdbi->dwMask & DBIM_INTEGRAL)
+ {
+ pdbi->ptIntegral = itemSize;
+ }
+ if (pdbi->dwMask & DBIM_ACTUAL)
+ {
+ pdbi->ptActual = actualSize;
+ }
+ if (pdbi->dwMask & DBIM_TITLE)
+ wcscpy(pdbi->wszTitle, L"Quick Launch");
+ if (pdbi->dwMask & DBIM_MODEFLAGS)
+ {
+ pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT |
DBIMF_USECHEVRON | DBIMF_NOMARGINS | DBIMF_BKCOLOR | DBIMF_ADDTOFRONT;
+ }
+ if (pdbi->dwMask & DBIM_BKCOLOR)
+ pdbi->dwMask &= ~DBIM_BKCOLOR;
+
+ return S_OK;
+ }
+
+ return E_FAIL;
+ }
+
+/*****************************************************************************/
+// *** IPersistStream ***
+ STDMETHODIMP CISFBand::GetClassID(OUT CLSID *pClassID)
+ {
+ TRACE("CISFBand::GetClassID(0x%p)\n", pClassID);
+ /* We're going to return the (internal!) CLSID of the quick launch band */
+ *pClassID = CLSID_QuickLaunchBand;
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::IsDirty()
+ {
+ /* The object hasn't changed since the last save! */
+
+ return S_FALSE;
+ }
+
+ STDMETHODIMP CISFBand::Load(IN IStream *pStm)
+ {
+ TRACE("CISFBand::Load called\n");
+ /* Nothing to do */
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::Save(IN IStream *pStm, IN BOOL fClearDirty)
+ {
+ /* Nothing to do */
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::GetSizeMax(OUT ULARGE_INTEGER *pcbSize)
+ {
+ TRACE("CISFBand::GetSizeMax called\n");
+
+ return S_OK;
+ }
+
+/*****************************************************************************/
+// *** IWinEventHandler ***
+ STDMETHODIMP CISFBand::ContainsWindow(IN HWND hWnd)
+ {
+ if (hWnd == m_hWnd || IsChild(hWnd))
+ {
+ TRACE("CISFBand::ContainsWindow(0x%p) returns S_OK\n", hWnd);
+ return S_OK;
+ }
+
+ return S_FALSE;
+ }
+
+ STDMETHODIMP CISFBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *theResult)
+ {
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ TBBUTTON tb;
+ bool chk = SendMessage(m_hWnd, TB_GETBUTTON, LOWORD(wParam),
(LPARAM)&tb);
+ if (chk)
+ SHInvokeDefaultCommand(m_hWnd, m_pISF, (LPITEMIDLIST)tb.dwData);
+
+ *theResult = TRUE;
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_RCLICK:
+ {
+ HRESULT hr;
+ POINT pt = ((LPNMMOUSE)lParam)->pt;
+ CComPtr<IContextMenu> picm;
+ HMENU fmenu = CreatePopupMenu();
+ TBBUTTON tb;
+
+ bool chk = SendMessage(m_hWnd, TB_GETBUTTON,
((LPNMMOUSE)lParam)->dwItemSpec, (LPARAM)&tb);
+ LPITEMIDLIST pidl = (LPITEMIDLIST)tb.dwData;
+
+ if (chk)
+ {
+ ClientToScreen(&pt);
+ hr = m_pISF->GetUIObjectOf(m_hWnd, 1, &pidl,
IID_NULL_PPV_ARG(IContextMenu, &picm));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = picm->QueryContextMenu(fmenu, 0, 1, 0x7FFF,
CMF_DEFAULTONLY);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ int id = TrackPopupMenuEx(fmenu, TPM_LEFTALIGN |
TPM_BOTTOMALIGN | TPM_RETURNCMD, pt.x, pt.y, m_hWnd, 0);
+ if (id > 0)
+ {
+ CMINVOKECOMMANDINFOEX info = { 0 };
+ info.cbSize = sizeof(info);
+ info.fMask = CMIC_MASK_PTINVOKE;
+ if (GetKeyState(VK_CONTROL) < 0)
+ {
+ info.fMask |= CMIC_MASK_CONTROL_DOWN;
+ }
+ if (GetKeyState(VK_SHIFT) < 0)
+ {
+ info.fMask |= CMIC_MASK_SHIFT_DOWN;
+ }
+ info.hwnd = m_hWnd;
+ info.lpVerb = MAKEINTRESOURCEA(id - 1);
+ info.nShow = SW_SHOWNORMAL;
+ info.ptInvoke = pt;
+
picm->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
+ }
+ }
+ DestroyMenu(fmenu);
+
+ *theResult = TRUE;
+ break;
+ }
+ default:
+ *theResult = FALSE;
+ }
+
+ break;
+ }
+ default:
+ *theResult = FALSE;
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::IsWindowOwner(HWND hWnd)
+ {
+ return (hWnd == m_hWnd) ? S_OK : S_FALSE;
+ }
+
+/*****************************************************************************/
+// *** IOleCommandTarget methods ***
+ STDMETHODIMP CISFBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD
prgCmds [], OLECMDTEXT *pCmdText)
+ {
+ UNIMPLEMENTED;
+
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CISFBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD
nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
+ {
+ if (IsEqualIID(*pguidCmdGroup, IID_IBandSite))
+ {
+ return S_OK;
+ }
+
+ if (IsEqualIID(*pguidCmdGroup, IID_IDeskBand))
+ {
+ return S_OK;
+ }
+
+ UNIMPLEMENTED;
+
+ return E_NOTIMPL;
+ }
+
+/*****************************************************************************/
+// *** IShellFolderBand ***
+ STDMETHODIMP CISFBand::GetBandInfoSFB(PBANDINFOSFB pbi)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CISFBand::InitializeSFB(IShellFolder *psf, PCIDLIST_ABSOLUTE pidl)
+ {
+ if (_ILIsDesktop(pidl))
+ {
+ m_pISF = psf;
+ m_pidl = ILClone(pidl);
+ }
+ else
+ {
+ psf->BindToObject(pidl, 0, IID_PPV_ARG(IShellFolder, &m_pISF));
+ m_pidl = ILClone(pidl);
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::SetBandInfoSFB( PBANDINFOSFB pbi)
+ {
+ return E_NOTIMPL;
+ }
+
+/*****************************************************************************/
+// *** IContextMenu ***
+ STDMETHODIMP CISFBand::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT
*pwReserved, LPSTR pszName, UINT cchMax)
+ {
+ /*HRESULT hr = E_INVALIDARG;
+
+ if (idCmd == IDM_DISPLAY)
+ {
+ switch (uFlags)
+ {
+ case GCS_HELPTEXTW:
+ // Only useful for pre-Vista versions of Windows that
+ // have a Status bar.
+ hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
+ cchMax,
+ L"Display File Name");
+ break;
+
+ case GCS_VERBW:
+ // GCS_VERBW is an optional feature that enables a caller
+ // to discover the canonical name for the verb that is passed in
+ // through idCommand.
+ hr = StringCchCopyW(reinterpret_cast<PWSTR>(pszName),
+ cchMax,
+ L"DisplayFileName");
+ break;
+ }
+ }
+ return hr; */
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
+ {
+ if (!HIWORD(pici->lpVerb))
+ {
+ switch (LOWORD(pici->lpVerb))
+ {
+ case IDM_LARGE_ICONS:
+ {
+ m_iconFlag = false;
+
+ HIMAGELIST* piml = (HIMAGELIST*) SendMessage(m_hWnd, TB_GETIMAGELIST,
0, 0);
+ HRESULT hr = SHGetImageList(SHIL_LARGE, IID_IImageList,
(void**)&piml);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
+ hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0,
NULL, NULL);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ break;
+ }
+ case IDM_SMALL_ICONS:
+ {
+ m_iconFlag = true;
+
+ HIMAGELIST* piml = (HIMAGELIST*)SendMessage(m_hWnd, TB_GETIMAGELIST,
0, 0);
+ HRESULT hr = SHGetImageList(SHIL_SMALL, IID_IImageList,
(void**)&piml);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ SendMessage(m_hWnd, TB_SETIMAGELIST, 0, (LPARAM)piml);
+ hr = IUnknown_Exec(m_Site, IID_IDeskBand, DBID_BANDINFOCHANGED, 0,
NULL, NULL);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ break;
+ }
+ case IDM_SHOW_TEXT:
+ {
+ if (m_textFlag)
+ {
+ m_textFlag = false;
+ SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0,
TBSTYLE_EX_MIXEDBUTTONS);
+ HRESULT hr = IUnknown_Exec(m_Site, IID_IDeskBand,
DBID_BANDINFOCHANGED, 0, NULL, NULL);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ }
+ else
+ {
+ m_textFlag = true;
+ SendMessage(m_hWnd, TB_SETEXTENDEDSTYLE, 0, 0);
+ HRESULT hr = IUnknown_Exec(m_Site, IID_IDeskBand,
DBID_BANDINFOCHANGED, 0, NULL, NULL);
+ if (FAILED_UNEXPECTEDLY(hr)) return hr;
+ }
+ break;
+ }
+ default:
+ return E_FAIL;
+ }
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP CISFBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags)
+ {
+ HMENU qMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(),
MAKEINTRESOURCE(IDM_POPUPMENU));
+ if(m_textFlag)
+ CheckMenuItem(qMenu, IDM_SHOW_TEXT, MF_CHECKED);
+ else
+ CheckMenuItem(qMenu, IDM_SHOW_TEXT, MF_UNCHECKED);
+
+ if (m_iconFlag)
+ {
+ CheckMenuItem(qMenu, IDM_SMALL_ICONS, MF_CHECKED);
+ CheckMenuItem(qMenu, IDM_LARGE_ICONS, MF_UNCHECKED);
+ }
+ else
+ {
+ CheckMenuItem(qMenu, IDM_LARGE_ICONS, MF_CHECKED);
+ CheckMenuItem(qMenu, IDM_SMALL_ICONS, MF_UNCHECKED);
+ }
+
+ 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));
+ }
+
+/*****************************************************************************/
+// C Constructor
+ extern "C"
+ HRESULT WINAPI CISFBand_CreateInstance(REFIID riid, void** ppv)
+ {
+ return ShellObjectCreator<CISFBand>(riid, ppv);
+ }
+
diff --git a/dll/shellext/qcklnch/CISFBand.h b/dll/shellext/qcklnch/CISFBand.h
new file mode 100644
index 0000000000..fc74db0b7c
--- /dev/null
+++ b/dll/shellext/qcklnch/CISFBand.h
@@ -0,0 +1,196 @@
+/*
+ * PROJECT: ReactOS shell extensions
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/shellext/qcklnch/CISFBand.h
+ * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
+ * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official(a)hotmail.com>
+ */
+#pragma once
+
+// COM class for cisfband
+class CISFBand :
+ public CWindow,
+ public CComCoClass<CISFBand>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IObjectWithSite,
+ public IDeskBand,
+ public IPersistStream,
+ public IWinEventHandler,
+ public IOleCommandTarget,
+ public IShellFolderBand,
+ public IContextMenu
+{
+ // Band
+ DWORD m_BandID;
+ CComPtr<IUnknown> m_Site;
+
+ // Toolbar
+ CComPtr<IShellFolder> m_pISF;
+ PCIDLIST_ABSOLUTE m_pidl;
+
+ // Menu
+ BOOL m_textFlag;
+ BOOL m_iconFlag;
+
+public:
+
+ CISFBand();
+ virtual ~CISFBand();
+
+// Personal Methods
+ HRESULT CreateSimpleToolbar(HWND hWndParent);
+
+// IObjectWithSite
+
+ virtual STDMETHODIMP GetSite(
+ IN REFIID riid,
+ OUT void **ppvSite
+ );
+
+ virtual STDMETHODIMP SetSite(
+ IN IUnknown *pUnkSite
+ );
+
+// IDeskBand
+
+ virtual STDMETHODIMP GetWindow(
+ OUT HWND *phwnd
+ );
+
+ virtual STDMETHODIMP ContextSensitiveHelp(
+ IN BOOL fEnterMode
+ );
+
+ virtual STDMETHODIMP ShowDW(
+ IN BOOL bShow
+ );
+
+ virtual STDMETHODIMP CloseDW(
+ IN DWORD dwReserved
+ );
+
+ virtual STDMETHODIMP ResizeBorderDW(
+ LPCRECT prcBorder,
+ IUnknown *punkToolbarSite,
+ BOOL fReserved
+ );
+
+ virtual STDMETHODIMP GetBandInfo(
+ IN DWORD dwBandID,
+ IN DWORD dwViewMode,
+ IN OUT DESKBANDINFO *pdbi
+ );
+
+// IPersistStream
+
+ virtual STDMETHODIMP GetClassID(
+ OUT CLSID *pClassID
+ );
+
+ virtual STDMETHODIMP GetSizeMax(
+ OUT ULARGE_INTEGER *pcbSize
+ );
+
+ virtual STDMETHODIMP IsDirty();
+
+ virtual STDMETHODIMP Load(
+ IN IStream *pStm
+ );
+
+ virtual STDMETHODIMP Save(
+ IN IStream *pStm,
+ IN BOOL fClearDirty
+ );
+
+// IWinEventHandler
+
+ virtual STDMETHODIMP ContainsWindow(
+ IN HWND hWnd
+ );
+
+ virtual STDMETHODIMP OnWinEvent(
+ HWND hWnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *theResult
+ );
+
+ virtual STDMETHODIMP IsWindowOwner(
+ HWND hWnd
+ );
+
+// IOleCommandTarget
+
+ virtual STDMETHODIMP Exec(
+ IN const GUID *pguidCmdGroup,
+ IN DWORD nCmdID,
+ IN DWORD nCmdexecopt,
+ IN VARIANT *pvaIn,
+ IN OUT VARIANT *pvaOut
+ );
+
+ virtual STDMETHODIMP QueryStatus(
+ IN const GUID *pguidCmdGroup,
+ IN ULONG cCmds,
+ IN OUT OLECMD prgCmds[],
+ IN OUT OLECMDTEXT *pCmdText
+ );
+
+// IShellFolderBand
+ virtual STDMETHODIMP GetBandInfoSFB(
+ PBANDINFOSFB pbi
+ );
+
+ virtual STDMETHODIMP InitializeSFB(
+ IShellFolder *psf,
+ PCIDLIST_ABSOLUTE pidl
+ );
+
+ virtual STDMETHODIMP SetBandInfoSFB(
+ PBANDINFOSFB pbi
+ );
+
+// IContextMenu
+ virtual STDMETHODIMP GetCommandString(
+ UINT_PTR idCmd,
+ UINT uFlags,
+ UINT *pwReserved,
+ LPSTR pszName,
+ UINT cchMax
+ );
+
+ virtual STDMETHODIMP InvokeCommand(
+ LPCMINVOKECOMMANDINFO pici
+ );
+
+ virtual STDMETHODIMP QueryContextMenu(
+ HMENU hmenu,
+ UINT indexMenu,
+ UINT idCmdFirst,
+ UINT idCmdLast,
+ UINT uFlags
+ );
+
+//*****************************************************************************************************
+
+ DECLARE_NOT_AGGREGATABLE(CISFBand)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CISFBand)
+ COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
+ COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
+ COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+ COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
+ COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
+ COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
+ COM_INTERFACE_ENTRY_IID(IID_IShellFolderBand, IShellFolderBand)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ END_COM_MAP()
+};
+
+// C Constructor
+extern "C"
+HRESULT WINAPI CISFBand_CreateInstance(REFIID riid, void** ppv);
\ No newline at end of file
diff --git a/dll/shellext/qcklnch/CMakeLists.txt b/dll/shellext/qcklnch/CMakeLists.txt
new file mode 100644
index 0000000000..bcc921891d
--- /dev/null
+++ b/dll/shellext/qcklnch/CMakeLists.txt
@@ -0,0 +1,43 @@
+
+project(SHELL)
+
+set_cpp(WITH_RUNTIME)
+
+if(NOT MSVC)
+ # HACK: this should be enabled globally!
+ add_compile_flags_language("-std=c++11" "CXX")
+endif()
+
+include_directories(
+ ${REACTOS_SOURCE_DIR}/sdk/lib/atl
+ ${REACTOS_SOURCE_DIR})
+
+spec2def(qcklnch.dll qcklnch.spec)
+
+add_library(qcklnch SHARED
+ qcklnch.rc
+ qcklnch.cpp
+ CQuickLaunchBand.cpp
+ CISFBand.cpp
+ CQuickLaunchBand.h
+ CISFBand.h
+ ${CMAKE_CURRENT_BINARY_DIR}/qcklnch.def)
+
+set_module_type(qcklnch win32dll UNICODE)
+target_link_libraries(qcklnch uuid wine atlnew)
+
+add_importlibs(qcklnch
+ advapi32
+ winmm
+ ole32
+ oleaut32
+ shlwapi
+ shell32
+ comctl32
+ msvcrt
+ gdi32
+ user32
+ kernel32
+ ntdll)
+
+add_cd_file(TARGET qcklnch DESTINATION reactos/system32 FOR all)
diff --git a/dll/shellext/qcklnch/CQuickLaunchBand.cpp
b/dll/shellext/qcklnch/CQuickLaunchBand.cpp
new file mode 100644
index 0000000000..d250a3c5ca
--- /dev/null
+++ b/dll/shellext/qcklnch/CQuickLaunchBand.cpp
@@ -0,0 +1,361 @@
+/*
+ * PROJECT: ReactOS shell extensions
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/shellext/qcklnch/CQuickLaunchBand.cpp
+ * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
+ * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official(a)hotmail.com>
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
+
+// {260CB95D-4544-44F6-A079-575BAA60B72F}
+static const GUID CLSID_QuickLaunchBand = { 0x260cb95d, 0x4544, 0x44f6, { 0xa0, 0x79,
0x57, 0x5b, 0xaa, 0x60, 0xb7, 0x2f } };
+
+// Componenet Category Registration
+ HRESULT RegisterComCat()
+ {
+ CComPtr<ICatRegister> pcr;
+ HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr));
+ if (SUCCEEDED(hr))
+ {
+ CATID catid = CATID_DeskBand;
+ hr = pcr->RegisterClassImplCategories(CLSID_QuickLaunchBand, 1,
&catid);
+ }
+ return hr;
+ }
+
+ HRESULT UnregisterComCat()
+ {
+ CComPtr<ICatRegister> pcr;
+ HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr));
+ if (SUCCEEDED(hr))
+ {
+ CATID catid = CATID_DeskBand;
+ hr = pcr->UnRegisterClassImplCategories(CLSID_QuickLaunchBand, 1,
&catid);
+ }
+ return hr;
+ }
+
+// Pidl Browser
+/*++
+* @name PidlBrowse
+*
+* Opens a folder browser dialog,
+* allowing the user to select a folder for enumeration.
+*
+* @param hwnd
+* A handle to browser dialog window.
+* @param nCSIDL
+* A CSIDL representing the root from which the browse folder dialog shows the
files and folders.
+*
+* @return The PIDL to selected folder.
+*
+*--*/
+ LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL)
+ {
+ CComHeapPtr<ITEMIDLIST> pidlRoot;
+
+ WCHAR path[MAX_PATH];
+
+ if (nCSIDL)
+ {
+ SHGetSpecialFolderLocation(hwnd, nCSIDL, &pidlRoot);
+ }
+
+ CString biTitle((LPCSTR)IDS_BROWSEINFO_TITLE);
+ BROWSEINFO bi = { hwnd, pidlRoot, path, biTitle, 0, NULL, 0, 0 };
+ LPITEMIDLIST pidlSelected = SHBrowseForFolder(&bi);
+
+ return pidlSelected;
+ }
+
+// CQuickLaunchBand
+
+ CQuickLaunchBand::CQuickLaunchBand() {}
+
+ CQuickLaunchBand::~CQuickLaunchBand() {}
+
+/*****************************************************************************/
+// ATL Construct
+/*++
+* @name FinalConstruct
+*
+* Creates an instance of CISFBand, and initializes its Shell Folder Band for
enumeration.
+*
+* @return The error code.
+*
+*--*/
+ HRESULT CQuickLaunchBand::FinalConstruct()
+ {
+ HRESULT hr = CISFBand_CreateInstance(IID_PPV_ARG(IUnknown, &m_punkISFB));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ CComPtr<IShellFolderBand> pISFB;
+ hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IShellFolderBand, &pISFB));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ CComPtr<IShellFolder> pISF;
+ hr = SHGetDesktopFolder(&pISF);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ CComHeapPtr<ITEMIDLIST> pidl(PidlBrowse(m_hWndBro, CSIDL_DESKTOP));
+ if (pidl == NULL)
+ return E_FAIL;
+ pISFB->InitializeSFB(pISF, pidl);
+
+ return hr;
+ }
+
+// IObjectWithSite
+ STDMETHODIMP CQuickLaunchBand::SetSite(IUnknown *pUnkSite)
+ {
+ TRACE("CQuickLaunchBand::SetSite(0x%p)\n", pUnkSite);
+
+ // Internal CISFBand Calls
+ CComPtr<IObjectWithSite> pIOWS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite,
&pIOWS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIOWS->SetSite(pUnkSite);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::GetSite(IN REFIID riid, OUT VOID **ppvSite)
+ {
+ TRACE("CQuickLaunchBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
+
+ // Internal CISFBand Calls
+ CComPtr<IObjectWithSite> pIOWS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite,
&pIOWS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIOWS->GetSite(riid, ppvSite);
+ }
+
+/*****************************************************************************/
+// IDeskBand
+ STDMETHODIMP CQuickLaunchBand::GetWindow(OUT HWND *phwnd)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->GetWindow(phwnd);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::ContextSensitiveHelp(IN BOOL fEnterMode)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->ContextSensitiveHelp(fEnterMode);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::ShowDW(IN BOOL bShow)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->ShowDW(bShow);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::CloseDW(IN DWORD dwReserved)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->CloseDW(dwReserved);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown
*punkToolbarSite, BOOL fReserved)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->ResizeBorderDW(prcBorder, punkToolbarSite, fReserved);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::GetBandInfo(IN DWORD dwBandID, IN DWORD dwViewMode, IN
OUT DESKBANDINFO *pdbi)
+ {
+ TRACE("CQuickLaunchBand::GetBandInfo(0x%x,0x%x,0x%p)\n", dwBandID,
dwViewMode, pdbi);
+
+ // Internal CISFBand Calls
+ CComPtr<IDeskBand> pIDB;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB));
+ if (FAILED(hr))
+ return hr;
+
+ return pIDB->GetBandInfo(dwBandID, dwViewMode, pdbi);
+ }
+
+/*****************************************************************************/
+// IPersistStream
+ STDMETHODIMP CQuickLaunchBand::GetClassID(OUT CLSID *pClassID)
+ {
+ TRACE("CQuickLaunchBand::GetClassID(0x%p)\n", pClassID);
+
+ // Internal CISFBand Calls
+ CComPtr<IPersistStream> pIPS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream,
&pIPS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIPS->GetClassID(pClassID);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::IsDirty()
+ {
+ // Internal CISFBand Calls
+ CComPtr<IPersistStream> pIPS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream,
&pIPS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIPS->IsDirty();
+ }
+
+ STDMETHODIMP CQuickLaunchBand::Load(IN IStream *pStm)
+ {
+ TRACE("CQuickLaunchBand::Load called\n");
+
+ // Internal CISFBand Calls
+ CComPtr<IPersistStream> pIPS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream,
&pIPS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIPS->Load(pStm);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::Save(IN IStream *pStm, IN BOOL fClearDirty)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IPersistStream> pIPS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream,
&pIPS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIPS->Save(pStm, fClearDirty);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::GetSizeMax(OUT ULARGE_INTEGER *pcbSize)
+ {
+ TRACE("CQuickLaunchBand::GetSizeMax called\n");
+
+ // Internal CISFBand Calls
+ CComPtr<IPersistStream> pIPS;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream,
&pIPS));
+ if (FAILED(hr))
+ return hr;
+
+ return pIPS->GetSizeMax(pcbSize);
+ }
+
+
+/*****************************************************************************/
+// IWinEventHandler
+ STDMETHODIMP CQuickLaunchBand::ContainsWindow(IN HWND hWnd)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CQuickLaunchBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam, LRESULT *theResult)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IWinEventHandler> pWEH;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler,
&pWEH));
+ if (FAILED(hr))
+ return hr;
+
+ return pWEH->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::IsWindowOwner(HWND hWnd)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IWinEventHandler> pWEH;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler,
&pWEH));
+ if (FAILED(hr))
+ return hr;
+
+ return pWEH->IsWindowOwner(hWnd);
+ }
+
+/*****************************************************************************/
+// *** IOleCommandTarget methods ***
+ STDMETHODIMP CQuickLaunchBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
OLECMD prgCmds [], OLECMDTEXT *pCmdText)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IOleCommandTarget> pOCT;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget,
&pOCT));
+ if (FAILED(hr))
+ return hr;
+
+ return pOCT->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD
nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IOleCommandTarget> pOCT;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget,
&pOCT));
+ if (FAILED(hr))
+ return hr;
+
+ return pOCT->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
+ }
+
+/*****************************************************************************/
+// *** IContextMenu ***
+ STDMETHODIMP CQuickLaunchBand::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT
*pwReserved, LPSTR pszName, UINT cchMax)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IContextMenu> pICM;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu,
&pICM));
+ if (FAILED(hr))
+ return hr;
+
+ return pICM->GetCommandString(idCmd, uFlags, pwReserved, pszName, cchMax);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IContextMenu> pICM;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu,
&pICM));
+ if (FAILED(hr))
+ return hr;
+
+ return pICM->InvokeCommand(pici);
+ }
+
+ STDMETHODIMP CQuickLaunchBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT
idCmdFirst, UINT idCmdLast, UINT uFlags)
+ {
+ // Internal CISFBand Calls
+ CComPtr<IContextMenu> pICM;
+ HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu,
&pICM));
+ if (FAILED(hr))
+ return hr;
+
+ return pICM->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast,
uFlags);
+ }
\ No newline at end of file
diff --git a/dll/shellext/qcklnch/CQuickLaunchBand.h
b/dll/shellext/qcklnch/CQuickLaunchBand.h
new file mode 100644
index 0000000000..c8a71dc9f4
--- /dev/null
+++ b/dll/shellext/qcklnch/CQuickLaunchBand.h
@@ -0,0 +1,174 @@
+/*
+ * PROJECT: ReactOS shell extensions
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/shellext/qcklnch/CQuickLaunchBand.h
+ * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
+ * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official(a)hotmail.com>
+ */
+#pragma once
+
+extern const GUID CLSID_QuickLaunchBand;
+
+// Component category registration
+HRESULT RegisterComCat();
+HRESULT UnregisterComCat();
+
+// COM class for quick launch
+class CQuickLaunchBand :
+ public CComCoClass<CQuickLaunchBand, &CLSID_QuickLaunchBand>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IObjectWithSite,
+ public IDeskBand,
+ public IPersistStream,
+ public IWinEventHandler,
+ public IOleCommandTarget,
+ public IContextMenu
+{
+ HWND m_hWndBro;
+ CComPtr<IUnknown> m_punkISFB;
+
+ public:
+
+ CQuickLaunchBand();
+ virtual ~CQuickLaunchBand();
+
+// ATL construct
+
+ HRESULT FinalConstruct();
+
+// IObjectWithSite
+
+ virtual STDMETHODIMP GetSite(
+ IN REFIID riid,
+ OUT void **ppvSite
+ );
+
+ virtual STDMETHODIMP SetSite(
+ IN IUnknown *pUnkSite
+ );
+
+// IDeskBand
+
+ virtual STDMETHODIMP GetWindow(
+ OUT HWND *phwnd
+ );
+
+ virtual STDMETHODIMP ContextSensitiveHelp(
+ IN BOOL fEnterMode
+ );
+
+ virtual STDMETHODIMP ShowDW(
+ IN BOOL bShow
+ );
+
+ virtual STDMETHODIMP CloseDW(
+ IN DWORD dwReserved
+ );
+
+ virtual STDMETHODIMP ResizeBorderDW(
+ LPCRECT prcBorder,
+ IUnknown *punkToolbarSite,
+ BOOL fReserved
+ );
+
+ virtual STDMETHODIMP GetBandInfo(
+ IN DWORD dwBandID,
+ IN DWORD dwViewMode,
+ IN OUT DESKBANDINFO *pdbi
+ );
+
+// IPersistStream
+
+ virtual STDMETHODIMP GetClassID(
+ OUT CLSID *pClassID
+ );
+
+ virtual STDMETHODIMP GetSizeMax(
+ OUT ULARGE_INTEGER *pcbSize
+ );
+
+ virtual STDMETHODIMP IsDirty();
+
+ virtual STDMETHODIMP Load(
+ IN IStream *pStm
+ );
+
+ virtual STDMETHODIMP Save(
+ IN IStream *pStm,
+ IN BOOL fClearDirty
+ );
+
+// IWinEventHandler
+
+ virtual STDMETHODIMP ContainsWindow(
+ IN HWND hWnd
+ );
+
+ virtual STDMETHODIMP OnWinEvent(
+ HWND hWnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *theResult
+ );
+
+ virtual STDMETHODIMP IsWindowOwner(
+ HWND hWnd
+ );
+
+// IOleCommandTarget
+
+ virtual STDMETHODIMP Exec(
+ IN const GUID *pguidCmdGroup,
+ IN DWORD nCmdID,
+ IN DWORD nCmdexecopt,
+ IN VARIANT *pvaIn,
+ IN OUT VARIANT *pvaOut
+ );
+
+ virtual STDMETHODIMP QueryStatus(
+ IN const GUID *pguidCmdGroup,
+ IN ULONG cCmds,
+ IN OUT OLECMD prgCmds[],
+ IN OUT OLECMDTEXT *pCmdText
+ );
+
+// IContextMenu
+ virtual STDMETHODIMP GetCommandString(
+ UINT_PTR idCmd,
+ UINT uFlags,
+ UINT *pwReserved,
+ LPSTR pszName,
+ UINT cchMax
+ );
+
+ virtual STDMETHODIMP InvokeCommand(
+ LPCMINVOKECOMMANDINFO pici
+ );
+
+ virtual STDMETHODIMP QueryContextMenu(
+ HMENU hmenu,
+ UINT indexMenu,
+ UINT idCmdFirst,
+ UINT idCmdLast,
+ UINT uFlags
+ );
+
+//*****************************************************************************************************
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_QCKLNCH)
+ DECLARE_NOT_AGGREGATABLE(CQuickLaunchBand)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CQuickLaunchBand)
+ COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
+ COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
+ COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+ COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
+ COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
+ COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ END_COM_MAP()
+};
\ No newline at end of file
diff --git a/dll/shellext/qcklnch/lang/en-US.rc b/dll/shellext/qcklnch/lang/en-US.rc
new file mode 100644
index 0000000000..81c08eb5d0
--- /dev/null
+++ b/dll/shellext/qcklnch/lang/en-US.rc
@@ -0,0 +1,19 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+IDM_POPUPMENU MENUEX DISCARDABLE
+BEGIN
+ POPUP ""
+ BEGIN
+ POPUP "&View", IDM_VIEW_MENU
+ BEGIN
+ MENUITEM "&Large Icons", IDM_LARGE_ICONS
+ MENUITEM "&Small Icons", IDM_SMALL_ICONS
+ END
+ MENUITEM "&Show Text", IDM_SHOW_TEXT
+ END
+END
+
+STRINGTABLE
+BEGIN
+ IDS_BROWSEINFO_TITLE "Choose a folder"
+END
diff --git a/dll/shellext/qcklnch/precomp.h b/dll/shellext/qcklnch/precomp.h
new file mode 100644
index 0000000000..12b27a9c15
--- /dev/null
+++ b/dll/shellext/qcklnch/precomp.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <tchar.h>
+
+#define COBJMACROS
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+#define NTOS_MODE_USER
+
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <winuser.h>
+#include <wincon.h>
+#include <ddeml.h>
+#include <shlguid_undoc.h>
+#include <shlwapi.h>
+#include <shlguid.h>
+#include <shlobj.h>
+#include <shlobj_undoc.h>
+#include <shlwapi_undoc.h>
+#include <tchar.h>
+#include <strsafe.h>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlwin.h>
+#include <atlstr.h>
+#include <undocshell.h>
+#include <shellutils.h>
+
+#include <shellapi.h>
+
+#include <wine/debug.h>
+#include <wine/unicode.h>
+
+#include "resource.h"
+#include "CQuickLaunchBand.h"
+#include "CISFBand.h"
\ No newline at end of file
diff --git a/dll/shellext/qcklnch/qcklnch.cpp b/dll/shellext/qcklnch/qcklnch.cpp
new file mode 100644
index 0000000000..79a5a45542
--- /dev/null
+++ b/dll/shellext/qcklnch/qcklnch.cpp
@@ -0,0 +1,70 @@
+/*
+ * PROJECT: ReactOS shell extensions
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/shellext/qcklnch/qcklnch.cpp
+ * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension)
+ * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official(a)hotmail.com>
+ */
+
+#include "precomp.h"
+
+#include <atlwin.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(qcklnch);
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ OBJECT_ENTRY(CLSID_QuickLaunchBand, CQuickLaunchBand)
+END_OBJECT_MAP()
+
+HINSTANCE g_hInstance;
+CComModule g_Module;
+
+STDAPI_(BOOL)
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInstance = hinstDLL;
+ DisableThreadLibraryCalls(g_hInstance);
+
+ g_Module.Init(ObjectMap, g_hInstance, NULL);
+ }
+ else if (fdwReason == DLL_PROCESS_DETACH)
+ {
+ g_hInstance = NULL;
+ g_Module.Term();
+ }
+ return TRUE;
+}
+
+STDAPI
+DllRegisterServer(void)
+{
+ HRESULT hr = g_Module.DllRegisterServer(FALSE);
+ if (FAILED(hr))
+ return hr;
+
+ return RegisterComCat();
+}
+
+STDAPI
+DllUnregisterServer(void)
+{
+ HRESULT hr = UnregisterComCat();
+ if (FAILED(hr))
+ return hr;
+
+ return g_Module.DllUnregisterServer(FALSE);
+}
+
+STDAPI
+DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ return g_Module.DllGetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI
+DllCanUnloadNow(void)
+{
+ return g_Module.DllCanUnloadNow();
+}
diff --git a/dll/shellext/qcklnch/qcklnch.rc b/dll/shellext/qcklnch/qcklnch.rc
new file mode 100644
index 0000000000..f44528e0af
--- /dev/null
+++ b/dll/shellext/qcklnch/qcklnch.rc
@@ -0,0 +1,15 @@
+#include <windef.h>
+#include <winuser.h>
+#include <commctrl.h>
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+IDR_QCKLNCH REGISTRY "rgs/qcklnch.rgs"
+
+#include <reactos/manifest_dll.rc>
+
+#ifdef LANGUAGE_EN_US
+ #include "lang/en-US.rc"
+#endif
+
diff --git a/dll/shellext/qcklnch/qcklnch.spec b/dll/shellext/qcklnch/qcklnch.spec
new file mode 100644
index 0000000000..069be11627
--- /dev/null
+++ b/dll/shellext/qcklnch/qcklnch.spec
@@ -0,0 +1,4 @@
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
\ No newline at end of file
diff --git a/dll/shellext/qcklnch/resource.h b/dll/shellext/qcklnch/resource.h
new file mode 100644
index 0000000000..b5613db3c2
--- /dev/null
+++ b/dll/shellext/qcklnch/resource.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#define IDR_QCKLNCH 1001
+
+#define IDM_POPUPMENU 2001
+#define IDM_LARGE_ICONS 1
+#define IDM_SMALL_ICONS 2
+#define IDM_SHOW_TEXT 3
+#define IDM_VIEW_MENU 4
+
+#define IDS_BROWSEINFO_TITLE 101
diff --git a/dll/shellext/qcklnch/rgs/qcklnch.rgs b/dll/shellext/qcklnch/rgs/qcklnch.rgs
new file mode 100644
index 0000000000..3df55ca1d3
--- /dev/null
+++ b/dll/shellext/qcklnch/rgs/qcklnch.rgs
@@ -0,0 +1,13 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {260CB95D-4544-44F6-A079-575BAA60B72F} = s 'Quick Launch'
+ {
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ }
+ }
+}
\ No newline at end of file