mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 08:30:21 +00:00
[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:
parent
3da5418d3f
commit
162ff471bb
26 changed files with 9863 additions and 11333 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
|
@ -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
|
||||
};
|
314
base/shell/explorer-new/dragdrop.cpp
Normal file
314
base/shell/explorer-new/dragdrop.cpp
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
239
base/shell/explorer-new/explorer.cpp
Normal file
239
base/shell/explorer-new/explorer.cpp
Normal 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);
|
||||
}
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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)
|
|
@ -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
796
base/shell/explorer-new/startmnu.cpp
Normal file
796
base/shell/explorer-new/startmnu.cpp
Normal 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;
|
||||
}
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
420
base/shell/explorer-new/taskband.cpp
Normal file
420
base/shell/explorer-new/taskband.cpp
Normal 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
2079
base/shell/explorer-new/taskswnd.cpp
Normal file
2079
base/shell/explorer-new/taskswnd.cpp
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
831
base/shell/explorer-new/tbsite.cpp
Normal file
831
base/shell/explorer-new/tbsite.cpp
Normal 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
1618
base/shell/explorer-new/trayntfy.cpp
Normal file
1618
base/shell/explorer-new/trayntfy.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
3084
base/shell/explorer-new/traywnd.cpp
Normal file
3084
base/shell/explorer-new/traywnd.cpp
Normal file
File diff suppressed because it is too large
Load diff
323
base/shell/explorer-new/util.cpp
Normal file
323
base/shell/explorer-new/util.cpp
Normal 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;
|
||||
}
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue