mirror of
https://github.com/reactos/reactos.git
synced 2024-09-02 00:28:00 +00:00
![David Quintana](/assets/img/avatar_default.png)
* Do not set the imagelist if the bitmap wasn't loaded. * Fix the flags that caused the toolbar not to relocate when toggling the lock mode. svn path=/branches/shell-experiments/; revision=63114
422 lines
14 KiB
C++
422 lines
14 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 toolbar band of a cabinet window
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
/* FIXME, I can't include windowsx because it conflicts with some #defines */
|
|
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
|
|
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
|
|
|
|
class CToolsBand :
|
|
public CWindowImpl<CToolsBand, CWindow, CControlWinTraits>,
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
public IDeskBand,
|
|
public IObjectWithSite,
|
|
public IInputObject,
|
|
public IPersistStream
|
|
{
|
|
private:
|
|
IDockingWindowSite *fDockSite;
|
|
GUID fExecCommandCategory;
|
|
CComPtr<IOleCommandTarget> fExecCommandTarget;
|
|
public:
|
|
CToolsBand();
|
|
~CToolsBand();
|
|
public:
|
|
// *** IDeskBand methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi);
|
|
|
|
// *** IObjectWithSite methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite);
|
|
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
|
|
|
|
// *** IOleWindow methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
|
|
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
|
|
|
|
// *** IDockingWindow methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
|
|
virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved);
|
|
virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
|
|
|
|
// *** IInputObject methods ***
|
|
virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
|
|
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
|
|
virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
|
|
|
|
// *** 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);
|
|
|
|
// message handlers
|
|
LRESULT OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled);
|
|
|
|
BEGIN_MSG_MAP(CToolsBand)
|
|
// MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
|
|
// MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
|
|
NOTIFY_HANDLER(0, TBN_GETBUTTONINFOW, OnGetButtonInfo)
|
|
END_MSG_MAP()
|
|
|
|
BEGIN_COM_MAP(CToolsBand)
|
|
COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
|
|
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
|
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
|
|
COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
|
|
COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
|
|
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
|
|
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
|
|
END_COM_MAP()
|
|
};
|
|
|
|
CToolsBand::CToolsBand()
|
|
{
|
|
fDockSite = NULL;
|
|
}
|
|
|
|
CToolsBand::~CToolsBand()
|
|
{
|
|
if (fDockSite)
|
|
fDockSite->Release();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
|
|
{
|
|
RECT actualRect;
|
|
POINTL actualSize;
|
|
POINTL idealSize;
|
|
POINTL maxSize;
|
|
POINTL itemSize;
|
|
|
|
::GetWindowRect(m_hWnd, &actualRect);
|
|
actualSize.x = actualRect.right - actualRect.left;
|
|
actualSize.y = actualRect.bottom - actualRect.top;
|
|
|
|
/* Obtain the ideal size, to be used as min and max */
|
|
SendMessageW(m_hWnd, TB_AUTOSIZE, 0, 0);
|
|
SendMessageW(m_hWnd, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&maxSize));
|
|
|
|
idealSize = maxSize;
|
|
SendMessageW(m_hWnd, TB_GETIDEALSIZE, FALSE, reinterpret_cast<LPARAM>(&idealSize));
|
|
|
|
/* Obtain the button size, to be used as the integral size */
|
|
DWORD size = SendMessageW(m_hWnd, TB_GETBUTTONSIZE, 0, 0);
|
|
itemSize.x = GET_X_LPARAM(size);
|
|
itemSize.y = GET_Y_LPARAM(size);
|
|
|
|
if (pdbi->dwMask & DBIM_MINSIZE)
|
|
{
|
|
pdbi->ptMinSize = idealSize;
|
|
}
|
|
if (pdbi->dwMask & DBIM_MAXSIZE)
|
|
{
|
|
pdbi->ptMaxSize = maxSize;
|
|
}
|
|
if (pdbi->dwMask & DBIM_INTEGRAL)
|
|
{
|
|
pdbi->ptIntegral = itemSize;
|
|
}
|
|
if (pdbi->dwMask & DBIM_ACTUAL)
|
|
{
|
|
pdbi->ptActual = actualSize;
|
|
}
|
|
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;
|
|
}
|
|
|
|
static const int backImageIndex = 0;
|
|
static const int forwardImageIndex = 1;
|
|
static const int favoritesImageIndex = 2;
|
|
// 3
|
|
// 4
|
|
static const int cutImageIndex = 5;
|
|
static const int copyImageIndex = 6;
|
|
static const int pasteImageIndex = 7;
|
|
static const int undoImageIndex = 8;
|
|
static const int redoImageIndex = 9;
|
|
static const int deleteImageIndex = 10;
|
|
// 11
|
|
// 12
|
|
// 13
|
|
// 14
|
|
static const int propertiesImageIndex = 15;
|
|
// 16
|
|
static const int searchImageIndex = 17;
|
|
// 18
|
|
// 19
|
|
// 20
|
|
// 21
|
|
static const int viewsImageIndex = 22;
|
|
// 23
|
|
// 24
|
|
// 25
|
|
// 26
|
|
// 27
|
|
static const int upImageIndex = 28;
|
|
static const int mapDriveImageIndex = 29;
|
|
static const int disconnectImageIndex = 30;
|
|
// 31
|
|
static const int viewsAltImageIndex = 32; // same image as viewsImageIndex
|
|
// 33
|
|
// 34
|
|
// 35
|
|
// 36
|
|
// 37
|
|
static const int viewsAlt2ImageIndex = 38; // same image as viewsAltImageIndex & viewsImageIndex
|
|
// 39
|
|
// 40
|
|
// 41
|
|
// 42
|
|
static const int foldersImageIndex = 43;
|
|
static const int moveToImageIndex = 44;
|
|
static const int copyToImageIndex = 45;
|
|
static const int folderOptionsImageIndex = 46;
|
|
|
|
const int numShownButtons = 13;
|
|
const int numHiddenButtons = 13;
|
|
TBBUTTON tbButtonsAdd[numShownButtons + numHiddenButtons] =
|
|
{
|
|
{backImageIndex, gBackCommandID, TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Back")},
|
|
{forwardImageIndex, gForwardCommandID, TBSTATE_ENABLED, BTNS_DROPDOWN, {0}, 0, (INT_PTR)_T("Forward")},
|
|
{upImageIndex, gUpLevelCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Up")},
|
|
{6, -1, TBSTATE_ENABLED, BTNS_SEP},
|
|
{searchImageIndex, gSearchCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Search")},
|
|
{foldersImageIndex, gFoldersCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Folders")},
|
|
{6, -1, TBSTATE_ENABLED, BTNS_SEP},
|
|
{moveToImageIndex, gMoveToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Move To")},
|
|
{copyToImageIndex, gCopyToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Copy To")},
|
|
{deleteImageIndex, gDeleteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Delete")},
|
|
{undoImageIndex, gUndoCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Undo")},
|
|
{6, -1, TBSTATE_ENABLED, BTNS_SEP},
|
|
{viewsImageIndex, gViewsCommandID, TBSTATE_ENABLED, BTNS_WHOLEDROPDOWN, {0}, 0, (INT_PTR)_T("Views")},
|
|
|
|
{0, gStopCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Stop")},
|
|
{0, gRefreshCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Refresh")},
|
|
{0, gHomeCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Home")},
|
|
{mapDriveImageIndex, gMapDriveCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Map Drive")},
|
|
{disconnectImageIndex, gDisconnectCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Disconnect")},
|
|
{favoritesImageIndex, gFavoritesCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, {0}, 0, (INT_PTR)_T("Favorites")},
|
|
{0, gHistoryCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("History")},
|
|
{0, gFullScreenCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Full Screen")},
|
|
{propertiesImageIndex, gPropertiesCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Properties")},
|
|
{cutImageIndex, gCutCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Cut")},
|
|
{copyImageIndex, gCopyCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Copy")},
|
|
{pasteImageIndex, gPasteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Paste")},
|
|
{folderOptionsImageIndex, gFolderOptionsCommandID, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, (INT_PTR)_T("Folder Options")},
|
|
};
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::SetSite(IUnknown* pUnkSite)
|
|
{
|
|
HWND parentWindow;
|
|
IOleWindow *oleWindow;
|
|
HWND toolbar;
|
|
HRESULT hResult;
|
|
|
|
if (fDockSite != NULL)
|
|
fDockSite->Release();
|
|
if (pUnkSite == NULL)
|
|
return S_OK;
|
|
hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fDockSite));
|
|
if (FAILED(hResult))
|
|
return hResult;
|
|
parentWindow = NULL;
|
|
hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
oleWindow->GetWindow(&parentWindow);
|
|
oleWindow->Release();
|
|
}
|
|
if (!::IsWindow(parentWindow))
|
|
return E_FAIL;
|
|
|
|
toolbar = CreateWindowEx(TBSTYLE_EX_DOUBLEBUFFER, TOOLBARCLASSNAMEW, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |
|
|
WS_CLIPCHILDREN | TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT |
|
|
CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP, 0, 0, 500, 20, parentWindow, NULL,
|
|
_AtlBaseModule.GetModuleInstance(), 0);
|
|
if (toolbar == NULL)
|
|
return E_FAIL;
|
|
SubclassWindow(toolbar);
|
|
|
|
SendMessage(WM_USER + 100, GetSystemMetrics(SM_CXEDGE) / 2, 0);
|
|
SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
SendMessage(TB_SETMAXTEXTROWS, 1, 0);
|
|
SendMessage(TB_SETEXTENDEDSTYLE, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS,
|
|
TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS);
|
|
|
|
HINSTANCE shell32Instance = GetModuleHandle(_T("shell32.dll"));
|
|
HBITMAP imageBitmap = reinterpret_cast<HBITMAP>(
|
|
LoadImage(shell32Instance, MAKEINTRESOURCE(214),
|
|
IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_CREATEDIBSECTION));
|
|
|
|
if (imageBitmap)
|
|
{
|
|
DIBSECTION bitmapInfo;
|
|
GetObjectW(imageBitmap, sizeof(bitmapInfo), &bitmapInfo);
|
|
HIMAGELIST imageList = ImageList_Create(bitmapInfo.dsBm.bmHeight, bitmapInfo.dsBm.bmHeight, ILC_COLOR32, 4, 4);
|
|
|
|
ImageList_Add(imageList, imageBitmap, NULL);
|
|
DeleteObject(imageBitmap);
|
|
|
|
SendMessage(TB_SETIMAGELIST, 0, (LPARAM) imageList);
|
|
}
|
|
|
|
SendMessage(TB_ADDBUTTONSW, numShownButtons, (LPARAM)&tbButtonsAdd);
|
|
|
|
return hResult;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::GetSite(REFIID riid, void **ppvSite)
|
|
{
|
|
if (fDockSite == NULL)
|
|
return E_FAIL;
|
|
return fDockSite->QueryInterface(riid, ppvSite);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::GetWindow(HWND *lphwnd)
|
|
{
|
|
if (lphwnd == NULL)
|
|
return E_POINTER;
|
|
*lphwnd = m_hWnd;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::CloseDW(DWORD dwReserved)
|
|
{
|
|
ShowDW(FALSE);
|
|
|
|
if (IsWindow())
|
|
DestroyWindow();
|
|
|
|
m_hWnd = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::ShowDW(BOOL fShow)
|
|
{
|
|
if (m_hWnd)
|
|
{
|
|
if (fShow)
|
|
ShowWindow(SW_SHOW);
|
|
else
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::HasFocusIO()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::TranslateAcceleratorIO(LPMSG lpMsg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::GetClassID(CLSID *pClassID)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::IsDirty()
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::Load(IStream *pStm)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::Save(IStream *pStm, BOOL fClearDirty)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CToolsBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
LRESULT CToolsBand::OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
|
|
{
|
|
TBNOTIFYW *pTBntf = reinterpret_cast<TBNOTIFYW *>(pNMHDR);
|
|
|
|
if (pTBntf->iItem >= 0 && pTBntf->iItem < (numShownButtons + numHiddenButtons))
|
|
{
|
|
pTBntf->tbButton = tbButtonsAdd[pTBntf->iItem];
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
return 0;
|
|
}
|
|
|
|
HRESULT CreateToolsBar(REFIID riid, void **ppv)
|
|
{
|
|
CComObject<CToolsBand> *theMenuBar;
|
|
HRESULT hResult;
|
|
|
|
if (ppv == NULL)
|
|
return E_POINTER;
|
|
*ppv = NULL;
|
|
ATLTRY (theMenuBar = new CComObject<CToolsBand>);
|
|
if (theMenuBar == NULL)
|
|
return E_OUTOFMEMORY;
|
|
hResult = theMenuBar->QueryInterface(riid, reinterpret_cast<void **>(ppv));
|
|
if (FAILED(hResult))
|
|
{
|
|
delete theMenuBar;
|
|
return hResult;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|