标题duilib ComboEdit
可编辑下拉选择框
可编辑下拉选择框,输入文本后,下拉选择框会自动显示相关的选项;
自己根据EditUI、ComboUI、ListUI自己弄出来的;
缺陷:
当窗口移动的时候(拖住窗口标题移动),combo窗口不会主动关闭,也不会主动跟着窗口移动,需要在窗口的WM_NCLBUTTONDOWN消息设置焦点到窗口或其他控件,使得CEditWnd收到KillFocus消息,从而把自己(CEditWnd)关闭,关闭时也把CComboWnd关闭;
但这样控件需要外部来控制,破坏控件的封装,且移动后焦点就不在ComboEdit上了;
LRESULT CMainFrame::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
switch (uMsg)
{
case WM_TIMER:
{
OnTimer(uMsg, wParam, lParam, bHandled);
}
break;
case WM_NCLBUTTONDOWN:
{
ShowMsg(_T("非客户区单击"));
SetFocus(GetHWND());
}
break;
default:
{
}
break;
}
return 0;
}
void CEditCombo_EditWnd::OnFinalMessage(HWND hWnd)
{
m_pOwner->Invalidate();
// Clear reference and die
if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);
m_pOwner->GetManager()->RemoveNativeWindow(hWnd);
m_pOwner->m_pEditWindow = NULL;
m_pOwner->EditDestroy(); // 告诉父亲自己destroy
delete this;
}
LRESULT CEditCombo_EditWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
if ((HWND)wParam != m_pOwner->GetManager()->GetPaintWindow()) {
::SendMessage(m_pOwner->GetManager()->GetPaintWindow(), WM_KILLFOCUS, wParam, lParam);
}
SendMessage(WM_CLOSE);
return lRes;
}
void CEditComboUI::EditDestroy()
{
if (NULL != m_pComboWindow)
{
m_pComboWindow->PostMessage(WM_CLOSE);
Invalidate();
}
}
CComboEditUI
1. UIComboEdit.h
#pragma once
#define DUI_CTR_EDITCOMBOELEMENT (_T("EditComboElement"))
#define DUI_CTR_EDITCOMBO (_T("EditCombo"))
class CEditCombo_EditWnd;
class CEditCombo_ComboWnd;
class IEditCombo_ControlUI
{
public:
virtual int GetWindowStyls() const = 0;
virtual CPaintManagerUI* GetManager() const = 0;
virtual CControlUI* GetParent() const = 0;
virtual LPVOID GetInterface(LPCTSTR pstrName) = 0;
virtual void Invalidate() = 0;
virtual bool IsEnabled() const = 0;
virtual CDuiString GetText() const = 0;
virtual void SetPos(RECT rc, bool bNeedInvalidate) = 0;
virtual const RECT& GetPos() const = 0;
virtual RECT GetRelativePos() const = 0;
virtual RECT GetClientPos() const = 0;
virtual bool IsVisible() const = 0;
virtual void DoEvent(TEventUI &event) = 0;
protected:
virtual void _SetText(LPCTSTR pstrText) = 0; // 仅仅设置m_sText
};
class IEditCombo_EditUI : public IEditCombo_ControlUI
{
friend class CEditCombo_EditWnd;
protected:
CEditCombo_EditWnd *m_pEditWindow; // Edit框
public:
IEditCombo_EditUI() : m_pEditWindow(NULL){
}
virtual int GetFont() const = 0;
virtual UINT GetTextStyle() const = 0;
virtual RECT GetTextPadding() const = 0;
virtual bool IsPasswordMode() const = 0;
virtual TCHAR GetPasswordChar() const = 0;
virtual bool IsReadOnly() const = 0;
virtual bool IsAutoSelAll() const = 0;
virtual UINT GetMaxChar() const = 0;
virtual DWORD GetTextColor() const = 0;
virtual DWORD GetNativeEditBkColor() const = 0;
virtual DWORD GetNativeEditTextColor() const = 0;
virtual void TextChange() = 0;
virtual void EditDestroy() = 0;
};
class IEditCombo_ComboUI : public IEditCombo_ControlUI
{
friend class CEditCombo_ComboWnd;
protected:
CEditCombo_ComboWnd *m_pComboWindow; // Combo弹窗
UINT m_uButtonState; // 状态
public:
IEditCombo_ComboUI() : m_pComboWindow(NULL), m_uButtonState(0){
}
virtual LPCTSTR GetClass() const = 0;
virtual bool IsFloat() const = 0;
virtual int GetCurSel() const = 0;
virtual int GetCount() const = 0;
virtual void SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit = true) = 0;
virtual CControlUI* GetItemAt(int id) = 0;
virtual void SetFocus() = 0;
virtual SIZE GetDropBoxSize() const = 0;
virtual CDuiString GetDropBoxAttributeList() = 0;
virtual TListInfoUI* GetListInfo() = 0;
virtual bool SelectItem(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true, bool bMutil = false) = 0;
};
class CEditComboElementUI : public CListLabelElementUI
{
public:
CEditComboElementUI() : CListLabelElementUI(){
}
LPCTSTR GetClass() const
{
return DUI_CTR_EDITCOMBOELEMENT;
}
LPVOID GetInterface(LPCTSTR pstrName)
{
if (0 == _tcscmp(pstrName, DUI_CTR_EDITCOMBOELEMENT))
{
return static_cast<CEditComboElementUI*>(this);
}
return CListLabelElementUI::GetInterface(pstrName);
}
void SetFocus() override{
}
};
class CEditComboUI : public CContainerUI, public IEditCombo_EditUI, public IEditCombo_ComboUI, public IListOwnerUI
{
public:
CEditComboUI(void);
virtual ~CEditComboUI(void);
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
UINT GetControlFlags() const;
HWND GetNativeWindow() const;
HWND GetNativeEditHWND() const;
int GetWindowStyls() const;
UINT GetTextStyle() const;
int GetFont() const;
CPaintManagerUI* GetManager() const;
CControlUI* GetParent() const;
void Invalidate();
bool IsEnabled() const;
void SetEnabled(bool bEnable);
CDuiString GetText() const;
void _SetText(LPCTSTR pstrtext);
void SetText(LPCTSTR pstrText);
RECT GetTextPadding() const;
void SetTextPadding(RECT rc);
void SetTextPadding(LPCTSTR pstrValue);
bool IsVisible() const;
void TextChange();
void EditDestroy();
void SetPasswordMode(bool bPasswordMode);
bool IsPasswordMode() const;
void SetPasswordChar(TCHAR szChar);
TCHAR GetPasswordChar() const;
void SetMaxChar(UINT uMax);
UINT GetMaxChar() const;
void SetReadOnly(bool bReadOnly);
bool IsReadOnly() const;
void SetNumberOnly(bool bNumberOnly);
bool IsNumberOnly() const;
void SetAutoSelAll(bool bAuto);
bool IsAutoSelAll() const;
void SetReplaceSel(LPCTSTR lpszReplace);
void SetFont(int index);
void SetPos(RECT rc, bool bNeedInvalidate);
const RECT& GetPos() const;
RECT GetRelativePos() const;
RECT GetClientPos() const;
void Move(SIZE szOffset, bool bNeedInvalidate);
void SetVisible(bool bVisible);
void SetInternVisible(bool bVisible);
SIZE EstimateSize(SIZE szAvailable);
void PaintStatusImage(HDC hDC);
void PaintText(HDC hDC);
LPCTSTR GetNormalImage();
void SetNormalImage(LPCTSTR pStrImage);
LPCTSTR GetHotImage();
void SetHotImage(LPCTSTR pStrImage);
LPCTSTR GetPushedImage() const;
void SetPushedIMage(LPCTSTR pStrImage);
LPCTSTR GetFocusedImage();
void SetFocusedImage(LPCTSTR pStrImage);
LPCTSTR GetDisabledImage();
void SetDisabledImage(LPCTSTR pStrImage);
DWORD GetTextColor() const;
void SetNativeEditBkColor(LPCTSTR pStrColor);
DWORD GetNativeEditBkColor() const;
void SetNativeEditTextColor(LPCTSTR pStrColor);
DWORD GetNativeEditTextColor() const;
void SetTipValue(LPCTSTR pStrTipValue);
void SetTipValueColor(LPCTSTR pStrColor);
DWORD GetTipValueColor();
CDuiString GetTipValue();
LPCTSTR GetSrcTipValue();
void SetTextStyle(UINT uStyle);
void SetTextColor(DWORD dwTextColor);
void SetDisabledTextColor(DWORD dwTextColor);
DWORD GetDisabledTextColor() const;
DWORD StringToColor(LPCTSTR pstrColor);
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
void DoEvent(TEventUI& event) override;
protected:
int m_iWindowStyls; // 类型
int m_iFont; // 字体
bool m_bReadOnly; // 是否只读
bool m_bPasswordMode; // 密码模式
TCHAR m_szPasswordChar; // 密码显示的字符
UINT m_uMaxChar; // 最大个数
bool m_bAutoSelAll; // 自动全选
UINT m_uButtonState; // 按钮状态
RECT m_rcTextPadding; // 文本间隔
DWORD m_dwEditBkColor; // Edit背景颜色
DWORD m_dwEditTextColor; // Edit文本颜色
DWORD m_dwTipValueColor; // 提示颜色
CDuiString m_sTipValue; // 提示的值
CDuiString m_sSrcTipValue; //
UINT m_uTextStyle;
DWORD m_dwTextColor;
DWORD m_dwDisabledTextColor;
TDrawInfo m_diNormal;
TDrawInfo m_diHot;
TDrawInfo m_diPushed;
TDrawInfo m_diFocused;
TDrawInfo m_diDisabled;
public:
bool IsFloat() const;
int GetCurSel() const;
int GetCount() const;
void SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit = true);
CControlUI* GetItemAt(int id);
void SetFocus();
void SetDropBoxSize(SIZE szSize);
void SetDropBoxSize(LPCTSTR pstrValue);
SIZE GetDropBoxSize() const;
void SetDropBoxAttributeList(LPCTSTR pstrList);
CDuiString GetDropBoxAttributeList();
TListInfoUI* GetListInfo();
bool SelectItem(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true, bool bMutil = false);
bool SelectRange(int iIndex, bool bTakeFocus = false, bool bTriggerEvent=true, bool bMutil = false);
bool ExpandItem(int iIndex, bool bExpand = true);
int GetExpandedItem() const;
bool SetItemIndex(CControlUI* pControl, int iNewIndex);
bool SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex);
bool Add(CControlUI* pControl);
bool AddAt(CControlUI* pControl, int iIndex);
bool Remove(CControlUI* pControl, bool bDoNotDestroy =false);
bool RemoveAt(int iIndex, bool bDoNotDestroy =false);
void RemoveAll();
void SetShowText(bool bShow);
bool GetShowText() const;
void SetSelectCloseFlag(bool flag);
bool GetSelectCloseFlag() const;
UINT GetItemFixedHeight();
void SetItemFixedHeight(UINT nHeight);
int GetItemFont(int index);
void SetItemFont(int index);
void SetItemAlign(LPCTSTR pstrValue);
UINT GetItemTextStyle();
void SetItemTextStyle(UINT uStyle);
RECT GetItemTextPadding() const;
void SetItemTextPadding(RECT rc);
void SetItemTextPadding(LPCTSTR pstrValue);
DWORD GetItemTextColor() const;
void SetItemTextColor(DWORD dwTextColor);
DWORD GetItemBkColor() const;
void SetItemBkColor(DWORD dwBkColor);
LPCTSTR GetItemBkImage() const;
void SetItemBkImage(LPCTSTR pStrImage);
bool IsItemAlternateBk() const;
void SetItemAlternateBk(bool bAlternateBk);
DWORD GetSelectedItemTextColor() const;
void SetSelectedItemTextColor(DWORD dwTextColor);
DWORD GetSelectedItemBkColor() const;
void SetSelectedItemBkColor(DWORD dwBkColor);
LPCTSTR GetSelectedItemImage() const;
void SetSelectedItemImage(LPCTSTR pStrImage);
DWORD GetHotItemTextColor() const;
void SetHotItemTextColor(DWORD dwTextColor);
DWORD GetHotItemBkColor() const;
void SetHotItemBkColor(DWORD dwBkColor);
LPCTSTR GetHotItemImage() const;
void SetHotItemImage(LPCTSTR pStrImage);
DWORD GetDisabledItemTextColor() const;
void SetDisabledItemTextColor(DWORD dwTextColor);
DWORD GetDisabledItemBkColor() const;
void SetDisabledItemBkColor(DWORD dwBkColor);
LPCTSTR GetDisabledItemImage() const;
void SetDisabledItemImage(LPCTSTR pStrImage);
int GetItemHLineSize() const;
void SetItemHLineSize(int iSize);
DWORD GetItemHLineColor() const;
void SetItemHLineColor(DWORD dwLineColor);
int GetItemVLineSize() const;
void SetItemVLineSize(int iSize);
DWORD GetItemVLineColor() const;
void SetItemVLineColor(DWORD dwLineColor);
bool IsItemShowHtml();
void SetItemShowHtml(bool bShowHtml = true);
private:
int m_iCurSel; // 当前选择的item
bool m_bShowText; // 不显示文本
bool m_bSelectCloseFlag; // (下拉框)关闭
SIZE m_szDropBox; // 下拉框大小
CDuiString m_sDropBoxAttributes; // 下拉框设置
// 列表设置
TListInfoUI m_ListInfo;
};
2. UIComboEdit.cpp
#include "stdafx.h"
#include "UIEditCombo.h"
//
class CEditCombo_EditWnd : public CWindowWnd
{
public:
CEditCombo_EditWnd();
void Init(IEditCombo_EditUI* pOwner);
RECT CalPos();
LPCTSTR GetWindowClassName() const;
LPCTSTR GetSuperClassName() const;
void OnFinalMessage(HWND hWnd);
LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
protected:
enum {
DEFAULT_TIMERID = 20,
};
IEditCombo_EditUI* m_pOwner;
HBRUSH m_hBkBrush;
bool m_bInit;
bool m_bDrawCaret;
};
CEditCombo_EditWnd::CEditCombo_EditWnd() : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false), m_bDrawCaret(false)
{
}
void CEditCombo_EditWnd::Init(IEditCombo_EditUI* pOwner)
{
m_pOwner = pOwner;
RECT rcPos = CalPos();
UINT uStyle = WS_CHILD | ES_AUTOHSCROLL | pOwner->GetWindowStyls();
UINT uTextStyle = m_pOwner->GetTextStyle();
if(uTextStyle & DT_LEFT) uStyle |= ES_LEFT;
else if(uTextStyle & DT_CENTER) uStyle |= ES_CENTER;
else if(uTextStyle & DT_RIGHT) uStyle |= ES_RIGHT;
if( m_pOwner->IsPasswordMode() ) uStyle |= ES_PASSWORD;
Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);
HFONT hFont=NULL;
int iFontIndex=m_pOwner->GetFont();
if (iFontIndex!=-1)
hFont=m_pOwner->GetManager()->GetFont(iFontIndex);
if (hFont==NULL)
hFont=m_pOwner->GetManager()->GetDefaultFontInfo()->hFont;
SetWindowFont(m_hWnd, hFont, TRUE);
Edit_LimitText(m_hWnd, m_pOwner->GetMaxChar());
if( m_pOwner->IsPasswordMode() ) Edit_SetPasswordChar(m_hWnd, m_pOwner->GetPasswordChar());
Edit_SetText(m_hWnd, m_pOwner->GetText());
Edit_SetModify(m_hWnd, FALSE);
SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELPARAM(0, 0));
Edit_Enable(m_hWnd, m_pOwner->IsEnabled() == true);
Edit_SetReadOnly(m_hWnd, m_pOwner->IsReadOnly() == true);
//Styls
::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
::SetFocus(m_hWnd);
if (m_pOwner->IsAutoSelAll()) {
int nSize = GetWindowTextLength(m_hWnd);
if( nSize == 0 ) nSize = 1;
Edit_SetSel(m_hWnd, 0, nSize);
}
else {
int nSize = GetWindowTextLength(m_hWnd);
Edit_SetSel(m_hWnd, nSize, nSize);
}
m_bInit = true;
}
RECT CEditCombo_EditWnd::CalPos()
{
CDuiRect rcPos = m_pOwner->GetPos();
RECT rcInset = m_pOwner->GetTextPadding();
rcPos.left += rcInset.left;
rcPos.top += rcInset.top;
rcPos.right -= rcInset.right;
rcPos.bottom -= rcInset.bottom;
LONG lEditHeight = m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->tm.tmHeight;
if( lEditHeight < rcPos.GetHeight() ) {
rcPos.top += (rcPos.GetHeight() - lEditHeight) / 2;
rcPos.bottom = rcPos.top + lEditHeight;
}
CControlUI* pParent = static_cast<CControlUI*>(m_pOwner->GetInterface(DUI_CTR_CONTROL));
RECT rcParent;
while( pParent = pParent->GetParent() ) {
if( !pParent->IsVisible() ) {
rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;
break;
}
rcParent = pParent->GetClientPos();
if( !::IntersectRect(&rcPos, &rcPos, &rcParent) ) {
rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;
break;
}
}
return rcPos;
}
LPCTSTR CEditCombo_EditWnd::GetWindowClassName() const
{
return _T("EditCombo_EditWnd");
}
LPCTSTR CEditCombo_EditWnd::GetSuperClassName() const
{
return WC_EDIT;
}
void CEditCombo_EditWnd::OnFinalMessage(HWND hWnd)
{
m_pOwner->Invalidate();
// Clear reference and die
if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);
m_pOwner->GetManager()->RemoveNativeWindow(hWnd);
m_pOwner->m_pEditWindow = NULL;
m_pOwner->EditDestroy();
delete this;
}
LRESULT CEditCombo_EditWnd