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

📄 addressbar.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:
#pragma once
////////////////////////////////////////////////////////////////////////////
// MTL Version 0.10
// Copyright (C) 2001 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// Mtlwin.h: Last updated: March 6, 2001
////////////////////////////////////////////////////////////////////////////
#include "HlinkDataObject.h"

#include <atlctrls.h>

namespace WTL
{

// Helper functions
struct __Mtl_Function_AddToComboBoxEx
{
	CComboBoxEx _comboBoxEx;
	__Mtl_Function_AddToComboBoxEx(HWND hWndComboBoxEx) : _comboBoxEx(hWndComboBoxEx) { }
	void operator()(const CString& str)
	{
		COMBOBOXEXITEM item;
		item.mask = CBEIF_TEXT;
		item.iItem = -1;
		item.pszText = (LPTSTR)(LPCTSTR)str;
		_comboBoxEx.InsertItem(&item);
	}
};

template <class _Function>
bool MtlLoadTypedURLs(HWND hWndComboBoxEx, _Function __f)
{
	CRegKey rk;
	LONG lRet = rk.Open(HKEY_CURRENT_USER,
		_T("Software\\Microsoft\\Internet Explorer\\TypedURLs"));
	if(lRet != ERROR_SUCCESS)
		return false;

	std::list<CString> urls;
	if (!MtlGetProfileString(rk, std::back_inserter(urls), _T("url"), 1, 25))// get only 25 items
		return false;
	
//	std::for_each(urls.begin(), urls.end(), __Mtl_Function_AddToComboBoxEx(hWndComboBoxEx));

	std::list<CString>::iterator it;
	for (it = urls.begin(); it != urls.end(); ++it) {
		CString strUrl = *it;
		COMBOBOXEXITEM item;
		__f(strUrl, item);
		CComboBoxEx(hWndComboBoxEx).InsertItem(&item);
	}

	return true;
}

template <class _OutputIterString>
bool __Mtl_AddFromComboBox(HWND hWndComboEx, _OutputIterString __result)
{
	CComboBoxEx combo(hWndComboEx);

	CString str;
	int nCount = combo.GetCount();
	if (nCount == 0)
		return false;

	for (int n = 0; n < nCount; ++n) {
		if (MtlGetLBTextFixed(combo, n, str) != CB_ERR)
			*__result++ = str;
	}

	return true;
}

inline bool MtlSaveTypedURLs(HWND hWndComboBoxEx)
{
	CRegKey rk;
	LONG lRet = rk.Open(HKEY_CURRENT_USER,
		_T("Software\\Microsoft\\Internet Explorer\\TypedURLs"));
	if(lRet != ERROR_SUCCESS)
		return false;

	std::list<CString> urls;
	__Mtl_AddFromComboBox(hWndComboBoxEx, std::back_inserter(urls));
	if (urls.size() == 0)
		return false;

	int nSize = 25;

	if (nSize > urls.size())
		nSize = urls.size();

	std::list<CString>::iterator end = urls.begin();
	std::advance(end, nSize);
	MtlWriteProfileString(urls.begin(), end, rk, _T("url"), 1);
	return true;
}

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

////////////////////////////////////////////////////////////////////////////
// CAddressBarCtrl

#define ABR_EX_AUTOCOMPLETE		0x00000001L
#define ABR_EX_LOADTYPEDURLS	0x00000002L
#define ABR_EX_GOBTNVISIBLE		0x00000004L

#define ABR_EX_USER				0x00010000L

#define ABR_PANE_STYLE WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN /*| WS_OVERLAPPED | WS_MAXIMIZEBOX*/ | CCS_NODIVIDER | CCS_NOMOVEY

class CAddressBarCtrlBase : public CComboBoxEx
{
public:

};

template <class T, class TBase = CAddressBarCtrlBase, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CAddressBarCtrlImpl :
	public CWindowImpl< T, TBase, TWinTraits >,
	public IDropTargetImpl<T>,
	public IDropSourceImpl<T>
{
public:
	typedef CWindowImpl< T, TBase, TWinTraits > baseClass;
	DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())

