[SHDOCVW] Initial implementation of Favorites bar (#7146)

First step to Favorites bar support.
Menu: [View]→[Explorer bar]
→[Favorites]

JIRA issue: CORE-19686

- Add CFavBand.cpp, CFavBand.h,
  favband.rgs, and resource.h files.
- Modify CMakeLists.txt.
- Add IDS_ADD and IDS_ORGANIZE
  resource strings.
- Implement empty Favorites bar.
- The treeview is not populated yet.
- The Add button is not
  implemented yet.
This commit is contained in:
Katayama Hirofumi MZ 2024-07-18 23:21:40 +09:00 committed by GitHub
parent 61b7fb99eb
commit 69931a4a7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 919 additions and 8 deletions

View file

@ -0,0 +1,647 @@
/*
* PROJECT: ReactOS Explorer
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Favorites bar
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <undocshell.h>
#include <shlobj_undoc.h>
#include <shlguid_undoc.h>
#include <shlwapi_undoc.h>
#include <shdeprecated.h>
#include <olectlid.h>
#include <exdispid.h>
#include <shellutils.h>
#include <ui/rosctrls.h>
#include "shdocvw.h"
#include "CFavBand.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
void *operator new(size_t size)
{
return ::LocalAlloc(LPTR, size);
}
void operator delete(void *ptr)
{
::LocalFree(ptr);
}
void operator delete(void *ptr, size_t size)
{
::LocalFree(ptr);
}
#if 1
#undef UNIMPLEMENTED
#define UNIMPLEMENTED ERR("%s is UNIMPLEMENTED!\n", __FUNCTION__)
#endif
CFavBand::CFavBand()
: m_fVisible(FALSE)
, m_bFocused(FALSE)
, m_dwBandID(0)
, m_hToolbarImageList(NULL)
, m_hTreeViewImageList(NULL)
{
::InterlockedIncrement(&SHDOCVW_refCount);
SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &m_pidlFav);
}
CFavBand::~CFavBand()
{
if (m_hToolbarImageList)
{
ImageList_Destroy(m_hToolbarImageList);
m_hToolbarImageList = NULL;
}
if (m_hTreeViewImageList)
{
ImageList_Destroy(m_hTreeViewImageList);
m_hTreeViewImageList = NULL;
}
::InterlockedDecrement(&SHDOCVW_refCount);
}
VOID CFavBand::OnFinalMessage(HWND)
{
// The message loop is finished, now we can safely destruct!
Release();
}
// *** helper methods ***
BOOL CFavBand::CreateToolbar()
{
#define IDB_SHELL_EXPLORER_SM 216 // Borrowed from browseui.dll
HINSTANCE hinstBrowseUI = LoadLibraryExW(L"browseui.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
ATLASSERT(hinstBrowseUI);
HBITMAP hbmToolbar = NULL;
if (hinstBrowseUI)
{
hbmToolbar = LoadBitmapW(hinstBrowseUI, MAKEINTRESOURCEW(IDB_SHELL_EXPLORER_SM));
FreeLibrary(hinstBrowseUI);
}
#undef IDB_SHELL_EXPLORER_SM
ATLASSERT(hbmToolbar);
if (!hbmToolbar)
return FALSE;
m_hToolbarImageList = ImageList_Create(16, 16, ILC_COLOR32, 0, 8);
ATLASSERT(m_hToolbarImageList);
if (!m_hToolbarImageList)
return FALSE;
ImageList_Add(m_hToolbarImageList, hbmToolbar, NULL);
DeleteObject(hbmToolbar);
DWORD style = WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_LIST | CCS_NODIVIDER |
TBSTYLE_WRAPABLE;
HWND hwndTB = ::CreateWindowExW(0, TOOLBARCLASSNAMEW, NULL, style, 0, 0, 0, 0, m_hWnd,
(HMENU)(LONG_PTR)IDW_TOOLBAR, instance, NULL);
ATLASSERT(hwndTB);
if (!hwndTB)
return FALSE;
m_hwndToolbar.Attach(hwndTB);
m_hwndToolbar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
m_hwndToolbar.SendMessage(TB_SETIMAGELIST, 0, (LPARAM)m_hToolbarImageList);
m_hwndToolbar.SendMessage(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
WCHAR szzAdd[MAX_PATH], szzOrganize[MAX_PATH];
ZeroMemory(szzAdd, sizeof(szzAdd));
ZeroMemory(szzOrganize, sizeof(szzOrganize));
LoadStringW(instance, IDS_ADD, szzAdd, _countof(szzAdd));
LoadStringW(instance, IDS_ORGANIZE, szzOrganize, _countof(szzOrganize));
TBBUTTON tbb[2] = { { 0 } };
INT iButton = 0;
tbb[iButton].iBitmap = 3;
tbb[iButton].idCommand = ID_ADD;
tbb[iButton].fsState = TBSTATE_ENABLED;
tbb[iButton].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;
tbb[iButton].iString = (INT)m_hwndToolbar.SendMessage(TB_ADDSTRING, 0, (LPARAM)szzAdd);
++iButton;
tbb[iButton].iBitmap = 42;
tbb[iButton].idCommand = ID_ORGANIZE;
tbb[iButton].fsState = TBSTATE_ENABLED;
tbb[iButton].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE | BTNS_SHOWTEXT;
tbb[iButton].iString = (INT)m_hwndToolbar.SendMessage(TB_ADDSTRING, 0, (LPARAM)szzOrganize);
++iButton;
ATLASSERT(iButton == _countof(tbb));
LRESULT ret = m_hwndToolbar.SendMessage(TB_ADDBUTTONS, iButton, (LPARAM)&tbb);
ATLASSERT(ret);
return ret;
}
BOOL CFavBand::CreateTreeView()
{
m_hTreeViewImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 64, 0);
ATLASSERT(m_hTreeViewImageList);
if (!m_hTreeViewImageList)
return FALSE;
DWORD style = TVS_NOHSCROLL | TVS_NONEVENHEIGHT | TVS_FULLROWSELECT | TVS_INFOTIP |
TVS_SINGLEEXPAND | TVS_TRACKSELECT | TVS_SHOWSELALWAYS | TVS_EDITLABELS |
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_TABSTOP;
HWND hwndTV = ::CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, NULL, style, 0, 0, 0, 0,
m_hWnd, (HMENU)(ULONG_PTR)IDW_TREEVIEW, instance, NULL);
ATLASSERT(hwndTV);
if (!hwndTV)
return FALSE;
m_hwndTreeView.Attach(hwndTV);
TreeView_SetImageList(m_hwndTreeView, m_hTreeViewImageList, TVSIL_NORMAL);
return TRUE;
}
// *** message handlers ***
LRESULT CFavBand::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
INITCOMMONCONTROLSEX iccx = { sizeof(iccx), ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES };
if (!::InitCommonControlsEx(&iccx) || !CreateToolbar() || !CreateTreeView())
return -1;
return 0;
}
LRESULT CFavBand::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_hwndTreeView.DestroyWindow();
m_hwndToolbar.DestroyWindow();
return 0;
}
LRESULT CFavBand::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (!m_hwndTreeView)
return 0;
RECT rc;
GetClientRect(&rc);
LONG cx = rc.right, cy = rc.bottom;
RECT rcTB;
m_hwndToolbar.SendMessage(TB_AUTOSIZE, 0, 0);
m_hwndToolbar.GetWindowRect(&rcTB);
LONG cyTB = rcTB.bottom - rcTB.top;
m_hwndTreeView.MoveWindow(0, cyTB, cx, cy - cyTB);
return 0;
}
LRESULT CFavBand::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
m_bFocused = TRUE;
IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), TRUE);
return 0;
}
LRESULT CFavBand::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), FALSE);
m_bFocused = FALSE;
return 0;
}
LRESULT CFavBand::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
switch (LOWORD(wParam))
{
case ID_ADD:
{
UNIMPLEMENTED;
SHELL_ErrorBox(m_hWnd, ERROR_NOT_SUPPORTED);
break;
}
case ID_ORGANIZE:
{
SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_IDLIST };
sei.hwnd = m_hWnd;
sei.nShow = SW_SHOWNORMAL;
sei.lpIDList = m_pidlFav;
::ShellExecuteExW(&sei);
break;
}
}
return 0;
}
// *** IOleWindow ***
STDMETHODIMP CFavBand::GetWindow(HWND *lphwnd)
{
if (!lphwnd)
return E_INVALIDARG;
*lphwnd = m_hWnd;
return S_OK;
}
STDMETHODIMP CFavBand::ContextSensitiveHelp(BOOL fEnterMode)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IDockingWindow ***
STDMETHODIMP CFavBand::CloseDW(DWORD dwReserved)
{
// We do nothing, we don't have anything to save yet
TRACE("CloseDW called\n");
return S_OK;
}
STDMETHODIMP CFavBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
{
/* Must return E_NOTIMPL according to MSDN */
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::ShowDW(BOOL fShow)
{
m_fVisible = fShow;
ShowWindow(fShow ? SW_SHOW : SW_HIDE);
return S_OK;
}
// *** IDeskBand ***
STDMETHODIMP CFavBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
{
if (!pdbi)
return E_INVALIDARG;
m_dwBandID = dwBandID;
if (pdbi->dwMask & DBIM_MINSIZE)
{
pdbi->ptMinSize.x = 200;
pdbi->ptMinSize.y = 30;
}
if (pdbi->dwMask & DBIM_MAXSIZE)
pdbi->ptMaxSize.y = -1;
if (pdbi->dwMask & DBIM_INTEGRAL)
pdbi->ptIntegral.y = 1;
if (pdbi->dwMask & DBIM_ACTUAL)
{
pdbi->ptActual.x = 200;
pdbi->ptActual.y = 30;
}
if (pdbi->dwMask & DBIM_TITLE)
{
#define IDS_FAVORITES 47 // Borrowed from shell32.dll
HINSTANCE hShell32 = LoadLibraryExW(L"shell32.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
if (hShell32)
{
LoadStringW(hShell32, IDS_FAVORITES, pdbi->wszTitle, _countof(pdbi->wszTitle));
FreeLibrary(hShell32);
}
#undef IDS_FAVORITES
}
if (pdbi->dwMask & DBIM_MODEFLAGS)
pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
if (pdbi->dwMask & DBIM_BKCOLOR)
pdbi->dwMask &= ~DBIM_BKCOLOR;
return S_OK;
}
// *** IObjectWithSite ***
STDMETHODIMP CFavBand::SetSite(IUnknown *pUnkSite)
{
HRESULT hr;
if (pUnkSite == m_pSite)
return S_OK;
TRACE("SetSite called\n");
if (!pUnkSite)
{
DestroyWindow();
m_hWnd = NULL;
}
if (pUnkSite != m_pSite)
m_pSite = NULL;
if (!pUnkSite)
return S_OK;
HWND hwndParent;
hr = IUnknown_GetWindow(pUnkSite, &hwndParent);
if (!SUCCEEDED(hr))
{
ERR("Could not get parent's window! 0x%08lX\n", hr);
return E_INVALIDARG;
}
m_pSite = pUnkSite;
if (m_hWnd)
{
SetParent(hwndParent); // Change its parent
}
else
{
this->Create(hwndParent, NULL, NULL, WS_CHILD | WS_VISIBLE, 0, (UINT)0, NULL);
}
return S_OK;
}
STDMETHODIMP CFavBand::GetSite(REFIID riid, void **ppvSite)
{
if (!ppvSite)
return E_POINTER;
*ppvSite = m_pSite;
return S_OK;
}
// *** IOleCommandTarget ***
STDMETHODIMP CFavBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IServiceProvider ***
STDMETHODIMP CFavBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IServiceProvider ***
STDMETHODIMP CFavBand::QueryContextMenu(
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::InvokeCommand(
LPCMINVOKECOMMANDINFO lpici)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::GetCommandString(
UINT_PTR idCmd,
UINT uType,
UINT *pwReserved,
LPSTR pszName,
UINT cchMax)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IInputObject ***
STDMETHODIMP CFavBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
{
if (fActivate)
{
//SetFocus();
SetActiveWindow();
}
if (lpMsg)
{
TranslateMessage(lpMsg);
DispatchMessage(lpMsg);
}
return S_OK;
}
STDMETHODIMP CFavBand::HasFocusIO()
{
return m_bFocused ? S_OK : S_FALSE;
}
STDMETHODIMP CFavBand::TranslateAcceleratorIO(LPMSG lpMsg)
{
if (lpMsg->hwnd == m_hWnd)
{
TranslateMessage(lpMsg);
DispatchMessage(lpMsg);
return S_OK;
}
return S_FALSE;
}
// *** IPersist ***
STDMETHODIMP CFavBand::GetClassID(CLSID *pClassID)
{
if (!pClassID)
return E_POINTER;
*pClassID = CLSID_SH_FavBand;
return S_OK;
}
// *** IPersistStream ***
STDMETHODIMP CFavBand::IsDirty()
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::Load(IStream *pStm)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::Save(IStream *pStm, BOOL fClearDirty)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
// TODO: calculate max size
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IWinEventHandler ***
STDMETHODIMP CFavBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::IsWindowOwner(HWND hWnd)
{
return (hWnd == m_hWnd) ? S_OK : S_FALSE;
}
// *** IBandNavigate ***
STDMETHODIMP CFavBand::Select(long paramC)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** INamespaceProxy ***
STDMETHODIMP CFavBand::GetNavigateTarget(long paramC, long param10, long param14)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::Invoke(long paramC)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::OnSelectionChanged(long paramC)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::RefreshFlags(long paramC, long param10, long param14)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::CacheItem(long paramC)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
// *** IDispatch ***
STDMETHODIMP CFavBand::GetTypeInfoCount(UINT *pctinfo)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::GetIDsOfNames(
REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
STDMETHODIMP CFavBand::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
switch (dispIdMember)
{
case DISPID_DOWNLOADCOMPLETE:
case DISPID_NAVIGATECOMPLETE2:
// FIXME: Update current location
return S_OK;
}
return E_INVALIDARG;
}
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SH_FavBand, CFavBand)
END_OBJECT_MAP()
class CFavBandModule : public CComModule
{
public:
};
static CFavBandModule gModule;
EXTERN_C VOID
CFavBand_Init(HINSTANCE hInstance)
{
gModule.Init(ObjectMap, hInstance, NULL);
}
EXTERN_C HRESULT
CFavBand_DllCanUnloadNow(VOID)
{
return gModule.DllCanUnloadNow();
}
EXTERN_C HRESULT
CFavBand_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
return gModule.DllGetClassObject(rclsid, riid, ppv);
}
EXTERN_C HRESULT
CFavBand_DllRegisterServer(VOID)
{
return gModule.DllRegisterServer(FALSE);
}
EXTERN_C HRESULT
CFavBand_DllUnregisterServer(VOID)
{
return gModule.DllUnregisterServer(FALSE);
}

View file

@ -0,0 +1,183 @@
/*
* PROJECT: ReactOS Explorer
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Favorites bar
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
*/
#pragma once
EXTERN_C VOID CFavBand_Init(HINSTANCE hInstance);
EXTERN_C HRESULT CFavBand_DllCanUnloadNow(VOID);
EXTERN_C HRESULT CFavBand_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
EXTERN_C HRESULT CFavBand_DllRegisterServer(VOID);
EXTERN_C HRESULT CFavBand_DllUnregisterServer(VOID);
#define FAVBANDCLASSNAME L"ReactOS Favorites Band"
#ifdef __cplusplus
class CFavBand
: public CComCoClass<CFavBand, &CLSID_SH_FavBand>
, public CComObjectRootEx<CComMultiThreadModelNoCS>
, public CWindowImpl<CFavBand>
, public IDispatch
, public IDeskBand
, public IObjectWithSite
, public IInputObject
, public IPersistStream
, public IOleCommandTarget
, public IServiceProvider
, public IContextMenu
, public IBandNavigate
, public IWinEventHandler
, public INamespaceProxy
{
public:
DECLARE_WND_CLASS_EX(FAVBANDCLASSNAME, 0, COLOR_3DFACE)
static LPCWSTR GetWndClassName() { return FAVBANDCLASSNAME; }
CFavBand();
virtual ~CFavBand();
// *** IOleWindow methods ***
STDMETHODIMP GetWindow(HWND *lphwnd) override;
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) override;
// *** IDockingWindow methods ***
STDMETHODIMP CloseDW(DWORD dwReserved) override;
STDMETHODIMP ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved) override;
STDMETHODIMP ShowDW(BOOL fShow) override;
// *** IDeskBand methods ***
STDMETHODIMP GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi) override;
// *** IObjectWithSite methods ***
STDMETHODIMP SetSite(IUnknown *pUnkSite) override;
STDMETHODIMP GetSite(REFIID riid, void **ppvSite) override;
// *** IOleCommandTarget methods ***
STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) override;
STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override;
// *** IServiceProvider methods ***
STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppvObject) override;
// *** IContextMenu methods ***
STDMETHODIMP QueryContextMenu(
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags) override;
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpici) override;
STDMETHODIMP GetCommandString(
UINT_PTR idCmd,
UINT uType,
UINT *pwReserved,
LPSTR pszName,
UINT cchMax) override;
// *** IInputObject methods ***
STDMETHODIMP UIActivateIO(BOOL fActivate, LPMSG lpMsg) override;
STDMETHODIMP HasFocusIO() override;
STDMETHODIMP TranslateAcceleratorIO(LPMSG lpMsg) override;
// *** IPersist methods ***
STDMETHODIMP GetClassID(CLSID *pClassID) override;
// *** IPersistStream methods ***
STDMETHODIMP IsDirty() override;
STDMETHODIMP Load(IStream *pStm) override;
STDMETHODIMP Save(IStream *pStm, BOOL fClearDirty) override;
STDMETHODIMP GetSizeMax(ULARGE_INTEGER *pcbSize) override;
// *** IWinEventHandler methods ***
STDMETHODIMP OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) override;
STDMETHODIMP IsWindowOwner(HWND hWnd) override;
// *** IBandNavigate methods ***
STDMETHODIMP Select(long paramC) override;
// *** INamespaceProxy methods ***
STDMETHODIMP GetNavigateTarget(long paramC, long param10, long param14) override;
STDMETHODIMP Invoke(long paramC) override;
STDMETHODIMP OnSelectionChanged(long paramC) override;
STDMETHODIMP RefreshFlags(long paramC, long param10, long param14) override;
STDMETHODIMP CacheItem(long paramC) override;
// *** IDispatch methods ***
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) override;
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override;
STDMETHODIMP GetIDsOfNames(
REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId) override;
STDMETHODIMP Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr) override;
DECLARE_REGISTRY_RESOURCEID(IDR_FAVBAND)
DECLARE_NOT_AGGREGATABLE(CFavBand)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CFavBand)
COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch)
COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand)
COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand)
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream)
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY2_IID(IID_IUnknown, IUnknown, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IBandNavigate, IBandNavigate)
COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
COM_INTERFACE_ENTRY_IID(IID_INamespaceProxy, INamespaceProxy)
END_COM_MAP()
BEGIN_MSG_MAP(CFavBand)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
END_MSG_MAP()
protected:
BOOL m_fVisible;
BOOL m_bFocused;
DWORD m_dwBandID;
CComPtr<IUnknown> m_pSite;
CComHeapPtr<ITEMIDLIST> m_pidlFav;
HIMAGELIST m_hToolbarImageList;
HIMAGELIST m_hTreeViewImageList;
CToolbar<> m_hwndToolbar;
CTreeView m_hwndTreeView;
VOID OnFinalMessage(HWND) override;
// *** helper methods ***
BOOL CreateToolbar();
BOOL CreateTreeView();
// *** message handlers ***
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
};
#endif // def __cplusplus

