📄 addressbar.h
字号:
#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 + -