	struct CGoBtnInfo
	{
		CGoBtnInfo(UINT nImageBmpID, UINT nHotImageBmpID, int cx, int cy, COLORREF clrMask, UINT nFlags)
			: _nImageBmpID(nImageBmpID), _nHotImageBmpID(nHotImageBmpID), _cx(cx), _cy(cy), 
			  _clrMask(clrMask), _nFlags(nFlags) { }

		UINT _nImageBmpID;
		UINT _nHotImageBmpID;
		int _cx, _cy;
		COLORREF _clrMask;
		UINT _nFlags;
	};

// Constants
	enum { s_kcxGap = 2 };

// Data members
	CToolBarCtrl m_wndGo;
	DWORD m_dwAddressBarExtendedStyle;
	UINT m_nGoBtnCmdID;
	int m_cx;
	int m_cxGoBtn;
	CGoBtnInfo* m_pGoBtnInfo;
	CContainedWindow m_wndCombo;
	CContainedWindowT<CEdit> m_wndEdit;
	CFlatComboBox m_comboFlat;

	bool m_bDragFromItself;

// Ctor/dtor
	CAddressBarCtrlImpl() : 
		m_dwAddressBarExtendedStyle(0/*ABR_EX_AUTOCOMPLETE|ABR_EX_LOADTYPEDURLS|ABR_EX_GOBTNVISIBLE*/),
		m_nGoBtnCmdID(0), m_cxGoBtn(0),
		m_wndCombo(this, 1), m_wndEdit(this, 2),
		m_bDragFromItself(false)
	{
	}

	HWND Create(HWND hWndParent, UINT nID, UINT nGoBtnCmdID,
		UINT nImageBmpID, UINT nHotImageBmpID,
		int cx, int cy, COLORREF clrMask, UINT nFlags = ILC_COLOR8)
	{
		m_nGoBtnCmdID = nGoBtnCmdID;
		m_pGoBtnInfo = new CGoBtnInfo(nImageBmpID, nHotImageBmpID, cx, cy, clrMask, nFlags); 

		return baseClass::Create(hWndParent, CRect(0, 0, 500, 250),
			NULL, ABR_PANE_STYLE | CBS_DROPDOWN | CBS_AUTOHSCROLL, 0, nID);
	}
// Attributes
	bool GetDroppedStateEx() const
	{
		return (GetDroppedState() || _AutoCompleteWindowVisible());
	}

	void ModifyAddressBarExtendedStyle(DWORD dwRemove, DWORD dwAdd)
	{
		DWORD dwOldStyle = m_dwAddressBarExtendedStyle;
		bool bOldShow = _check_flag(dwOldStyle, ABR_EX_GOBTNVISIBLE);

		m_dwAddressBarExtendedStyle = (m_dwAddressBarExtendedStyle & ~dwRemove) | dwAdd;

		bool bNewShow = _check_flag(m_dwAddressBarExtendedStyle, ABR_EX_GOBTNVISIBLE);
		if (bNewShow != bOldShow)
			_ShowGoButton(bNewShow);
	}

	void SetAddressBarExtendedStyle(DWORD dwStyle)
	{
		DWORD dwOldStyle = m_dwAddressBarExtendedStyle;
		bool bOldShow = _check_flag(dwOldStyle, ABR_EX_GOBTNVISIBLE);

		m_dwAddressBarExtendedStyle = dwStyle;

		bool bNewShow = _check_flag(m_dwAddressBarExtendedStyle, ABR_EX_GOBTNVISIBLE);
		if (bNewShow != bOldShow)
			_ShowGoButton(bNewShow);
	}

	DWORD GetAddressBarExtendedStyle() const
	{
		return m_dwAddressBarExtendedStyle;
	}

/*	void SetWindowText(const CString& strText)
	{
		abrTRACE(_T("CAddressBarCtrlImpl::SetWindowText\n"));
		T* pT = static_cast<T*>(this);
		COMBOBOXEXITEM item;
		pT->OnGetItem(strText, item);
		item.iItem = -1;// on edit control
		item.pszText = (LPTSTR)(LPCTSTR)strText;

		MTLVERIFY(SetItem(&item));
	}*/

// Overridables
	void OnItemSelected(const CString& str)
	{
	}

	void OnInit()
	{
	}

	void OnTerm()
	{
	}

	void OnGetItem(const CString& str, COMBOBOXEXITEM& item)
	{
	}

	void OnGetDispInfo(COMBOBOXEXITEM& item)
	{
	}

// Methods
	BYTE PreTranslateMessage(MSG* pMsg)
	{
		UINT msg = pMsg->message;
		int vKey =  pMsg->wParam;
			
		if (msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP || msg == WM_KEYDOWN) {

			if (!IsWindowVisible() || !IsChild(pMsg->hwnd))	// ignore
				return _MTL_TRANSLATE_PASS;

			if (vKey == VK_F4) {
				if (::GetKeyState(VK_SHIFT) >= 0 && ::GetKeyState(VK_CONTROL) >= 0) // only F4 pressed
					return _MTL_TRANSLATE_WANT;					// I want!
			}

			// left or right pressed, check shift and control key.
			if (vKey == VK_UP || vKey == VK_DOWN || vKey == VK_LEFT || vKey == VK_RIGHT || vKey == VK_HOME || vKey == VK_END) {
				if (::GetKeyState(VK_SHIFT) < 0 || ::GetKeyState(VK_CONTROL) < 0)
					return _MTL_TRANSLATE_WANT;// pass to edit control
			}

			// return key have to be passed
			if (vKey == VK_RETURN) {
				return _MTL_TRANSLATE_WANT;
			}

			// other key have to be passed
			if (VK_LBUTTON <= vKey && vKey <= VK_HELP) {
				BOOL bAlt = HIWORD(pMsg->lParam) & KF_ALTDOWN;
				if (!bAlt && ::GetKeyState(VK_SHIFT) >= 0 && ::GetKeyState(VK_CONTROL) >= 0)// not pressed
					return _MTL_TRANSLATE_WANT;// pass to edit control
			}
		}

		return _MTL_TRANSLATE_PASS;
	}

// Message map and handlers
	BEGIN_MSG_MAP(CAddressBarCtrlBaseImpl)
		MSG_WM_CREATE(OnCreate)
		MSG_WM_DESTROY(OnDestroy)
		MSG_WM_COMMAND(OnCommand)
		MSG_WM_SIZE(OnSize)
		MSG_WM_SETTEXT(OnSetText)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
		REFLECTED_COMMAND_CODE_HANDLER_EX(CBN_SELENDOK, OnCbnSelendok)
		NOTIFY_CODE_HANDLER(TTN_GETDISPINFO, OnToolTipText)
		REFLECTED_NOTIFY_CODE_HANDLER_EX(CBEN_GETDISPINFO, OnCbenGetDispInfo)
	ALT_MSG_MAP(1)
		MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnComboWindowPosChanging)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnComboEraseBackground)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
	ALT_MSG_MAP(2)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEditEraseBackground)
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnEditLButtonDblClk)
		MSG_WM_KEYDOWN(OnEditKeyDown)
	END_MSG_MAP()

	LRESULT OnSetText(LPCTSTR lpszText)
	{
		CString strText(lpszText);
		if (MtlGetWindowText(GetEditCtrl()) == strText)
			return TRUE;

		T* pT = static_cast<T*>(this);
		COMBOBOXEXITEM item;
//		if (strText.IsEmpty())
//			return TRUE;

//		if (strText.IsEmpty()) {
//			item.mask = CBEIF_IMAGE | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;
//			item.iImage = item.iSelectedImage = -1;
//			item.iItem = -1;// on edit control
//			item.pszText = _T("");
//			MTLVERIFY(SetItem(&item));
//			return TRUE;
//		}


//		item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT;
//		item.iImage = -1;
//		item.iSelectedImage = -1;
//		item.iItem = -1;
//		item.pszText = _T("");
//		MTLVERIFY(SetItem(&item));

		// Strangely, Icon on edit control never be changed... tell me why?
//		pT->OnGetItem(lpszText, item);
		item.mask = CBEIF_TEXT;
		item.iItem = -1;// on edit control
		item.pszText = (LPTSTR)(LPCTSTR)strText;
		MTLVERIFY(SetItem(&item));

		// insert it to tail and select
//		InsertItem(&item);
///		SetCurSel(GetCount()-1);
//		DeleteItem(GetCount()-1);
	
		return TRUE;
	}

	LRESULT OnCreate(LPCREATESTRUCT)
	{
		_CreateGoButton(m_pGoBtnInfo->_nImageBmpID, m_pGoBtnInfo->_nHotImageBmpID,
			m_pGoBtnInfo->_cx, m_pGoBtnInfo->_cy,
			m_pGoBtnInfo->_clrMask, m_pGoBtnInfo->_nFlags);
		delete m_pGoBtnInfo;

		LRESULT lRet = DefWindowProc();

		SetExtendedStyle(0, CBES_EX_NOSIZELIMIT);

		_GetProfile();

		if (_check_flag(m_dwAddressBarExtendedStyle, ABR_EX_AUTOCOMPLETE))
			MtlAutoComplete(GetEditCtrl());

		if (_check_flag(m_dwAddressBarExtendedStyle, ABR_EX_LOADTYPEDURLS))
			_LoadTypedURLs();
		
		if (_check_flag(m_dwAddressBarExtendedStyle, ABR_EX_GOBTNVISIBLE))
			_ShowGoButton(true);
		else
			_ShowGoButton(false);

		m_wndCombo.SubclassWindow(GetComboCtrl());
		m_wndEdit.SubclassWindow(GetEditCtrl());
		m_comboFlat.FlatComboBox_Install(GetComboCtrl());

		T* pT = static_cast<T*>(this);
		pT->OnInit();

		return lRet;
	}

	void OnDestroy()
	{
		_WriteProfile();
		MtlDestroyImageLists(m_wndGo);

		if (_check_flag(m_dwAddressBarExtendedStyle, ABR_EX_LOADTYPEDURLS))
			MtlSaveTypedURLs(m_hWnd);

		m_wndCombo.UnsubclassWindow();
		m_wndEdit.UnsubclassWindow();

		T* pT = static_cast<T*>(this);
		pT->OnTerm();
	}

	void OnSize(UINT nFlags, CSize size)
	{
		abrTRACE(_T("CAddressBarCtrlImpl::OnSize\n"));

//		if (m_wndGo.IsWindowVisible()) {
			int cxGo = _GetGoBtnWidth();
			CRect rc; GetClientRect(rc);
			m_wndGo.MoveWindow(rc.right - cxGo + s_kcxGap, 0, cxGo, rc.Height());
			InvalidateRect(CRect(rc.right - cxGo, 0, rc.right - cxGo + s_kcxGap, rc.Height()));
//		}
	}

	LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
		m_cx = lpWP->cx;

		LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);

		if (m_wndGo.m_hWnd) {
			CSize size; m_wndGo.GetButtonSize(size);
			if(lpWP->cy < size.cy)
				lpWP->cy = size.cy;
		}

		return lRet;
	}

	void OnCommand(UINT, int nID, HWND hWndCtrl)
	{
		if (hWndCtrl == m_wndGo.m_hWnd) {
			ATLASSERT(nID == m_nGoBtnCmdID);
			CEdit edit = GetEditCtrl();
			CString str = MtlGetWindowText(edit);
			if (!str.IsEmpty()) {
				T* pT = static_cast<T*>(this);
				pT->OnItemSelected(str);
			}			
		}
		else {
			SetMsgHandled(FALSE);
		}
	}

	void OnCbnSelendok(UINT, int, HWND)
	{
		CString strLB;
		MtlGetLBTextFixed(m_hWnd, GetCurSel(), strLB);
		CEdit edit = GetEditCtrl();
		CString strText = MtlGetWindowText(edit);

⌨️ 快捷键说明

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