duilib Combo 支持 编辑

ComboEdit.h

#ifndef __UICOMBOEDIT_H__
#define __UICOMBOEDIT_H__
#pragma once

namespace DuiLib
{
    class CComboEditWnd;
    class DUILIB_API CComboEditUI:public CComboUI
    {
    public:
        CComboEditUI();
        LPCTSTR GetClass() const;
        LPVOID GetInterface(LPCTSTR pstrName);

    

        CDuiString GetText() const;


        void DoEvent(TEventUI& event);
        int  GetFont();
        void SetFont(int iFont);
        UINT GetTextStyle();
        void SetTextStyle(UINT iTextStyle);
        int  GetMaxChar();
        void SetMaxChar(int iMaxChar);
        DWORD  GetNativeEditBkColor();
        void SetNativeEditBkColor(DWORD dwColor);
        DWORD GetTextColor();
        void SetTextColor(DWORD dwColor);
        
        CDuiString m_sText;
        CComboEditWnd* m_pEditWnd;
        BOOL SelectItem(int iIndex, BOOL bTakeFocus = FALSE, BOOL bTriggerEvent = TRUE);
        void PaintText(HDC hDC);
    private:
        int GetCurSel() const;
        int m_iMaxChar;
        int m_iFont;
        UINT m_uTextStyle;
        DWORD m_dwNativeEditBkColor;
        DWORD m_dwTextColor;
        DWORD m_dwDisabledTextColor;
    };

}// end Duilib
#endif // __UICOMBOEDIT_H__

ComboEdit.cpp

#include "stdafx.h"
#include "UIComboEdit.h"
#include <olectl.h>

namespace DuiLib
{
	
	class DUILIB_API CComboEditWnd : public CWindowWnd
	{
	public:
		CComboEditWnd();

		void Init(CComboEditUI* 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,
		};

		CComboEditUI* m_pOwner;
		HBRUSH m_hBkBrush;
		BOOL m_bInit;
		BOOL m_bDrawCaret;
	};

	CComboEditWnd::CComboEditWnd() : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(FALSE), m_bDrawCaret(FALSE)
	{
	}

	void CComboEditWnd::Init(CComboEditUI* pOwner)
	{
		m_pOwner = pOwner;
		RECT rcPos = CalPos();
		UINT uStyle = WS_CHILD | ES_AUTOHSCROLL ;
		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;
		
		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());

		
		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);
		

		//Styls
		::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
		::SetFocus(m_hWnd);

		int nSize = GetWindowTextLength(m_hWnd);
		Edit_SetSel(m_hWnd, nSize, nSize);
	

		m_bInit = TRUE;
	}

	RECT CComboEditWnd::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 = m_pOwner;
		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 CComboEditWnd::GetWindowClassName() const
	{
		return _T("ComboEditWnd");
	}

	LPCTSTR CComboEditWnd::GetSuperClassName() const
	{
		return WC_EDIT;
	}

	void CComboEditWnd::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_pEditWnd= NULL;
		delete this;
	}

	LRESULT CComboEditWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		LRESULT lRes = 0;
		BOOL bHandled = TRUE;
		if (uMsg == WM_CREATE) {
			m_pOwner->GetManager()->AddNativeWindow(m_pOwner, m_hWnd);
			if (m_pOwner->GetManager()->IsLayered()) {
				::SetTimer(m_hWnd, DEFAULT_TIMERID, ::GetCaretBlinkTime(), NULL);
			}
			bHandled = FALSE;
		}
		else if (uMsg == WM_KILLFOCUS) lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
		else if (uMsg == OCM_COMMAND) {
			if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) lRes = OnEditChanged(uMsg, wParam, lParam, bHandled);
			else if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_UPDATE) {
				RECT rcClient;
				::GetClientRect(m_hWnd, &rcClient);
				::InvalidateRect(m_hWnd, &rcClient, FALSE);
			}
		}
		else if (uMsg == WM_KEYDOWN && TCHAR(wParam) == VK_RETURN) {
			m_pOwner->GetManager()->SendNotify(m_pOwner, DUI_MSGTYPE_RETURN);
		}
		else if (uMsg == OCM__BASE + WM_CTLCOLOREDIT || uMsg == OCM__BASE + WM_CTLCOLORSTATIC) {
			if (m_pOwner->GetManager()->IsLayered() && !m_pOwner->GetManager()->IsPainting()) {
				m_pOwner->GetManager()->AddNativeWindow(m_pOwner, m_hWnd);
			}
			DWORD clrColor = m_pOwner->GetNativeEditBkColor();
			if (clrColor == 0xFFFFFFFF) return 0;
			::SetBkMode((HDC)wParam, TRANSPARENT);
			DWORD dwTextColor = m_pOwner->GetTextColor();
			::SetTextColor((HDC)wParam, RGB(GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor)));
			if (clrColor < 0xFF000000) {
				if (m_hBkBrush != NULL) ::DeleteObject(m_hBkBrush);
				RECT rcWnd = m_pOwner->GetManager()->GetNativeWindowRect(m_hWnd);
				HBITMAP hBmpEditBk = CRenderEngine::GenerateBitmap(m_pOwner->GetManager(), rcWnd, m_pOwner, clrColor);
				m_hBkBrush = ::CreatePatternBrush(hBmpEditBk);
				::DeleteObject(hBmpEditBk);
			}
			else {
				if (m_hBkBrush == NULL) {
					m_hBkBrush = ::CreateSolidBrush(RGB(GetBValue(clrColor), GetGValue(clrColor), GetRValue(clrColor)));
				}
			}
			return (LRESULT)m_hBkBrush;
		}
		else if (uMsg == WM_PAINT) {
			if (m_pOwner->GetManager()->IsLayered()) {
				m_pOwner->GetManager()->AddNativeWindow(m_pOwner, m_hWnd);
			}
			bHandled = FALSE;
		}
		else if (uMsg == WM_PRINT) {
			if (m_pOwner->GetManager()->IsLayered()) {
				lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
				if (m_pOwner->IsEnabled() && m_bDrawCaret) { // todo:判断是否enabled
					RECT rcClient;
					::GetClientRect(m_hWnd, &rcClient);
					POINT ptCaret;
					::GetCaretPos(&ptCaret);
					RECT rcCaret = { ptCaret.x, ptCaret.y, ptCaret.x, ptCaret.y + rcClient.bottom - rcClient.top };
					CRenderEngine::DrawLine((HDC)wParam, rcCaret, 1, 0xFF000000);
				}
				return lRes;
			}
			bHandled = FALSE;
		}
		else if (uMsg == WM_TIMER) {
			if (wParam == DEFAULT_TIMERID) {
				m_bDrawCaret = !m_bDrawCaret;
				RECT rcClient;
				::GetClientRect(m_hWnd, &rcClient);
				::InvalidateRect(m_hWnd, &rcClient, FALSE);
				return 0;
			}
			bHandled = FALSE;
		}
		else bHandled = FALSE;
		if (!bHandled) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
		return lRes;
	}

	LRESULT CComboEditWnd::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;
	}

	LRESULT CComboEditWnd::OnEditChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if (!m_bInit) return 0;
		if (m_pOwner == NULL) return 0;
		// Copy text back
		int cchLen = ::GetWindowTextLength(m_hWnd) + 1;
		LPTSTR pstr = static_cast<LPTSTR>(_alloca(cchLen * sizeof(TCHAR)));
		ASSERT(pstr);
		if (pstr == NULL) return 0;
		::GetWindowText(m_hWnd, pstr, cchLen);
		m_pOwner->m_sText = pstr;
		m_pOwner->SetToolTip(pstr);
		
		m_pOwner->GetManager()->SendNotify(m_pOwner, DUI_MSGTYPE_TEXTCHANGED);
		if (m_pOwner->GetManager()->IsLayered()) m_pOwner->Invalidate();
		return 0;
	}


	CComboEditUI::CComboEditUI()
	{
		m_iMaxChar = -1;
		m_pEditWnd = NULL;
		m_iFont = 1;
		m_uTextStyle = DT_VCENTER | DT_SINGLELINE;
		m_dwNativeEditBkColor = 0x00000000;
		m_dwTextColor = 0x00000000;
		m_dwDisabledTextColor = 0;
	}

	LPCTSTR CComboEditUI::GetClass() const
	{
		return DUI_CTR_COMBOEDIT;
	}


	LPVOID CComboEditUI::GetInterface(LPCTSTR pstrName)
	{
		if (_tcscmp(pstrName, DUI_CTR_COMBO) == 0) return static_cast<CComboEditUI*>(this);
		return CComboUI::GetInterface(pstrName);
	}


	DuiLib::CDuiString CComboEditUI::GetText() const
	{
		return m_sText;
	}

	void CComboEditUI::DoEvent(TEventUI& event)
	{
		if (!IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND) {
			if (m_pParent != NULL) m_pParent->DoEvent(event);
			else CComboUI::DoEvent(event);
			return;
		}
		
		if (event.Type == UIEVENT_KILLFOCUS)
		{
			if (m_pEditWnd)
			{
				m_pEditWnd->ShowWindow(FALSE, FALSE);
			}
			
			return;
		}
		if ( event.Type == UIEVENT_DBLCLICK || event.Type== UIEVENT_RBUTTONDOWN)
		{
			
			
			if (m_pEditWnd)
			{
				m_pEditWnd->ShowWindow(TRUE, TRUE);
			}

			if (m_pEditWnd) return;
			m_pEditWnd = new CComboEditWnd();
			ASSERT(m_pEditWnd);
			m_pEditWnd->Init(this);

			
			
		}
		

		CComboUI::DoEvent(event);
	}

	int CComboEditUI::GetFont()
	{
		return m_iFont;
	}

	void CComboEditUI::SetFont(int iFont)
	{
		m_iFont = iFont;

	}

	UINT CComboEditUI::GetTextStyle()
	{
		return m_uTextStyle;
	}

	void CComboEditUI::SetTextStyle(UINT iTextStyle)
	{
		m_uTextStyle = iTextStyle;
	}

	int CComboEditUI::GetMaxChar()
	{
		return m_iMaxChar;
	}

	void CComboEditUI::SetMaxChar(int iMaxChar)
	{
		m_iMaxChar = iMaxChar;
	}

	DWORD CComboEditUI::GetNativeEditBkColor()
	{
		return m_dwNativeEditBkColor;
	}

	void CComboEditUI::SetNativeEditBkColor(DWORD dwColor)
	{
		m_dwNativeEditBkColor = dwColor;
	}

	DWORD CComboEditUI::GetTextColor()
	{
		return m_dwTextColor;
	}

	void CComboEditUI::SetTextColor(DWORD dwColor)
	{
		m_dwTextColor = dwColor;
	}



	BOOL CComboEditUI::SelectItem(int iIndex, BOOL bTakeFocus /*= FALSE*/, BOOL bTriggerEvent /*= TRUE*/)
	{
		if (m_bSelectCloseFlag && m_pWindow != NULL) m_pWindow->Close();
		if (iIndex == m_iCurSel) return TRUE;
		int iOldSel = m_iCurSel;
		if (m_iCurSel >= 0) {
			CControlUI* pControl = static_cast<CControlUI*>(m_items[m_iCurSel]);
			if (!pControl) return FALSE;
			
			IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
			if (pListItem != NULL) pListItem->Select(FALSE, bTriggerEvent);
			m_iCurSel = -1;
		}
		if (iIndex < 0) return FALSE;
		if (m_items.GetSize() == 0) return FALSE;
		if (iIndex >= m_items.GetSize()) iIndex = m_items.GetSize() - 1;
		CControlUI* pControl = static_cast<CControlUI*>(m_items[iIndex]);
		if (!pControl || !pControl->IsVisible() || !pControl->IsEnabled()) return FALSE;
		
		m_sText = pControl->GetText();
		SetToolTip(m_sText);
		IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
		if (pListItem == NULL) return FALSE;
		m_iCurSel = iIndex;
		if (m_pWindow != NULL || bTakeFocus) pControl->SetFocus();
		pListItem->Select(TRUE, bTriggerEvent);
		if (m_pManager != NULL && bTriggerEvent) m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMSELECT, m_iCurSel, iOldSel);
		
		
		Invalidate();
		return TRUE;
	}

	void CComboEditUI::PaintText(HDC hDC)
	{
		if (!m_bShowText)
		{
			return;
		}
		if (m_pEditWnd && IsWindowVisible(m_pEditWnd->GetHWND()))
		{
			return;
		}
		RECT rcText = m_rcItem;
		rcText.left += m_rcTextPadding.left;
		rcText.right -= m_rcTextPadding.right;
		rcText.top += m_rcTextPadding.top;
		rcText.bottom -= m_rcTextPadding.bottom;

		if (m_iCurSel >= 0) {
			CListLabelElementUI* pControl = static_cast<CListLabelElementUI*>(m_items[m_iCurSel]);
			
			if (pControl)
			{
				CDuiString strIcon = pControl->GetIcon();
				SIZE szIcon = pControl->GetIconSize();
				if (strIcon != _T(""))
				{
					IListOwnerUI* pOwner = pControl->GetOwner();
					if (pOwner == NULL) return;
					TListInfoUI* pInfo = pOwner->GetListInfo();
					if (pInfo == NULL) return;

					int left, right;
					left =0;
					right = left + szIcon.cx;
					TDrawInfo	diIcon;
					CDuiString pStrImage;
					int bottom, top = (rcText.bottom - rcText.top - szIcon.cy) / 2;
					bottom = top + szIcon.cy;
					pStrImage.SmallFormat(_T("file='%s' dest='%d,%d,%d,%d'"), strIcon.GetData(), left, top, right, bottom);
					diIcon.Clear();
					diIcon.sDrawString = pStrImage;
					CRenderEngine::DrawImage(hDC, m_pManager, rcText, m_rcPaint, diIcon);
					m_uTextStyle |=  pInfo->uTextStyle;
				}
				
				rcText.left += szIcon.cx;
			}
			

		}

		if (m_dwTextColor == 0) m_dwTextColor = m_pManager->GetDefaultFontColor();
		if (m_dwDisabledTextColor == 0) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();

		if (m_sText.IsEmpty()) return;

		
		
		
		if (IsEnabled()) {
			CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \
				m_iFont, DT_SINGLELINE | m_uTextStyle);
		}
		else {
			CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, m_dwDisabledTextColor, \
				m_iFont, DT_SINGLELINE | m_uTextStyle);

		}
	}
	

	int CComboEditUI::GetCurSel() const
	{
		return -1;
	}

}// end duilib

  效果,右键或者双击启动编辑功能

<Default name="ComboEdit"  value="normalimage=&quot;file='res\buttons\combo_normal.png' corner='20,0,20,0'&quot; hotimage=&quot;file='res\buttons\combo_down.png' corner='20,0,20,0'&quot; pushedimage=&quot;file='res\buttons\combo_down.png' corner='20,0,20,0'&quot; vscrollbar=&quot;true&quot; textpadding=&quot;6,0,20,0&quot; itemtextpadding=&quot;6,0,0,0&quot; " />

 

posted @ 2018-07-05 17:21  m4sterx  阅读(1692)  评论(4编辑  收藏  举报