📄 dropbar.cpp
字号:
// copy params to new safe array
SAFEARRAYBOUND paramsBounds = { countParams, 0 };
SAFEARRAY *paramsArray = SafeArrayCreate(VT_VARIANT, 1, ¶msBounds);
if (params)
{
long i;
for (i = 0; i < countParams; i++)
{
SafeArrayPutElement(paramsArray, &i, &(VARIANT)params->at(i));
}
}
script->AllowUI = VARIANT_TRUE;
script->Language = (bstr)scriptNode->getAttribute(L"language");
script->AddObject(L"dropBar", this, VARIANT_FALSE);
script->AddCode(scriptNode->text);
// check for existence of the function by comparing known functions name
// with function parameter
bool hasFunction = false;
long i, n;
for (i = 1, n = script->Procedures->Count; i <= n && ! hasFunction; i++)
{
hasFunction = 0 == function.Compare(script->Procedures->Item[i]->Name);
}
// run only if function found
if (hasFunction)
{
script->Run(asBSTR(function), ¶msArray);
}
// remove array
SafeArrayDestroy(paramsArray);
}
}
catch (com_error &err)
{
bool stdErr = true;
if (! isNull(script))
{
IScriptErrorPtr scriptErr = script->Error;
if (! isNull(scriptErr))
{
CString
msg
, src = asCString(scriptErr->Text);
src.TrimLeft();
src.TrimRight();
msg.Format(
CString(MAKEINTRESOURCE(IDS_ERR_EXECSCRIPT))
, asCString(scriptErr->Description)
, src
, scriptErr->Line);
errorMsg(0, msg);
stdErr = false;
}
}
if (stdErr)
{
errorMsg(&err);
}
}
}
}
STDMETHODIMP CDropBar::BringWindowToTop(OLE_HANDLE hWnd)
{
::BringWindowToTop((HWND)hWnd);
return S_OK;
}
void CDropBar::initMouseLeave()
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
}
LRESULT CDropBar::OnMouseLeave(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
if (isLastButton())
{
Invalidate();
resetLastButton();
}
return 0;
}
LRESULT CDropBar::OnMouseMove(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
onToolsRelayEvent();
// want WM_MOUSELEAVE messages
initMouseLeave();
int button = hitTestButton(CPoint(LOWORD(lParam), HIWORD(lParam)));
setIsOverPressedButton(isPressedButton(button));
if (! isLastButton(button))
{
setLastButton(button);
Invalidate();
}
return 0;
}
LRESULT CDropBar::OnLButtonDown(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
onToolsRelayEvent();
setPressedButton(hitTestButton(CPoint(LOWORD(lParam), HIWORD(lParam))));
bool isPressed = isPressedButton();
setIsOverPressedButton(isPressed);
if (isPressed)
{
int button = getPressedButton();
setLastButton(button);
Invalidate();
SetCapture();
}
return 0;
}
LRESULT CDropBar::OnLButtonUp(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled)
{
onToolsRelayEvent();
int
button = hitTestButton(CPoint(LOWORD(lParam), HIWORD(lParam)))
, invokedButton = -1;
if (isPressedButton(button))
{
invokedButton = button;
}
if (isPressedButton())
{
Invalidate();
}
ReleaseCapture();
resetPressedButton();
setIsOverPressedButton(false);
if (invokedButton != -1)
{
// call the onClick() script from buttons script node
execScript(getButtons()->item[invokedButton]->selectSingleNode(L"script"), L"onClick");
}
return 0;
}
void CDropBar::setConfigFileChange(HANDLE newConfigFileChange)
{
if (configFileChange != INVALID_HANDLE_VALUE)
{
FindCloseChangeNotification(configFileChange);
}
configFileChange = newConfigFileChange;
}
HANDLE CDropBar::getConfigFileChange() const
{
return configFileChange;
}
CCmdListener &CDropBar::getCmdListener()
{
return cmdListener;
}
CWindow &CDropBar::getTools()
{
return tools;
}
CIcons &CDropBar::getIcons()
{
if (icons.size() == 0)
{
// create vector of icons
// read icon file and index from node
// if icon could not be loaded a default icon will be used instead
IXMLDOMNodeListPtr buttons = getButtons();
int i, n;
for (i = 0, n = buttons->length; i < n; i++)
{
IXMLDOMElementPtr nodeIcon = buttons->item[i]->selectSingleNode(L"icon");
HICON icon;
bool ok = ! isNull(nodeIcon) && 1 == ExtractIconEx(
asCString(nodeIcon->getAttribute(L"file"))
, (long)nodeIcon->getAttribute(L"index")
, 0
, &icon
, 1);
icons.push_back((ok) ? icon : LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDI_DEFAULT)));
}
}
return icons;
}
int CDropBar::getLastButton() const
{
return lastButton;
}
void CDropBar::setLastButton(int newLastButton)
{
lastButton = newLastButton;
}
void CDropBar::resetLastButton()
{
setLastButton(-1);
}
bool CDropBar::isLastButton(int button) const
{
return getLastButton() == button;
}
bool CDropBar::isLastButton() const
{
return ! isLastButton(-1);
}
//
int CDropBar::getPressedButton() const
{
return pressedButton;
}
void CDropBar::setPressedButton(int newPressedButton)
{
pressedButton = newPressedButton;
}
void CDropBar::resetPressedButton()
{
setPressedButton(-1);
}
bool CDropBar::isPressedButton(int button) const
{
return getPressedButton() == button;
}
bool CDropBar::isPressedButton() const
{
return ! isPressedButton(-1);
}
bool CDropBar::getIsOverPressedButton() const
{
return isOverPressedButton;
}
void CDropBar::setIsOverPressedButton(bool newIsOverPressedButton)
{
isOverPressedButton = newIsOverPressedButton;
}
int CDropBar::minHeight() const
{
return 2 + (2 * DROPRECTSPACE + GetSystemMetrics(SM_CYSMICON));
}
STDMETHODIMP CDropBar::DragEnter(LPDATAOBJECT dataObject, DWORD keyState, POINTL p, LPDWORD effect)
{
tryIt
{
checkPointer(effect);
setDataObject(dataObject);
*effect = dropEffect(p);
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::DragOver(DWORD keyState, POINTL p, LPDWORD effect)
{
tryIt
{
checkPointer(effect);
int button = hitTestButton(adjustDragPoint(p));
if (! isLastButton(button))
{
setLastButton(button);
Invalidate();
}
*effect = dropEffect(p);
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::DragLeave()
{
tryIt
{
if (isLastButton())
{
resetLastButton();
Invalidate();
}
resetDataObject();
return S_OK;
}
catchIt
}
STDMETHODIMP CDropBar::Drop(LPDATAOBJECT dataObject, DWORD keyState, POINTL p, LPDWORD effect)
{
resetLastButton();
Invalidate();
const int BUF_SIZE = 2 * _MAX_PATH;
TCHAR path[BUF_SIZE];
HDROP drop = getHDROP();
IXMLDOMNodePtr scriptNode = getButtons()->item[hitTestButton(adjustDragPoint(p))]->selectSingleNode(L"script");
int i, n;
for (i = 0, n = DragQueryFile(drop, 0xffffffff, path, BUF_SIZE); i < n; i++)
{
DragQueryFile(drop, i, path, BUF_SIZE);
execScript(scriptNode, L"onDrop", &CParams(variant(path)));
}
DragFinish(drop);
resetDataObject();
return S_OK;
}
HDROP CDropBar::getHDROP()
{
FORMATETC fmte =
{
CF_HDROP
, 0
, DVASPECT_CONTENT
, -1
, TYMED_HGLOBAL
};
STGMEDIUM medium;
getDataObject()->GetData(&fmte, &medium);
return (HDROP)medium.hGlobal;
}
DWORD CDropBar::dropEffect(CPoint p)
{
FORMATETC fmte =
{
CF_HDROP
, 0
, DVASPECT_CONTENT
, -1
, -1
};
// query HDROP
bool ok = SUCCEEDED(getDataObject()->QueryGetData(&fmte));
if (ok)
{
ok = hitTestButton(adjustDragPoint(p)) != -1;
}
return (ok) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
}
CPoint CDropBar::adjustDragPoint(CPoint pDrag)
{
ScreenToClient(&pDrag);
return pDrag;
}
IDataObjectPtr CDropBar::getDataObject() const
{
return dataObject;
}
void CDropBar::setDataObject(IDataObjectPtr newDataObject)
{
dataObject = newDataObject;
}
void CDropBar::resetDataObject()
{
setDataObject(0);
}
void CDropBar::checkConfig()
{
HANDLE change = getConfigFileChange();
if (WAIT_OBJECT_0 == WaitForSingleObject(change, 1))
{
// something has changed in config path.
// check if signaled by config file.
FILETIME time = configTime();
if (! isLastConfigTime(time))
{
reset();
setLastConfigTime(time);
}
}
FindNextChangeNotification(change);
}
FILETIME CDropBar::getLastConfigTime() const
{
return lastConfigTime;
}
void CDropBar::setLastConfigTime(FILETIME newLastConfigTime)
{
lastConfigTime = newLastConfigTime;
}
bool CDropBar::isLastConfigTime(FILETIME time) const
{
return 0 == CompareFileTime(&time, &getLastConfigTime());
}
FILETIME CDropBar::configTime() const
{
FILETIME time;
HANDLE file = CreateFile(
getConfigFile()
, 0
, FILE_SHARE_READ
, 0
, OPEN_EXISTING
, 0
, 0);
if (file != INVALID_HANDLE_VALUE)
{
BY_HANDLE_FILE_INFORMATION bhfi;
GetFileInformationByHandle(file, &bhfi);
time = bhfi.ftLastWriteTime;
CloseHandle(file);
}
else
{
ZeroMemory(&time, sizeof(time));
}
return time;
}
IUnknownPtr CDropBar::createObject(CString progId)
{
CLSID clsid;
IUnknownPtr object;
if (SUCCEEDED(CLSIDFromProgID(progId, &clsid)))
{
object.CreateInstance(clsid);
}
if (isNull(object))
{
CString msg;
msg.Format(
CString(MAKEINTRESOURCE(IDS_ERR_CREATEOBJECT))
, progId);
errorMsg(0, msg);
}
return object;
}
bool CDropBar::isSeparator(int button) const
{
return IXMLDOMElementPtr(getButtons()->item[button])->getAttribute(L"separator") != variant(L"0");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -