📄 mtlmisc.h
字号:
return FALSE;
// open shell
lRet = rkShell.Create(rkExt, _T("shell"));
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkDonut.Create(rkShell, strName);
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkDonut.SetValue(strName);
ATLASSERT(lRet == ERROR_SUCCESS);
// command has /dde
lRet = rkCommand.Create(rkDonut, _T("command"));
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkCommand.SetValue(strExe + _T(" /dde"));//\"%1\""));
ATLASSERT(lRet == ERROR_SUCCESS);
// DDE
CRegKey rkDDEExec; // order is important
CRegKey rkApplication;
CRegKey rkTopic;
lRet = rkDDEExec.Create(rkDonut, _T("ddeexec"));
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkDDEExec.SetValue(_T("[open(\"%1\")]"));
ATLASSERT(lRet == ERROR_SUCCESS);
lRet = rkApplication.Create(rkDDEExec, _T("application"));
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkApplication.SetValue(strName);
ATLASSERT(lRet == ERROR_SUCCESS);
lRet = rkTopic.Create(rkDDEExec, _T("topic"));
if(lRet != ERROR_SUCCESS)
return FALSE;
lRet = rkTopic.SetValue(_T("system"));
ATLASSERT(lRet == ERROR_SUCCESS);
}
else {
// open shell
lRet = rkShell.Open(rkExt, _T("shell"));
if(lRet != ERROR_SUCCESS)
return FALSE;
// clean up name if my name
DWORD nLen;
lRet = rkShell.QueryValue(NULL, NULL, &nLen);
if(lRet != ERROR_SUCCESS)
return FALSE;
ATLTRACE2(atlTraceUser, 4, _T("MtlIsExecutable :%d\n"), nLen);
LPTSTR lpszText = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
lRet = rkShell.QueryValue(lpszText, NULL, &nLen);
if (::lstrcmp(lpszText, strName) == 0) {
lRet = rkExt.SetKeyValue(_T("shell"), _T(""));
if(lRet != ERROR_SUCCESS)
return FALSE;
}
lRet = rkShell.DeleteSubKey(strName);
if(lRet != ERROR_SUCCESS)
return FALSE;
}
return TRUE;
}
inline BOOL MtlIsExecutable(const CString& strExt, const CString& strName)
{
CRegKey rkExt;
CRegKey rkShell;
LONG lRet;
// open ROOT
lRet = rkExt.Open(HKEY_CLASSES_ROOT, strExt);
if(lRet != ERROR_SUCCESS)
return FALSE;
// open shell
lRet = rkShell.Open(rkExt, _T("shell"));
if(lRet != ERROR_SUCCESS)
return FALSE;
DWORD nLen;
lRet = rkShell.QueryValue(NULL, NULL, &nLen);
if(lRet != ERROR_SUCCESS)
return FALSE;
ATLTRACE2(atlTraceUser, 4, _T("MtlIsExecutable :%d\n"), nLen);
LPTSTR lpszText = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
lRet = rkShell.QueryValue(lpszText, NULL, &nLen);
ATLTRACE2(atlTraceUser, 4, _T("MtlIsExecutable :%s\n"), lpszText);
if (::lstrcmp(lpszText, strName) == 0)
return TRUE;
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// MtlOpenHttpFiles
inline bool MtlIsInternetFileMaybe(const CString& strPath)
{
if (strPath.Right(1) == _T("/"))// all I can do
return true;
int nIndex = strPath.ReverseFind(_T('/'));
if (nIndex == -1)
return false;
nIndex = __MtlFindChar(strPath, nIndex, _T('.'));
if (nIndex == -1)
return false;
CString strExt3 = strPath.Mid(nIndex, 4);
CString strExt4 = strPath.Mid(nIndex, 5);
CString strExt5 = strPath.Mid(nIndex, 6);
if (strExt4.CompareNoCase(_T(".html")) == 0 ||
strExt5.CompareNoCase(_T(".shtml")) == 0 ||
strExt3.CompareNoCase(_T(".htm")) == 0 ||
strExt3.CompareNoCase(_T(".url")) == 0 ||
strExt3.CompareNoCase(_T(".cgi")) == 0 ||
strExt3.CompareNoCase(_T(".asp")) == 0)
return true;
else
return false;
}
bool __MtlIsMeaninglessCharInHttp(TCHAR ch)
{
return ch == _T('\\') || ch == _T(':') ||
ch == _T(',') || ch == _T(';') ||
ch == _T('*') || ch == _T('\"') ||
ch == _T('<') || ch == _T('>') ||
ch == _T('|') ||
ch == _T(' ') || ch == _T('\t') ||
ch == _T('\r');
}
inline CString __MtlRemoveTrailingMeaninglessChar(const CString& str_)
{
ATLTRACE2(atlTraceUser, 4, _T("__MtlRemoveTrailingMeaninglessChar: (%s)\n"), str_);
CString str = str_;
int nCount = 0;
for (int i = str.GetLength() - 1; i >= 0; --i) {
ATLTRACE2(atlTraceUser, 4, _T(" : (%d, %d)\n"), str[i], i);
if (__MtlIsMeaninglessCharInHttp(str[i])) {
nCount++;
}
else
break;
}
return str.Left(str.GetLength() - nCount);
}
void MtlOpenHttpFiles(CSimpleArray<CString>& arrFiles, const CString& strCmdLine_)
{
ATLTRACE2(atlTraceUser, 4, _T("MtlOpenHttpFiles :%s\n"), strCmdLine_.Left(100));
CString strCmdLine = strCmdLine_;
if (strCmdLine.IsEmpty())
return;
int nFirst = 0;
int nLast;
CString strFile;
do {
ATLTRACE2(atlTraceUser, 4, _T(" step1\n"));
nFirst = __MtlFind(strCmdLine, nFirst, _T("http:"));
if (nFirst == -1)
break;
ATLTRACE2(atlTraceUser, 4, _T(" step2\n"));
nLast = __MtlFindChar(strCmdLine, nFirst + 4, _T('\n'));
if (nLast == -1) {
strFile = strCmdLine.Mid(nFirst);
}
else {
ATLASSERT(strCmdLine.GetAt(nLast) == _T('\n'));
strFile = strCmdLine.Mid(nFirst, nLast - nFirst);
ATLASSERT(strFile.Right(1) != _T('\n'));
}
ATLTRACE2(atlTraceUser, 4, _T(" step3\n"));
strFile = __MtlRemoveTrailingMeaninglessChar(strFile);
ATLTRACE2(atlTraceUser, 4, _T(" :cleaned(%s)\n"), strFile);
if (MtlIsInternetFileMaybe(strFile)) {
ATLTRACE2(atlTraceUser, 4, _T(" :open (%s)\n"), strFile);
arrFiles.Add(strFile);
}
if (nLast == -1)
break;
ATLTRACE2(atlTraceUser, 4, _T(" step4\n"));
nFirst = nLast;
} while (nFirst < strCmdLine.GetLength());
}
template <class T>
class CDDEMessageHandler
{
public:
// Data members
ATOM m_atomApp, m_atomSystemTopic;
// Constructor/Destructor
CDDEMessageHandler(const CString& strAppName)
{
m_atomApp = ::GlobalAddAtom(strAppName);
m_atomSystemTopic = ::GlobalAddAtom(_T("system"));
}
~CDDEMessageHandler()
{
::GlobalDeleteAtom(m_atomApp);
::GlobalDeleteAtom(m_atomSystemTopic);
#ifdef _DEBUG
// TCHAR szAtomName[_MAX_PATH];
// ATLASSERT(::GlobalGetAtomName(m_atomApp, szAtomName, _MAX_PATH - 1) == 0);
// ATLASSERT(::GlobalGetAtomName(m_atomSystemTopic, szAtomName, _MAX_PATH - 1) == 0);
#endif
}
// Overridables
bool OnDDEOpenFile(const CString& strFileName)
{
return true;
}
// Message map and handlers
BEGIN_MSG_MAP(CDDEMessageHandler)
MESSAGE_HANDLER(WM_DDE_INITIATE, OnDDEInitiate)
MESSAGE_HANDLER(WM_DDE_EXECUTE, OnDDEExecute)
MESSAGE_HANDLER(WM_DDE_TERMINATE, OnDDETerminate)
END_MSG_MAP()
LRESULT OnDDEInitiate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
if (LOWORD(lParam) != 0 && HIWORD(lParam) != 0 &&
(ATOM)LOWORD(lParam) == m_atomApp &&
(ATOM)HIWORD(lParam) == m_atomSystemTopic)
{
ATLTRACE2(atlTraceUser, 4, _T("OnDDEInitiate - from windows shell\n"));
// make duplicates of the incoming atoms (really adding a reference)
TCHAR szAtomName[_MAX_PATH];
MTLVERIFY(::GlobalGetAtomName(m_atomApp,
szAtomName, _MAX_PATH - 1) != 0);
MTLVERIFY(::GlobalAddAtom(szAtomName) == m_atomApp);
MTLVERIFY(::GlobalGetAtomName(m_atomSystemTopic,
szAtomName, _MAX_PATH - 1) != 0);
MTLVERIFY(::GlobalAddAtom(szAtomName) == m_atomSystemTopic);
// send the WM_DDE_ACK (caller will delete duplicate atoms)
T* pT = static_cast<T*>(this);
::SendMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)pT->m_hWnd,
MAKELPARAM(m_atomApp, m_atomSystemTopic));
}
return 0L;
}
// always ACK the execute command - even if we do nothing
LRESULT OnDDEExecute(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
ATLTRACE2(atlTraceUser, 4, _T("OnDDEExecute - from windows shell\n"));
// unpack the DDE message
UINT unused;
HGLOBAL hData;
MTLVERIFY(UnpackDDElParam(WM_DDE_EXECUTE, lParam, &unused, (UINT*)&hData));
// get the command string
CString strCommand(reinterpret_cast<LPCTSTR>( ::GlobalLock(hData) ));
GlobalUnlock(hData);
T* pT = static_cast<T*>(this);
// acknowledge now - before attempting to execute
::PostMessage((HWND)wParam, WM_DDE_ACK, (WPARAM)pT->m_hWnd,
ReuseDDElParam(lParam, WM_DDE_EXECUTE, WM_DDE_ACK,
(UINT)0x8000, (UINT)hData));
// don't execute the command when the window is disabled
if (!pT->IsWindowEnabled())
{
ATLTRACE(_T("Warning: DDE command '%s' ignored because window is disabled.\n"),
strCommand);
return 0;
}
// execute the command
if (!_OnDDECommand(strCommand))
ATLTRACE(_T("Error: failed to execute DDE command '%s'.\n"), strCommand);
return 0L;
}
LRESULT OnDDETerminate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
::PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)pT->m_hWnd, lParam);
return 0L;
}
bool _OnDDECommand(const CString& _strCommand)
{
CString strCommand = _strCommand;
// open format is "[open("%s")]" - no whitespace allowed, one per line
if (strCommand.Left(7) == _T("[open(\""))
{
strCommand = strCommand.Right(strCommand.GetLength() - 7);
}
else {
return false;
}
int i = strCommand.Find('"');
if (i == -1)
return false; // illegally terminated
CString strFileName = strCommand.Left(i);
T* pT = static_cast<T*>(this);
return pT->OnDDEOpenFile(strFileName);
}
};
void MtlDrawDragRectFixed(CDCHandle dc, LPCRECT lpRect, SIZE size, LPCRECT lpRectLast, SIZE sizeLast, HBRUSH hBrush = NULL, HBRUSH hBrushLast = NULL)
{
// first, determine the update region and select it
HRGN hRgnNew;
HRGN hRgnOutside, hRgnInside;
hRgnOutside = ::CreateRectRgnIndirect(lpRect);
RECT rect = *lpRect;
::InflateRect(&rect, -size.cx, -size.cy);
::IntersectRect(&rect, &rect, lpRect);
hRgnInside = ::CreateRectRgnIndirect(&rect);
hRgnNew = ::CreateRectRgn(0, 0, 0, 0);
::CombineRgn(hRgnNew, hRgnOutside, hRgnInside, RGN_XOR);
HBRUSH hBrushOld = NULL;
if(hBrush == NULL)
hBrush = CDCHandle::GetHalftoneBrush();
if(hBrushLast == NULL)
hBrushLast = hBrush;
HRGN hRgnLast = NULL, hRgnUpdate = NULL;
if(lpRectLast != NULL)
{
// find difference between new region and old region
hRgnLast = ::CreateRectRgn(0, 0, 0, 0);
::SetRectRgn(hRgnOutside, lpRectLast->left, lpRectLast->top, lpRectLast->right, lpRectLast->bottom);
rect = *lpRectLast;
::InflateRect(&rect, -sizeLast.cx, -sizeLast.cy);
::IntersectRect(&rect, &rect, lpRectLast);
::SetRectRgn(hRgnInside, rect.left, rect.top, rect.right, rect.bottom);
::CombineRgn(hRgnLast, hRgnOutside, hRgnInside, RGN_XOR);
// only diff them if brushes are the same
if(hBrush == hBrushLast)
{
hRgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
::CombineRgn(hRgnUpdate, hRgnLast, hRgnNew, RGN_XOR);
}
}
if(hBrush != hBrushLast && lpRectLast != NULL)
{
// brushes are different -- erase old region first
dc.SelectClipRgn(hRgnLast);
dc.GetClipBox(&rect);
hBrushOld = dc.SelectBrush(hBrushLast);
dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
dc.SelectBrush(hBrushOld);
hBrushOld = NULL;
}
// draw into the update/new region
dc.SelectClipRgn(hRgnUpdate != NULL ? hRgnUpdate : hRgnNew);
dc.GetClipBox(&rect);
hBrushOld = dc.SelectBrush(hBrush);
dc.PatBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, PATINVERT);
// cleanup DC ******************* fixed ************************
if(hBrushOld != NULL)
dc.SelectBrush(hBrushOld);
dc.SelectClipRgn(NULL);
if(NULL != hBrush)
DeleteObject(hBrush); //Free our halftone brush
DeleteObject(hRgnNew);
DeleteObject(hRgnOutside);
DeleteObject(hRgnInside);
if (NULL != hRgnLast)
DeleteObject(hRgnLast);
if (NULL != hRgnUpdate)
DeleteObject(hRgnUpdate);
}
} // namespace MTL;
#endif // __MTLMISC_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -