- Commit rshell.exe that allows explorer_new to run in windows 8

svn path=/branches/shell-experiments/; revision=61978
This commit is contained in:
Giannis Adamopoulos 2014-02-04 12:11:51 +00:00
commit 222f0efde5
7 changed files with 1051 additions and 0 deletions

View file

@ -3,3 +3,4 @@ add_subdirectory(cmd)
add_subdirectory(explorer)
add_subdirectory(explorer-new)
add_subdirectory(filebrowser)
add_subdirectory(rshell)

View file

@ -0,0 +1,582 @@
/*
* Shell Desktop
*
* Copyright 2008 Thomas Bluemel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(desktop);
BOOL WINAPI SetShellWindowEx(HWND, HWND);
#define SHDESK_TAG 0x4b534544
static const WCHAR szProgmanClassName[] = {'P','r','o','g','m','a','n'};
static const WCHAR szProgmanWindowName[] = {
'P','r','o','g','r','a','m',' ','M','a','n','a','g','e','r'
};
class CDesktopBrowser :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellBrowser,
public ICommDlgBrowser,
public IServiceProvider
{
public:
DWORD Tag;
private:
HWND hWnd;
HWND hWndShellView;
HWND hWndDesktopListView;
CComPtr<IShellDesktopTray> ShellDesk;
CComPtr<IShellView> DesktopView;
IShellBrowser *DefaultShellBrowser;
LPITEMIDLIST pidlDesktopDirectory;
LPITEMIDLIST pidlDesktop;
public:
CDesktopBrowser();
~CDesktopBrowser();
HRESULT Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx);
HWND FindDesktopListView ();
BOOL CreateDeskWnd();
HWND DesktopGetWindowControl(IN UINT id);
static LRESULT CALLBACK ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam);
static BOOL MessageLoop();
// *** IOleWindow methods ***
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
// *** IShellBrowser methods ***
virtual HRESULT STDMETHODCALLTYPE InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
virtual HRESULT STDMETHODCALLTYPE SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject);
virtual HRESULT STDMETHODCALLTYPE RemoveMenusSB(HMENU hmenuShared);
virtual HRESULT STDMETHODCALLTYPE SetStatusTextSB(LPCOLESTR pszStatusText);
virtual HRESULT STDMETHODCALLTYPE EnableModelessSB(BOOL fEnable);
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorSB(MSG *pmsg, WORD wID);
virtual HRESULT STDMETHODCALLTYPE BrowseObject(LPCITEMIDLIST pidl, UINT wFlags);
virtual HRESULT STDMETHODCALLTYPE GetViewStateStream(DWORD grfMode, IStream **ppStrm);
virtual HRESULT STDMETHODCALLTYPE GetControlWindow(UINT id, HWND *lphwnd);
virtual HRESULT STDMETHODCALLTYPE SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret);
virtual HRESULT STDMETHODCALLTYPE QueryActiveShellView(struct IShellView **ppshv);
virtual HRESULT STDMETHODCALLTYPE OnViewWindowActive(struct IShellView *ppshv);
virtual HRESULT STDMETHODCALLTYPE SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags);
// *** ICommDlgBrowser methods ***
virtual HRESULT STDMETHODCALLTYPE OnDefaultCommand (struct IShellView *ppshv);
virtual HRESULT STDMETHODCALLTYPE OnStateChange (struct IShellView *ppshv, ULONG uChange);
virtual HRESULT STDMETHODCALLTYPE IncludeObject (struct IShellView *ppshv, LPCITEMIDLIST pidl);
// *** IServiceProvider methods ***
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
BEGIN_COM_MAP(CDesktopBrowser)
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
COM_INTERFACE_ENTRY_IID(IID_ICommDlgBrowser, ICommDlgBrowser)
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
END_COM_MAP()
};
CDesktopBrowser::CDesktopBrowser()
{
Tag = SHDESK_TAG;
hWnd = NULL;
hWndShellView = NULL;
hWndDesktopListView = NULL;
DefaultShellBrowser = NULL;
pidlDesktopDirectory = NULL;
pidlDesktop = NULL;
}
CDesktopBrowser::~CDesktopBrowser()
{
if (DesktopView.p != NULL)
{
if (hWndShellView != NULL)
DesktopView->DestroyViewWindow();
hWndShellView = NULL;
hWndDesktopListView = NULL;
}
if (pidlDesktopDirectory != NULL)
{
ILFree(pidlDesktopDirectory);
pidlDesktopDirectory = NULL;
}
if (pidlDesktop != NULL)
{
ILFree(pidlDesktop);
pidlDesktop = NULL;
}
}
HRESULT CDesktopBrowser::Initialize(HWND hWndx, IShellDesktopTray *ShellDeskx)
{
CComPtr<IShellFolder> psfDesktopFolder;
CSFV csfv;
HRESULT hRet;
hWnd = hWndx;
ShellDesk = ShellDeskx;
ShellDesk->AddRef();
pidlDesktopDirectory = SHCloneSpecialIDList(hWnd, CSIDL_DESKTOPDIRECTORY, FALSE);
hRet = SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &pidlDesktop);
if (FAILED(hRet))
return hRet;
hRet = SHGetDesktopFolder(&psfDesktopFolder);
if (FAILED(hRet))
return hRet;
ZeroMemory(&csfv, sizeof(csfv));
csfv.cbSize = sizeof(csfv);
csfv.pshf = psfDesktopFolder;
csfv.psvOuter = NULL;
hRet = SHCreateShellFolderViewEx(&csfv, &DesktopView);
return hRet;
}
static CDesktopBrowser *SHDESK_Create(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
IShellDesktopTray *ShellDesk;
CComObject<CDesktopBrowser> *pThis;
HRESULT hRet;
ShellDesk = (IShellDesktopTray *)lpCreateStruct->lpCreateParams;
if (ShellDesk == NULL)
{
WARN("No IShellDesk interface provided!");
return NULL;
}
pThis = new CComObject<CDesktopBrowser>;
if (pThis == NULL)
return NULL;
pThis->AddRef();
hRet = pThis->Initialize(hWnd, ShellDesk);
if (FAILED(hRet))
{
pThis->Release();
return NULL;
}
return pThis;
}
HWND CDesktopBrowser::FindDesktopListView ()
{
return FindWindowExW(hWndShellView, NULL, WC_LISTVIEW, NULL);
}
BOOL CDesktopBrowser::CreateDeskWnd()
{
FOLDERSETTINGS fs;
RECT rcClient;
HRESULT hRet;
if (!GetClientRect(hWnd, &rcClient))
{
return FALSE;
}
fs.ViewMode = FVM_ICON;
fs.fFlags = FWF_DESKTOP | FWF_NOCLIENTEDGE | FWF_NOSCROLL | FWF_TRANSPARENT;
hRet = DesktopView->CreateViewWindow(NULL, &fs, (IShellBrowser *)this, &rcClient, &hWndShellView);
if (!SUCCEEDED(hRet))
return FALSE;
SetShellWindowEx(hWnd, FindDesktopListView());
#if 1
/* A windows 8 specific hack */
::ShowWindow(hWndShellView, SW_SHOW);
::ShowWindow(FindDesktopListView(), SW_SHOW);
#endif
return TRUE;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetWindow(HWND *phwnd)
{
if (hWnd != NULL)
{
*phwnd = hWnd;
return S_OK;
}
*phwnd = NULL;
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::ContextSensitiveHelp(BOOL fEnterMode)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::RemoveMenusSB(HMENU hmenuShared)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetStatusTextSB(LPCOLESTR lpszStatusText)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::EnableModelessSB(BOOL fEnable)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::TranslateAcceleratorSB(LPMSG lpmsg, WORD wID)
{
return S_FALSE;
}
typedef HRESULT (WINAPI *SH_OPEN_NEW_FRAME)(LPITEMIDLIST pidl, IUnknown *paramC, long param10, long param14);
HRESULT STDMETHODCALLTYPE CDesktopBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
{
/*
* We should use IShellWindows interface here in order to attempt to
* find an open shell window that shows the requested pidl and activate it
*/
#if 0
HMODULE hBrowseui = LoadLibraryW(L"browseui.dll");
if (hBrowseui)
{
SH_OPEN_NEW_FRAME SHOpenNewFrame = (SH_OPEN_NEW_FRAME)GetProcAddress(hBrowseui, (LPCSTR)103);
return SHOpenNewFrame((LPITEMIDLIST)pidl, NULL, 0, 0);
}
#endif
return E_FAIL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
{
return E_NOTIMPL;
}
HWND CDesktopBrowser::DesktopGetWindowControl(IN UINT id)
{
switch (id)
{
case FCW_TOOLBAR:
case FCW_STATUS:
case FCW_TREE:
case FCW_PROGRESS:
return NULL;
default:
return NULL;
}
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::GetControlWindow(UINT id, HWND *lphwnd)
{
HWND hWnd;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*lphwnd = hWnd;
return S_OK;
}
*lphwnd = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SendControlMsg(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
{
HWND hWnd;
if (pret == NULL)
return E_POINTER;
hWnd = DesktopGetWindowControl(id);
if (hWnd != NULL)
{
*pret = SendMessageW(hWnd,
uMsg,
wParam,
lParam);
return S_OK;
}
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryActiveShellView(IShellView **ppshv)
{
*ppshv = DesktopView;
if (DesktopView != NULL)
DesktopView->AddRef();
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnViewWindowActive(IShellView *ppshv)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnDefaultCommand(IShellView *ppshv)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::OnStateChange(IShellView *ppshv, ULONG uChange)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::IncludeObject(IShellView *ppshv, LPCITEMIDLIST pidl)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE CDesktopBrowser::QueryService(REFGUID guidService, REFIID riid, PVOID *ppv)
{
/* FIXME - handle guidService */
return QueryInterface(riid, ppv);
}
BOOL CDesktopBrowser::MessageLoop()
{
MSG Msg;
BOOL bRet;
while ((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0)
{
if (bRet != -1)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
return TRUE;
}
LRESULT CALLBACK CDesktopBrowser::ProgmanWindowProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
{
CDesktopBrowser *pThis = NULL;
LRESULT Ret = FALSE;
if (uMsg != WM_NCCREATE)
{
pThis = (CDesktopBrowser*)GetWindowLongPtrW(hwnd,
0);
if (pThis == NULL)
goto DefMsgHandler;
}
if (pThis != NULL || uMsg == WM_NCCREATE)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return (LRESULT)PaintDesktop((HDC)wParam);
case WM_GETISHELLBROWSER:
Ret = (LRESULT)((IShellBrowser *)pThis);
break;
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
/* Hey, we're the desktop!!! */
ShowWindow(hwnd,
SW_RESTORE);
}
else
{
RECT rcDesktop;
rcDesktop.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesktop.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesktop.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesktop.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
/* FIXME: Update work area */
}
break;
case WM_SYSCOLORCHANGE:
case WM_SETTINGCHANGE:
{
if (uMsg == WM_SYSCOLORCHANGE || wParam == SPI_SETDESKWALLPAPER || wParam == 0)
{
if (pThis->hWndShellView != NULL)
{
/* Forward the message */
SendMessageW(pThis->hWndShellView,
uMsg,
wParam,
lParam);
}
}
break;
}
case WM_CREATE:
{
pThis->ShellDesk->RegisterDesktopWindow(pThis->hWnd);
if (!pThis->CreateDeskWnd())
WARN("Could not create the desktop view control!\n");
break;
}
case WM_NCCREATE:
{
LPCREATESTRUCT CreateStruct = (LPCREATESTRUCT)lParam;
pThis = SHDESK_Create(hwnd, CreateStruct);
if (pThis == NULL)
{
WARN("Failed to create desktop structure\n");
break;
}
SetWindowLongPtrW(hwnd,
0,
(LONG_PTR)pThis);
Ret = TRUE;
break;
}
case WM_NCDESTROY:
{
pThis->Release();
break;
}
default:
DefMsgHandler:
Ret = DefWindowProcW(hwnd, uMsg, wParam, lParam);
break;
}
}
return Ret;
}
static BOOL
RegisterProgmanWindowClass(VOID)
{
WNDCLASSW wcProgman;
wcProgman.style = CS_DBLCLKS;
wcProgman.lpfnWndProc = CDesktopBrowser::ProgmanWindowProc;
wcProgman.cbClsExtra = 0;
wcProgman.cbWndExtra = sizeof(CDesktopBrowser *);
wcProgman.hInstance = shell32_hInstance;
wcProgman.hIcon = NULL;
wcProgman.hCursor = LoadCursorW(NULL, IDC_ARROW);
wcProgman.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wcProgman.lpszMenuName = NULL;
wcProgman.lpszClassName = szProgmanClassName;
return RegisterClassW(&wcProgman) != 0;
}
/*************************************************************************
* SHCreateDesktop [SHELL32.200]
*
*/
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
{
HWND hWndDesk;
RECT rcDesk;
if (ShellDesk == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
if (RegisterProgmanWindowClass() == 0)
{
WARN("Failed to register the Progman window class!\n");
return NULL;
}
rcDesk.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
rcDesk.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
rcDesk.right = rcDesk.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
rcDesk.bottom = rcDesk.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (IsRectEmpty(&rcDesk))
{
rcDesk.left = rcDesk.top = 0;
rcDesk.right = GetSystemMetrics(SM_CXSCREEN);
rcDesk.bottom = GetSystemMetrics(SM_CYSCREEN);
}
hWndDesk = CreateWindowExW(0, szProgmanClassName, szProgmanWindowName,
WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
rcDesk.left, rcDesk.top, rcDesk.right, rcDesk.bottom,
NULL, NULL, shell32_hInstance, (LPVOID)ShellDesk);
if (hWndDesk != NULL)
return (HANDLE)GetWindowLongPtrW(hWndDesk, 0);
return NULL;
}
/*************************************************************************
* SHCreateDesktop [SHELL32.201]
*
*/
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
{
CDesktopBrowser *Desk = (CDesktopBrowser *)hDesktop;
if (Desk == NULL || Desk->Tag != SHDESK_TAG)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return Desk->MessageLoop();
}

View file

@ -0,0 +1,31 @@
PROJECT(SHELL)
set_cpp(WITH_RUNTIME)
include_directories(${REACTOS_SOURCE_DIR}/lib/atl)
spec2def(rshell.dll rshell.spec ADD_IMPORTLIB)
list(APPEND SOURCE
CDesktopBrowser.cpp
CStartMenu.cpp
misc.cpp
${CMAKE_CURRENT_BINARY_DIR}/rshell.def)
add_library(rshell SHARED ${SOURCE})
set_module_type(rshell win32dll UNICODE)
target_link_libraries(rshell
atlnew
uuid
wine)
add_importlibs(rshell
shlwapi
shell32
ole32
user32
msvcrt
kernel32
ntdll)

View file

@ -0,0 +1,318 @@
/*
* ReactOS Explorer
*
* Copyright 2014 Giannis Adamopoulos
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
/* NOTE: The following constants may *NOT* be changed because
they're hardcoded and need to be the exact values
in order to get the start menu to work! */
#define IDM_PROGRAMS 504
#define IDM_FAVORITES 507
#define IDM_DOCUMENTS 501
#define IDM_SETTINGS 508
#define IDM_CONTROLPANEL 505
#define IDM_SECURITY 5001
#define IDM_NETWORKCONNECTIONS 557
#define IDM_PRINTERSANDFAXES 510
#define IDM_TASKBARANDSTARTMENU 413
#define IDM_SEARCH 520
#define IDM_HELPANDSUPPORT 503
#define IDM_RUN 401
#define IDM_SYNCHRONIZE 553
#define IDM_LOGOFF 402
#define IDM_DISCONNECT 5000
#define IDM_UNDOCKCOMPUTER 410
#define IDM_SHUTDOWN 506
#define IDM_LASTSTARTMENU_SEPARATOR 450
/*
* TODO:
* 1. append the start menu contents from all users
* 2. implement the context menu for start menu entries (programs, control panel, network connetions, printers)
* 3. filter out programs folder from the shell folder part of the start menu
*/
class CShellMenuCallback :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellMenuCallback
{
private:
HWND m_hwndTray;
CComPtr<IShellMenu> m_pShellMenu;
CComPtr<IBandSite> m_pBandSite;
CComPtr<IDeskBar> m_pDeskBar;
CComPtr<ITrayPriv> m_pTrayPriv;
HRESULT OnInitMenu()
{
HMENU hmenu;
HRESULT hr;
if (m_pTrayPriv.p)
return S_OK;
hr = IUnknown_GetSite(m_pDeskBar, IID_PPV_ARG(ITrayPriv, &m_pTrayPriv));
hr = IUnknown_GetWindow(m_pTrayPriv, &m_hwndTray);
hr = m_pTrayPriv->AppendMenuW(&hmenu);
hr = m_pShellMenu->SetMenu(hmenu, NULL, SMSET_BOTTOM);
return hr;
}
HRESULT OnGetInfo(LPSMDATA psmd, SMINFO *psminfo)
{
int iconIndex = 0;
switch (psmd->uId)
{
case IDM_PROGRAMS: iconIndex = -20; break;
case IDM_FAVORITES: iconIndex = -173; break;
case IDM_DOCUMENTS: iconIndex = -21; break;
case IDM_SETTINGS: iconIndex = -22; break;
case IDM_CONTROLPANEL: iconIndex = -22; break;
//case IDM_SECURITY: iconIndex = -21; break;
case IDM_NETWORKCONNECTIONS: iconIndex = -257; break;
case IDM_PRINTERSANDFAXES: iconIndex = -138; break;
case IDM_TASKBARANDSTARTMENU: iconIndex = -40; break;
case IDM_SEARCH: iconIndex = -23; break;
case IDM_HELPANDSUPPORT: iconIndex = -24; break;
case IDM_RUN: iconIndex = -25; break;
//case IDM_SYNCHRONIZE: iconIndex = -21; break;
case IDM_LOGOFF: iconIndex = -45; break;
//case IDM_DISCONNECT: iconIndex = -21; break;
//case IDM_UNDOCKCOMPUTER: iconIndex = -21; break;
case IDM_SHUTDOWN: iconIndex = -28; break;
default:
return S_FALSE;
}
if (iconIndex)
{
psminfo->dwMask = SMIM_ICON;
psminfo->iIcon = Shell_GetCachedImageIndex(L"shell32.dll", iconIndex, FALSE);
}
return S_OK;
}
HRESULT OnGetSubMenu(LPSMDATA psmd, REFIID iid, void ** pv)
{
HRESULT hr;
int csidl = 0;
IShellMenu *pShellMenu;
switch (psmd->uId)
{
case IDM_PROGRAMS: csidl = CSIDL_PROGRAMS; break;
case IDM_FAVORITES: csidl = CSIDL_FAVORITES; break;
case IDM_DOCUMENTS: csidl = CSIDL_RECENT; break;
}
hr = CoCreateInstance(CLSID_MenuBand,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IShellMenu,&pShellMenu));
hr = pShellMenu->Initialize(this, 0, ANCESTORDEFAULT, SMINIT_VERTICAL);
if (csidl)
{
LPITEMIDLIST pidlStartMenu;
IShellFolder *psfDestop, *psfStartMenu;
hr = SHGetFolderLocation(NULL, csidl, 0, 0, &pidlStartMenu);
hr = SHGetDesktopFolder(&psfDestop);
hr = psfDestop->BindToObject(pidlStartMenu, NULL, IID_PPV_ARG(IShellFolder, &psfStartMenu));
hr = pShellMenu->SetShellFolder(psfStartMenu, NULL, NULL, 0);
}
else
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (GetMenuItemInfoW( psmd->hmenu, psmd->uId, FALSE, &mii))
{
hr = pShellMenu->SetMenu(mii.hSubMenu, NULL, SMSET_BOTTOM);
}
}
return pShellMenu->QueryInterface(iid, pv);
}
HRESULT OnGetContextMenu(LPSMDATA psmd, REFIID iid, void ** pv)
{
if (psmd->uId == IDM_PROGRAMS ||
psmd->uId == IDM_CONTROLPANEL ||
psmd->uId == IDM_NETWORKCONNECTIONS ||
psmd->uId == IDM_PRINTERSANDFAXES)
{
//UNIMPLEMENTED
}
return S_FALSE;
}
HRESULT OnGetObject(LPSMDATA psmd, REFIID iid, void ** pv)
{
if (IsEqualIID(iid , IID_IShellMenu))
return OnGetSubMenu(psmd, iid, pv);
else if (IsEqualIID( iid, IID_IContextMenu))
return OnGetContextMenu(psmd, iid, pv);
return S_FALSE;
}
HRESULT OnExec(LPSMDATA psmd)
{
if(psmd->uId == IDM_CONTROLPANEL)
ShellExecuteW(NULL, L"open", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}", NULL,NULL, 1);
else if(psmd->uId == IDM_NETWORKCONNECTIONS)
ShellExecuteW(NULL, L"open", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}", NULL,NULL, 1);
else if(psmd->uId == IDM_PRINTERSANDFAXES)
ShellExecuteW(NULL, L"open", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}", NULL,NULL, 1);
else
PostMessageW( m_hwndTray, WM_COMMAND, psmd->uId, 0);
return S_OK;
}
public:
DECLARE_NOT_AGGREGATABLE(CShellMenuCallback)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CShellMenuCallback)
COM_INTERFACE_ENTRY_IID(IID_IShellMenuCallback, IShellMenuCallback)
END_COM_MAP()
void Initialize(
IShellMenu* pShellMenu,
IBandSite* pBandSite,
IDeskBar* pDeskBar)
{
m_pShellMenu.Attach(pShellMenu);
m_pBandSite.Attach(pBandSite);
m_pDeskBar.Attach(pDeskBar);
}
~CShellMenuCallback()
{
m_pShellMenu.Release();
m_pBandSite.Release();
m_pDeskBar.Release();
}
HRESULT STDMETHODCALLTYPE CallbackSM(
LPSMDATA psmd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case SMC_INITMENU:
return OnInitMenu();
case SMC_GETINFO:
return OnGetInfo(psmd, reinterpret_cast<SMINFO*>(lParam));
case SMC_GETOBJECT:
return OnGetObject(psmd, *reinterpret_cast<IID *>(wParam), reinterpret_cast<void **>(lParam));
case SMC_EXEC:
return OnExec(psmd);
case SMC_SFEXEC:
m_pTrayPriv->Execute(psmd->psf, psmd->pidlItem);
break;
}
return S_FALSE;
}
};
extern "C"
HRESULT
CStartMenu_Constructor(
REFIID riid,
void **ppv)
{
IShellMenu* pShellMenu;
IBandSite* pBandSite;
IDeskBar* pDeskBar;
IShellMenuCallback* callback;
LPITEMIDLIST pidlStartMenu;
HRESULT hr;
IShellFolder *shellFolder;
IShellFolder *psfStartMenu;
hr = CoCreateInstance(CLSID_MenuBand,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IShellMenu, &pShellMenu));
if (FAILED(hr))
return NULL;
#if 1
hr = CoCreateInstance(CLSID_MenuBandSite,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IBandSite, &pBandSite));
#else
hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
#endif
if (FAILED(hr))
return NULL;
hr = CoCreateInstance(CLSID_MenuDeskBar,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IDeskBar, &pDeskBar));
if (FAILED(hr))
return NULL;
CComObject<CShellMenuCallback> *pCallback;
hr = CComObject<CShellMenuCallback>::CreateInstance(&pCallback);
if (FAILED(hr))
return FALSE;
pCallback->AddRef(); // CreateInstance returns object with 0 ref count */
pCallback->Initialize(pShellMenu, pBandSite, pDeskBar);
callback = pCallback;
hr = CShellMenuCallback::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellMenuCallback, &callback));
if (FAILED(hr))
return NULL;
pShellMenu->Initialize(pCallback, -1, 0, SMINIT_TOPLEVEL | SMINIT_VERTICAL);
if (FAILED(hr))
return NULL;
hr = SHGetFolderLocation(NULL, CSIDL_STARTMENU, 0, 0, &pidlStartMenu);
hr = SHGetDesktopFolder(&shellFolder);
hr = shellFolder->BindToObject(pidlStartMenu, NULL, IID_IShellFolder, (void**)&psfStartMenu);
hr = pShellMenu->SetShellFolder(psfStartMenu, NULL, NULL, 0);
hr = pDeskBar->SetClient(pBandSite);
if (FAILED(hr))
return NULL;
hr = pBandSite->AddBand(pShellMenu);
if (FAILED(hr))
return NULL;
return pDeskBar->QueryInterface(riid, ppv);
}

View file

@ -0,0 +1,60 @@
/*
* ReactOS Explorer
*
* Copyright 2014 Giannis Adamopoulos
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "precomp.h"
DWORD WINAPI WinList_Init(void)
{
/* do something here (perhaps we may want to add our own implementation fo win8) */
return 0;
}
void *operator new (size_t, void *buf)
{
return buf;
}
class CRShellModule : public CComModule
{
public:
};
CRShellModule gModule;
CAtlWinModule gWinModule;
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID fImpLoad)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
/* HACK - the global constructors don't run, so I placement new them here */
new (&gModule) CRShellModule;
new (&gWinModule) CAtlWinModule;
new (&_AtlBaseModule) CAtlBaseModule;
new (&_AtlComModule) CAtlComModule;
gModule.Init(NULL, hInstance, NULL);
DisableThreadLibraryCalls (hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
gModule.Term();
}
return TRUE;
}

View file

@ -0,0 +1,55 @@
#include <stdio.h>
#include <tchar.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define COBJMACROS
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <wingdi.h>
#include <winnls.h>
#include <wincon.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shlobj_undoc.h>
#include <shlwapi.h>
#include <shlguid_undoc.h>
#include <uxtheme.h>
#include <strsafe.h>
#include <atlbase.h>
#include <atlcom.h>
#include <wine/debug.h>
#define shell32_hInstance 0
#define SMC_EXEC 4
extern "C" INT WINAPI Shell_GetCachedImageIndex(LPCWSTR szPath, INT nIndex, UINT bSimulateDoc);
extern "C" HRESULT CMenuSite_Constructor(REFIID riid, void **ppv);
#define INTERFACE IExplorerHostCreator
DECLARE_INTERFACE_(IExplorerHostCreator,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
/*** IExplorerHostCreator ***/
STDMETHOD_(HRESULT,CreateHost)(/*THIS,*/ const GUID* guid) PURE;
STDMETHOD_(HRESULT,RunHost)(THIS) PURE;
};
#undef INTERFACE
#if defined(COBJMACROS)
/*** IUnknown methods ***/
#define IExplorerHostCreator_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define IExplorerHostCreator_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IExplorerHostCreator_Release(p) (p)->lpVtbl->Release(p)
/*** IExplorerHostCreator methods ***/
#define IExplorerHostCreator_CreateHost(p,a) (p)->lpVtbl->CreateHost(p,a)
#define IExplorerHostCreator_RunHost(p) (p)->lpVtbl->RunHost(p)
#endif

View file

@ -0,0 +1,4 @@
@ stdcall CStartMenu_Constructor(ptr ptr)
@ stdcall SHDesktopMessageLoop(ptr)
@ stdcall SHCreateDesktop(ptr)
@ stdcall WinList_Init()