mirror of
https://github.com/reactos/reactos.git
synced 2024-08-18 09:28:36 +00:00
457 lines
13 KiB
C++
457 lines
13 KiB
C++
/*
|
|
* ReactOS Explorer
|
|
*
|
|
* Copyright 2009 Andrew Hill <ash77 at domain 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
/*
|
|
Implements the logo band of a cabinet window. Most remarkable feature is the
|
|
animation.
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
/*
|
|
TODO:
|
|
Add Exec command handlers
|
|
Properly implement GetBandInfo
|
|
Fix SetSite to revoke brand band service when site is cleared
|
|
*/
|
|
|
|
inline void FillSolidRect(HDC dc, const RECT *bounds)
|
|
{
|
|
::ExtTextOut(dc, 0, 0, ETO_OPAQUE, bounds, NULL, 0, NULL);
|
|
}
|
|
|
|
inline void FillSolidRect(HDC dc, const RECT *bounds, COLORREF clr)
|
|
{
|
|
::SetBkColor(dc, clr);
|
|
::ExtTextOut(dc, 0, 0, ETO_OPAQUE, bounds, NULL, 0, NULL);
|
|
}
|
|
|
|
//static const int gSmallImageSize = 22;
|
|
static const int gMediumImageSize = 26;
|
|
static const int gLargeImageSize = 38;
|
|
|
|
static const int gTrueColorResourceBase = 240;
|
|
static const int g256ColorResourceBase = 245;
|
|
|
|
CBrandBand::CBrandBand()
|
|
{
|
|
fProfferCookie = 0;
|
|
fCurrentFrame = 0;
|
|
fMaxFrameCount = 0;
|
|
fImageBitmap = NULL;
|
|
fBitmapSize = 0;
|
|
fAdviseCookie = 0;
|
|
}
|
|
|
|
CBrandBand::~CBrandBand()
|
|
{
|
|
DeleteObject(fImageBitmap);
|
|
}
|
|
|
|
void CBrandBand::StartAnimation()
|
|
{
|
|
fCurrentFrame = 0;
|
|
SetTimer(5678, 30, NULL);
|
|
}
|
|
|
|
void CBrandBand::StopAnimation()
|
|
{
|
|
KillTimer(5678);
|
|
fCurrentFrame = 0;
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
void CBrandBand::SelectImage()
|
|
{
|
|
int screenDepth;
|
|
RECT clientRect;
|
|
int clientWidth;
|
|
int clientHeight;
|
|
int clientSize;
|
|
BITMAP bitmapInfo;
|
|
int resourceID;
|
|
|
|
screenDepth = SHGetCurColorRes();
|
|
GetClientRect(&clientRect);
|
|
clientWidth = clientRect.right - clientRect.left;
|
|
clientHeight = clientRect.bottom - clientRect.top;
|
|
clientSize = min(clientWidth, clientHeight);
|
|
if (screenDepth > 8)
|
|
resourceID = gTrueColorResourceBase;
|
|
else
|
|
resourceID = g256ColorResourceBase;
|
|
if (clientSize >= gLargeImageSize)
|
|
resourceID += 2;
|
|
else if (clientSize >= gMediumImageSize)
|
|
resourceID += 1;
|
|
fImageBitmap = LoadBitmap(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(resourceID));
|
|
GetObjectW(fImageBitmap, sizeof(bitmapInfo), &bitmapInfo);
|
|
fBitmapSize = bitmapInfo.bmWidth;
|
|
fMaxFrameCount = bitmapInfo.bmHeight / fBitmapSize;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
|
|
{
|
|
if (pdbi->dwMask & DBIM_MINSIZE)
|
|
{
|
|
pdbi->ptMinSize.x = 38;
|
|
pdbi->ptMinSize.y = 22;
|
|
}
|
|
if (pdbi->dwMask & DBIM_MAXSIZE)
|
|
{
|
|
pdbi->ptMaxSize.x = 38;
|
|
pdbi->ptMaxSize.y = 38;
|
|
}
|
|
if (pdbi->dwMask & DBIM_INTEGRAL)
|
|
{
|
|
pdbi->ptIntegral.x = 38;
|
|
pdbi->ptIntegral.y = 38;
|
|
}
|
|
if (pdbi->dwMask & DBIM_ACTUAL)
|
|
{
|
|
pdbi->ptActual.x = 38;
|
|
pdbi->ptActual.y = 38;
|
|
}
|
|
if (pdbi->dwMask & DBIM_TITLE)
|
|
wcscpy(pdbi->wszTitle, L"");
|
|
if (pdbi->dwMask & DBIM_MODEFLAGS)
|
|
pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
|
|
if (pdbi->dwMask & DBIM_BKCOLOR)
|
|
pdbi->crBkgnd = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::SetSite(IUnknown* pUnkSite)
|
|
{
|
|
CComPtr<IBrowserService> browserService;
|
|
CComPtr<IOleWindow> oleWindow;
|
|
CComPtr<IServiceProvider> serviceProvider;
|
|
CComPtr<IProfferService> profferService;
|
|
HWND parentWindow;
|
|
HWND hwnd;
|
|
HRESULT hResult;
|
|
|
|
fSite.Release();
|
|
if (pUnkSite == NULL)
|
|
{
|
|
hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
|
|
// TODO: revoke brand band service
|
|
return S_OK;
|
|
}
|
|
|
|
// get window handle of parent
|
|
hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fSite));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
parentWindow = NULL;
|
|
hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
|
|
if (SUCCEEDED(hResult))
|
|
hResult = oleWindow->GetWindow(&parentWindow);
|
|
if (!::IsWindow(parentWindow))
|
|
return E_FAIL;
|
|
|
|
// create worker window in parent window
|
|
hwnd = SHCreateWorkerWindowW(0, parentWindow, 0,
|
|
WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
|
|
if (hwnd == NULL)
|
|
return E_FAIL;
|
|
SubclassWindow(hwnd);
|
|
|
|
// take advice to watch events
|
|
hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
hResult = serviceProvider->QueryService(
|
|
SID_SBrandBand, IID_PPV_ARG(IProfferService, &profferService));
|
|
if (SUCCEEDED(hResult))
|
|
hResult = profferService->ProfferService(SID_SBrandBand,
|
|
static_cast<IServiceProvider *>(this), &fProfferCookie);
|
|
hResult = serviceProvider->QueryService(SID_SShellBrowser,
|
|
IID_PPV_ARG(IBrowserService, &browserService));
|
|
if (SUCCEEDED(hResult))
|
|
hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
|
|
}
|
|
|
|
// ignore any hResult errors up to here - they are nonfatal
|
|
hResult = S_OK;
|
|
SelectImage();
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetSite(REFIID riid, void **ppvSite)
|
|
{
|
|
if (ppvSite == NULL)
|
|
return E_POINTER;
|
|
if (fSite.p == NULL)
|
|
{
|
|
*ppvSite = NULL;
|
|
return E_FAIL;
|
|
}
|
|
return fSite.p->QueryInterface(riid, ppvSite);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetWindow(HWND *lphwnd)
|
|
{
|
|
if (lphwnd == NULL)
|
|
return E_POINTER;
|
|
*lphwnd = m_hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::CloseDW(DWORD dwReserved)
|
|
{
|
|
ShowDW(FALSE);
|
|
|
|
if (IsWindow())
|
|
DestroyWindow();
|
|
|
|
m_hWnd = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::ResizeBorderDW(
|
|
const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::ShowDW(BOOL fShow)
|
|
{
|
|
if (m_hWnd)
|
|
{
|
|
if (fShow)
|
|
ShowWindow(SW_SHOW);
|
|
else
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::HasFocusIO()
|
|
{
|
|
if (GetFocus() == m_hWnd)
|
|
return S_OK;
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::TranslateAcceleratorIO(LPMSG lpMsg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetClassID(CLSID *pClassID)
|
|
{
|
|
if (pClassID == NULL)
|
|
return E_POINTER;
|
|
*pClassID = CLSID_BrandBand;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::IsDirty()
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::Load(IStream *pStm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::Save(IStream *pStm, BOOL fClearDirty)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::OnWinEvent(
|
|
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::IsWindowOwner(HWND hWnd)
|
|
{
|
|
if (hWnd == m_hWnd)
|
|
return S_OK;
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::QueryStatus(
|
|
const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::Exec(const GUID *pguidCmdGroup,
|
|
DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
|
{
|
|
if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
|
|
{
|
|
}
|
|
else if (IsEqualIID(*pguidCmdGroup, CGID_BrandCmdGroup))
|
|
{
|
|
switch (nCmdID)
|
|
{
|
|
case BBID_STARTANIMATION:
|
|
StartAnimation();
|
|
return S_OK;
|
|
case BBID_STOPANIMATION:
|
|
StopAnimation();
|
|
return S_OK;
|
|
}
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
|
|
{
|
|
CComPtr<IServiceProvider> serviceProvider;
|
|
HRESULT hResult;
|
|
|
|
if (IsEqualIID(guidService, SID_SBrandBand))
|
|
return this->QueryInterface(riid, ppvObject);
|
|
hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
return serviceProvider->QueryService(guidService, riid, ppvObject);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetTypeInfoCount(UINT *pctinfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
|
|
LCID lcid, DISPID *rgDispId)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBrandBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
|
|
DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
|
|
{
|
|
if (pDispParams == NULL)
|
|
return E_INVALIDARG;
|
|
switch (dispIdMember)
|
|
{
|
|
case DISPID_DOWNLOADCOMPLETE:
|
|
StopAnimation();
|
|
break;
|
|
case DISPID_DOWNLOADBEGIN:
|
|
StartAnimation();
|
|
break;
|
|
}
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
LRESULT CBrandBand::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
Invalidate(FALSE);
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBrandBand::OnEraseBkgnd (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
LRESULT CBrandBand::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
PAINTSTRUCT paintInfo;
|
|
HDC dc;
|
|
POINT destinationPoint;
|
|
HDC sourceDC;
|
|
HBITMAP oldBitmap;
|
|
RECT clientRect;
|
|
RECT tempRect;
|
|
|
|
dc = BeginPaint(&paintInfo);
|
|
GetClientRect(&clientRect);
|
|
|
|
destinationPoint.x = (clientRect.right - clientRect.left - fBitmapSize) / 2;
|
|
destinationPoint.y = (clientRect.bottom - clientRect.top - fBitmapSize) / 2;
|
|
|
|
::SetBkColor(dc, RGB(255, 255, 255));
|
|
|
|
tempRect.left = 0;
|
|
tempRect.top = 0;
|
|
tempRect.right = clientRect.right;
|
|
tempRect.bottom = destinationPoint.y;
|
|
FillSolidRect(dc, &tempRect, RGB(255, 255, 255));
|
|
|
|
tempRect.left = 0;
|
|
tempRect.top = destinationPoint.y + fBitmapSize;
|
|
tempRect.right = clientRect.right;
|
|
tempRect.bottom = clientRect.bottom;
|
|
FillSolidRect(dc, &paintInfo.rcPaint, RGB(255, 255, 255));
|
|
|
|
tempRect.left = 0;
|
|
tempRect.top = destinationPoint.y;
|
|
tempRect.right = destinationPoint.x;
|
|
tempRect.bottom = destinationPoint.y + fBitmapSize;
|
|
FillSolidRect(dc, &paintInfo.rcPaint, RGB(255, 255, 255));
|
|
|
|
tempRect.left = destinationPoint.x + fBitmapSize;
|
|
tempRect.top = destinationPoint.y;
|
|
tempRect.right = clientRect.right;
|
|
tempRect.bottom = destinationPoint.y + fBitmapSize;
|
|
FillSolidRect(dc, &paintInfo.rcPaint, RGB(255, 255, 255));
|
|
|
|
sourceDC = CreateCompatibleDC(dc);
|
|
oldBitmap = reinterpret_cast<HBITMAP>(SelectObject(sourceDC, fImageBitmap));
|
|
|
|
BitBlt(dc, destinationPoint.x, destinationPoint.y, fBitmapSize, fBitmapSize, sourceDC, 0, fCurrentFrame * fBitmapSize, SRCCOPY);
|
|
|
|
SelectObject(sourceDC, oldBitmap);
|
|
DeleteDC(sourceDC);
|
|
|
|
EndPaint(&paintInfo);
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBrandBand::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
fCurrentFrame++;
|
|
if (fCurrentFrame >= fMaxFrameCount)
|
|
fCurrentFrame = 0;
|
|
Invalidate(FALSE);
|
|
return 0;
|
|
}
|