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

📄 donutclipboardbar.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
字号:

#pragma once

// for debug
#ifdef _DEBUG
	const bool _Mtl_ClipboardBar_traceOn = false;
	#define clbTRACE if (_Mtl_ClipboardBar_traceOn) ATLTRACE
#else
	#define clbTRACE
#endif

// Note. When I made dialogs, I've encountered a strange kernel32 exception.
//       If a form view has a check box, kernel32 exception occurs when an app unloaded.
//       I can't get the reason.

#define CLPV_EX_ON			0x00000001L
#define CLPV_EX_DIRECT		0x00000002L
#define CLPV_EX_FLUSH		0x00000004L

class CDonutClipboardBar :
	public CDialogImpl<CDonutClipboardBar>,
	public CDialogResize<CDonutClipboardBar>,
	public CClipboardViewer<CDonutClipboardBar>,
	public CWinDataExchange<CDonutClipboardBar>
{
public:
	enum { IDD = IDD_CLIPBAR_FORM };

// Data members
	DWORD m_dwExStyle;
	CString m_strExts;
	int m_nOn;
	int m_nDirect, m_nFlush;

// Windows
	CEdit m_edit;
	CContainedWindowT<CListBox> m_box;

// Ctor
	CDonutClipboardBar() : m_dwExStyle(0), m_box(this, 1)
	{
	}

// Methods
	CString GetExtsList()
	{
		return MtlGetWindowText(m_edit);
	}

	void OpenClipboardUrl()
	{
		CString strText = MtlGetClipboardText();
		if (strText.IsEmpty())
			return;

		CSimpleArray<CString> arrExt;
		MtlBuildExtArray(arrExt, GetExtsList());

		CSimpleArray<CString> arrUrl;
		MtlBuildUrlArray(arrUrl, arrExt, strText);

		for (int i = 0; i < arrUrl.GetSize(); ++i) {
			DonutOpenFile(m_hWnd, arrUrl[i], 0);					
		}
	}

// Overrides
	void OnUpdateClipboard()
	{
		if (CMainOption::s_bIgnoreUpdateClipboard)
			return;

		clbTRACE(_T("OnUpdateClipboard\n"));
		CString strText = MtlGetClipboardText();
		if (strText.IsEmpty())
			return;

		CWebBrowser2 browser = DonutGetIWebBrowser2(GetTopLevelParent());
		if (!browser.IsBrowserNull()) {
			CString strUrl = browser.GetLocationURL();
			if (strUrl == strText)
				return;
		}

		if (_check_flag(CLPV_EX_FLUSH, m_dwExStyle))
			m_box.ResetContent();
			
		CSimpleArray<CString> arrExt;
		MtlBuildExtArray(arrExt, MtlGetWindowText(m_edit));

		CSimpleArray<CString> arrUrl;
		MtlBuildUrlArray(arrUrl, arrExt, strText);

		if (arrUrl.GetSize() == 0) {
			return;
		}
		else {
			if (_check_flag(CLPV_EX_FLUSH, m_dwExStyle))
				m_box.ResetContent();
		}

		for (int i = 0; i < arrUrl.GetSize(); ++i) {
			if (m_box.GetCount() == 0)
				m_box.AddString(arrUrl[i]);
			else
				m_box.InsertString(0, arrUrl[i]);
		}

		if (_check_flag(CLPV_EX_DIRECT, m_dwExStyle)) {
			for (int i = 0; i < arrUrl.GetSize(); ++i) {
				DonutOpenFile(m_hWnd, arrUrl[i], 0);					
			}
		}
	}

// Methods	
	BYTE PreTranslateMessage(MSG* pMsg)
	{
		UINT msg = pMsg->message;
		int vKey =  pMsg->wParam;
		HWND hWnd = pMsg->hwnd;

		if (msg == WM_KEYDOWN) {
			if (hWnd != m_edit.m_hWnd && ::GetKeyState(VK_CONTROL) < 0)	// may be accelerator
				return _MTL_TRANSLATE_PASS;
		}
		else if (msg == WM_SYSKEYDOWN) {								// I gave up to add accesskeys to bar 
				return _MTL_TRANSLATE_PASS;
		}

		if (IsDialogMessage(pMsg))// is very smart.
			return _MTL_TRANSLATE_HANDLE;
	
		return _MTL_TRANSLATE_PASS;
	}

// Message map and handlers
	BEGIN_MSG_MAP(CDonutClipboardBar)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)

		COMMAND_ID_HANDLER(IDC_CHECK_CB_ON, OnCheckCommand)
		COMMAND_ID_HANDLER(IDC_CHECK_CB_DIRECT, OnCheckCommand)
		COMMAND_ID_HANDLER(IDC_CHECK_CB_FLUSH, OnCheckCommand)

		COMMAND_ID_HANDLER(IDC_BUTTON_OPEN, OnButtonOpen)
		COMMAND_ID_HANDLER(IDC_BUTTON_CB_PASTE, OnButtonPaste)
		COMMAND_ID_HANDLER(IDC_BUTTON_DELETE, OnButtonDelete)
		COMMAND_ID_HANDLER(IDC_BUTTON_DELETEALL, OnButtonDeleteAll)
		COMMAND_ID_HANDLER(IDC_BUTTON_CB_PASTE_DONUT, OnButtonPasteDonut)
		COMMAND_ID_HANDLER(IDOK, OnIdOk)

		CHAIN_MSG_MAP(CClipboardViewer<CDonutClipboardBar>)
		CHAIN_MSG_MAP(CDialogResize<CDonutClipboardBar>)

	ALT_MSG_MAP(1) // list box
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLBLButtonDblClk)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		DlgResize_Init(false, true, WS_CLIPCHILDREN);

		m_edit.Attach(GetDlgItem(IDC_EDIT_CB_EXT));
		m_box.SubclassWindow(GetDlgItem(IDC_LIST_CB_CONT));

		_GetProfile();
		_SetData();
		DoDataExchange(FALSE);
		
		return TRUE;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		DoDataExchange(TRUE);
		_GetData();
		_WriteProfile();

		return 0;
	}

	LRESULT OnCheckCommand(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		if (wNotifyCode == BN_CLICKED) {
			DoDataExchange(TRUE);
			_GetData();
		}

		return 0;
	}

	LRESULT OnButtonDelete(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		_MtlForEachListBoxSelectedItem(m_box.m_hWnd, _Function_DeleteString());

		return 0;
	}

	LRESULT OnButtonOpen(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		_MtlForEachListBoxSelectedItem(m_box.m_hWnd, _Function_Open());

		return 0;
	}

	LRESULT OnButtonPaste(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		OnUpdateClipboard();

		return 0;
	}

	LRESULT OnButtonPasteDonut(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		OpenClipboardUrl();

		return 0;
	}

	LRESULT OnButtonDeleteAll(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		m_box.ResetContent();

		return 0;
	}

	LRESULT OnIdOk(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		if (::GetFocus() == m_box.m_hWnd)
			_MtlForEachListBoxSelectedItem(m_box.m_hWnd, _Function_Open());

		return 0;
	}

	LRESULT OnLBLButtonDblClk(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		CPoint pt(LOWORD(lParam), HIWORD(lParam));

		BOOL bOutside;
		UINT nIndex = m_box.ItemFromPoint(pt, bOutside);
		if (!bOutside)
			_OnItemOpen(nIndex);

		return 0;
	}

// Dlg resize map
	BEGIN_DLGRESIZE_MAP(CDonutClipboardBar)
		DLGRESIZE_CONTROL(IDC_CHECK_CB_ON, DLSZ_SIZE_X)
		DLGRESIZE_CONTROL(IDC_LIST_CB_CONT, DLSZ_SIZE_X|DLSZ_SIZE_Y)
		DLGRESIZE_CONTROL(IDC_BUTTON_OPEN, DLSZ_MOVE_Y|DLSZ_SIZE_X)

		BEGIN_DLGRESIZE_GROUP()
			DLGRESIZE_CONTROL(IDC_BUTTON_CB_PASTE, DLSZ_SIZE_X)
			DLGRESIZE_CONTROL(IDC_BUTTON_DELETE, DLSZ_SIZE_X)
			DLGRESIZE_CONTROL(IDC_BUTTON_DELETEALL, DLSZ_SIZE_X)
		END_DLGRESIZE_GROUP()

		DLGRESIZE_CONTROL(IDC_BUTTON_CB_PASTE_DONUT, DLSZ_SIZE_X|DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(IDC_CHECK_CB_DIRECT, DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(IDC_CHECK_CB_FLUSH, DLSZ_MOVE_Y)

		DLGRESIZE_CONTROL(IDC_STATIC_CB_EXT, DLSZ_MOVE_Y)
		DLGRESIZE_CONTROL(IDC_EDIT_CB_EXT, DLSZ_MOVE_Y|DLSZ_SIZE_X)
	END_DLGRESIZE_MAP()

// DDX map
	BEGIN_DDX_MAP(CDonutClipboardBar)
		DDX_TEXT(IDC_EDIT_CB_EXT, m_strExts)
		DDX_CHECK(IDC_CHECK_CB_ON, m_nOn)
		DDX_CHECK(IDC_CHECK_CB_DIRECT, m_nDirect)
		DDX_CHECK(IDC_CHECK_CB_FLUSH, m_nFlush)
	END_DDX_MAP()

// Implementation
	void _GetData()
	{
		// update style
		m_dwExStyle = 0;
	
		if (m_nOn == 1)
			m_dwExStyle |= CLPV_EX_ON;
		if (m_nDirect == 1)
			m_dwExStyle |= CLPV_EX_DIRECT;
		if (m_nFlush == 1)
			m_dwExStyle |= CLPV_EX_FLUSH;

		if (_check_flag(CLPV_EX_ON, m_dwExStyle))
			InstallClipboardViewer();
		else
			UninstallClipboardViewer();
	}

	void _SetData()
	{
		m_nOn = _check_flag(CLPV_EX_ON, m_dwExStyle) ? 1 : 0;
		m_nDirect = _check_flag(CLPV_EX_DIRECT, m_dwExStyle) ? 1 : 0;
		m_nFlush = _check_flag(CLPV_EX_FLUSH, m_dwExStyle) ? 1 : 0;
	}

	void _GetProfile()
	{
		CIniSection pr;

		pr.Open(MtlGetChangedExtFromModuleName(_T(".ini")), _T("ClipboardBar"));
		pr.QueryValue(m_dwExStyle, _T("Extended_Style"));

		DWORD dwCount = 4096;
		TCHAR szExts[4096];
		if (pr.QueryValue(szExts, _T("Ext_List"), &dwCount) != ERROR_SUCCESS)
			::lstrcpyn(szExts, _T("/;html;htm;shtml;cgi;asp;com;net;jp;lnk;url;"), 4096);	

		m_strExts = szExts;

		if (_check_flag(CLPV_EX_ON, m_dwExStyle))
			InstallClipboardViewer();
	}

	void _WriteProfile()
	{
		CIniSection pr;

		pr.Open(MtlGetChangedExtFromModuleName(_T(".ini")), _T("ClipboardBar"));
		pr.SetValue(m_dwExStyle, _T("Extended_Style"));
		pr.SetValue(m_strExts,  _T("Ext_List"));

		UninstallClipboardViewer();
	}


	template <class _Function>
	bool _MtlForEachListBoxSelectedItem(CListBox box, _Function __f)
	{
		int nCount = box.GetSelCount();
		if (nCount == 0)
			return false;

		LPINT rgIndex = (LPINT)_alloca(sizeof(INT)*nCount);

		nCount = box.GetSelItems(nCount, rgIndex);

		if (nCount == LB_ERR)
			return false;

		CSimpleArray<int> arrIndex;
		for (int i = 0; i < nCount; ++i) {
			arrIndex.Add(rgIndex[i]);
		}

		std::sort(_begin(arrIndex), _end(arrIndex));

		for (int j = arrIndex.GetSize() - 1; j >= 0; --j)// from the tail, you can delete it
			__f(box.m_hWnd, arrIndex[j], nCount);

		return true;
	}

	struct _Function_DeleteString
	{
		void operator()(CListBox box, int nIndex, int nCount)
		{
			box.DeleteString(nIndex);
		}
	};

	struct _Function_Open
	{
		void operator()(CListBox box, int nIndex, int nCount)
		{
			CString str;
			MtlListBoxGetText(box.m_hWnd, nIndex, str);
			if (str.IsEmpty())
				return;

			DonutOpenFile(box.m_hWnd, str, 0);
		}
	};
/*
	static void _BuildExtArray(CSimpleArray<CString>& arrExt, const CString& strExts)
	{
		int nFirst = 0;
		int nLast = 0;

		while (nFirst < strExts.GetLength()) {
			nLast = __MtlFindChar(strExts, nFirst, _T(';'));
			if (nLast == -1)
				nLast = strExts.GetLength();

			CString strExt = strExts.Mid(nFirst, nLast - nFirst);
			if (!strExt.IsEmpty() && arrExt.Find(strExt) == -1) {
				clbTRACE(_T("_BuildExtsArray.Add(%s)\n"), strExt);
				arrExt.Add(strExt);
			}

			nFirst = nLast + 1;
		}
	}

	static void _BuildUrlArray(CSimpleArray<CString>& arrUrl, const CSimpleArray<CString>& arrExt, const CString& strText_)
	{
		int nFirst = 0;
		int nLast = 0;

		CString strText = strText_;
		strText.Replace(_T("\r"), _T(""));


		while (nFirst < strText.GetLength()) {
			nLast = __MtlFindChar(strText, nFirst, _T('\n'));
			if (nLast == -1)
				nLast = strText.GetLength();

			CString strPart = strText.Mid(nFirst, nLast - nFirst);
			if (!strPart.IsEmpty()) {
				CString strExt = _MtlGetExt(strPart, true);
				if (_FindExtFromArray(arrExt, strExt)) {
					clbTRACE(_T("_BuildUrlArray.Add(%s)\n"), strPart);
					arrUrl.Add(strPart);
				}
				else {
					strExt = _MtlGetExt(strPart, false);
					if (_FindExtFromArray(arrExt, strExt)) {
						clbTRACE(_T("_BuildUrlArray.Add(%s)\n"), strPart);
						arrUrl.Add(strPart);
					}
					else {
						strExt = _MtlGetTrailingSeparator(strPart);
						if (_FindExtFromArray(arrExt, strExt)) {
							clbTRACE(_T("_BuildUrlArray.Add(%s)\n"), strPart);
							arrUrl.Add(strPart);
						}
					}
				}
			}

			nFirst = nLast + 1;
		}
	}

	static bool _FindExtFromArray(const CSimpleArray<CString>& arrExt, const CString& strExt)
	{
		if (strExt.IsEmpty())
			return false;

		for (int i = 0; i < arrExt.GetSize(); ++i) {
			if (strExt.CompareNoCase(arrExt[i]) == 0)
				return true;
		}

		return false;
	}

	static CString _MtlGetTrailingSeparator(const CString& strUrl)
	{
		int nIndex =  strUrl.ReverseFind(_T('/'));
		if (nIndex == strUrl.GetLength() - 1)
			return _T('/');

		nIndex = strUrl.ReverseFind(_T('\\'));
		if (nIndex == strUrl.GetLength() - 1)
			return _T('\\');

		return CString();
	}

	static CString _MtlGetExt(const CString& strUrl, bool bFromLeft)
	{
		if (strUrl.IsEmpty())
			return CString();

		int nIndex = -1;
		if (bFromLeft) {
			int nIndexName = strUrl.ReverseFind(_T('/'));
			if (nIndexName == -1)
				nIndexName = strUrl.ReverseFind(_T('\\'));

			if (nIndexName == -1)
				return CString();

			nIndex = __MtlFindChar(strUrl, nIndexName, _T('.'));
		}
		else {
			nIndex = strUrl.ReverseFind(_T('.'));
		}

		if (nIndex == -1)
			return CString();

		CString str_ = strUrl.Mid(nIndex + 1);

		int nLen = str_.GetLength() + 1;
		LPTSTR lpsz = (LPTSTR)_alloca(nLen * sizeof(TCHAR));
		::lstrcpy(lpsz, str_);
		
		for (LPCTSTR lpszRunner = lpsz; *lpszRunner != _T('\0'); lpszRunner = ::CharNext(lpszRunner)) {
			if (!Mtl_isalpha(*lpszRunner))
				break;
		}

		return strUrl.Mid(nIndex + 1, lpszRunner - lpsz);
	}
*/
	void _OnItemOpen(int nIndex)
	{
		clbTRACE(_T("_OnItemOpen\n"));
		CString str;
		MtlListBoxGetText(m_box.m_hWnd, nIndex, str);
		if (str.IsEmpty())
			return;

		DonutOpenFile(m_hWnd, str, 0);
	}
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -