[EXPLORER-NEW]

* Convert codebase to C++ and make use of C++ classes for the COM objects.

svn path=/branches/shell-experiments/; revision=65197
This commit is contained in:
David Quintana 2014-11-02 20:18:54 +00:00
parent 3da5418d3f
commit 162ff471bb
26 changed files with 9863 additions and 11333 deletions

View file

@ -1,28 +1,34 @@
PROJECT(SHELL)
add_definitions(-DWIN32)
set_cpp(WITH_RUNTIME)
include_directories(${REACTOS_SOURCE_DIR}/lib/atl)
list(APPEND SOURCE
desktop.c
dragdrop.c
explorer.c
rshell.c
settings.c
shellservice.c
startmnu.c
startup.c
taskband.c
taskswnd.c
tbsite.c
trayntfy.c
trayprop.c
traywnd.c
desktop.cpp
dragdrop.cpp
explorer.cpp
rshell.cpp
settings.cpp
shellservice.cpp
startmnu.cpp
startup.cpp
taskband.cpp
taskswnd.cpp
tbsite.cpp
trayntfy.cpp
trayprop.cpp
traywnd.cpp
util.cpp
precomp.h)
add_executable(explorer ${SOURCE} explorer.rc)
target_link_libraries(explorer uuid wine)
target_link_libraries(explorer uuid atlnew wine)
set_module_type(explorer win32gui UNICODE)
add_importlibs(explorer advapi32 gdi32 user32 comctl32 ole32 oleaut32 shell32 browseui shlwapi shdocvw version uxtheme msvcrt kernel32 ntdll)
add_pch(explorer precomp.h SOURCE)
add_cd_file(TARGET explorer DESTINATION reactos FOR all)

View file

@ -27,30 +27,29 @@ typedef struct _DESKCREATEINFO
HANDLE hDesktop;
} DESKCREATEINFO, *PDESKCREATEINFO;
HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk);
BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop);
static DWORD CALLBACK
DesktopThreadProc(IN OUT LPVOID lpParameter)
{
volatile DESKCREATEINFO *DeskCreateInfo = (volatile DESKCREATEINFO *)lpParameter;
IShellDesktopTray *pSdt;
CComPtr<IShellDesktopTray> pSdt;
HANDLE hDesktop;
HRESULT hRet;
OleInitialize(NULL);
hRet = ITrayWindow_QueryInterface(DeskCreateInfo->Tray,
&IID_IShellDesktopTray,
(PVOID*)&pSdt);
hRet = DeskCreateInfo->Tray->QueryInterface(IID_PPV_ARG(IShellDesktopTray, &pSdt));
if (!SUCCEEDED(hRet))
return 1;
hDesktop = SHCreateDesktop(pSdt);
hDesktop = _SHCreateDesktop(pSdt);
IShellDesktopTray_Release(pSdt);
if (hDesktop == NULL)
return 1;
(void)InterlockedExchangePointer(&DeskCreateInfo->hDesktop,
hDesktop);
(void)InterlockedExchangePointer(&DeskCreateInfo->hDesktop, hDesktop);
if (!SetEvent(DeskCreateInfo->hEvent))
{
@ -59,7 +58,7 @@ DesktopThreadProc(IN OUT LPVOID lpParameter)
return 1;
}
SHDesktopMessageLoop(hDesktop);
_SHDesktopMessageLoop(hDesktop);
/* FIXME: Properly rundown the main thread! */
ExitProcess(0);

View file

@ -1,411 +0,0 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
static const IDropTargetVtbl IDropTargetImpl_Vtbl;
/*
* IDropTarget
*/
typedef struct
{
const IDropTargetVtbl *lpVtbl;
LONG Ref;
HWND hwndTarget;
IDropTargetHelper *DropTargetHelper;
PVOID Context;
BOOL CanDrop;
DROPTARGET_CALLBACKS Callbacks;
DWORD FormatsCount;
FORMATETC Formats[0];
} IDropTargetImpl;
static IUnknown *
IUnknown_from_impl(IDropTargetImpl *This)
{
return (IUnknown *)&This->lpVtbl;
}
static IDropTarget *
IDropTarget_from_impl(IDropTargetImpl *This)
{
return (IDropTarget *)&This->lpVtbl;
}
static IDropTargetImpl *
impl_from_IDropTarget(IDropTarget *iface)
{
return (IDropTargetImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDropTargetImpl,
lpVtbl));
}
static VOID
IDropTargetImpl_Free(IDropTargetImpl *This)
{
IDropTargetHelper_Release(This->DropTargetHelper);
HeapFree(hProcessHeap,
0,
This);
}
static ULONG STDMETHODCALLTYPE
IDropTargetImpl_Release(IN OUT IDropTarget *iface)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
ULONG Ret;
Ret = InterlockedDecrement(&This->Ref);
if (Ret == 0)
IDropTargetImpl_Free(This);
return Ret;
}
static ULONG STDMETHODCALLTYPE
IDropTargetImpl_AddRef(IN OUT IDropTarget *iface)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
return InterlockedIncrement(&This->Ref);
}
static HRESULT STDMETHODCALLTYPE
IDropTargetImpl_QueryInterface(IN OUT IDropTarget *iface,
IN REFIID riid,
OUT LPVOID *ppvObj)
{
IDropTargetImpl *This;
if (ppvObj == NULL)
return E_POINTER;
This = impl_from_IDropTarget(iface);
if (IsEqualIID(riid,
&IID_IUnknown))
{
*ppvObj = IUnknown_from_impl(This);
}
else if (IsEqualIID(riid,
&IID_IDropTarget))
{
*ppvObj = IDropTarget_from_impl(This);
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
IDropTargetImpl_AddRef(iface);
return S_OK;
}
IDropTarget *
CreateDropTarget(IN HWND hwndTarget,
IN DWORD nSupportedFormats,
IN const FORMATETC *Formats OPTIONAL,
IN PVOID Context OPTIONAL,
IN const DROPTARGET_CALLBACKS *Callbacks OPTIONAL)
{
IDropTargetImpl *This;
HRESULT hr;
This = HeapAlloc(hProcessHeap,
HEAP_ZERO_MEMORY,
FIELD_OFFSET(IDropTargetImpl,
Formats[nSupportedFormats]));
if (This != NULL)
{
This->lpVtbl = &IDropTargetImpl_Vtbl;
This->Ref = 1;
This->hwndTarget = hwndTarget;
This->FormatsCount = nSupportedFormats;
if (nSupportedFormats != 0)
{
CopyMemory(This->Formats,
Formats,
sizeof(Formats[0]) * nSupportedFormats);
}
This->Context = Context;
if (Callbacks != NULL)
{
CopyMemory(&This->Callbacks,
Callbacks,
sizeof(*Callbacks));
}
hr = CoCreateInstance(&CLSID_DragDropHelper,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IDropTargetHelper,
(PVOID *)&This->DropTargetHelper);
if (!SUCCEEDED(hr))
{
HeapFree(hProcessHeap,
0,
This);
return NULL;
}
return IDropTarget_from_impl(This);
}
return NULL;
}
static const FORMATETC *
IDropTargetImpl_FindSupportedFormat(IN OUT IDropTargetImpl *This,
IN IDataObject *pDataObject)
{
FORMATETC *Current, *Last;
HRESULT hr;
/* NOTE: we could use IDataObject::EnumFormatEtc(),
but this appears to be a lot easier! */
Last = This->Formats + This->FormatsCount;
for (Current = This->Formats;
Current != Last;
Current++)
{
hr = IDataObject_QueryGetData(pDataObject,
Current);
if (SUCCEEDED(hr))
return Current;
}
return NULL;
}
static HRESULT STDMETHODCALLTYPE
IDropTargetImpl_DragEnter(IN OUT IDropTarget *iface,
IN IDataObject *pDataObject,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
const FORMATETC *Format;
HRESULT hr;
if (pDataObject == NULL)
return E_INVALIDARG;
This->CanDrop = FALSE;
hr = IDropTargetHelper_DragEnter(This->DropTargetHelper,
This->hwndTarget,
pDataObject,
(POINT *)&pt,
*pdwEffect);
if (SUCCEEDED(hr))
{
Format = IDropTargetImpl_FindSupportedFormat(This,
pDataObject);
if (Format != NULL)
{
/* We found a format that we support! */
if (This->Callbacks.OnDragEnter != NULL)
{
hr = This->Callbacks.OnDragEnter(iface,
This->Context,
Format,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr == S_OK)
This->CanDrop = TRUE;
else
{
/* Special return value by the callback routine,
doesn't want to allow dragging */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
static HRESULT STDMETHODCALLTYPE
IDropTargetImpl_DragOver(IN OUT IDropTarget *iface,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
HRESULT hr;
hr = IDropTargetHelper_DragOver(This->DropTargetHelper,
(POINT *)&pt,
*pdwEffect);
if (SUCCEEDED(hr))
{
if (This->CanDrop)
{
if (This->Callbacks.OnDragOver != NULL)
{
hr = This->Callbacks.OnDragOver(iface,
This->Context,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr != S_OK)
{
/* Special return value by the callback routine,
doesn't want to allow dropping here */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
static HRESULT STDMETHODCALLTYPE
IDropTargetImpl_DragLeave(IN OUT IDropTarget *iface)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
HRESULT hr;
hr = IDropTargetHelper_DragLeave(This->DropTargetHelper);
if (SUCCEEDED(hr))
{
if (This->Callbacks.OnDragLeave != NULL)
{
hr = This->Callbacks.OnDragLeave(iface,
This->Context);
}
}
return hr;
}
static HRESULT STDMETHODCALLTYPE
IDropTargetImpl_Drop(IN OUT IDropTarget *iface,
IN IDataObject *pDataObject,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
IDropTargetImpl *This = impl_from_IDropTarget(iface);
const FORMATETC *Format;
HRESULT hr;
if (pDataObject == NULL)
return E_INVALIDARG;
hr = IDropTargetHelper_Drop(This->DropTargetHelper,
pDataObject,
(POINT *)&pt,
*pdwEffect);
if (SUCCEEDED(hr) && This->CanDrop)
{
Format = IDropTargetImpl_FindSupportedFormat(This,
pDataObject);
if (Format != NULL)
{
/* We found a format that we support! */
if (This->Callbacks.OnDrop != NULL)
{
hr = This->Callbacks.OnDrop(iface,
This->Context,
Format,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr == S_OK)
This->CanDrop = TRUE;
else
{
/* Special return value by the callback routine,
doesn't want to allow dragging */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
static const IDropTargetVtbl IDropTargetImpl_Vtbl =
{
/* IUnknown */
IDropTargetImpl_QueryInterface,
IDropTargetImpl_AddRef,
IDropTargetImpl_Release,
/* IDropTarget */
IDropTargetImpl_DragEnter,
IDropTargetImpl_DragOver,
IDropTargetImpl_DragLeave,
IDropTargetImpl_Drop
};

View file

@ -0,0 +1,314 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
class CDropTarget :
public CComCoClass<CDropTarget>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTarget
{
HWND hwndTarget;
CComPtr<IDropTargetHelper> DropTargetHelper;
PVOID Context;
BOOL CanDrop;
DROPTARGET_CALLBACKS Callbacks;
DWORD FormatsCount;
FORMATETC* Formats;
const FORMATETC *
FindSupportedFormat(IN IDataObject *pDataObject)
{
FORMATETC *Current, *Last;
HRESULT hr;
/* NOTE: we could use IDataObject::EnumFormatEtc(),
but this appears to be a lot easier! */
Last = Formats + FormatsCount;
for (Current = Formats;
Current != Last;
Current++)
{
hr = pDataObject->QueryGetData(Current);
if (SUCCEEDED(hr))
return Current;
}
return NULL;
}
public:
CDropTarget() :
hwndTarget(NULL),
Context(NULL),
CanDrop(FALSE),
FormatsCount(0),
Formats(NULL)
{
ZeroMemory(&Callbacks, sizeof(Callbacks));
}
virtual ~CDropTarget() { }
HRESULT Initialize(IN HWND hwndTarget,
IN DWORD nSupportedFormats,
IN const FORMATETC *formats OPTIONAL,
IN PVOID Context OPTIONAL,
IN const DROPTARGET_CALLBACKS *Callbacks OPTIONAL)
{
this->hwndTarget = hwndTarget;
FormatsCount = nSupportedFormats;
if (nSupportedFormats != 0)
{
Formats = new FORMATETC[nSupportedFormats];
CopyMemory(Formats,
formats,
sizeof(formats[0]) * nSupportedFormats);
}
this->Context = Context;
if (Callbacks != NULL)
{
CopyMemory(&this->Callbacks,
Callbacks,
sizeof(*Callbacks));
}
HRESULT hr = CoCreateInstance(CLSID_DragDropHelper,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IDropTargetHelper, &DropTargetHelper));
return hr;
}
virtual HRESULT STDMETHODCALLTYPE DragEnter(
IN IDataObject *pDataObject,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
const FORMATETC *Format;
HRESULT hr;
if (pDataObject == NULL)
return E_INVALIDARG;
CanDrop = FALSE;
hr = DropTargetHelper->DragEnter(
hwndTarget,
pDataObject,
(POINT *) &pt,
*pdwEffect);
if (SUCCEEDED(hr))
{
Format = FindSupportedFormat(
pDataObject);
if (Format != NULL)
{
/* We found a format that we support! */
if (Callbacks.OnDragEnter != NULL)
{
hr = Callbacks.OnDragEnter(this,
Context,
Format,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr == S_OK)
CanDrop = TRUE;
else
{
/* Special return value by the callback routine,
doesn't want to allow dragging */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
virtual HRESULT STDMETHODCALLTYPE DragOver(
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
HRESULT hr;
hr = DropTargetHelper->DragOver(
(POINT *) &pt,
*pdwEffect);
if (SUCCEEDED(hr))
{
if (CanDrop)
{
if (Callbacks.OnDragOver != NULL)
{
hr = Callbacks.OnDragOver(this,
Context,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr != S_OK)
{
/* Special return value by the callback routine,
doesn't want to allow dropping here */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
virtual HRESULT STDMETHODCALLTYPE DragLeave()
{
HRESULT hr;
hr = DropTargetHelper->DragLeave();
if (SUCCEEDED(hr))
{
if (Callbacks.OnDragLeave != NULL)
{
hr = Callbacks.OnDragLeave(this,
Context);
}
}
return hr;
}
virtual HRESULT STDMETHODCALLTYPE Drop(
IN IDataObject *pDataObject,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect)
{
const FORMATETC *Format;
HRESULT hr;
if (pDataObject == NULL)
return E_INVALIDARG;
hr = DropTargetHelper->Drop(
pDataObject,
(POINT *) &pt,
*pdwEffect);
if (SUCCEEDED(hr) && CanDrop)
{
Format = FindSupportedFormat(pDataObject);
if (Format != NULL)
{
/* We found a format that we support! */
if (Callbacks.OnDrop != NULL)
{
hr = Callbacks.OnDrop(this,
Context,
Format,
grfKeyState,
pt,
pdwEffect);
if (SUCCEEDED(hr))
{
if (hr == S_OK)
CanDrop = TRUE;
else
{
/* Special return value by the callback routine,
doesn't want to allow dragging */
*pdwEffect = DROPEFFECT_NONE;
}
hr = S_OK;
}
else
{
*pdwEffect = DROPEFFECT_NONE;
hr = S_OK;
}
}
else
*pdwEffect = DROPEFFECT_NONE;
}
else
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
DECLARE_NOT_AGGREGATABLE(CDropTarget)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDropTarget)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};
IDropTarget *
CreateDropTarget(IN HWND hwndTarget,
IN DWORD nSupportedFormats,
IN const FORMATETC *Formats OPTIONAL,
IN PVOID Context OPTIONAL,
IN const DROPTARGET_CALLBACKS *Callbacks OPTIONAL)
{
IDropTarget *dt;
HRESULT hr = ShellObjectCreatorInit<CDropTarget>(hwndTarget, nSupportedFormats, Formats, Context, Callbacks, IID_IDropTarget, &dt);
if (FAILED_UNEXPECTEDLY(hr))
return NULL;
return dt;
}

View file

@ -1,485 +0,0 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
#include <shlwapi_undoc.h>
#include <winver.h>
HINSTANCE hExplorerInstance;
HMODULE hUser32;
HANDLE hProcessHeap;
HKEY hkExplorer = NULL;
DRAWCAPTEMP DrawCapTemp = NULL;
typedef struct _LANGCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} LANGCODEPAGE, *PLANGCODEPAGE;
LONG
SetWindowStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle)
{
LONG PrevStyle, Style;
ASSERT((~dwStyleMask & dwStyle) == 0);
PrevStyle = GetWindowLong(hWnd,
GWL_STYLE);
if (PrevStyle != 0 &&
(PrevStyle & dwStyleMask) != dwStyle)
{
Style = PrevStyle & ~dwStyleMask;
Style |= dwStyle;
PrevStyle = SetWindowLong(hWnd,
GWL_STYLE,
Style);
}
return PrevStyle;
}
LONG
SetWindowExStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle)
{
LONG PrevStyle, Style;
ASSERT((~dwStyleMask & dwStyle) == 0);
PrevStyle = GetWindowLong(hWnd,
GWL_EXSTYLE);
if (PrevStyle != 0 &&
(PrevStyle & dwStyleMask) != dwStyle)
{
Style = PrevStyle & ~dwStyleMask;
Style |= dwStyle;
PrevStyle = SetWindowLong(hWnd,
GWL_EXSTYLE,
Style);
}
return PrevStyle;
}
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCTSTR lpMenuName)
{
HMENU hMenu, hSubMenu = NULL;
hMenu = LoadMenu(hInstance,
lpMenuName);
if (hMenu != NULL)
{
hSubMenu = GetSubMenu(hMenu,
0);
if (hSubMenu != NULL &&
!RemoveMenu(hMenu,
0,
MF_BYPOSITION))
{
hSubMenu = NULL;
}
DestroyMenu(hMenu);
}
return hSubMenu;
}
HMENU
FindSubMenu(IN HMENU hMenu,
IN UINT uItem,
IN BOOL fByPosition)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (GetMenuItemInfo(hMenu,
uItem,
fByPosition,
&mii))
{
return mii.hSubMenu;
}
return NULL;
}
BOOL
GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
IN DWORD dwBufferSize)
{
DWORD dwType;
DWORD dwSize;
/* Query the user name from the registry */
dwSize = (dwBufferSize * sizeof(TCHAR)) - 1;
if (RegQueryValueEx(hkExplorer,
TEXT("Logon User Name"),
0,
&dwType,
(LPBYTE)szBuffer,
&dwSize) == ERROR_SUCCESS &&
(dwSize / sizeof(TCHAR)) > 1 &&
szBuffer[0] != _T('\0'))
{
szBuffer[dwSize / sizeof(TCHAR)] = _T('\0');
return TRUE;
}
/* Fall back to GetUserName() */
dwSize = dwBufferSize;
if (!GetUserName(szBuffer,
&dwSize))
{
szBuffer[0] = _T('\0');
return FALSE;
}
return TRUE;
}
BOOL
FormatMenuString(IN HMENU hMenu,
IN UINT uPosition,
IN UINT uFlags,
...)
{
va_list vl;
MENUITEMINFO mii;
TCHAR szBuf[128];
TCHAR szBufFmt[128];
/* Find the menu item and read the formatting string */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = (LPTSTR)szBufFmt;
mii.cch = sizeof(szBufFmt) / sizeof(szBufFmt[0]);
if (GetMenuItemInfo(hMenu,
uPosition,
uFlags,
&mii))
{
/* Format the string */
va_start(vl, uFlags);
_vsntprintf(szBuf,
(sizeof(szBuf) / sizeof(szBuf[0])) - 1,
szBufFmt,
vl);
va_end(vl);
szBuf[(sizeof(szBuf) / sizeof(szBuf[0])) - 1] = _T('\0');
/* Update the menu item */
mii.dwTypeData = (LPTSTR)szBuf;
if (SetMenuItemInfo(hMenu,
uPosition,
uFlags,
&mii))
{
return TRUE;
}
}
return FALSE;
}
BOOL
GetExplorerRegValueSet(IN HKEY hKey,
IN LPCTSTR lpSubKey,
IN LPCTSTR lpValue)
{
TCHAR szBuffer[MAX_PATH];
HKEY hkSubKey;
DWORD dwType, dwSize;
BOOL Ret = FALSE;
StringCbCopy(szBuffer, sizeof(szBuffer),
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"));
if (FAILED(StringCbCat(szBuffer, sizeof(szBuffer),
_T("\\"))))
return FALSE;
if (FAILED(StringCbCat(szBuffer, sizeof(szBuffer),
lpSubKey)))
return FALSE;
dwSize = sizeof(szBuffer);
if (RegOpenKeyEx(hKey,
szBuffer,
0,
KEY_QUERY_VALUE,
&hkSubKey) == ERROR_SUCCESS)
{
ZeroMemory(szBuffer,
sizeof(szBuffer));
if (RegQueryValueEx(hkSubKey,
lpValue,
0,
&dwType,
(LPBYTE)szBuffer,
&dwSize) == ERROR_SUCCESS)
{
if (dwType == REG_DWORD && dwSize == sizeof(DWORD))
Ret = *((PDWORD)szBuffer) != 0;
else if (dwSize > 0)
Ret = *((PUCHAR)szBuffer) != 0;
}
RegCloseKey(hkSubKey);
}
return Ret;
}
static BOOL
SetShellReadyEvent(IN LPCTSTR lpEventName)
{
HANDLE hEvent;
hEvent = OpenEvent(EVENT_MODIFY_STATE,
FALSE,
lpEventName);
if (hEvent != NULL)
{
SetEvent(hEvent);
CloseHandle(hEvent);
return TRUE;
}
return FALSE;
}
BOOL
GetVersionInfoString(IN TCHAR *szFileName,
IN TCHAR *szVersionInfo,
OUT TCHAR *szBuffer,
IN UINT cbBufLen)
{
LPVOID lpData = NULL;
TCHAR szSubBlock[128];
TCHAR *lpszLocalBuf = NULL;
LANGID UserLangId;
PLANGCODEPAGE lpTranslate = NULL;
DWORD dwLen;
DWORD dwHandle;
UINT cbTranslate;
UINT cbLen;
BOOL bRet = FALSE;
unsigned int i;
dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
if (dwLen > 0)
{
lpData = HeapAlloc(hProcessHeap, 0, dwLen);
if (lpData != NULL)
{
if (GetFileVersionInfo(szFileName,
0,
dwLen,
lpData) != 0)
{
UserLangId = GetUserDefaultLangID();
VerQueryValue(lpData,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID *)&lpTranslate,
&cbTranslate);
for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
{
/* If the bottom eight bits of the language id's
match, use this version information (since this
means that the version information and the users
default language are the same). */
if ((lpTranslate[i].wLanguage & 0xFF) ==
(UserLangId & 0xFF))
{
wnsprintf(szSubBlock,
sizeof(szSubBlock) / sizeof(szSubBlock[0]),
TEXT("\\StringFileInfo\\%04X%04X\\%s"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage,
szVersionInfo);
if (VerQueryValue(lpData,
szSubBlock,
(LPVOID *)&lpszLocalBuf,
&cbLen) != 0)
{
_tcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
bRet = TRUE;
break;
}
}
}
}
HeapFree(hProcessHeap, 0, lpData);
lpData = NULL;
}
}
return bRet;
}
static VOID
HideMinimizedWindows(IN BOOL bHide)
{
MINIMIZEDMETRICS mm;
mm.cbSize = sizeof(mm);
if (!SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
{
ERR("SystemParametersInfo failed with %lu\n", GetLastError());
return;
}
if (bHide)
mm.iArrange |= ARW_HIDE;
else
mm.iArrange &= ~ARW_HIDE;
if (!SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
ERR("SystemParametersInfo failed with %lu\n", GetLastError());
}
INT WINAPI
_tWinMain(IN HINSTANCE hInstance,
IN HINSTANCE hPrevInstance,
IN LPTSTR lpCmdLine,
IN INT nCmdShow)
{
ITrayWindow *Tray = NULL;
HANDLE hShellDesktop = NULL;
BOOL CreateShellDesktop = FALSE;
DbgPrint("Explorer starting... Commandline: %S\n", lpCmdLine);
/*
* Set our shutdown parameters: we want to shutdown the very last,
* but before any TaskMgr instance (which has a shutdown level of 1).
*/
SetProcessShutdownParameters(2, 0);
if (GetShellWindow() == NULL)
CreateShellDesktop = TRUE;
if (!CreateShellDesktop)
{
EXPLORER_CMDLINE_PARSE_RESULTS parseResults = { 0 };
if (SHExplorerParseCmdLine(&parseResults))
return SHCreateFromDesktop(&parseResults);
if (parseResults.strPath)
SHFree(parseResults.strPath);
if (parseResults.pidlPath)
ILFree(parseResults.pidlPath);
if (parseResults.pidlRoot)
ILFree(parseResults.pidlRoot);
}
if (RegOpenKey(HKEY_CURRENT_USER,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"),
&hkExplorer) != ERROR_SUCCESS)
{
TCHAR Message[256];
LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256);
MessageBox(NULL, Message, NULL, MB_ICONERROR);
return 1;
}
hExplorerInstance = hInstance;
hProcessHeap = GetProcessHeap();
LoadAdvancedSettings();
hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
if (hUser32 != NULL)
{
DrawCapTemp = (DRAWCAPTEMP)GetProcAddress(hUser32,
PROC_NAME_DRAWCAPTIONTEMP);
}
InitCommonControls();
OleInitialize(NULL);
ProcessStartupItems();
/* Initialize shell dde support */
ShellDDEInit(TRUE);
/* Initialize shell icons */
FileIconInit(TRUE);
/* Initialize CLSID_ShellWindows class */
WinList_Init();
if (RegisterTrayWindowClass() && RegisterTaskSwitchWndClass())
{
Tray = CreateTrayWindow();
/* This not only hides the minimized window captions in the bottom
left screen corner, but is also needed in order to receive
HSHELL_* notification messages (which are required for taskbar
buttons to work right) */
HideMinimizedWindows(TRUE);
if (Tray != NULL)
hShellDesktop = DesktopCreateWindow(Tray);
}
/* WinXP: Notify msgina to hide the welcome screen */
if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
if (Tray != NULL)
{
RegisterHotKey(NULL, IDHK_RUN, MOD_WIN, 'R');
TrayMessageLoop(Tray);
HideMinimizedWindows(FALSE);
ITrayWindow_Release(Tray);
UnregisterTrayWindowClass();
}
if (hShellDesktop != NULL)
DesktopDestroyShellWindow(hShellDesktop);
/* FIXME - shutdown SSO Thread */
OleUninitialize();
RegCloseKey(hkExplorer);
hkExplorer = NULL;
return 0;
}

View file

@ -0,0 +1,239 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
#include <shlwapi_undoc.h>
DWORD WINAPI _WinList_Init(void);
void WINAPI _ShellDDEInit(BOOL bInit);
HINSTANCE hExplorerInstance;
HMODULE hUser32;
HANDLE hProcessHeap;
HKEY hkExplorer = NULL;
DRAWCAPTEMP DrawCapTemp = NULL;
class CExplorerModule : public CComModule
{
public:
};
BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()
CExplorerModule gModule;
CAtlWinModule gWinModule;
void *operator new (size_t, void *buf)
{
return buf;
}
static VOID InitializeAtlModule(HINSTANCE hInstance, BOOL bInitialize)
{
if (bInitialize)
{
/* HACK - the global constructors don't run, so I placement new them here */
new (&gModule) CExplorerModule;
new (&gWinModule) CAtlWinModule;
new (&_AtlBaseModule) CAtlBaseModule;
new (&_AtlComModule) CAtlComModule;
gModule.Init(ObjectMap, hInstance, NULL);
}
else
{
gModule.Term();
}
}
#if !WIN7_COMPAT_MODE
static BOOL
SetShellReadyEvent(IN LPCTSTR lpEventName)
{
HANDLE hEvent;
hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, lpEventName);
if (hEvent != NULL)
{
SetEvent(hEvent);
CloseHandle(hEvent);
return TRUE;
}
return FALSE;
}
static VOID
HideMinimizedWindows(IN BOOL bHide)
{
MINIMIZEDMETRICS mm;
mm.cbSize = sizeof(mm);
if (!SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
{
ERR("SystemParametersInfo failed with %lu\n", GetLastError());
return;
}
if (bHide)
mm.iArrange |= ARW_HIDE;
else
mm.iArrange &= ~ARW_HIDE;
if (!SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0))
ERR("SystemParametersInfo failed with %lu\n", GetLastError());
}
static INT
StartWithCommandLine(IN HINSTANCE hInstance)
{
BOOL b = FALSE;
EXPLORER_CMDLINE_PARSE_RESULTS parseResults = { 0 };
if (SHExplorerParseCmdLine(&parseResults))
b = SHCreateFromDesktop(&parseResults);
if (parseResults.strPath)
SHFree(parseResults.strPath);
if (parseResults.pidlPath)
ILFree(parseResults.pidlPath);
if (parseResults.pidlRoot)
ILFree(parseResults.pidlRoot);
return b;
}
#endif
static INT
StartWithDesktop(IN HINSTANCE hInstance)
{
InitializeAtlModule(hInstance, TRUE);
if (RegOpenKey(HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
&hkExplorer) != ERROR_SUCCESS)
{
WCHAR Message[256];
LoadString(hInstance, IDS_STARTUP_ERROR, Message, 256);
MessageBox(NULL, Message, NULL, MB_ICONERROR);
return 1;
}
hExplorerInstance = hInstance;
hProcessHeap = GetProcessHeap();
LoadAdvancedSettings();
hUser32 = GetModuleHandle(TEXT("USER32.DLL"));
if (hUser32 != NULL)
{
DrawCapTemp = (DRAWCAPTEMP) GetProcAddress(hUser32, PROC_NAME_DRAWCAPTIONTEMP);
}
InitCommonControls();
OleInitialize(NULL);
#if !WIN7_COMPAT_MODE
ProcessStartupItems();
/* Initialize shell dde support */
_ShellDDEInit(TRUE);
#endif
/* Initialize shell icons */
FileIconInit(TRUE);
/* Initialize CLSID_ShellWindows class */
_WinList_Init();
CComPtr<ITrayWindow> Tray;
CreateTrayWindow(&Tray);
#if !WIN7_COMPAT_MODE
/* This not only hides the minimized window captions in the bottom
left screen corner, but is also needed in order to receive
HSHELL_* notification messages (which are required for taskbar
buttons to work right) */
HideMinimizedWindows(TRUE);
HANDLE hShellDesktop = NULL;
if (Tray != NULL)
hShellDesktop = DesktopCreateWindow(Tray);
/* WinXP: Notify msgina to hide the welcome screen */
if (!SetShellReadyEvent(TEXT("msgina: ShellReadyEvent")))
SetShellReadyEvent(TEXT("Global\\msgina: ShellReadyEvent"));
#endif
if (Tray != NULL)
{
#if !WIN7_COMPAT_MODE
RegisterHotKey(NULL, IDHK_RUN, MOD_WIN, 'R');
#endif
TrayMessageLoop(Tray);
#if !WIN7_COMPAT_MODE
HideMinimizedWindows(FALSE);
#endif
}
#if !WIN7_COMPAT_MODE
if (hShellDesktop != NULL)
DesktopDestroyShellWindow(hShellDesktop);
#endif
OleUninitialize();
RegCloseKey(hkExplorer);
hkExplorer = NULL;
InitializeAtlModule(hInstance, FALSE);
return 0;
}
INT WINAPI
_tWinMain(IN HINSTANCE hInstance,
IN HINSTANCE hPrevInstance,
IN LPTSTR lpCmdLine,
IN INT nCmdShow)
{
#if !WIN7_COMPAT_MODE
BOOL CreateShellDesktop = FALSE;
DbgPrint("Explorer starting... Commandline: %S\n", lpCmdLine);
/*
* Set our shutdown parameters: we want to shutdown the very last,
* but before any TaskMgr instance (which has a shutdown level of 1).
*/
SetProcessShutdownParameters(2, 0);
if (GetShellWindow() == NULL)
CreateShellDesktop = TRUE;
if (!CreateShellDesktop)
{
return StartWithCommandLine(hInstance);
}
#endif
return StartWithDesktop(hInstance);
}

View file

@ -1,6 +1,8 @@
#ifndef _EXPLORER_PRECOMP__H_
#define _EXPLORER_PRECOMP__H_
#define WIN7_COMPAT_MODE 0
#include <stdio.h>
#include <tchar.h>
@ -16,6 +18,9 @@
#include <wingdi.h>
#include <winnls.h>
#include <wincon.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shlobj_undoc.h>
@ -24,6 +29,7 @@
#include <uxtheme.h>
#include <strsafe.h>
#include <undocuser.h>
#include <undocshell.h>
#include "tmschema.h"
#include "resource.h"
@ -34,62 +40,26 @@
WINE_DEFAULT_DEBUG_CHANNEL(explorernew);
/* dynamic imports due to lack of support in msvc linker libs */
typedef INT (APIENTRY *REGSHELLHOOK)(HWND, DWORD);
typedef INT(APIENTRY *REGSHELLHOOK)(HWND, DWORD);
#ifdef UNICODE
#define PROC_NAME_DRAWCAPTIONTEMP "DrawCaptionTempW"
typedef BOOL (APIENTRY *DRAWCAPTEMP)(HWND, HDC, const RECT*, HFONT, HICON, LPCWSTR, UINT);
typedef BOOL(APIENTRY *DRAWCAPTEMP)(HWND, HDC, const RECT*, HFONT, HICON, LPCWSTR, UINT);
#else
#define PROC_NAME_DRAWCAPTIONTEMP "DrawCaptionTempA"
typedef BOOL (APIENTRY *DRAWCAPTEMP)(HWND, HDC, const RECT*, HFONT, HICON, LPCSTR, UINT);
#endif
typedef HRESULT (APIENTRY *SHINVDEFCMD)(HWND, IShellFolder*, LPCITEMIDLIST);
typedef HRESULT(APIENTRY *SHINVDEFCMD)(HWND, IShellFolder*, LPCITEMIDLIST);
typedef void (APIENTRY *RUNFILEDLG)(HWND, HICON, LPCWSTR, LPCWSTR, LPCWSTR, UINT);
typedef void (APIENTRY *EXITWINDLG)(HWND);
typedef HRESULT (APIENTRY *SHWINHELP)(HWND, LPWSTR, UINT, DWORD);
typedef HRESULT(APIENTRY *SHWINHELP)(HWND, LPWSTR, UINT, DWORD);
/* Constants for RunFileDlg */
#define RFF_CALCDIRECTORY 0x04 /* Calculates the working directory from the file name. */
static __inline ULONG
Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...)
{
char szMsg[512];
char *szMsgStart;
const char *fname;
va_list vl;
ULONG uRet;
fname = strrchr(filename, '\\');
if (fname == NULL)
{
fname = strrchr(filename, '/');
if (fname != NULL)
fname++;
}
else
fname++;
if (fname == NULL)
fname = filename;
szMsgStart = szMsg + sprintf(szMsg, "%s:%d: ", fname, line);
va_start(vl, lpFormat);
uRet = (ULONG)vsprintf(szMsgStart, lpFormat, vl);
va_end(vl);
OutputDebugStringA(szMsg);
return uRet;
}
#define ASSERT(cond) \
do if (!(cond)) { \
Win32DbgPrint(__FILE__, __LINE__, "ASSERTION %s FAILED!\n", #cond); \
} while (0)
#define DbgPrint(fmt, ...) \
Win32DbgPrint(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
} while (0)
extern HINSTANCE hExplorerInstance;
extern HMODULE hUser32;
@ -103,33 +73,33 @@ extern DRAWCAPTEMP DrawCapTemp;
typedef struct _DROPTARGET_CALLBACKS
{
HRESULT (*OnDragEnter)(IN IDropTarget *pDropTarget,
IN PVOID Context,
IN const FORMATETC *Format,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect);
HRESULT (*OnDragOver)(IN IDropTarget *pDropTarget,
HRESULT(*OnDragEnter)(IN IDropTarget *pDropTarget,
IN PVOID Context,
IN const FORMATETC *Format,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect);
HRESULT (*OnDragLeave)(IN IDropTarget *pDropTarget,
IN PVOID Context);
HRESULT (*OnDrop)(IN IDropTarget *pDropTarget,
IN PVOID Context,
IN const FORMATETC *Format,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect);
HRESULT(*OnDragOver)(IN IDropTarget *pDropTarget,
IN PVOID Context,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect);
HRESULT(*OnDragLeave)(IN IDropTarget *pDropTarget,
IN PVOID Context);
HRESULT(*OnDrop)(IN IDropTarget *pDropTarget,
IN PVOID Context,
IN const FORMATETC *Format,
IN DWORD grfKeyState,
IN POINTL pt,
IN OUT DWORD *pdwEffect);
} DROPTARGET_CALLBACKS, *PDROPTARGET_CALLBACKS;
IDropTarget *
CreateDropTarget(IN HWND hwndTarget,
IN DWORD nSupportedFormats,
IN const FORMATETC *Formats OPTIONAL,
IN PVOID Context OPTIONAL,
IN const DROPTARGET_CALLBACKS *Callbacks OPTIONAL);
IN DWORD nSupportedFormats,
IN const FORMATETC *Formats OPTIONAL,
IN PVOID Context OPTIONAL,
IN const DROPTARGET_CALLBACKS *Callbacks OPTIONAL);
/*
* explorer.c
@ -139,46 +109,44 @@ CreateDropTarget(IN HWND hwndTarget,
LONG
SetWindowStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle);
IN LONG dwStyleMask,
IN LONG dwStyle);
LONG
SetWindowExStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle);
IN LONG dwStyleMask,
IN LONG dwStyle);
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCTSTR lpMenuName);
IN LPCTSTR lpMenuName);
HMENU
FindSubMenu(IN HMENU hMenu,
IN UINT uItem,
IN BOOL fByPosition);
IN UINT uItem,
IN BOOL fByPosition);
BOOL
GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
IN DWORD dwBufferSize);
IN DWORD dwBufferSize);
BOOL
FormatMenuString(IN HMENU hMenu,
IN UINT uPosition,
IN UINT uFlags,
...);
IN UINT uPosition,
IN UINT uFlags,
...);
BOOL
GetExplorerRegValueSet(IN HKEY hKey,
IN LPCTSTR lpSubKey,
IN LPCTSTR lpValue);
IN LPCTSTR lpSubKey,
IN LPCTSTR lpValue);
/*
* rshell.c
*/
HRESULT
CStartMenu_Constructor(
REFIID riid,
void **ppv);
HRESULT WINAPI
_CStartMenu_Constructor(REFIID riid, void **ppv);
/*
* traywnd.c
@ -186,13 +154,13 @@ CStartMenu_Constructor(
#define TWM_OPENSTARTMENU (WM_USER + 260)
typedef HMENU (*PCREATECTXMENU)(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL);
typedef VOID (*PCTXMENUCOMMAND)(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL);
typedef HMENU(*PCREATECTXMENU)(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL);
typedef VOID(*PCTXMENUCOMMAND)(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL);
typedef struct _TRAYWINDOW_CTXMENU
{
@ -203,22 +171,22 @@ typedef struct _TRAYWINDOW_CTXMENU
extern const GUID IID_IShellDesktopTray;
#define INTERFACE ITrayWindow
DECLARE_INTERFACE_(ITrayWindow,IUnknown)
DECLARE_INTERFACE_(ITrayWindow, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD_(HRESULT, QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
/*** ITrayWindow methods ***/
STDMETHOD_(HRESULT,Open) (THIS) PURE;
STDMETHOD_(HRESULT,Close) (THIS) PURE;
STDMETHOD_(HWND,GetHWND) (THIS) PURE;
STDMETHOD_(BOOL,IsSpecialHWND) (THIS_ HWND hWnd) PURE;
STDMETHOD_(BOOL,IsHorizontal) (THIS) PURE;
STDMETHOD_(HFONT,GetCaptionFonts) (THIS_ HFONT *phBoldCaption) PURE;
STDMETHOD_(HWND,DisplayProperties) (THIS) PURE;
STDMETHOD_(BOOL,ExecContextMenuCmd) (THIS_ UINT uiCmd) PURE;
STDMETHOD_(BOOL,Lock) (THIS_ BOOL bLock) PURE;
STDMETHOD_(HRESULT, Open) (THIS) PURE;
STDMETHOD_(HRESULT, Close) (THIS) PURE;
STDMETHOD_(HWND, GetHWND) (THIS) PURE;
STDMETHOD_(BOOL, IsSpecialHWND) (THIS_ HWND hWnd) PURE;
STDMETHOD_(BOOL, IsHorizontal) (THIS) PURE;
STDMETHOD_(HFONT, GetCaptionFonts) (THIS_ HFONT *phBoldCaption) PURE;
STDMETHOD_(HWND, DisplayProperties) (THIS) PURE;
STDMETHOD_(BOOL, ExecContextMenuCmd) (THIS_ UINT uiCmd) PURE;
STDMETHOD_(BOOL, Lock) (THIS_ BOOL bLock) PURE;
};
#undef INTERFACE
@ -245,8 +213,7 @@ RegisterTrayWindowClass(VOID);
VOID
UnregisterTrayWindowClass(VOID);
ITrayWindow *
CreateTrayWindow(VOID);
HRESULT CreateTrayWindow(ITrayWindow ** ppTray);
VOID
TrayProcessMessages(IN OUT ITrayWindow *Tray);
@ -259,20 +226,21 @@ TrayMessageLoop(IN OUT ITrayWindow *Tray);
*/
/* Structure to hold non-default options*/
typedef struct _ADVANCED_SETTINGS {
typedef struct _ADVANCED_SETTINGS
{
BOOL bShowSeconds;
} ADVANCED_SETTINGS, *PADVANCED_SETTINGS;
extern ADVANCED_SETTINGS AdvancedSettings;
extern const TCHAR szAdvancedSettingsKey[];
extern const TCHAR szAdvancedSettingsKey [];
VOID
LoadAdvancedSettings(VOID);
BOOL
SaveSettingDword(IN PCTSTR pszKeyName,
IN PCTSTR pszValueName,
IN DWORD dwValue);
IN PCTSTR pszValueName,
IN DWORD dwValue);
/*
* startup.c
@ -305,14 +273,14 @@ DesktopDestroyShellWindow(IN HANDLE hDesktop);
extern const GUID CLSID_ITaskBand;
#define INTERFACE ITaskBand
DECLARE_INTERFACE_(ITaskBand,IUnknown)
DECLARE_INTERFACE_(ITaskBand, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD_(HRESULT, QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
/*** ITaskBand methods ***/
STDMETHOD_(HRESULT,GetRebarBandID)(THIS_ DWORD *pdwBandID) PURE;
STDMETHOD_(HRESULT, GetRebarBandID)(THIS_ DWORD *pdwBandID) PURE;
};
#undef INTERFACE
@ -333,20 +301,20 @@ CreateTaskBand(IN OUT ITrayWindow *Tray);
*/
#define INTERFACE ITrayBandSite
DECLARE_INTERFACE_(ITrayBandSite,IUnknown)
DECLARE_INTERFACE_(ITrayBandSite, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD_(HRESULT, QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
/*** IBandSiteStreamCallback ***/
STDMETHOD_(HRESULT,OnLoad)(THIS_ IStream *pStm, REFIID riid, PVOID *pvObj) PURE;
STDMETHOD_(HRESULT,OnSave)(THIS_ IUnknown *pUnk, IStream *pStm) PURE;
STDMETHOD_(HRESULT, OnLoad)(THIS_ IStream *pStm, REFIID riid, PVOID *pvObj) PURE;
STDMETHOD_(HRESULT, OnSave)(THIS_ IUnknown *pUnk, IStream *pStm) PURE;
/*** ITrayBandSite methods ***/
STDMETHOD_(HRESULT,IsTaskBand) (THIS_ IUnknown *punk) PURE;
STDMETHOD_(HRESULT,ProcessMessage) (THIS_ HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) PURE;
STDMETHOD_(HRESULT,AddContextMenus) (THIS_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags, IContextMenu **ppcm) PURE;
STDMETHOD_(HRESULT,Lock) (THIS_ BOOL bLock) PURE;
STDMETHOD_(HRESULT, IsTaskBand) (THIS_ IUnknown *punk) PURE;
STDMETHOD_(HRESULT, ProcessMessage) (THIS_ HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) PURE;
STDMETHOD_(HRESULT, AddContextMenus) (THIS_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags, IContextMenu **ppcm) PURE;
STDMETHOD_(HRESULT, Lock) (THIS_ BOOL bLock) PURE;
};
#undef INTERFACE
@ -367,8 +335,8 @@ DECLARE_INTERFACE_(ITrayBandSite,IUnknown)
ITrayBandSite *
CreateTrayBandSite(IN OUT ITrayWindow *Tray,
OUT HWND *phWndRebar,
OUT HWND *phWndTaskSwitch);
OUT HWND *phWndRebar,
OUT HWND *phWndTaskSwitch);
/*
* startmnu.c
@ -377,12 +345,12 @@ CreateTrayBandSite(IN OUT ITrayWindow *Tray,
extern const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu;
#define INTERFACE IStartMenuSite
DECLARE_INTERFACE_(IStartMenuSite,IUnknown)
DECLARE_INTERFACE_(IStartMenuSite, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
STDMETHOD_(HRESULT, QueryInterface) (THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
STDMETHOD_(ULONG, Release) (THIS) PURE;
/*** IStartMenuSite ***/
};
#undef INTERFACE
@ -397,14 +365,14 @@ DECLARE_INTERFACE_(IStartMenuSite,IUnknown)
IMenuPopup*
CreateStartMenu(IN ITrayWindow *Tray,
OUT IMenuBand **ppMenuBand,
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons);
OUT IMenuBand **ppMenuBand,
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons);
HRESULT
UpdateStartMenu(IN OUT IMenuPopup *pMenuPopup,
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons);
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons);
/*
* trayntfy.c
@ -431,16 +399,14 @@ UnregisterTrayNotifyWndClass(VOID);
HWND
CreateTrayNotifyWnd(IN OUT ITrayWindow *TrayWindow,
IN BOOL bHideClock);
IN BOOL bHideClock);
VOID
TrayNotify_NotifyMsg(IN HWND hwnd,
IN WPARAM wParam,
IN LPARAM lParam);
TrayNotify_NotifyMsg(IN WPARAM wParam,
IN LPARAM lParam);
BOOL
TrayNotify_GetClockRect(IN HWND hwnd,
OUT PRECT rcClock);
TrayNotify_GetClockRect(OUT PRECT rcClock);
/*
* taskswnd.c
@ -457,9 +423,12 @@ UnregisterTaskSwitchWndClass(VOID);
HWND
CreateTaskSwitchWnd(IN HWND hWndParent,
IN OUT ITrayWindow *Tray);
IN OUT ITrayWindow *Tray);
HRESULT
Tray_OnStartMenuDismissed();
HRESULT
IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2);
#endif /* _EXPLORER_PRECOMP__H_ */

View file

@ -24,7 +24,7 @@ static HINSTANCE hRShell = NULL;
typedef HRESULT(WINAPI * PSTARTMENU_CONSTRUCTOR)(REFIID riid, void **ppv);
HRESULT CStartMenu_Constructor(REFIID riid, void **ppv)
HRESULT WINAPI _CStartMenu_Constructor(REFIID riid, void **ppv)
{
if (!hRShell)
{
@ -40,7 +40,7 @@ HRESULT CStartMenu_Constructor(REFIID riid, void **ppv)
}
}
return CoCreateInstance(&CLSID_StartMenu,
return CoCreateInstance(CLSID_StartMenu,
NULL,
CLSCTX_INPROC_SERVER,
riid,
@ -49,7 +49,7 @@ HRESULT CStartMenu_Constructor(REFIID riid, void **ppv)
typedef HANDLE(WINAPI * PSHCREATEDESKTOP)(IShellDesktopTray *ShellDesk);
HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk)
{
HINSTANCE hFallback;
@ -83,7 +83,7 @@ HANDLE WINAPI SHCreateDesktop(IShellDesktopTray *ShellDesk)
typedef BOOL(WINAPI *PSHDESKTOPMESSAGELOOP)(HANDLE hDesktop);
BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop)
{
HINSTANCE hFallback;
@ -117,7 +117,7 @@ BOOL WINAPI SHDesktopMessageLoop(HANDLE hDesktop)
typedef DWORD(WINAPI* PWINLIST_INIT)(void);
DWORD WINAPI WinList_Init(void)
DWORD WINAPI _WinList_Init(void)
{
HINSTANCE hFallback;
@ -151,7 +151,7 @@ DWORD WINAPI WinList_Init(void)
typedef void (WINAPI *PSHELLDDEINIT)(BOOL bInit);
void WINAPI ShellDDEInit(BOOL bInit)
void WINAPI _ShellDDEInit(BOOL bInit)
{
HINSTANCE hFallback;

View file

@ -21,8 +21,7 @@
#include "precomp.h"
ADVANCED_SETTINGS AdvancedSettings;
const TCHAR szAdvancedSettingsKey[] = TEXT("Software\\ReactOS\\Features\\Explorer");
const WCHAR szAdvancedSettingsKey[] = TEXT("Software\\ReactOS\\Features\\Explorer");
VOID
LoadAdvancedSettings(VOID)

View file

@ -25,26 +25,26 @@ extern HRESULT ShutdownShellServices(HDPA hdpa);
static int CALLBACK InitializeAllCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = pItem;
HRESULT * phr = pData;
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
HRESULT * phr = reinterpret_cast<HRESULT *>(pData);
TRACE("Initializing SSO %p\n", pOct);
*phr = IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
*phr = pOct->Exec(&CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
return SUCCEEDED(*phr);
}
static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = pItem;
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
TRACE("Shutting down SSO %p\n", pOct);
IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
pOct->Exec(&CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
return TRUE;
}
static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData)
{
IOleCommandTarget * pOct = pItem;
IOleCommandTarget * pOct = reinterpret_cast<IOleCommandTarget *>(pItem);
TRACE("Releasing SSO %p\n", pOct);
IUnknown_Release(pOct);
pOct->Release();
return TRUE;
}
@ -92,14 +92,14 @@ HRESULT InitShellServices(HDPA * phdpa)
}
hr = CLSIDFromString(value, &clsid);
if (FAILED(hr))
if (FAILED_UNEXPECTEDLY(hr))
{
ERR("CLSIDFromString failed %08x.\n", hr);
goto cleanup;
}
hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (VOID**) &pOct);
if (FAILED(hr))
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &pOct));
if (FAILED_UNEXPECTEDLY(hr))
{
ERR("CoCreateInstance failed %08x.\n", hr);
goto cleanup;
@ -122,7 +122,7 @@ HRESULT InitShellServices(HDPA * phdpa)
/* Initialize */
DPA_EnumCallback(hdpa, InitializeAllCallback, &hr);
if (FAILED(hr))
if (FAILED_UNEXPECTEDLY(hr))
goto cleanup;
*phdpa = hdpa;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,796 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
/*
* Start menu button context menu
*/
typedef struct _STARTMNU_CTMENU_CTX
{
IContextMenu *pcm;
LPITEMIDLIST pidl;
} STARTMNU_CTMENU_CTX, *PSTARTMNU_CTMENU_CTX;
static HMENU
CreateStartContextMenu(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL);
static VOID
OnStartContextMenuCommand(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL);
const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu = {
CreateStartContextMenu,
OnStartContextMenuCommand
};
static HMENU
CreateContextMenuFromShellFolderPidl(IN HWND hWndOwner,
IN OUT IShellFolder *psf,
IN OUT LPITEMIDLIST pidl,
OUT IContextMenu **ppcm)
{
CComPtr<IContextMenu> pcm;
HRESULT hRet;
HMENU hPopup;
hRet = psf->GetUIObjectOf(hWndOwner, 1, (LPCITEMIDLIST *)&pidl, IID_NULL_PPV_ARG(IContextMenu, &pcm));
if (SUCCEEDED(hRet))
{
hPopup = CreatePopupMenu();
if (hPopup != NULL)
{
hRet = pcm->QueryContextMenu(
hPopup,
0,
ID_SHELL_CMD_FIRST,
ID_SHELL_CMD_LAST,
CMF_VERBSONLY);
if (SUCCEEDED(hRet))
{
*ppcm = pcm;
return hPopup;
}
DestroyMenu(hPopup);
}
}
return NULL;
}
static VOID
OnStartContextMenuCommand(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL)
{
PSTARTMNU_CTMENU_CTX psmcmc = (PSTARTMNU_CTMENU_CTX) pcmContext;
if (uiCmdId != 0)
{
if ((uiCmdId >= ID_SHELL_CMD_FIRST) && (uiCmdId <= ID_SHELL_CMD_LAST))
{
CMINVOKECOMMANDINFO cmici = {0};
CHAR szDir[MAX_PATH];
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
cmici.lpVerb = (LPCSTR)MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
/* FIXME: Support Unicode!!! */
if (SHGetPathFromIDListA(psmcmc->pidl,
szDir))
{
cmici.lpDirectory = szDir;
}
psmcmc->pcm->InvokeCommand(&cmici);
}
else
{
ITrayWindow * TrayWnd = (ITrayWindow *) Context;
TrayWnd->ExecContextMenuCmd(uiCmdId);
}
}
psmcmc->pcm->Release();
HeapFree(hProcessHeap, 0, psmcmc);
}
static VOID
AddStartContextMenuItems(IN HWND hWndOwner,
IN HMENU hPopup)
{
WCHAR szBuf[MAX_PATH];
HRESULT hRet;
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_PROPERTIES,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_PROPERTIES,
szBuf);
}
if (!SHRestricted(REST_NOCOMMONGROUPS))
{
/* Check if we should add menu items for the common start menu */
hRet = SHGetFolderPath(hWndOwner,
CSIDL_COMMON_STARTMENU,
NULL,
SHGFP_TYPE_CURRENT,
szBuf);
if (SUCCEEDED(hRet) && hRet != S_FALSE)
{
/* The directory exists, but only show the items if the
user can actually make any changes to the common start
menu. This is most likely only the case if the user
has administrative rights! */
if (IsUserAnAdmin())
{
AppendMenu(hPopup,
MF_SEPARATOR,
0,
NULL);
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_OPEN_ALL_USERS,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_OPEN_ALL_USERS,
szBuf);
}
/* Add the "Explore All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_EXPLORE_ALL_USERS,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_EXPLORE_ALL_USERS,
szBuf);
}
}
}
}
}
static HMENU
CreateStartContextMenu(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL)
{
LPITEMIDLIST pidlStart, pidlLast;
CComPtr<IShellFolder> psfStart;
CComPtr<IShellFolder> psfDesktop;
CComPtr<IContextMenu> pcm;
HRESULT hRet;
HMENU hPopup;
pidlStart = SHCloneSpecialIDList(hWndOwner,
CSIDL_STARTMENU,
TRUE);
if (pidlStart != NULL)
{
pidlLast = ILClone(ILFindLastID(pidlStart));
ILRemoveLastID(pidlStart);
if (pidlLast != NULL)
{
hRet = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hRet))
{
hRet = psfDesktop->BindToObject(pidlStart, NULL, IID_PPV_ARG(IShellFolder, &psfStart));
if (SUCCEEDED(hRet))
{
hPopup = CreateContextMenuFromShellFolderPidl(hWndOwner,
psfStart,
pidlLast,
&pcm);
if (hPopup != NULL)
{
PSTARTMNU_CTMENU_CTX psmcmc;
psmcmc = (PSTARTMNU_CTMENU_CTX) HeapAlloc(hProcessHeap, 0, sizeof(*psmcmc));
if (psmcmc != NULL)
{
psmcmc->pcm = pcm;
psmcmc->pidl = pidlLast;
AddStartContextMenuItems(hWndOwner,
hPopup);
*ppcmContext = psmcmc;
return hPopup;
}
else
{
DestroyMenu(hPopup);
hPopup = NULL;
}
}
}
}
ILFree(pidlLast);
}
ILFree(pidlStart);
}
return NULL;
}
/*****************************************************************************
** IStartMenuSite ***********************************************************
*****************************************************************************/
class IStartMenuSiteImpl :
public CComCoClass<IStartMenuSiteImpl>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IStartMenuSite,
public IServiceProvider,
public ITrayPriv,
public IOleCommandTarget,
public IMenuPopup
{
CComPtr<ITrayWindow> Tray;
CComPtr<IMenuPopup> StartMenuPopup;
public:
IStartMenuSiteImpl()
{
}
virtual ~IStartMenuSiteImpl() { }
/*******************************************************************/
virtual HRESULT STDMETHODCALLTYPE QueryService(
IN REFGUID guidService,
IN REFIID riid,
OUT PVOID *ppvObject)
{
if (IsEqualGUID(guidService, SID_SMenuPopup))
{
return QueryInterface(riid, ppvObject);
}
return E_NOINTERFACE;
}
/*******************************************************************/
virtual HRESULT STDMETHODCALLTYPE GetWindow(
OUT HWND *phwnd)
{
TRACE("ITrayPriv::GetWindow\n");
*phwnd = Tray->GetHWND();
if (*phwnd != NULL)
return S_OK;
return E_FAIL;
}
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
IN BOOL fEnterMode)
{
TRACE("ITrayPriv::ContextSensitiveHelp\n");
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Execute(
IN IShellFolder *pShellFolder,
IN LPCITEMIDLIST pidl)
{
HMODULE hShlwapi;
HRESULT ret = S_FALSE;
TRACE("ITrayPriv::Execute\n");
hShlwapi = GetModuleHandle(TEXT("SHLWAPI.DLL"));
if (hShlwapi != NULL)
{
SHINVDEFCMD SHInvokeDefCmd;
/* SHInvokeDefaultCommand */
SHInvokeDefCmd = (SHINVDEFCMD) GetProcAddress(hShlwapi,
(LPCSTR) ((LONG) 279));
if (SHInvokeDefCmd != NULL)
{
ret = SHInvokeDefCmd(Tray->GetHWND(),
pShellFolder,
pidl);
}
}
return ret;
}
virtual HRESULT STDMETHODCALLTYPE Unknown(
IN PVOID Unknown1,
IN PVOID Unknown2,
IN PVOID Unknown3,
IN PVOID Unknown4)
{
TRACE("ITrayPriv::Unknown(0x%p,0x%p,0x%p,0x%p)\n", Unknown1, Unknown2, Unknown3, Unknown4);
return E_NOTIMPL;
}
virtual BOOL
ShowUndockMenuItem(VOID)
{
TRACE("ShowUndockMenuItem() not implemented!\n");
/* FIXME: How do we detect this?! */
return FALSE;
}
virtual BOOL
ShowSynchronizeMenuItem(VOID)
{
TRACE("ShowSynchronizeMenuItem() not implemented!\n");
/* FIXME: How do we detect this?! */
return FALSE;
}
virtual HRESULT STDMETHODCALLTYPE AppendMenu(
OUT HMENU* phMenu)
{
HMENU hMenu, hSettingsMenu;
DWORD dwLogoff;
BOOL bWantLogoff;
UINT uLastItemsCount = 5; /* 5 menu items below the last separator */
WCHAR szUser[128];
TRACE("ITrayPriv::AppendMenu\n");
hMenu = LoadPopupMenu(hExplorerInstance,
MAKEINTRESOURCE(IDM_STARTMENU));
*phMenu = hMenu;
if (hMenu == NULL)
return E_FAIL;
/* Remove menu items that don't apply */
dwLogoff = SHRestricted(REST_STARTMENULOGOFF);
bWantLogoff = (dwLogoff == 2 ||
SHRestricted(REST_FORCESTARTMENULOGOFF) ||
GetExplorerRegValueSet(HKEY_CURRENT_USER,
TEXT("Advanced"),
TEXT("StartMenuLogoff")));
/* Favorites */
if (!GetExplorerRegValueSet(HKEY_CURRENT_USER,
TEXT("Advanced"),
TEXT("StartMenuFavorites")))
{
DeleteMenu(hMenu,
IDM_FAVORITES,
MF_BYCOMMAND);
}
/* Documents */
if (SHRestricted(REST_NORECENTDOCSMENU))
{
DeleteMenu(hMenu,
IDM_DOCUMENTS,
MF_BYCOMMAND);
}
/* Settings */
hSettingsMenu = FindSubMenu(hMenu,
IDM_SETTINGS,
FALSE);
if (hSettingsMenu != NULL)
{
if (SHRestricted(REST_NOSETFOLDERS))
{
/* Control Panel */
if (SHRestricted(REST_NOCONTROLPANEL))
{
DeleteMenu(hSettingsMenu,
IDM_CONTROLPANEL,
MF_BYCOMMAND);
/* Delete the separator below it */
DeleteMenu(hSettingsMenu,
0,
MF_BYPOSITION);
}
/* Network Connections */
if (SHRestricted(REST_NONETWORKCONNECTIONS))
{
DeleteMenu(hSettingsMenu,
IDM_NETWORKCONNECTIONS,
MF_BYCOMMAND);
}
/* Printers and Faxes */
DeleteMenu(hSettingsMenu,
IDM_PRINTERSANDFAXES,
MF_BYCOMMAND);
}
/* Security */
if (GetSystemMetrics(SM_REMOTECONTROL) == 0 ||
SHRestricted(REST_NOSECURITY))
{
DeleteMenu(hSettingsMenu,
IDM_SECURITY,
MF_BYCOMMAND);
}
if (GetMenuItemCount(hSettingsMenu) == 0)
{
DeleteMenu(hMenu,
IDM_SETTINGS,
MF_BYCOMMAND);
}
}
/* Search */
/* FIXME: Enable after implementing */
/* if (SHRestricted(REST_NOFIND)) */
{
DeleteMenu(hMenu,
IDM_SEARCH,
MF_BYCOMMAND);
}
/* FIXME: Help */
/* Run */
if (SHRestricted(REST_NORUN))
{
DeleteMenu(hMenu,
IDM_RUN,
MF_BYCOMMAND);
}
/* Synchronize */
if (!ShowSynchronizeMenuItem())
{
DeleteMenu(hMenu,
IDM_SYNCHRONIZE,
MF_BYCOMMAND);
uLastItemsCount--;
}
/* Log off */
if (dwLogoff != 1 && bWantLogoff)
{
/* FIXME: We need a more sophisticated way to determine whether to show
or hide it, it might be hidden in too many cases!!! */
/* Update Log Off menu item */
if (!GetCurrentLoggedOnUserName(szUser,
sizeof(szUser) / sizeof(szUser[0])))
{
szUser[0] = _T('\0');
}
if (!FormatMenuString(hMenu,
IDM_LOGOFF,
MF_BYCOMMAND,
szUser))
{
/* We couldn't update the menu item, delete it... */
DeleteMenu(hMenu,
IDM_LOGOFF,
MF_BYCOMMAND);
}
}
else
{
DeleteMenu(hMenu,
IDM_LOGOFF,
MF_BYCOMMAND);
uLastItemsCount--;
}
/* Disconnect */
if (GetSystemMetrics(SM_REMOTECONTROL) == 0)
{
DeleteMenu(hMenu,
IDM_DISCONNECT,
MF_BYCOMMAND);
uLastItemsCount--;
}
/* Undock computer */
if (!ShowUndockMenuItem())
{
DeleteMenu(hMenu,
IDM_UNDOCKCOMPUTER,
MF_BYCOMMAND);
uLastItemsCount--;
}
/* Shut down */
if (SHRestricted(REST_NOCLOSE))
{
DeleteMenu(hMenu,
IDM_SHUTDOWN,
MF_BYCOMMAND);
uLastItemsCount--;
}
if (uLastItemsCount == 0)
{
/* Remove the separator at the end of the menu */
DeleteMenu(hMenu,
IDM_LASTSTARTMENU_SEPARATOR,
MF_BYCOMMAND);
}
return S_OK;
}
/*******************************************************************/
virtual HRESULT STDMETHODCALLTYPE QueryStatus(
IN const GUID *pguidCmdGroup OPTIONAL,
IN ULONG cCmds,
IN OUT OLECMD *prgCmds,
IN OUT OLECMDTEXT *pCmdText OPTIONAL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Exec(
IN const GUID *pguidCmdGroup OPTIONAL,
IN DWORD nCmdID,
IN DWORD nCmdExecOpt,
IN VARIANTARG *pvaIn OPTIONAL,
IN VARIANTARG *pvaOut OPTIONAL)
{
return E_NOTIMPL;
}
/*******************************************************************/
virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown ** ppunkClient)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet)
{
if (!fSet)
{
return Tray_OnStartMenuDismissed();
}
return S_OK;
}
/*******************************************************************/
HRESULT Initialize(IN ITrayWindow *tray)
{
Tray = tray;
return S_OK;
}
DECLARE_NOT_AGGREGATABLE(IStartMenuSiteImpl)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(IStartMenuSiteImpl)
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
COM_INTERFACE_ENTRY_IID(IID_ITrayPriv, ITrayPriv)
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup)
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
END_COM_MAP()
};
HRESULT CreateStartMenuSite(IN OUT ITrayWindow *Tray, const IID & riid, PVOID * ppv)
{
return ShellObjectCreatorInit<IStartMenuSiteImpl>(Tray, riid, ppv);
}
HRESULT
UpdateStartMenu(IN OUT IMenuPopup *pMenuPopup,
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons)
{
CComPtr<IBanneredBar> pbb;
HRESULT hRet;
hRet = pMenuPopup->QueryInterface(IID_PPV_ARG(IBanneredBar, &pbb));
if (SUCCEEDED(hRet))
{
hRet = pbb->SetBitmap( hbmBanner);
/* Update the icon size */
hRet = pbb->SetIconSize(bSmallIcons ? BMICON_SMALL : BMICON_LARGE);
}
return hRet;
}
IMenuPopup *
CreateStartMenu(IN ITrayWindow *Tray,
OUT IMenuBand **ppMenuBand,
IN HBITMAP hbmBanner OPTIONAL,
IN BOOL bSmallIcons)
{
HRESULT hr;
IObjectWithSite *pOws = NULL;
IMenuPopup *pMp = NULL;
IUnknown *pSms = NULL;
IMenuBand *pMb = NULL;
IInitializeObject *pIo;
IUnknown *pUnk = NULL;
IBandSite *pBs = NULL;
DWORD dwBandId = 0;
hr = CreateStartMenuSite(Tray, IID_PPV_ARG(IUnknown, &pSms));
if (FAILED_UNEXPECTEDLY(hr))
return NULL;
#if 0
hr = CoCreateInstance(&CLSID_StartMenu,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IMenuPopup,
(PVOID *)&pMp);
#else
hr = _CStartMenu_Constructor(IID_PPV_ARG(IMenuPopup, &pMp));
#endif
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("CoCreateInstance failed: %x\n", hr);
goto cleanup;
}
hr = pMp->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pOws));
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IMenuPopup_QueryInterface failed: %x\n", hr);
goto cleanup;
}
/* Set the menu site so we can handle messages */
hr = pOws->SetSite(pSms);
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IObjectWithSite_SetSite failed: %x\n", hr);
goto cleanup;
}
/* Initialize the menu object */
hr = pMp->QueryInterface(IID_PPV_ARG(IInitializeObject, &pIo));
if (SUCCEEDED(hr))
{
hr = pIo->Initialize();
pIo->Release();
}
else
hr = S_OK;
/* Everything is initialized now. Let's get the IMenuBand interface. */
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IMenuPopup_QueryInterface failed: %x\n", hr);
goto cleanup;
}
hr = pMp->GetClient( &pUnk);
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IMenuPopup_GetClient failed: %x\n", hr);
goto cleanup;
}
hr = pUnk->QueryInterface(IID_PPV_ARG(IBandSite, &pBs));
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IUnknown_QueryInterface pBs failed: %x\n", hr);
goto cleanup;
}
/* Finally we have the IBandSite interface, there's only one
band in it that apparently provides the IMenuBand interface */
hr = pBs->EnumBands( 0, &dwBandId);
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IBandSite_EnumBands failed: %x\n", hr);
goto cleanup;
}
hr = pBs->GetBandObject( dwBandId, IID_PPV_ARG(IMenuBand, &pMb));
if (FAILED_UNEXPECTEDLY(hr))
{
TRACE("IBandSite_GetBandObject failed: %x\n", hr);
goto cleanup;
}
UpdateStartMenu(pMp,
hbmBanner,
bSmallIcons);
cleanup:
if (SUCCEEDED(hr))
*ppMenuBand = pMb;
else if (pMb != NULL)
pMb->Release();
if (pBs != NULL)
pBs->Release();
if (pUnk != NULL)
pUnk->Release();
if (pOws != NULL)
pOws->Release();
if (pMp != NULL)
pMp->Release();
if (pSms != NULL)
pSms->Release();
if (FAILED_UNEXPECTEDLY(hr))
return NULL;
return pMp;
}

View file

@ -176,7 +176,7 @@ static BOOL ProcessRunKeys(HKEY hkRoot, LPCWSTR szKeyName, BOOL bDelete,
goto end;
}
szCmdLine = HeapAlloc(hProcessHeap,
szCmdLine = (WCHAR*)HeapAlloc(hProcessHeap,
0,
cbMaxCmdLine);
if (szCmdLine == NULL)
@ -188,7 +188,7 @@ static BOOL ProcessRunKeys(HKEY hkRoot, LPCWSTR szKeyName, BOOL bDelete,
}
++cchMaxValue;
szValue = HeapAlloc(hProcessHeap,
szValue = (WCHAR*)HeapAlloc(hProcessHeap,
0,
cchMaxValue * sizeof(*szValue));
if (szValue == NULL)

View file

@ -1,660 +0,0 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
/*****************************************************************************
** ITaskBand ****************************************************************
*****************************************************************************/
const GUID CLSID_ITaskBand = {0x68284FAA,0x6A48,0x11D0,{0x8C,0x78,0x00,0xC0,0x4F,0xD9,0x18,0xB4}};
static const ITaskBandVtbl ITaskBandImpl_Vtbl;
static const IDeskBandVtbl IDeskBandImpl_Vtbl;
static const IObjectWithSiteVtbl IObjectWithSiteImpl_Vtbl;
static const IDeskBarVtbl IDeskBarImpl_Vtbl;
static const IPersistStreamVtbl IPersistStreamImpl_Vtbl;
static const IWinEventHandlerVtbl IWinEventHandlerImpl_Vtbl;
typedef struct
{
const ITaskBandVtbl *lpVtbl;
const IDeskBandVtbl *lpDeskBandVtbl;
const IObjectWithSiteVtbl *lpObjectWithSiteVtbl;
const IDeskBarVtbl *lpDeskBarVtbl;
const IPersistStreamVtbl *lpPersistStreamVtbl;
const IWinEventHandlerVtbl *lpWindowEventHandlerVtbl;
/* FIXME: Implement IOleCommandTarget */
LONG Ref;
ITrayWindow *Tray;
IUnknown *punkSite;
HWND hWnd;
DWORD dwBandID;
} ITaskBandImpl;
static IUnknown *
IUnknown_from_ITaskBandImpl(ITaskBandImpl *This)
{
return (IUnknown *)&This->lpVtbl;
}
IMPL_CASTS(ITaskBand, ITaskBand, lpVtbl)
IMPL_CASTS(IDeskBand, ITaskBand, lpDeskBandVtbl)
IMPL_CASTS(IObjectWithSite, ITaskBand, lpObjectWithSiteVtbl)
IMPL_CASTS(IDeskBar, ITaskBand, lpDeskBarVtbl)
IMPL_CASTS(IPersistStream, ITaskBand, lpPersistStreamVtbl)
IMPL_CASTS(IWinEventHandler, ITaskBand, lpWindowEventHandlerVtbl)
static ULONG STDMETHODCALLTYPE
ITaskBandImpl_AddRef(IN OUT ITaskBand *iface)
{
ITaskBandImpl *This = ITaskBandImpl_from_ITaskBand(iface);
return InterlockedIncrement(&This->Ref);
}
static VOID
ITaskBandImpl_Free(IN OUT ITaskBandImpl *This)
{
if (This->punkSite != NULL)
{
IUnknown_Release(This->punkSite);
This->punkSite = NULL;
}
HeapFree(hProcessHeap,
0,
This);
}
static ULONG STDMETHODCALLTYPE
ITaskBandImpl_Release(IN OUT ITaskBand *iface)
{
ITaskBandImpl *This = ITaskBandImpl_from_ITaskBand(iface);
ULONG Ret;
Ret = InterlockedDecrement(&This->Ref);
if (Ret == 0)
ITaskBandImpl_Free(This);
return Ret;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_QueryInterface(IN OUT ITaskBand *iface,
IN REFIID riid,
OUT LPVOID *ppvObj)
{
ITaskBandImpl *This;
if (ppvObj == NULL)
return E_POINTER;
This = ITaskBandImpl_from_ITaskBand(iface);
if (IsEqualIID(riid,
&IID_IUnknown))
{
*ppvObj = IUnknown_from_ITaskBandImpl(This);
}
else if (IsEqualIID(riid,
&IID_IDeskBand) ||
IsEqualIID(riid,
&IID_IOleWindow) ||
IsEqualIID(riid,
&IID_IDockingWindow))
{
*ppvObj = IDeskBand_from_ITaskBandImpl(This);
}
else if (IsEqualIID(riid,
&IID_IObjectWithSite))
{
*ppvObj = IObjectWithSite_from_ITaskBandImpl(This);
}
else if (IsEqualIID(riid,
&IID_IDeskBar))
{
*ppvObj = IDeskBar_from_ITaskBandImpl(This);
}
else if (IsEqualIID(riid,
&IID_IWinEventHandler))
{
/* When run on Windows the system queries this interface, which is completely
undocumented :( It's queried during initialization of the tray band site.
The system apparently uses this interface to forward messages to be handled
by the band child window. This interface appears to be implemented by a number
of classes provided by the shell, including the IBandSite interface. In that
we (the host application) forward messages to the default message handler (in
our case the IBandSite default message handler for the Rebar control)! This
interface in the ITaskBand implementation is only actually used if we use
the same interface to forward messages to the IBandSite implementation of
the shell! */
*ppvObj = IWinEventHandler_from_ITaskBandImpl(This);
}
#if 0
else if (IsEqualIID(riid,
&IID_IPersistStream) ||
IsEqualIID(riid,
&IID_IPersist))
{
*ppvObj = IPersistStream_from_ITaskBandImpl(This);
}
#endif
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
ITaskBandImpl_AddRef(iface);
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetRebarBandID(IN OUT ITaskBand *iface,
OUT DWORD *pdwBandID)
{
ITaskBandImpl *This = ITaskBandImpl_from_ITaskBand(iface);
if (This->dwBandID != (DWORD)-1)
{
if (pdwBandID != NULL)
*pdwBandID = This->dwBandID;
return S_OK;
}
return E_FAIL;
}
static const ITaskBandVtbl ITaskBandImpl_Vtbl =
{
/*** IUnknown methods ***/
ITaskBandImpl_QueryInterface,
ITaskBandImpl_AddRef,
ITaskBandImpl_Release,
/*** ITaskBand methods ***/
ITaskBandImpl_GetRebarBandID
};
/*****************************************************************************/
METHOD_IUNKNOWN_INHERITED_ADDREF(IDeskBand, ITaskBand)
METHOD_IUNKNOWN_INHERITED_RELEASE(IDeskBand, ITaskBand)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IDeskBand, ITaskBand)
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetWindow(IN OUT IDeskBand *iface,
OUT HWND *phwnd)
{
ITaskBandImpl *This = ITaskBandImpl_from_IDeskBand(iface);
/* NOTE: We have to return the tray window here so that ITaskBarClient
knows the parent window of the Rebar control it creates when
calling ITaskBarClient::SetDeskBarSite()! However, once we
created a window we return the task switch window! */
if (This->hWnd != NULL)
*phwnd = This->hWnd;
else
*phwnd = ITrayWindow_GetHWND(This->Tray);
TRACE("ITaskBand::GetWindow(0x%p->0x%p)\n", phwnd, *phwnd);
if (*phwnd != NULL)
return S_OK;
return E_FAIL;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_ContextSensitiveHelp(IN OUT IDeskBand *iface,
IN BOOL fEnterMode)
{
/* FIXME: Implement */
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_ShowDW(IN OUT IDeskBand *iface,
IN BOOL bShow)
{
/* We don't do anything... */
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_CloseDW(IN OUT IDeskBand *iface,
IN DWORD dwReserved)
{
/* We don't do anything... */
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_ResizeBoderDW(IN OUT IDeskBand *iface,
IN LPCRECT prcBorder,
IN IUnknown *punkToolbarSite,
IN BOOL fReserved)
{
/* No need to implement this method */
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetBandInfo(IN OUT IDeskBand *iface,
IN DWORD dwBandID,
IN DWORD dwViewMode,
IN OUT DESKBANDINFO *pdbi)
{
ITaskBandImpl *This = ITaskBandImpl_from_IDeskBand(iface);
TRACE("ITaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID, dwViewMode, pdbi, This->hWnd);
/* NOTE: We could save dwBandID in the instance in case we need it later... */
if (This->hWnd != NULL)
{
/* The task band never has a title */
pdbi->dwMask &= ~DBIM_TITLE;
/* NOTE: We don't return DBIMF_UNDELETEABLE here, the band site will
handle us differently and add this flag for us. The reason for
this is future changes that might allow it to be deletable.
We want the band site to be in charge of this decision rather
the band itself! */
/* FIXME: What about DBIMF_NOGRIPPER and DBIMF_ALWAYSGRIPPER */
pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
if (dwViewMode & DBIF_VIEWMODE_VERTICAL)
{
pdbi->ptIntegral.y = 1;
pdbi->ptMinSize.y = 1;
/* FIXME: Get the button metrics from the task bar object!!! */
pdbi->ptMinSize.x = (3 * GetSystemMetrics(SM_CXEDGE) / 2) + /* FIXME: Might be wrong if only one column! */
GetSystemMetrics(SM_CXSIZE) + (2 * GetSystemMetrics(SM_CXEDGE)); /* FIXME: Min button size, query!!! */
}
else
{
pdbi->ptMinSize.y = GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE)); /* FIXME: Query */
pdbi->ptIntegral.y = pdbi->ptMinSize.y + (3 * GetSystemMetrics(SM_CYEDGE) / 2); /* FIXME: Query metrics */
/* We're not going to allow task bands where not even the minimum button size fits into the band */
pdbi->ptMinSize.x = pdbi->ptIntegral.y;
}
/* Ignored: pdbi->ptMaxSize.x */
pdbi->ptMaxSize.y = -1;
/* FIXME: We should query the height from the task bar object!!! */
pdbi->ptActual.y = GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE));
/* Save the band ID for future use in case we need to check whether a given band
is the task band */
This->dwBandID = dwBandID;
TRACE("H: %d, Min: %d,%d, Integral.y: %d Actual: %d,%d\n", (dwViewMode & DBIF_VIEWMODE_VERTICAL) == 0,
pdbi->ptMinSize.x, pdbi->ptMinSize.y, pdbi->ptIntegral.y,
pdbi->ptActual.x,pdbi->ptActual.y);
return S_OK;
}
return E_FAIL;
}
static const IDeskBandVtbl IDeskBandImpl_Vtbl =
{
/*** IUnknown methods ***/
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IDeskBand, ITaskBand),
METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IDeskBand, ITaskBand),
METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IDeskBand, ITaskBand),
/*** IOleWindow methods ***/
ITaskBandImpl_GetWindow,
ITaskBandImpl_ContextSensitiveHelp,
/*** IDockingWindow methods ***/
ITaskBandImpl_ShowDW,
ITaskBandImpl_CloseDW,
ITaskBandImpl_ResizeBoderDW,
/*** IDeskBand methods ***/
ITaskBandImpl_GetBandInfo
};
/*****************************************************************************/
METHOD_IUNKNOWN_INHERITED_ADDREF(IDeskBar, ITaskBand)
METHOD_IUNKNOWN_INHERITED_RELEASE(IDeskBar, ITaskBand)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IDeskBar, ITaskBand)
static HRESULT STDMETHODCALLTYPE
IDeskBarImpl_GetWindow(IN OUT IDeskBar *iface,
OUT HWND *phwnd)
{
ITaskBandImpl *This = ITaskBandImpl_from_IDeskBar(iface);
IDeskBand *DeskBand = IDeskBand_from_ITaskBandImpl(This);
/* Proxy to IDeskBand interface */
return IDeskBand_GetWindow(DeskBand,
phwnd);
}
static HRESULT STDMETHODCALLTYPE
IDeskBarImpl_ContextSensitiveHelp(IN OUT IDeskBar *iface,
IN BOOL fEnterMode)
{
ITaskBandImpl *This = ITaskBandImpl_from_IDeskBar(iface);
IDeskBand *DeskBand = IDeskBand_from_ITaskBandImpl(This);
/* Proxy to IDeskBand interface */
return IDeskBand_ContextSensitiveHelp(DeskBand,
fEnterMode);
}
static HRESULT STDMETHODCALLTYPE
IDeskBarImpl_SetClient(IN OUT IDeskBar *iface,
IN IUnknown *punkClient)
{
TRACE("IDeskBar::SetClient(0x%p)\n", punkClient);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
IDeskBarImpl_GetClient(IN OUT IDeskBar *iface,
OUT IUnknown **ppunkClient)
{
TRACE("IDeskBar::GetClient(0x%p)\n", ppunkClient);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
IDeskBarImpl_OnPosRectChangeDB(IN OUT IDeskBar *iface,
IN RECT *prc)
{
TRACE("IDeskBar::OnPosRectChangeDB(0x%p=(%d,%d,%d,%d))\n", prc, prc->left, prc->top, prc->right, prc->bottom);
if (prc->bottom - prc->top == 0)
return S_OK;
return S_FALSE;
}
static const IDeskBarVtbl IDeskBarImpl_Vtbl =
{
/*** IUnknown methods ***/
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IDeskBar, ITaskBand),
METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IDeskBar, ITaskBand),
METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IDeskBar, ITaskBand),
/*** IOleWindow methods ***/
IDeskBarImpl_GetWindow,
IDeskBarImpl_ContextSensitiveHelp,
/*** IDeskBar methods ***/
IDeskBarImpl_SetClient,
IDeskBarImpl_GetClient,
IDeskBarImpl_OnPosRectChangeDB
};
/*****************************************************************************/
METHOD_IUNKNOWN_INHERITED_ADDREF(IPersistStream, ITaskBand)
METHOD_IUNKNOWN_INHERITED_RELEASE(IPersistStream, ITaskBand)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IPersistStream, ITaskBand)
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetClassID(IN OUT IPersistStream *iface,
OUT CLSID *pClassID)
{
TRACE("ITaskBand::GetClassID(0x%p)\n", pClassID);
/* We're going to return the (internal!) CLSID of the task band interface */
*pClassID = CLSID_ITaskBand;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_IsDirty(IN OUT IPersistStream *iface)
{
/* The object hasn't changed since the last save! */
return S_FALSE;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_Load(IN OUT IPersistStream *iface,
IN IStream *pStm)
{
TRACE("ITaskBand::Load called\n");
/* Nothing to do */
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_Save(IN OUT IPersistStream *iface,
IN IStream *pStm,
IN BOOL fClearDirty)
{
/* Nothing to do */
return S_OK;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetSizeMax(IN OUT IPersistStream *iface,
OUT ULARGE_INTEGER *pcbSize)
{
TRACE("ITaskBand::GetSizeMax called\n");
/* We don't need any space for the task band */
pcbSize->QuadPart = 0;
return S_OK;
}
static const IPersistStreamVtbl IPersistStreamImpl_Vtbl =
{
/*** IUnknown methods ***/
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IPersistStream, ITaskBand),
METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IPersistStream, ITaskBand),
METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IPersistStream, ITaskBand),
/*** IPersist methods ***/
ITaskBandImpl_GetClassID,
/*** IPersistStream methods ***/
ITaskBandImpl_IsDirty,
ITaskBandImpl_Load,
ITaskBandImpl_Save,
ITaskBandImpl_GetSizeMax
};
/*****************************************************************************/
METHOD_IUNKNOWN_INHERITED_ADDREF(IObjectWithSite, ITaskBand)
METHOD_IUNKNOWN_INHERITED_RELEASE(IObjectWithSite, ITaskBand)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IObjectWithSite, ITaskBand)
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_SetSite(IN OUT IObjectWithSite *iface,
IN IUnknown* pUnkSite)
{
ITaskBandImpl *This = ITaskBandImpl_from_IObjectWithSite(iface);
HRESULT hRet = E_FAIL;
TRACE("ITaskBand::SetSite(0x%p)\n", pUnkSite);
/* Release the current site */
if (This->punkSite != NULL)
{
IUnknown_Release(This->punkSite);
}
This->punkSite = NULL;
This->hWnd = NULL;
if (pUnkSite != NULL)
{
IOleWindow *OleWindow;
/* Check if the site supports IOleWindow */
hRet = IUnknown_QueryInterface(pUnkSite,
&IID_IOleWindow,
(PVOID *)&OleWindow);
if (SUCCEEDED(hRet))
{
HWND hWndParent = NULL;
hRet = IOleWindow_GetWindow(OleWindow,
&hWndParent);
if (SUCCEEDED(hRet))
{
/* Attempt to create the task switch window */
TRACE("CreateTaskSwitchWnd(Parent: 0x%p)\n", hWndParent);
This->hWnd = CreateTaskSwitchWnd(hWndParent,
This->Tray);
if (This->hWnd != NULL)
{
This->punkSite = pUnkSite;
hRet = S_OK;
}
else
{
TRACE("CreateTaskSwitchWnd() failed!\n");
IUnknown_Release(OleWindow);
hRet = E_FAIL;
}
}
else
IUnknown_Release(OleWindow);
}
else
TRACE("Querying IOleWindow failed: 0x%x\n", hRet);
}
return hRet;
}
static HRESULT STDMETHODCALLTYPE
ITaskBandImpl_GetSite(IN OUT IObjectWithSite *iface,
IN REFIID riid,
OUT VOID **ppvSite)
{
ITaskBandImpl *This = ITaskBandImpl_from_IObjectWithSite(iface);
TRACE("ITaskBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
if (This->punkSite != NULL)
{
return IUnknown_QueryInterface(This->punkSite,
riid,
ppvSite);
}
*ppvSite = NULL;
return E_FAIL;
}
static const IObjectWithSiteVtbl IObjectWithSiteImpl_Vtbl =
{
/*** IUnknown methods ***/
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IObjectWithSite, ITaskBand),
METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IObjectWithSite, ITaskBand),
METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IObjectWithSite, ITaskBand),
/*** IObjectWithSite methods ***/
ITaskBandImpl_SetSite,
ITaskBandImpl_GetSite
};
/*****************************************************************************/
METHOD_IUNKNOWN_INHERITED_ADDREF(IWinEventHandler, ITaskBand)
METHOD_IUNKNOWN_INHERITED_RELEASE(IWinEventHandler, ITaskBand)
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE(IWinEventHandler, ITaskBand)
static HRESULT STDMETHODCALLTYPE
IWinEventHandlerImpl_ProcessMessage(IN OUT IWinEventHandler *iface,
IN HWND hWnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam,
OUT LRESULT *plrResult)
{
TRACE("ITaskBand: IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p)\n", hWnd, uMsg, wParam, lParam, plrResult);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE
IWinEventHandlerImpl_ContainsWindow(IN OUT IWinEventHandler *iface,
IN HWND hWnd)
{
ITaskBandImpl *This = ITaskBandImpl_from_IWinEventHandler(iface);
if (This->hWnd == hWnd ||
IsChild(This->hWnd, hWnd))
{
TRACE("ITaskBand::ContainsWindow(0x%p) returns S_OK\n", hWnd);
return S_OK;
}
return S_FALSE;
}
static const IWinEventHandlerVtbl IWinEventHandlerImpl_Vtbl =
{
/*** IUnknown methods ***/
METHOD_IUNKNOWN_INHERITED_QUERYINTERFACE_NAME(IWinEventHandler, ITaskBand),
METHOD_IUNKNOWN_INHERITED_ADDREF_NAME(IWinEventHandler, ITaskBand),
METHOD_IUNKNOWN_INHERITED_RELEASE_NAME(IWinEventHandler, ITaskBand),
/*** IWinEventHandler methods ***/
IWinEventHandlerImpl_ProcessMessage,
IWinEventHandlerImpl_ContainsWindow
};
/*****************************************************************************/
static ITaskBandImpl *
ITaskBandImpl_Construct(IN OUT ITrayWindow *Tray)
{
ITaskBandImpl *This;
This = HeapAlloc(hProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(*This));
if (This == NULL)
return NULL;
This->lpVtbl = &ITaskBandImpl_Vtbl;
This->lpDeskBandVtbl = &IDeskBandImpl_Vtbl;
This->lpObjectWithSiteVtbl = &IObjectWithSiteImpl_Vtbl;
This->lpDeskBarVtbl = &IDeskBarImpl_Vtbl;
This->lpPersistStreamVtbl = &IPersistStreamImpl_Vtbl;
This->lpWindowEventHandlerVtbl = &IWinEventHandlerImpl_Vtbl;
This->Ref = 1;
This->Tray = Tray;
This->dwBandID = (DWORD)-1;
return This;
}
ITaskBand *
CreateTaskBand(IN OUT ITrayWindow *Tray)
{
ITaskBandImpl *This;
This = ITaskBandImpl_Construct(Tray);
if (This != NULL)
{
return ITaskBand_from_ITaskBandImpl(This);
}
return NULL;
}

View file

@ -0,0 +1,420 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
/*****************************************************************************
** ITaskBand ****************************************************************
*****************************************************************************/
const GUID CLSID_ITaskBand = { 0x68284FAA, 0x6A48, 0x11D0, { 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4 } };
class ITaskBandImpl :
public CComCoClass<ITaskBandImpl>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IObjectWithSite,
public ITaskBand,
public IDeskBand,
public IDeskBar,
public IPersistStream,
public IWinEventHandler,
public IOleCommandTarget
{
CComPtr<ITrayWindow> Tray;
CComPtr<IUnknown> punkSite;
HWND hWnd;
DWORD dwBandID;
public:
ITaskBandImpl() :
hWnd(NULL),
dwBandID(0)
{
}
virtual ~ITaskBandImpl() { }
virtual HRESULT STDMETHODCALLTYPE GetRebarBandID(
OUT DWORD *pdwBandID)
{
if (dwBandID != (DWORD) -1)
{
if (pdwBandID != NULL)
*pdwBandID = dwBandID;
return S_OK;
}
return E_FAIL;
}
/*****************************************************************************/
virtual HRESULT STDMETHODCALLTYPE GetWindow(
OUT HWND *phwnd)
{
/* NOTE: We have to return the tray window here so that ITaskBarClient
knows the parent window of the Rebar control it creates when
calling ITaskBarClient::SetDeskBarSite()! However, once we
created a window we return the task switch window! */
if (hWnd != NULL)
*phwnd = hWnd;
else
*phwnd = Tray->GetHWND();
TRACE("ITaskBand::GetWindow(0x%p->0x%p)\n", phwnd, *phwnd);
if (*phwnd != NULL)
return S_OK;
return E_FAIL;
}
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
IN BOOL fEnterMode)
{
/* FIXME: Implement */
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ShowDW(
IN BOOL bShow)
{
/* We don't do anything... */
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE CloseDW(
IN DWORD dwReserved)
{
/* We don't do anything... */
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(
LPCRECT prcBorder,
IUnknown *punkToolbarSite,
BOOL fReserved)
{
/* No need to implement this method */
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetBandInfo(
IN DWORD dwBandID,
IN DWORD dwViewMode,
IN OUT DESKBANDINFO *pdbi)
{
TRACE("ITaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID, dwViewMode, pdbi, hWnd);
if (hWnd != NULL)
{
/* The task band never has a title */
pdbi->dwMask &= ~DBIM_TITLE;
/* NOTE: We don't return DBIMF_UNDELETEABLE here, the band site will
handle us differently and add this flag for us. The reason for
this is future changes that might allow it to be deletable.
We want the band site to be in charge of this decision rather
the band itself! */
/* FIXME: What about DBIMF_NOGRIPPER and DBIMF_ALWAYSGRIPPER */
pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
if (dwViewMode & DBIF_VIEWMODE_VERTICAL)
{
pdbi->ptIntegral.y = 1;
pdbi->ptMinSize.y = 1;
/* FIXME: Get the button metrics from the task bar object!!! */
pdbi->ptMinSize.x = (3 * GetSystemMetrics(SM_CXEDGE) / 2) + /* FIXME: Might be wrong if only one column! */
GetSystemMetrics(SM_CXSIZE) + (2 * GetSystemMetrics(SM_CXEDGE)); /* FIXME: Min button size, query!!! */
}
else
{
pdbi->ptMinSize.y = GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE)); /* FIXME: Query */
pdbi->ptIntegral.y = pdbi->ptMinSize.y + (3 * GetSystemMetrics(SM_CYEDGE) / 2); /* FIXME: Query metrics */
/* We're not going to allow task bands where not even the minimum button size fits into the band */
pdbi->ptMinSize.x = pdbi->ptIntegral.y;
}
/* Ignored: pdbi->ptMaxSize.x */
pdbi->ptMaxSize.y = -1;
/* FIXME: We should query the height from the task bar object!!! */
pdbi->ptActual.y = GetSystemMetrics(SM_CYSIZE) + (2 * GetSystemMetrics(SM_CYEDGE));
/* Save the band ID for future use in case we need to check whether a given band
is the task band */
this->dwBandID = dwBandID;
TRACE("H: %d, Min: %d,%d, Integral.y: %d Actual: %d,%d\n", (dwViewMode & DBIF_VIEWMODE_VERTICAL) == 0,
pdbi->ptMinSize.x, pdbi->ptMinSize.y, pdbi->ptIntegral.y,
pdbi->ptActual.x, pdbi->ptActual.y);
return S_OK;
}
return E_FAIL;
}
/*****************************************************************************/
// *** IOleCommandTarget methods ***
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE 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;
}
/*****************************************************************************/
virtual HRESULT STDMETHODCALLTYPE SetClient(
IN IUnknown *punkClient)
{
TRACE("IDeskBar::SetClient(0x%p)\n", punkClient);
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetClient(
OUT IUnknown **ppunkClient)
{
TRACE("IDeskBar::GetClient(0x%p)\n", ppunkClient);
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(
IN RECT *prc)
{
TRACE("IDeskBar::OnPosRectChangeDB(0x%p=(%d,%d,%d,%d))\n", prc, prc->left, prc->top, prc->right, prc->bottom);
if (prc->bottom - prc->top == 0)
return S_OK;
return S_FALSE;
}
/*****************************************************************************/
virtual HRESULT STDMETHODCALLTYPE GetClassID(
OUT CLSID *pClassID)
{
TRACE("ITaskBand::GetClassID(0x%p)\n", pClassID);
/* We're going to return the (internal!) CLSID of the task band interface */
*pClassID = CLSID_ITaskBand;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE IsDirty()
{
/* The object hasn't changed since the last save! */
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE Load(
IN IStream *pStm)
{
TRACE("ITaskBand::Load called\n");
/* Nothing to do */
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Save(
IN IStream *pStm,
IN BOOL fClearDirty)
{
/* Nothing to do */
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetSizeMax(
OUT ULARGE_INTEGER *pcbSize)
{
TRACE("ITaskBand::GetSizeMax called\n");
/* We don't need any space for the task band */
pcbSize->QuadPart = 0;
return S_OK;
}
/*****************************************************************************/
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite)
{
HRESULT hRet = E_FAIL;
TRACE("ITaskBand::SetSite(0x%p)\n", pUnkSite);
/* Release the current site */
if (punkSite != NULL)
{
punkSite->Release();
}
punkSite = NULL;
hWnd = NULL;
if (pUnkSite != NULL)
{
IOleWindow *OleWindow;
/* Check if the site supports IOleWindow */
hRet = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &OleWindow));
if (SUCCEEDED(hRet))
{
HWND hWndParent = NULL;
hRet = OleWindow->GetWindow(
&hWndParent);
if (SUCCEEDED(hRet))
{
/* Attempt to create the task switch window */
TRACE("CreateTaskSwitchWnd(Parent: 0x%p)\n", hWndParent);
hWnd = CreateTaskSwitchWnd(hWndParent, Tray);
if (hWnd != NULL)
{
punkSite = pUnkSite;
hRet = S_OK;
}
else
{
TRACE("CreateTaskSwitchWnd() failed!\n");
OleWindow->Release();
hRet = E_FAIL;
}
}
else
OleWindow->Release();
}
else
TRACE("Querying IOleWindow failed: 0x%x\n", hRet);
}
return hRet;
}
virtual HRESULT STDMETHODCALLTYPE GetSite(
IN REFIID riid,
OUT VOID **ppvSite)
{
TRACE("ITaskBand::GetSite(0x%p,0x%p)\n", riid, ppvSite);
if (punkSite != NULL)
{
return punkSite->QueryInterface(riid, ppvSite);
}
*ppvSite = NULL;
return E_FAIL;
}
/*****************************************************************************/
virtual HRESULT STDMETHODCALLTYPE ProcessMessage(
IN HWND hWnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam,
OUT LRESULT *plrResult)
{
TRACE("ITaskBand: IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p)\n", hWnd, uMsg, wParam, lParam, plrResult);
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ContainsWindow(
IN HWND hWnd)
{
if (hWnd == hWnd ||
IsChild(hWnd, hWnd))
{
TRACE("ITaskBand::ContainsWindow(0x%p) returns S_OK\n", hWnd);
return S_OK;
}
return S_FALSE;
}
virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
{
UNIMPLEMENTED;
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd)
{
return (hWnd == this->hWnd) ? S_OK : S_FALSE;
}
/*****************************************************************************/
HRESULT STDMETHODCALLTYPE _Init(IN OUT ITrayWindow *tray)
{
Tray = tray;
dwBandID = (DWORD) -1;
return S_OK;
}
DECLARE_NOT_AGGREGATABLE(ITaskBandImpl)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(ITaskBandImpl)
COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, 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)
END_COM_MAP()
};
ITaskBand * CreateTaskBand(IN OUT ITrayWindow *Tray)
{
HRESULT hr;
ITaskBandImpl * tb = new CComObject<ITaskBandImpl>();
if (!tb)
return NULL;
hr = tb->AddRef();
hr = tb->_Init(Tray);
if (FAILED_UNEXPECTEDLY(hr))
tb->Release();
return tb;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,831 @@
/*
* ReactOS Explorer
*
* Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
*
* 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"
#include <shdeprecated.h>
#include "undoc.h"
/*****************************************************************************
** ITrayBandSite ************************************************************
*****************************************************************************/
// WARNING: Can't use ATL for this class due to our ATL not fully supporting the AGGREGATION functions needed for this class to be an "outer" class
// it works just fine this way.
class ITrayBandSiteImpl :
public ITrayBandSite,
public IBandSite,
public IBandSiteStreamCallback
/* TODO: IWinEventHandler */
{
volatile LONG m_RefCount;
CComPtr<ITrayWindow> Tray;
CComPtr<IUnknown> punkInner;
CComPtr<IBandSite> BandSite;
CComPtr<ITaskBand> TaskBand;
CComPtr<IWinEventHandler> WindowEventHandler;
CComPtr<IContextMenu> ContextMenu;
HWND hWndRebar;
union
{
DWORD dwFlags;
struct
{
DWORD Locked : 1;
};
};
public:
virtual ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release()
{
ULONG Ret = InterlockedDecrement(&m_RefCount);
if (Ret == 0)
delete this;
return Ret;
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(IN REFIID riid, OUT LPVOID *ppvObj)
{
if (ppvObj == NULL)
return E_POINTER;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IBandSiteStreamCallback))
{
// return IBandSiteStreamCallback's IUnknown
*ppvObj = static_cast<IBandSiteStreamCallback*>(this);
}
else if (IsEqualIID(riid, IID_IBandSite))
{
*ppvObj = static_cast<IBandSite*>(this);
}
else if (IsEqualIID(riid, IID_IWinEventHandler))
{
TRACE("ITaskBandSite: IWinEventHandler queried!\n");
*ppvObj = NULL;
return E_NOINTERFACE;
}
else if (punkInner != NULL)
{
return punkInner->QueryInterface(riid, ppvObj);
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
public:
ITrayBandSiteImpl() :
m_RefCount(0),
hWndRebar(NULL)
{
}
virtual ~ITrayBandSiteImpl() { }
virtual HRESULT STDMETHODCALLTYPE OnLoad(
IN OUT IStream *pStm,
IN REFIID riid,
OUT PVOID *pvObj)
{
LARGE_INTEGER liPosZero;
ULARGE_INTEGER liCurrent;
CLSID clsid;
ULONG ulRead;
HRESULT hRet;
/* NOTE: Callback routine called by the shell while loading the task band
stream. We use it to intercept the default behavior when the task
band is loaded from the stream.
NOTE: riid always points to IID_IUnknown! This is because the shell hasn't
read anything from the stream and therefore doesn't know what CLSID
it's dealing with. We'll have to find it out ourselves by reading
the GUID from the stream. */
/* Read the current position of the stream, we'll have to reset it everytime
we read a CLSID that's not the task band... */
ZeroMemory(&liPosZero,
sizeof(liPosZero));
hRet = pStm->Seek(liPosZero, STREAM_SEEK_CUR, &liCurrent);
if (SUCCEEDED(hRet))
{
/* Now let's read the CLSID from the stream and see if it's our task band */
hRet = pStm->Read(&clsid, (ULONG)sizeof(clsid), &ulRead);
if (SUCCEEDED(hRet) && ulRead == sizeof(clsid))
{
if (IsEqualGUID(clsid, CLSID_ITaskBand))
{
ASSERT(TaskBand != NULL);
/* We're trying to load the task band! Let's create it... */
hRet = TaskBand->QueryInterface(
riid,
pvObj);
if (SUCCEEDED(hRet))
{
/* Load the stream */
TRACE("IBandSiteStreamCallback::OnLoad intercepted the task band CLSID!\n");
}
return hRet;
}
}
}
/* Reset the position and let the shell do all the work for us */
hRet = pStm->Seek(
*(LARGE_INTEGER*) &liCurrent,
STREAM_SEEK_SET,
NULL);
if (SUCCEEDED(hRet))
{
/* Let the shell handle everything else for us :) */
hRet = OleLoadFromStream(pStm,
riid,
pvObj);
}
if (!SUCCEEDED(hRet))
{
TRACE("IBandSiteStreamCallback::OnLoad(0x%p, 0x%p, 0x%p) returns 0x%x\n", pStm, riid, pvObj, hRet);
}
return hRet;
}
virtual HRESULT STDMETHODCALLTYPE OnSave(
IN OUT IUnknown *pUnk,
IN OUT IStream *pStm)
{
/* NOTE: Callback routine called by the shell while saving the task band
stream. We use it to intercept the default behavior when the task
band is saved to the stream */
/* FIXME: Implement */
TRACE("IBandSiteStreamCallback::OnSave(0x%p, 0x%p) returns E_NOTIMPL\n", pUnk, pStm);
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE IsTaskBand(
IN IUnknown *punk)
{
return IsSameObject((IUnknown *) BandSite,
punk);
}
virtual HRESULT STDMETHODCALLTYPE ProcessMessage(
IN HWND hWnd,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam,
OUT LRESULT *plResult)
{
HRESULT hRet;
ASSERT(hWndRebar != NULL);
/* Custom task band behavior */
switch (uMsg)
{
case WM_NOTIFY:
{
const NMHDR *nmh = (const NMHDR *) lParam;
if (nmh->hwndFrom == hWndRebar)
{
switch (nmh->code)
{
case NM_NCHITTEST:
{
LPNMMOUSE nmm = (LPNMMOUSE) lParam;
if (nmm->dwHitInfo == RBHT_CLIENT || nmm->dwHitInfo == RBHT_NOWHERE ||
nmm->dwItemSpec == (DWORD_PTR) -1)
{
/* Make the rebar control appear transparent so the user
can drag the tray window */
*plResult = HTTRANSPARENT;
}
return S_OK;
}
case RBN_MINMAX:
/* Deny if an Administrator disabled this "feature" */
*plResult = (SHRestricted(REST_NOMOVINGBAND) != 0);
return S_OK;
}
}
//TRACE("ITrayBandSite::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u...\n", hWnd, nmh->hwndFrom, NM_FIRST - nmh->code);
break;
}
}
/* Forward to the shell's IWinEventHandler interface to get the default shell behavior! */
if (!WindowEventHandler)
return E_FAIL;
/*TRACE("Calling IWinEventHandler::ProcessMessage(0x%p, 0x%x, 0x%p, 0x%p, 0x%p) hWndRebar=0x%p\n", hWnd, uMsg, wParam, lParam, plResult, hWndRebar);*/
hRet = WindowEventHandler->OnWinEvent(
hWnd,
uMsg,
wParam,
lParam,
plResult);
if (FAILED_UNEXPECTEDLY(hRet))
{
if (uMsg == WM_NOTIFY)
{
const NMHDR *nmh = (const NMHDR *) lParam;
ERR("ITrayBandSite->IWinEventHandler::ProcessMessage: WM_NOTIFY for 0x%p, From: 0x%p, Code: NM_FIRST-%u returned 0x%x\n", hWnd, nmh->hwndFrom, NM_FIRST - nmh->code, hRet);
}
else
{
ERR("ITrayBandSite->IWinEventHandler::ProcessMessage(0x%p,0x%x,0x%p,0x%p,0x%p->0x%p) returned: 0x%x\n", hWnd, uMsg, wParam, lParam, plResult, *plResult, hRet);
}
}
return hRet;
}
virtual HRESULT STDMETHODCALLTYPE AddContextMenus(
IN HMENU hmenu,
IN UINT indexMenu,
IN UINT idCmdFirst,
IN UINT idCmdLast,
IN UINT uFlags,
OUT IContextMenu **ppcm)
{
IShellService *pSs;
HRESULT hRet;
if (ContextMenu == NULL)
{
/* Cache the context menu so we don't need to CoCreateInstance all the time... */
hRet = CoCreateInstance(CLSID_IShellBandSiteMenu, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellService, &pSs));
TRACE("CoCreateInstance(CLSID_IShellBandSiteMenu) for IShellService returned: 0x%x\n", hRet);
if (!SUCCEEDED(hRet))
return hRet;
hRet = pSs->SetOwner((IBandSite*)this);
if (!SUCCEEDED(hRet))
{
pSs->Release();
return hRet;
}
hRet = pSs->QueryInterface(IID_PPV_ARG(IContextMenu, &ContextMenu));
pSs->Release();
if (!SUCCEEDED(hRet))
return hRet;
}
if (ppcm != NULL)
{
ContextMenu->AddRef();
*ppcm = ContextMenu;
}
/* Add the menu items */
return ContextMenu->QueryContextMenu(
hmenu,
indexMenu,
idCmdFirst,
idCmdLast,
uFlags);
}
virtual HRESULT STDMETHODCALLTYPE Lock(
IN BOOL bLock)
{
BOOL bPrevLocked = Locked;
BANDSITEINFO bsi;
HRESULT hRet;
ASSERT(BandSite != NULL);
if (bPrevLocked != bLock)
{
Locked = bLock;
bsi.dwMask = BSIM_STYLE;
bsi.dwStyle = (Locked ? BSIS_LOCKED | BSIS_NOGRIPPER : BSIS_AUTOGRIPPER);
hRet = BandSite->SetBandSiteInfo(&bsi);
if (SUCCEEDED(hRet))
{
hRet = Update();
}
return hRet;
}
return S_FALSE;
}
/*******************************************************************/
virtual HRESULT STDMETHODCALLTYPE AddBand(
IN IUnknown *punk)
{
IOleCommandTarget *pOct;
HRESULT hRet;
hRet = punk->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOct));
if (SUCCEEDED(hRet))
{
/* Send the DBID_DELAYINIT command to initialize the band to be added */
/* FIXME: Should be delayed */
pOct->Exec(
&IID_IDeskBand,
DBID_DELAYINIT,
0,
NULL,
NULL);
pOct->Release();
}
return BandSite->AddBand(
punk);
}
virtual HRESULT STDMETHODCALLTYPE EnumBands(
IN UINT uBand,
OUT DWORD *pdwBandID)
{
return BandSite->EnumBands(
uBand,
pdwBandID);
}
virtual HRESULT STDMETHODCALLTYPE QueryBand(
IN DWORD dwBandID,
OUT IDeskBand **ppstb,
OUT DWORD *pdwState,
OUT LPWSTR pszName,
IN int cchName)
{
HRESULT hRet;
IDeskBand *pstb = NULL;
hRet = BandSite->QueryBand(
dwBandID,
&pstb,
pdwState,
pszName,
cchName);
if (SUCCEEDED(hRet))
{
hRet = IsSameObject(pstb, TaskBand);
if (hRet == S_OK)
{
/* Add the BSSF_UNDELETEABLE flag to pdwState because the task bar band shouldn't be deletable */
if (pdwState != NULL)
*pdwState |= BSSF_UNDELETEABLE;
}
else if (!SUCCEEDED(hRet))
{
pstb->Release();
pstb = NULL;
}
if (ppstb != NULL)
*ppstb = pstb;
}
else if (ppstb != NULL)
*ppstb = NULL;
return hRet;
}
virtual HRESULT STDMETHODCALLTYPE SetBandState(
IN DWORD dwBandID,
IN DWORD dwMask,
IN DWORD dwState)
{
return BandSite->SetBandState(dwBandID, dwMask, dwState);
}
virtual HRESULT STDMETHODCALLTYPE RemoveBand(
IN DWORD dwBandID)
{
return BandSite->RemoveBand(dwBandID);
}
virtual HRESULT STDMETHODCALLTYPE GetBandObject(
IN DWORD dwBandID,
IN REFIID riid,
OUT VOID **ppv)
{
return BandSite->GetBandObject(dwBandID, riid, ppv);
}
virtual HRESULT STDMETHODCALLTYPE SetBandSiteInfo(
IN const BANDSITEINFO *pbsinfo)
{
return BandSite->SetBandSiteInfo(pbsinfo);
}
virtual HRESULT STDMETHODCALLTYPE GetBandSiteInfo(
IN OUT BANDSITEINFO *pbsinfo)
{
return BandSite->GetBandSiteInfo(pbsinfo);
}
virtual BOOL HasTaskBand()
{
ASSERT(TaskBand != NULL);
return SUCCEEDED(TaskBand->GetRebarBandID(
NULL));
}
virtual HRESULT AddTaskBand()
{
#if 0
/* FIXME: This is the code for the simple taskbar */
IObjectWithSite *pOws;
HRESULT hRet;
hRet = TaskBand->QueryInterface(
&IID_IObjectWithSite,
(PVOID*) &pOws);
if (SUCCEEDED(hRet))
{
hRet = pOws->SetSite(
(IUnknown *)TaskBand);
pOws->Release();
}
return hRet;
#else
if (!HasTaskBand())
{
return BandSite->AddBand(TaskBand);
}
return S_OK;
#endif
}
virtual HRESULT Update()
{
IOleCommandTarget *pOct;
HRESULT hRet;
hRet = punkInner->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOct));
if (SUCCEEDED(hRet))
{
/* Send the DBID_BANDINFOCHANGED command to update the band site */
hRet = pOct->Exec(
&IID_IDeskBand,
DBID_BANDINFOCHANGED,
0,
NULL,
NULL);
pOct->Release();
}
return hRet;
}
virtual VOID BroadcastOleCommandExec(const GUID *pguidCmdGroup,
DWORD nCmdID,
DWORD nCmdExecOpt,
VARIANTARG *pvaIn,
VARIANTARG *pvaOut)
{
IOleCommandTarget *pOct;
DWORD dwBandID;
UINT uBand = 0;
/* Enumerate all bands */
while (SUCCEEDED(BandSite->EnumBands(uBand, &dwBandID)))
{
if (SUCCEEDED(BandSite->GetBandObject(dwBandID, IID_PPV_ARG(IOleCommandTarget, &pOct))))
{
/* Execute the command */
pOct->Exec(
pguidCmdGroup,
nCmdID,
nCmdExecOpt,
pvaIn,
pvaOut);
pOct->Release();
}
uBand++;
}
}
virtual HRESULT FinishInit()
{
/* Broadcast the DBID_FINISHINIT command */
BroadcastOleCommandExec(&IID_IDeskBand, DBID_FINISHINIT, 0, NULL, NULL);
return S_OK;
}
virtual HRESULT Show(
IN BOOL bShow)
{
IDeskBarClient *pDbc;
HRESULT hRet;
hRet = BandSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDbc));
if (SUCCEEDED(hRet))
{
hRet = pDbc->UIActivateDBC(
bShow ? DBC_SHOW : DBC_HIDE);
pDbc->Release();
}
return hRet;
}
virtual HRESULT LoadFromStream(IN OUT IStream *pStm)
{
IPersistStream *pPStm;
HRESULT hRet;
ASSERT(BandSite != NULL);
/* We implement the undocumented COM interface IBandSiteStreamCallback
that the shell will query so that we can intercept and custom-load
the task band when it finds the task band's CLSID (which is internal).
This way we can prevent the shell from attempting to CoCreateInstance
the (internal) task band, resulting in a failure... */
hRet = BandSite->QueryInterface(IID_PPV_ARG(IPersistStream, &pPStm));
if (SUCCEEDED(hRet))
{
hRet = pPStm->Load(
pStm);
TRACE("->Load() returned 0x%x\n", hRet);
pPStm->Release();
}
return hRet;
}
virtual IStream *
GetUserBandsStream(IN DWORD grfMode)
{
HKEY hkStreams;
IStream *Stream = NULL;
if (RegCreateKey(hkExplorer,
TEXT("Streams"),
&hkStreams) == ERROR_SUCCESS)
{
Stream = SHOpenRegStream(hkStreams,
TEXT("Desktop"),
TEXT("TaskbarWinXP"),
grfMode);
RegCloseKey(hkStreams);
}
return Stream;
}
virtual IStream *
GetDefaultBandsStream(IN DWORD grfMode)
{
HKEY hkStreams;
IStream *Stream = NULL;
if (RegCreateKey(HKEY_LOCAL_MACHINE,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Streams"),
&hkStreams) == ERROR_SUCCESS)
{
Stream = SHOpenRegStream(hkStreams,
TEXT("Desktop"),
TEXT("Default Taskbar"),
grfMode);
RegCloseKey(hkStreams);
}
return Stream;
}
virtual HRESULT Load()
{
IStream *pStm;
HRESULT hRet;
/* Try to load the user's settings */
pStm = GetUserBandsStream(STGM_READ);
if (pStm != NULL)
{
hRet = LoadFromStream(pStm);
TRACE("Loaded user bands settings: 0x%x\n", hRet);
pStm->Release();
}
else
hRet = E_FAIL;
/* If the user's settings couldn't be loaded, try with
default settings (ie. when the user logs in for the
first time! */
if (!SUCCEEDED(hRet))
{
pStm = GetDefaultBandsStream(STGM_READ);
if (pStm != NULL)
{
hRet = LoadFromStream(pStm);
TRACE("Loaded default user bands settings: 0x%x\n", hRet);
pStm->Release();
}
else
hRet = E_FAIL;
}
return hRet;
}
HRESULT _Init(IN OUT ITrayWindow *tray, OUT HWND *phWndRebar, OUT HWND *phwndTaskSwitch)
{
IDeskBarClient *pDbc;
IDeskBand *pDb;
IOleWindow *pOw;
HRESULT hRet;
*phWndRebar = NULL;
*phwndTaskSwitch = NULL;
Tray = tray;
/* Create a RebarBandSite provided by the shell */
hRet = CoCreateInstance(CLSID_RebarBandSite,
static_cast<IBandSite*>(this),
CLSCTX_INPROC_SERVER,
IID_PPV_ARG(IUnknown, &punkInner));
if (!SUCCEEDED(hRet))
{
return hRet;
}
hRet = punkInner->QueryInterface(IID_PPV_ARG(IBandSite, &BandSite));
if (!SUCCEEDED(hRet))
{
return hRet;
}
hRet = punkInner->QueryInterface(IID_PPV_ARG(IWinEventHandler, &WindowEventHandler));
if (!SUCCEEDED(hRet))
{
return hRet;
}
TaskBand = CreateTaskBand(Tray);
if (TaskBand != NULL)
{
/* Add the task band to the site */
hRet = BandSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDbc));
if (SUCCEEDED(hRet))
{
hRet = TaskBand->QueryInterface(IID_PPV_ARG(IOleWindow, &pOw));
if (SUCCEEDED(hRet))
{
/* We cause IDeskBarClient to create the rebar control by passing the new
task band to it. The band reports the tray window handle as window handle
so that IDeskBarClient knows the parent window of the Rebar control that
it wants to create. */
hRet = pDbc->SetDeskBarSite(pOw);
if (SUCCEEDED(hRet))
{
/* The Rebar control is now created, we can query the window handle */
hRet = pDbc->GetWindow(&hWndRebar);
if (SUCCEEDED(hRet))
{
/* We need to manually remove the RBS_BANDBORDERS style! */
SetWindowStyle(hWndRebar, RBS_BANDBORDERS, 0);
}
}
pOw->Release();
}
if (SUCCEEDED(hRet))
{
DWORD dwMode = 0;
/* Set the Desk Bar mode to the current one */
/* FIXME: We need to set the mode (and update) whenever the user docks
the tray window to another monitor edge! */
if (!Tray->IsHorizontal())
dwMode = DBIF_VIEWMODE_VERTICAL;
hRet = pDbc->SetModeDBC(dwMode);
}
pDbc->Release();
}
/* Load the saved state of the task band site */
/* FIXME: We should delay loading shell extensions, also see DBID_DELAYINIT */
Load();
/* Add the task bar band if it hasn't been added already */
hRet = AddTaskBand();
if (SUCCEEDED(hRet))
{
hRet = TaskBand->QueryInterface(IID_PPV_ARG(IDeskBand, &pDb));
if (SUCCEEDED(hRet))
{
hRet = pDb->GetWindow(phwndTaskSwitch);
if (!SUCCEEDED(hRet))
*phwndTaskSwitch = NULL;
pDb->Release();
}
}
/* Should we send this after showing it? */
Update();
/* FIXME: When should we send this? Does anyone care anyway? */
FinishInit();
/* Activate the band site */
Show(
TRUE);
}
*phWndRebar = hWndRebar;
return S_OK;
}
};
/*******************************************************************/
ITrayBandSite *
CreateTrayBandSite(IN OUT ITrayWindow *Tray,
OUT HWND *phWndRebar,
OUT HWND *phWndTaskSwitch)
{
HRESULT hr;
ITrayBandSiteImpl * tb = new ITrayBandSiteImpl();
if (!tb)
return NULL;
tb->AddRef();
hr = tb->_Init(Tray, phWndRebar, phWndTaskSwitch);
if (FAILED_UNEXPECTEDLY(hr))
tb->Release();
return tb;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -78,7 +78,7 @@ UpdateTaskbarBitmap(PPROPSHEET_INFO pPropInfo)
DeleteObject(pPropInfo->hTaskbarBitmap);
}
pPropInfo->hTaskbarBitmap = LoadImage(hExplorerInstance,
pPropInfo->hTaskbarBitmap = (HBITMAP)LoadImage(hExplorerInstance,
lpImageName,
IMAGE_BITMAP,
0,
@ -367,7 +367,7 @@ DisplayTrayProperties(IN HWND hwndOwner)
PROPSHEET_INFO propInfo;
PROPSHEETHEADER psh;
PROPSHEETPAGE psp[5];
TCHAR szCaption[256];
WCHAR szCaption[256];
if (!LoadString(hExplorerInstance,
IDS_TASKBAR_STARTMENU_PROP_CAPTION,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,323 @@
#include "precomp.h"
#include <winver.h>
typedef struct _LANGCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} LANGCODEPAGE, *PLANGCODEPAGE;
HRESULT
IsSameObject(IN IUnknown *punk1, IN IUnknown *punk2)
{
HRESULT hRet;
hRet = punk1->QueryInterface(IID_PPV_ARG(IUnknown, &punk1));
if (!SUCCEEDED(hRet))
return hRet;
hRet = punk2->QueryInterface(IID_PPV_ARG(IUnknown, &punk2));
punk1->Release();
if (!SUCCEEDED(hRet))
return hRet;
punk2->Release();
/* We're dealing with the same object if the IUnknown pointers are equal */
return (punk1 == punk2) ? S_OK : S_FALSE;
}
LONG
SetWindowStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle)
{
LONG PrevStyle, Style;
ASSERT((~dwStyleMask & dwStyle) == 0);
PrevStyle = GetWindowLong(hWnd, GWL_STYLE);
if (PrevStyle != 0 &&
(PrevStyle & dwStyleMask) != dwStyle)
{
Style = PrevStyle & ~dwStyleMask;
Style |= dwStyle;
PrevStyle = SetWindowLong(hWnd, GWL_STYLE, Style);
}
return PrevStyle;
}
LONG
SetWindowExStyle(IN HWND hWnd,
IN LONG dwStyleMask,
IN LONG dwStyle)
{
LONG PrevStyle, Style;
ASSERT((~dwStyleMask & dwStyle) == 0);
PrevStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
if (PrevStyle != 0 &&
(PrevStyle & dwStyleMask) != dwStyle)
{
Style = PrevStyle & ~dwStyleMask;
Style |= dwStyle;
PrevStyle = SetWindowLong(hWnd, GWL_EXSTYLE, Style);
}
return PrevStyle;
}
HMENU
LoadPopupMenu(IN HINSTANCE hInstance,
IN LPCTSTR lpMenuName)
{
HMENU hMenu, hSubMenu = NULL;
hMenu = LoadMenu(hInstance,
lpMenuName);
if (hMenu != NULL)
{
hSubMenu = GetSubMenu(hMenu,
0);
if (hSubMenu != NULL &&
!RemoveMenu(hMenu,
0,
MF_BYPOSITION))
{
hSubMenu = NULL;
}
DestroyMenu(hMenu);
}
return hSubMenu;
}
HMENU
FindSubMenu(IN HMENU hMenu,
IN UINT uItem,
IN BOOL fByPosition)
{
MENUITEMINFO mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
if (GetMenuItemInfo(hMenu,
uItem,
fByPosition,
&mii))
{
return mii.hSubMenu;
}
return NULL;
}
BOOL
GetCurrentLoggedOnUserName(OUT LPTSTR szBuffer,
IN DWORD dwBufferSize)
{
DWORD dwType;
DWORD dwSize;
/* Query the user name from the registry */
dwSize = (dwBufferSize * sizeof(WCHAR)) - 1;
if (RegQueryValueEx(hkExplorer,
TEXT("Logon User Name"),
0,
&dwType,
(LPBYTE) szBuffer,
&dwSize) == ERROR_SUCCESS &&
(dwSize / sizeof(WCHAR)) > 1 &&
szBuffer[0] != _T('\0'))
{
szBuffer[dwSize / sizeof(WCHAR)] = _T('\0');
return TRUE;
}
/* Fall back to GetUserName() */
dwSize = dwBufferSize;
if (!GetUserName(szBuffer,
&dwSize))
{
szBuffer[0] = _T('\0');
return FALSE;
}
return TRUE;
}
BOOL
FormatMenuString(IN HMENU hMenu,
IN UINT uPosition,
IN UINT uFlags,
...)
{
va_list vl;
MENUITEMINFO mii;
WCHAR szBuf[128];
WCHAR szBufFmt[128];
/* Find the menu item and read the formatting string */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = (LPTSTR) szBufFmt;
mii.cch = sizeof(szBufFmt) / sizeof(szBufFmt[0]);
if (GetMenuItemInfo(hMenu,
uPosition,
uFlags,
&mii))
{
/* Format the string */
va_start(vl, uFlags);
_vsntprintf(szBuf,
(sizeof(szBuf) / sizeof(szBuf[0])) - 1,
szBufFmt,
vl);
va_end(vl);
szBuf[(sizeof(szBuf) / sizeof(szBuf[0])) - 1] = _T('\0');
/* Update the menu item */
mii.dwTypeData = (LPTSTR) szBuf;
if (SetMenuItemInfo(hMenu,
uPosition,
uFlags,
&mii))
{
return TRUE;
}
}
return FALSE;
}
BOOL
GetExplorerRegValueSet(IN HKEY hKey,
IN LPCTSTR lpSubKey,
IN LPCTSTR lpValue)
{
WCHAR szBuffer[MAX_PATH];
HKEY hkSubKey;
DWORD dwType, dwSize;
BOOL Ret = FALSE;
StringCbCopy(szBuffer, sizeof(szBuffer),
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"));
if (FAILED_UNEXPECTEDLY(StringCbCat(szBuffer, sizeof(szBuffer),
_T("\\"))))
return FALSE;
if (FAILED_UNEXPECTEDLY(StringCbCat(szBuffer, sizeof(szBuffer),
lpSubKey)))
return FALSE;
dwSize = sizeof(szBuffer);
if (RegOpenKeyEx(hKey,
szBuffer,
0,
KEY_QUERY_VALUE,
&hkSubKey) == ERROR_SUCCESS)
{
ZeroMemory(szBuffer,
sizeof(szBuffer));
if (RegQueryValueEx(hkSubKey,
lpValue,
0,
&dwType,
(LPBYTE) szBuffer,
&dwSize) == ERROR_SUCCESS)
{
if (dwType == REG_DWORD && dwSize == sizeof(DWORD))
Ret = *((PDWORD) szBuffer) != 0;
else if (dwSize > 0)
Ret = *((PCHAR) szBuffer) != 0;
}
RegCloseKey(hkSubKey);
}
return Ret;
}
BOOL
GetVersionInfoString(IN WCHAR *szFileName,
IN WCHAR *szVersionInfo,
OUT WCHAR *szBuffer,
IN UINT cbBufLen)
{
LPVOID lpData = NULL;
WCHAR szSubBlock[128];
WCHAR *lpszLocalBuf = NULL;
LANGID UserLangId;
PLANGCODEPAGE lpTranslate = NULL;
DWORD dwLen;
DWORD dwHandle;
UINT cbTranslate;
UINT cbLen;
BOOL bRet = FALSE;
unsigned int i;
dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
if (dwLen > 0)
{
lpData = HeapAlloc(hProcessHeap, 0, dwLen);
if (lpData != NULL)
{
if (GetFileVersionInfo(szFileName,
0,
dwLen,
lpData) != 0)
{
UserLangId = GetUserDefaultLangID();
VerQueryValue(lpData,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID *) &lpTranslate,
&cbTranslate);
for (i = 0; i < cbTranslate / sizeof(LANGCODEPAGE); i++)
{
/* If the bottom eight bits of the language id's
match, use this version information (since this
means that the version information and the users
default language are the same). */
if ((lpTranslate[i].wLanguage & 0xFF) ==
(UserLangId & 0xFF))
{
wnsprintf(szSubBlock,
sizeof(szSubBlock) / sizeof(szSubBlock[0]),
TEXT("\\StringFileInfo\\%04X%04X\\%s"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage,
szVersionInfo);
if (VerQueryValue(lpData,
szSubBlock,
(LPVOID *) &lpszLocalBuf,
&cbLen) != 0)
{
_tcsncpy(szBuffer, lpszLocalBuf, cbBufLen / sizeof(*szBuffer));
bRet = TRUE;
break;
}
}
}
}
HeapFree(hProcessHeap, 0, lpData);
lpData = NULL;
}
}
return bRet;
}

View file

@ -634,7 +634,7 @@ HRESULT STDMETHODCALLTYPE CBandSiteBase::SetDeskBarSite(IUnknown *pUnk)
if (FAILED_UNEXPECTEDLY(hRet))
return E_FAIL;
style = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT |
style = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT | RBS_AUTOSIZE |
RBS_BANDBORDERS | CCS_NODIVIDER | CCS_NORESIZE | CCS_NOPARENTALIGN;
fRebarWindow = CreateWindowExW(WS_EX_TOOLWINDOW,