⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtlmisc.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:
			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 + -