View file

@ -1,9 +1,7 @@
add_definitions(
-D__WINESRC__
-D_SHDOCVW_)
include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
spec2def(shdocvw.dll shdocvw.spec ADD_IMPORTLIB)
list(APPEND SOURCE
@ -19,12 +17,23 @@ add_library(shdocvw MODULE
${SOURCE}
mrulist.cpp
shdocvw.rc
$<TARGET_OBJECTS:shdocvw_sublib>
${CMAKE_CURRENT_BINARY_DIR}/shdocvw.def)
set_module_type(shdocvw win32dll)
target_include_directories(shdocvw BEFORE PRIVATE
${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine
)
set_module_type(shdocvw win32dll UNICODE)
target_link_libraries(shdocvw uuid wine)
add_delay_importlibs(shdocvw shell32 ole32 oleaut32 ieframe)
add_importlibs(shdocvw shlwapi advapi32 msvcrt kernel32 ntdll)
add_delay_importlibs(shdocvw shell32 user32 gdi32 ole32 oleaut32 ieframe)
add_importlibs(shdocvw shlwapi advapi32 msvcrt comctl32 kernel32 ntdll)
add_dependencies(shdocvw stdole2)
add_pch(shdocvw precomp.h SOURCE)
add_cd_file(TARGET shdocvw DESTINATION reactos/system32 FOR all)
add_library(shdocvw_sublib OBJECT CFavBand.cpp)
target_link_libraries(shdocvw_sublib PRIVATE atl_classes)
target_compile_definitions(shdocvw_sublib PRIVATE $<TARGET_PROPERTY:shdocvw,COMPILE_DEFINITIONS>)
target_compile_options(shdocvw_sublib PRIVATE $<TARGET_PROPERTY:shdocvw,COMPILE_OPTIONS>)
add_dependencies(shdocvw_sublib psdk)

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {EFA24E61-B078-11D0-89E4-00C04FC9E26E} = s 'Favorites Band'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -0,0 +1,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
STRINGTABLE
BEGIN
IDS_ADD "Add"
IDS_ORGANIZE "Organize"
END

View file

@ -0,0 +1,12 @@
#define IDR_SHDOCVW 1
#define IDR_FAVBAND 2
#define IDR_TYPELIB 1
#define IDW_TOOLBAR 2
#define IDW_TREEVIEW 100
#define ID_ADD 100
#define ID_ORGANIZE 101
#define IDS_ADD 1000
#define IDS_ORGANIZE 1001

View file

@ -60,9 +60,17 @@ static inline void SHDOCVW_LockModule(void) { InterlockedIncrement( &SHDOCVW_ref
static inline void SHDOCVW_UnlockModule(void) { InterlockedDecrement( &SHDOCVW_refCount ); }
#ifdef __REACTOS__
#include "resource.h"
EXTERN_C HRESULT CMruLongList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3);
EXTERN_C HRESULT CMruPidlList_CreateInstance(DWORD_PTR dwUnused1, void **ppv, DWORD_PTR dwUnused3);
EXTERN_C HRESULT CMruClassFactory_CreateInstance(REFIID riid, void **ppv);
#define ARRAY_SIZE(array) _countof(array)
#ifdef __cplusplus
void *operator new(size_t size);
void operator delete(void *ptr);
void operator delete(void *ptr, size_t size);
#endif
EXTERN_C HINSTANCE instance;
#endif // def __REACTOS__
#endif /* __WINE_SHDOCVW_H */

View file

@ -17,10 +17,13 @@
*/
#include "windef.h"
#include "resource.h"
1 WINE_REGISTRY "shdocvw_v1.rgs"
IDR_SHDOCVW WINE_REGISTRY "shdocvw_v1.rgs"
1 TYPELIB "shdocvw_v1.tlb"
IDR_FAVBAND REGISTRY "favband.rgs"
IDR_TYPELIB TYPELIB "shdocvw_v1.tlb"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
@ -33,3 +36,10 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
#include "wine/wine_common_ver.rc"
/* UTF-8 */
#pragma code_page(65001)
#ifdef LANGUAGE_EN_US
#include "lang/en-US.rc"
#endif

View file

@ -32,6 +32,7 @@
#include "winnls.h"
#include <shlguid_undoc.h>
#include <rpcproxy.h> /* for __wine_register_resources / __wine_unregister_resources */
#include "CFavBand.h"
#endif
#include "shlwapi.h"
#include "wininet.h"
@ -46,7 +47,7 @@ LONG SHDOCVW_refCount = 0;
static HMODULE SHDOCVW_hshell32 = 0;
static HINSTANCE ieframe_instance;
#ifdef __REACTOS__
static HINSTANCE instance;
HINSTANCE instance;
#endif
static HINSTANCE get_ieframe_instance(void)
@ -93,6 +94,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
return get_ieframe_object(rclsid, riid, ppv);
#ifdef __REACTOS__
{
HRESULT hr = CFavBand_DllGetClassObject(rclsid, riid, ppv);
if (hr != CLASS_E_CLASSNOTAVAILABLE)
return hr;
}
if (IsEqualGUID(riid, &IID_IClassFactory) || IsEqualGUID(riid, &IID_IUnknown))
{
if (IsEqualGUID(rclsid, &CLSID_MruLongList) ||
@ -122,6 +128,7 @@ HRESULT WINAPI DllRegisterServer(void)
{
TRACE("\n");
#ifdef __REACTOS__
CFavBand_DllRegisterServer();
return __wine_register_resources(instance);
#else
return S_OK;
@ -135,6 +142,7 @@ HRESULT WINAPI DllUnregisterServer(void)
{
TRACE("\n");
#ifdef __REACTOS__
CFavBand_DllUnregisterServer();
return __wine_unregister_resources(instance);
#else
return S_OK;
@ -181,6 +189,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
case DLL_PROCESS_ATTACH:
#ifdef __REACTOS__
instance = hinst;
CFavBand_Init(hinst);
#endif
DisableThreadLibraryCalls(hinst);
break;
@ -198,6 +207,10 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
#ifdef __REACTOS__
if (CFavBand_DllCanUnloadNow() != S_OK)
return S_FALSE;
#endif
return SHDOCVW_refCount ? S_FALSE : S_OK;
}

View file

@ -160,7 +160,11 @@ static HRESULT WINAPI RegistryPropertyBag_IPropertyBag_Write(IPropertyBag *iface
return E_NOTIMPL;
}
#ifdef __REACTOS__
static IPropertyBagVtbl RegistryPropertyBag_IPropertyBagVtbl = {
#else
static const IPropertyBagVtbl RegistryPropertyBag_IPropertyBagVtbl = {
#endif
RegistryPropertyBag_IPropertyBag_QueryInterface,
RegistryPropertyBag_IPropertyBag_AddRef,
RegistryPropertyBag_IPropertyBag_Release,
@ -305,7 +309,11 @@ static HRESULT WINAPI InstanceObjectFactory_IClassFactory_LockServer(IClassFacto
return S_OK;
}
#ifdef __REACTOS__
static IClassFactoryVtbl InstanceObjectFactory_IClassFactoryVtbl = {
#else
static const IClassFactoryVtbl InstanceObjectFactory_IClassFactoryVtbl = {
#endif
InstanceObjectFactory_IClassFactory_QueryInterface,
InstanceObjectFactory_IClassFactory_AddRef,
InstanceObjectFactory_IClassFactory_Release,