📄 dropbar.cpp
字号:
// DropBar.cpp
//
// @author christian oetterli
//
#include "stdafx.h"
#include "Droppolino.h"
#include "DropBar.h"
CString CDropBar::NAME = L"DropBar";
CDropBar::CDropBar()
: cmdListener(this)
{
m_bWindowOnly = TRUE;
resetLastButton();
resetPressedButton();
setIsOverPressedButton(false);
setLastConfigTime(configTime());
// listen on config path for changes
setConfigFileChange(FindFirstChangeNotification(
getConfigPath()
, FALSE
, FILE_NOTIFY_CHANGE_LAST_WRITE));
}
CDropBar::~CDropBar()
{
}
void CDropBar::errorMsg(com_error *err, LPCTSTR msg) const
{
CString m = msg;
if (err)
{
m += CString(L"\n\n") + asCString(err->ErrorMessage());
m += CString(L"\n\n") + asCString(err->Description());
}
::MessageBox(m_hWnd, m, NAME, MB_ICONEXCLAMATION);
}
LRESULT CDropBar::OnDestroy(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
RevokeDragDrop(m_hWnd);
setConfigFileChange(INVALID_HANDLE_VALUE);
return 0;
}
LRESULT CDropBar::OnContextMenu(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
HMENU
menu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_DROPBAR))
, popup = GetSubMenu(menu, 0);
int
x = LOWORD(lParam)
, y = HIWORD(lParam);
TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, getCmdListener().m_hWnd, 0);
handled = TRUE;
return 0;
}
LRESULT CDropBar::OnEraseBkgnd(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
handled = TRUE;
return 0;
}
void CDropBar::onToolsRelayEvent()
{
// forward to tools
getTools().SendMessage(TTM_RELAYEVENT, 0, (LPARAM)GetCurrentMessage());
}
int CDropBar::hitTestButton(CPoint p) const
{
int
index = -1
, i, n;
const CRects &bounds = getButtonBounds();
for (i = 0, n = bounds.size(); i < n && -1 == index; i++)
{
if (! isSeparator(i) && bounds[i].isPointInMe(p))
{
index = i;
}
}
return index;
}
IXMLDOMNodeListPtr CDropBar::getButtons() const
{
return getConfig()->selectNodes(L"button");
}
void CDropBar::clearButtonBounds()
{
buttonBounds.clear();
}
const CRects &CDropBar::getButtonBounds() const
{
if (buttonBounds.size() == 0)
{
CRect bounds;
GetClientRect(bounds);
int
cy = minHeight()
, space = (bounds.height() - cy) / 2
, i, n;
CPoint leftTop(bounds.left, bounds.top + space);
CSize size(cy + 1, cy);
for (i = 0, n = getButtons()->length; i < n; i++)
{
CSize sz =
isSeparator(i)
? CSize(2, cy)
: size;
buttonBounds.push_back(CRect(leftTop, sz));
leftTop.move(sz.cx + DROPRECTSPACE);
}
}
return buttonBounds;
}
HRESULT CDropBar::OnDraw(ATL_DRAWINFO& di)
{
tryIt
{
// check if a change was made and reset Drop Bar
checkConfig();
IXMLDOMNodeListPtr buttons = getButtons();
CIcons &icons = getIcons();
const CRects &bs = getButtonBounds();
CRect bounds = *di.prcBounds;
CDC dc = CreateCompatibleDC(di.hdcDraw);
HBITMAP
bm = CreateCompatibleBitmap(di.hdcDraw, bounds.width(), bounds.height())
, bmOld = (HBITMAP)SelectObject(dc, bm);
dc.fillSolidRect(bounds, GetSysColor(COLOR_3DFACE));
int
cy = GetSystemMetrics(SM_CYSMICON)
, i, n;
bool isOverPressedButton = getIsOverPressedButton();
for (i = 0, n = bs.size(); i < n; i++)
{
const CRect &rc = bs[i];
int space = (rc.height() - cy) / 2;
if (isSeparator(i))
{
dc.draw3dRect(
rc//CRect(rc.leftTop(), CSize(2, rc.height()))
, GetSysColor(COLOR_3DSHADOW)
, GetSysColor(COLOR_3DHILIGHT));
}
else
{
int isPressed = isPressedButton(i);
bool
drawDepressed = isPressed && isOverPressedButton
, drawRaised = (isPressed && ! isOverPressedButton) || (isLastButton(i) && ! isPressedButton());
if (drawDepressed)
{
dc.draw3dRect(rc, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
}
if (drawRaised)
{
dc.draw3dRect(rc, GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
}
DrawIconEx(
dc
, rc.left + space
, rc.top + space
, icons[i]
, cy
, cy
, 0
, 0
, DI_NORMAL);
}
}
BitBlt(
di.hdcDraw
, bounds.left
, bounds.top
, bounds.width()
, bounds.height()
, dc
, bounds.left
, bounds.top
, SRCCOPY);
SelectObject(dc, bmOld);
DeleteObject(bm);
DeleteDC(dc);
return S_OK;
}
catchIt
}
CString CDropBar::getConfigPath() const
{
CString path;
SHGetSpecialFolderPath(m_hWnd, path.GetBuffer(_MAX_PATH), CSIDL_PERSONAL, FALSE);
path.ReleaseBuffer();
return path;
}
CString CDropBar::getConfigFile() const
{
return getConfigPath() + L"\\dropBar.xml";
}
void CDropBar::delTools()
{
int i, n;
TOOLINFO ti = { sizeof(ti), 0, m_hWnd };
CWindow &tools = getTools();
// remove all tools
for (i = 0, n = tools.SendMessage(TTM_GETTOOLCOUNT); i < n; i++)
{
ti.uId = i + BUTTONIDXTOTOOLID;
tools.SendMessage(TTM_DELTOOL, 0, (LPARAM)&ti);
}
}
void CDropBar::addTools()
{
CWindow &tools = getTools();
const CRects &bs = getButtonBounds();
IXMLDOMNodeListPtr buttons = getButtons();
int i, n;
TOOLINFO ti = { sizeof(ti), 0, m_hWnd };
for (i = 0, n = bs.size(); i < n; i++)
{
if (! isSeparator(i))
{
variant description = IXMLDOMElementPtr(buttons->item[i])->getAttribute(L"description");
if (! isNull(description))
{
ti.uId = i + BUTTONIDXTOTOOLID;
ti.rect = bs[i];
ti.lpszText = (bstr)description;
tools.SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti);
}
}
}
}
void CDropBar::reset()
{
clearButtonBounds();
getIcons().destroy();
delTools();
loadConfig();
addTools();
Invalidate();
}
void CDropBar::loadConfig()
{
CXMLDOMDocument xml = createObject(L"MSXML.DOMDocument");
xml->async = VARIANT_FALSE;
CString file = getConfigFile();
if (! xml->load(asBSTR(file)))
{
IXMLDOMParseErrorPtr err = xml->parseError;
CString
msg
, src = asCString(err->srcText);
src.TrimLeft();
src.TrimRight();
msg.Format(
CString(MAKEINTRESOURCE(IDS_ERR_LOADCONFIG))
, file
, asCString(err->reason)
, src
, err->line);
errorMsg(0, msg);
// load a default config
xml.loadXMLRes(MAKEINTRESOURCE(IDR_DEFAULTCONFIG));
}
config = xml->documentElement;
}
IXMLDOMNodePtr CDropBar::getConfig() const
{
if (isNull(config))
{
const_cast<CDropBar*>(this)->loadConfig();
}
return config;
}
// IOleWindow
STDMETHODIMP CDropBar::GetWindow(HWND *hwnd)
{
tryIt
{
checkPointer(hwnd);
*hwnd = m_hWnd;
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::ContextSensitiveHelp(BOOL enterMode)
{
return E_NOTIMPL;
}
// IObjectWithSite
STDMETHODIMP CDropBar::SetSite(IUnknown *newSite)
{
tryIt
{
site = newSite;
if (! isNull(site))
{
HWND hwndParent;
IOleWindowPtr(site)->GetWindow(&hwndParent);
// Drop Bar bounds
CRect bounds(0, 0, 50, minHeight());
// create window
Create(hwndParent, bounds, 0, WS_CLIPSIBLINGS | WS_CHILD, 0, DROPBARID);
// register drop target
RegisterDragDrop(m_hWnd, this);
getTools().Create(TOOLTIPS_CLASS, m_hWnd, 0, 0, WS_POPUP);
addTools();
// create listener
getCmdListener().Create(m_hWnd);
}
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::GetSite(REFIID riid, void **outSite)
{
tryIt
{
if (! isNull(site))
{
site->QueryInterface(riid, outSite);
}
else
{
checkPointer(outSite);
*outSite = 0;
}
return S_OK;
}
catchIt
}
// IDockingWindow
STDMETHODIMP CDropBar::CloseDW(DWORD)
{
if (IsWindow())
{
SendMessage(WM_CLOSE);
}
return S_OK;
}
STDMETHODIMP CDropBar::ResizeBorderDW(LPCRECT border, IUnknown* toolbarSite, BOOL)
{
return E_NOTIMPL;
}
STDMETHODIMP CDropBar::ShowDW(BOOL show)
{
if (IsWindow())
{
ShowWindow((show) ? SW_SHOW : SW_HIDE);
}
return S_OK;
}
// IPersistStream
STDMETHODIMP CDropBar::GetClassID(LPCLSID classID)
{
tryIt
{
checkPointer(classID);
*classID = uuid_of(DropBar);
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::IsDirty(void)
{
return S_FALSE;
}
STDMETHODIMP CDropBar::Load(LPSTREAM stream)
{
return S_OK;
}
STDMETHODIMP CDropBar::Save(LPSTREAM stream, BOOL clearDirty)
{
return S_OK;
}
STDMETHODIMP CDropBar::GetSizeMax(ULARGE_INTEGER *size)
{
return E_NOTIMPL;
}
// IDeskBand
STDMETHODIMP CDropBar::GetBandInfo(DWORD newBandID, DWORD viewMode, DESKBANDINFO* dbi)
{
tryIt
{
if (dbi->dwMask & DBIM_MINSIZE)
{
dbi->ptMinSize.x = dbi->ptMinSize.y = minHeight();
}
if (dbi->dwMask & DBIM_MAXSIZE)
{
dbi->ptMaxSize.x = dbi->ptMaxSize.y = -1;
}
if (dbi->dwMask & DBIM_INTEGRAL)
{
dbi->ptIntegral.x = dbi->ptIntegral.y = 1;
}
if (dbi->dwMask & DBIM_ACTUAL)
{
dbi->ptActual.x = dbi->ptActual.y = 0;
}
if (dbi->dwMask & DBIM_TITLE)
{
*dbi->wszTitle = 0;
}
if (dbi->dwMask & DBIM_MODEFLAGS)
{
dbi->dwModeFlags = DBIMF_NORMAL;
}
if (dbi->dwMask & DBIM_BKCOLOR)
{
dbi->dwMask &= ~DBIM_BKCOLOR;
}
return S_OK;
}
catchIt
}
void CDropBar::onCustomize()
{
// call the onCustomize(file) script from Drop Bars script node
execScript(getConfig()->selectSingleNode(L"script"), L"onCustomize", &CParams(asBSTR(getConfigFile())));
}
void CDropBar::execScript(IXMLDOMElementPtr scriptNode, CString function, CParams *params)
{
if (! isNull(scriptNode))
{
IScriptControlPtr script;
try
{
// create script control
script = createObject(L"MSScriptControl.ScriptControl");
if (! isNull(script))
{
int countParams = (params) ? params->size() : 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -