mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
558 lines
17 KiB
C++
558 lines
17 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
|
|
*/
|
|
|
|
/*
|
|
This class knows how to contain base bar site in a cabinet window.
|
|
*/
|
|
|
|
#include "shellbars.h"
|
|
|
|
/*
|
|
Base bar that contains a vertical or horizontal explorer band. It also
|
|
provides resizing abilities.
|
|
*/
|
|
/*
|
|
TODO:
|
|
**Make base bar support resizing -- almost done (need to support integral ?)
|
|
Add context menu for base bar
|
|
Fix base bar to correctly initialize fVertical field
|
|
Fix base bar to correctly reposition its base bar site when resized -- done ?
|
|
*/
|
|
|
|
class CBaseBar :
|
|
public CWindowImpl<CBaseBar, CWindow, CControlWinTraits>,
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
public IInputObjectSite,
|
|
public IOleCommandTarget,
|
|
public IServiceProvider,
|
|
public IInputObject,
|
|
public IDeskBar,
|
|
public IDockingWindow,
|
|
public IPersistStream,
|
|
public IPersistStreamInit,
|
|
public IPersistPropertyBag,
|
|
public IObjectWithSite
|
|
{
|
|
private:
|
|
CComPtr<IUnknown> fSite;
|
|
CComPtr<IUnknown> fClient;
|
|
HWND fClientWindow;
|
|
bool fVertical;
|
|
bool fVisible;
|
|
int fNeededSize; // width or height
|
|
|
|
// used by resize tracking loop
|
|
bool fTracking;
|
|
POINT fLastLocation;
|
|
public:
|
|
CBaseBar();
|
|
~CBaseBar();
|
|
HRESULT Initialize(BOOL);
|
|
|
|
public:
|
|
HRESULT ReserveBorderSpace();
|
|
|
|
// *** IOleWindow methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
|
|
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
|
|
|
|
// *** IInputObjectSite specific methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus);
|
|
|
|
// *** IOleCommandTarget specific methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
|
|
OLECMD prgCmds[ ], OLECMDTEXT *pCmdText);
|
|
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
|
|
DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
|
|
|
|
// *** IServiceProvider methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
|
|
|
|
// *** IInputObject methods ***
|
|
// forward the methods to the contained active bar
|
|
virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
|
|
virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
|
|
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
|
|
|
|
// *** IDeskBar methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient);
|
|
virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown **ppunkClient);
|
|
virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(LPRECT prc);
|
|
|
|
// *** IDockingWindow methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
|
|
virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
|
|
virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved);
|
|
|
|
// *** IObjectWithSite methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
|
|
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
|
|
|
|
// *** IPersist methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
|
|
|
|
// *** IPersistStream methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE IsDirty();
|
|
virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
|
|
virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
|
|
virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
|
|
|
|
// *** IPersistStreamInit methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE InitNew();
|
|
|
|
// *** IPersistPropertyBag methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog);
|
|
virtual HRESULT STDMETHODCALLTYPE Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
|
|
|
|
// message handlers
|
|
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnCancelMode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
LRESULT OnCaptureChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
|
|
|
DECLARE_WND_CLASS_EX(_T("BaseBar"), 0, COLOR_3DFACE)
|
|
|
|
BEGIN_MSG_MAP(CBaseBar)
|
|
MESSAGE_HANDLER(WM_SIZE, OnSize)
|
|
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
|
|
MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
|
|
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
|
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
|
|
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
|
|
MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode)
|
|
MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
|
|
END_MSG_MAP()
|
|
|
|
BEGIN_COM_MAP(CBaseBar)
|
|
COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDockingWindow)
|
|
COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite)
|
|
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
|
COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
|
|
COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
|
|
COM_INTERFACE_ENTRY_IID(IID_IDeskBar, IDeskBar)
|
|
COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
|
|
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
|
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream)
|
|
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
|
|
COM_INTERFACE_ENTRY_IID(IID_IPersistStreamInit, IPersistStreamInit)
|
|
COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag, IPersistPropertyBag)
|
|
END_COM_MAP()
|
|
};
|
|
|
|
CBaseBar::CBaseBar()
|
|
{
|
|
fClientWindow = NULL;
|
|
fVertical = true;
|
|
fVisible = false;
|
|
fNeededSize = 200;
|
|
fTracking = false;
|
|
}
|
|
|
|
CBaseBar::~CBaseBar()
|
|
{
|
|
}
|
|
|
|
HRESULT CBaseBar::Initialize(BOOL vert)
|
|
{
|
|
fVertical = (vert == TRUE);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CBaseBar::ReserveBorderSpace()
|
|
{
|
|
CComPtr<IDockingWindowSite> dockingWindowSite;
|
|
RECT availableBorderSpace;
|
|
RECT neededBorderSpace;
|
|
HRESULT hResult;
|
|
|
|
hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
hResult = dockingWindowSite->GetBorderDW(static_cast<IDeskBar *>(this), &availableBorderSpace);
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
memset(&neededBorderSpace, 0, sizeof(neededBorderSpace));
|
|
if (fVisible)
|
|
{
|
|
if (fVertical)
|
|
neededBorderSpace.left = fNeededSize + GetSystemMetrics(SM_CXFRAME);
|
|
else
|
|
neededBorderSpace.bottom = fNeededSize + GetSystemMetrics(SM_CXFRAME);
|
|
}
|
|
hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDeskBar *>(this), &neededBorderSpace);
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
return S_OK;
|
|
}
|
|
|
|
// current bar size is stored in the registry under
|
|
// key=HKCU\Software\Microsoft\Internet Explorer\Explorer Bars
|
|
// value=current bar GUID
|
|
// result is 8 bytes of binary data, 2 longs. First is the size, second is reserved and will always be 0
|
|
/*HRESULT CBaseBar::StopCurrentBar()
|
|
{
|
|
CComPtr<IOleCommandTarget> commandTarget;
|
|
HRESULT hResult;
|
|
|
|
if (fCurrentBar.p != NULL)
|
|
{
|
|
hResult = fCurrentBar->QueryInterface(IID_IOleCommandTarget, (void **)&commandTarget);
|
|
hResult = commandTarget->Exec(NULL, 0x17, 0, NULL, NULL);
|
|
}
|
|
// hide the current bar
|
|
memcpy(&fCurrentActiveClass, &GUID_NULL, sizeof(fCurrentActiveClass));
|
|
return S_OK;
|
|
}*/
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::GetWindow(HWND *lphwnd)
|
|
{
|
|
if (lphwnd == NULL)
|
|
return E_POINTER;
|
|
*lphwnd = m_hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::OnFocusChangeIS (IUnknown *punkObj, BOOL fSetFocus)
|
|
{
|
|
return IUnknown_OnFocusChangeIS(fSite, punkObj, fSetFocus);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
|
|
OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
|
|
DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
|
{
|
|
if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
|
|
{
|
|
// pass through to the explorer ?
|
|
}
|
|
else if (IsEqualIID(*pguidCmdGroup, IID_IDeskBarClient))
|
|
{
|
|
switch (nCmdID)
|
|
{
|
|
case 0:
|
|
// hide current band
|
|
break;
|
|
case 2:
|
|
// switch bands
|
|
break;
|
|
case 3:
|
|
break;
|
|
}
|
|
}
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
|
|
{
|
|
CComPtr<IServiceProvider> serviceProvider;
|
|
HRESULT hResult;
|
|
|
|
if (fSite == NULL)
|
|
return E_FAIL;
|
|
hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
// called for SID_STopLevelBrowser, IID_IBrowserService to find top level browser
|
|
// called for SID_IWebBrowserApp, IID_IConnectionPointContainer
|
|
// connection point called for DIID_DWebBrowserEvents2 to establish connection
|
|
return serviceProvider->QueryService(guidService, riid, ppvObject);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
|
|
{
|
|
return IUnknown_UIActivateIO(fClient, fActivate, lpMsg);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::HasFocusIO()
|
|
{
|
|
return IUnknown_HasFocusIO(fClient);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::TranslateAcceleratorIO(LPMSG lpMsg)
|
|
{
|
|
return IUnknown_TranslateAcceleratorIO(fClient, lpMsg);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::SetClient(IUnknown *punkClient)
|
|
{
|
|
CComPtr<IOleWindow> oleWindow;
|
|
HWND ownerWindow;
|
|
HRESULT hResult;
|
|
|
|
/* Clean up old client */
|
|
fClient = NULL;
|
|
|
|
if (punkClient)
|
|
{
|
|
hResult = punkClient->QueryInterface(IID_PPV_ARG(IUnknown, &fClient));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
hResult = fSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
hResult = oleWindow->GetWindow(&ownerWindow);
|
|
if (FAILED_UNEXPECTEDLY(hResult))
|
|
return hResult;
|
|
Create(ownerWindow, 0, NULL,
|
|
WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW);
|
|
ReserveBorderSpace();
|
|
}
|
|
else
|
|
{
|
|
DestroyWindow();
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::GetClient(IUnknown **ppunkClient)
|
|
{
|
|
if (ppunkClient == NULL)
|
|
return E_POINTER;
|
|
*ppunkClient = fClient;
|
|
if (fClient.p != NULL)
|
|
fClient.p->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::OnPosRectChangeDB(LPRECT prc)
|
|
{
|
|
if (prc == NULL)
|
|
return E_POINTER;
|
|
if (fVertical)
|
|
fNeededSize = prc->right - prc->left;
|
|
else
|
|
fNeededSize = prc->bottom - prc->top;
|
|
ReserveBorderSpace();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::ShowDW(BOOL fShow)
|
|
{
|
|
fVisible = fShow ? true : false;
|
|
ShowWindow(fShow);
|
|
ReserveBorderSpace();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::CloseDW(DWORD dwReserved)
|
|
{
|
|
ShowDW(0);
|
|
// Detach from our client
|
|
SetClient(NULL);
|
|
// Destroy our site
|
|
SetSite(NULL);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
|
|
{
|
|
ReserveBorderSpace();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::SetSite(IUnknown *pUnkSite)
|
|
{
|
|
fSite = pUnkSite;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::GetSite(REFIID riid, void **ppvSite)
|
|
{
|
|
if (ppvSite == NULL)
|
|
return E_POINTER;
|
|
*ppvSite = fSite;
|
|
if (fSite.p != NULL)
|
|
fSite.p->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::GetClassID(CLSID *pClassID)
|
|
{
|
|
if (pClassID == NULL)
|
|
return E_POINTER;
|
|
// TODO: what class to return here?
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::IsDirty()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::Load(IStream *pStm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::Save(IStream *pStm, BOOL fClearDirty)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|
{
|
|
if (pcbSize == NULL)
|
|
return E_POINTER;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::InitNew()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CBaseBar::Save(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
DWORD dwWidth;
|
|
DWORD dwHeight;
|
|
CComPtr<IOleWindow> pClient;
|
|
HWND clientHwnd;
|
|
HRESULT hr;
|
|
|
|
if (fVisible)
|
|
{
|
|
dwWidth = LOWORD(lParam);
|
|
dwHeight = HIWORD(lParam);
|
|
|
|
// substract resizing grips to child's window size
|
|
if (fVertical)
|
|
dwWidth -= GetSystemMetrics(SM_CXFRAME);
|
|
else
|
|
dwHeight -= GetSystemMetrics(SM_CXFRAME);
|
|
hr = fClient->QueryInterface(IID_PPV_ARG(IOleWindow, &pClient));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return 0;
|
|
hr = pClient->GetWindow(&clientHwnd);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return 0;
|
|
::SetWindowPos(clientHwnd, NULL, 0, (fVertical) ? 0 : GetSystemMetrics(SM_CXFRAME), dwWidth, dwHeight, NULL);
|
|
bHandled = TRUE;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
|
|
{
|
|
bHandled = FALSE;
|
|
return 0;
|
|
}
|
|
if (fVertical)
|
|
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
|
|
else
|
|
SetCursor(LoadCursor(NULL, IDC_SIZENS));
|
|
return 1;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
CComPtr<IWinEventHandler> winEventHandler;
|
|
LRESULT result;
|
|
HRESULT hResult;
|
|
|
|
result = 0;
|
|
if (fClient.p != NULL)
|
|
{
|
|
hResult = fClient->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
|
|
if (SUCCEEDED(hResult) && winEventHandler.p != NULL)
|
|
hResult = winEventHandler->OnWinEvent(NULL, uMsg, wParam, lParam, &result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
SetCapture();
|
|
fTracking = true;
|
|
fLastLocation.x = (short)LOWORD(lParam);
|
|
fLastLocation.y = (short)HIWORD(lParam);
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
ReleaseCapture();
|
|
fTracking = false;
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
POINT newLocation;
|
|
int delta;
|
|
|
|
if (fTracking)
|
|
{
|
|
newLocation.x = (short)LOWORD(lParam);
|
|
newLocation.y = (short)HIWORD(lParam);
|
|
if (fVertical)
|
|
delta = newLocation.x - fLastLocation.x;
|
|
else
|
|
delta = fLastLocation.y - newLocation.y;
|
|
if (fNeededSize + delta < 0)
|
|
return 0;
|
|
fNeededSize += delta;
|
|
fLastLocation = newLocation;
|
|
ReserveBorderSpace();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnCancelMode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
fTracking = false;
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CBaseBar::OnCaptureChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
|
{
|
|
fTracking = false;
|
|
return 0;
|
|
}
|
|
|
|
HRESULT CBaseBar_CreateInstance(REFIID riid, void **ppv, BOOL vertical)
|
|
{
|
|
return ShellObjectCreatorInit<CBaseBar, BOOL>(vertical, riid, ppv);
|
|
}
|