Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

控件不响应接收不到 #463

Open
alancaven opened this issue Nov 12, 2022 · 2 comments
Open

控件不响应接收不到 #463

alancaven opened this issue Nov 12, 2022 · 2 comments

Comments

@alancaven
Copy link

移植原版DUILIB的EDIT控件时,发现EDIT的窗口无法接收到OCM_COMMAND消息,请问需要怎样解决

@nmgwddj
Copy link
Collaborator

nmgwddj commented Nov 17, 2022

请将您移植的代码示例通过示例代码的方式或者仓库的方式提供,我们一起来看一下。

@alancaven
Copy link
Author

`#ifndef UIEDIT_H
#define UIEDIT_H

#pragma once

namespace ui
{
class EditWnd;

class UILIB_API EditUI : public Control
{
	friend class EditWnd;
public:
	EditUI();
	/// 重写父类方法,提供个性化功能,请参考父类声明
	virtual std::wstring GetType() const override;
	virtual void DoInit() override;
	virtual UINT GetControlFlags() const override;
	virtual void HandleMessage(EventArgs& msg) override;
	virtual void SetAttribute(const std::wstring& strName, const std::wstring& strValue) override;
	/// 渲染部分
	virtual void PaintText(IRenderContext* pRender) override;
	virtual void PaintChild(IRenderContext* pRender, const UiRect& rcPaint) override;
	virtual void PaintStatusImage(IRenderContext* pRender) override;

	void SetEnabled(bool bEnable = true);
	void SetMaxChar(UINT uMax);
	UINT GetMaxChar();
	void SetReadOnly(bool bReadOnly);
	bool IsReadOnly() const;
	void SetPasswordMode(bool bPasswordMode);
	bool IsPasswordMode() const;
	void SetPasswordChar(TCHAR cPasswordChar);
	TCHAR GetPasswordChar() const;
	void SetNumberOnly(bool bNumberOnly);
	bool IsNumberOnly() const;
	void SetLowerCase(bool bLowerCase);
	bool IsLowerCase() const;
	void SetUpperCase(bool bUpperCase);
	bool IsUpperCase() const;
	int GetWindowStyls() const;

	void SetNativeEditBkColor(DWORD dwBkColor);
	DWORD GetNativeEditBkColor() const;
	void SetNativeEditTextColor( LPCTSTR pStrColor );
	DWORD GetNativeEditTextColor() const;

	void SetPos(RECT rc, bool bNeedInvalidate = true);
	void SetVisible(bool bVisible = true);
	void SetInternVisible(bool bVisible = true);

	virtual std::wstring GetText() const;
	virtual void SetText(const std::wstring& strText);
	/**
	 * @brief 设置文本样式
	 * @param[in] uStyle 要设置的样式
	 * @return 无
	 */
	void SetTextStyle(UINT uStyle);

	/**
	 * @brief 获取文本样式
	 * @return 返回文本样式
	 */
	UINT GetTextStyle() const;
	/**
	 * @brief 获取文字边距
	 * @return 返回文字的边距信息
	 */
	UiRect GetTextPadding() const;

	/**
	 * @brief 设置文字边距信息
	 * @param[in] rc 边距信息
	 * @return 无
	 */
	void SetTextPadding(UiRect rc);

	/**
	 * @brief 获取当前字体编号
	 * @return 返回字体编号,该编号在 global.xml 中标识
	 */
	std::wstring GetFont() const;

	/**
	 * @brief 设置当前字体
	 * @param[in] index 要设置的字体编号,该编号必须在 global.xml 中存在
	 * @return 无
	 */
	void SetFont(const std::wstring& strFontId);
	/**
	 * @brief 设置是否显示提示文字
	 * @param[in] bPrompt 设置为 true 为显示,false 为不显示
	 * @return 无
	 */
	void SetPromptMode(bool bPrompt);

	/**
	 * @brief 获取提示文字
	 * @return 返回提示文字内容
	 */
	std::wstring GetPromptText() const;
	/**
	 * @brief 设置提示文字
	 * @param[in] strText 要设置的提示文字
	 * @return 无
	 */
	void SetPromptText(const std::wstring& strText);
	/**
	 * @brief 绘制提示文字
	 * @param[in] pRender 绘制引擎
	 * @return 无
	 */
	void PaintPromptText(IRenderContext* pRender);
	/**
	 * @brief 创建光标
	 * @param[in] xWidth 光标宽度
	 * @param[in] yHeight 光标高度
	 * @return 成功返回 true,失败返回 false
	 */
	BOOL CreateCaret(INT xWidth, INT yHeight);

	/**
	 * @brief 设置是否显示光标
	 * @param[in] fShow 设置 true 为显示,false 为不显示
	 * @return 成功返回 true,失败返回 false
	 */
	BOOL ShowCaret(BOOL fShow);

	/**
	 * @brief 设置光标颜色
	 * @param[in] dwColor 要设置的颜色值,该值必须在 global.xml 中存在
	 * @return 无
	 */
	void SetCaretColor(const std::wstring& dwColor);

	/**
	 * @brief 获取光标颜色
	 * @return 返回光标颜色
	 */
	std::wstring GetCaretColor();

	/**
	 * @brief 获取光标矩形位置
	 * @return 返回光标矩形位置
	 */
	RECT GetCaretRect();

	/**
	 * @brief 设置光标位置
	 * @param[in] x X 轴坐标
	 * @param[in] y Y 轴坐标
	 * @return 成功返回 true,失败返回 false
	 */
	BOOL SetCaretPos(INT x, INT y);

	/**
	 * @brief 切换光标是否显示
	 * @return 无
	 */
	void ChangeCaretVisiable();

	/**
	 * @brief 切换光标是否显示
	 * @return 无
	 */
	bool IsCaretVisiable() { return m_bIsCaretVisiable; }

	/**
	 * @brief 绘制光标
	 * @param[in] pRender 绘制引擎
	 * @param[in] rcPaint 绘制位置
	 * @return 无
	 */
	void PaintCaret(IRenderContext* pRender, const UiRect& rcPaint);

	/**
	 * @brief 设置只读模式不显示光标
	 * @return 无
	 */
	void SetNoCaretReadonly();

protected:
	bool	m_bInited;
	EditWnd* m_pWindow;

	UINT m_uMaxChar;
	bool m_bReadOnly;
	bool m_bPasswordMode;
	TCHAR m_cPasswordChar;
	UINT m_uButtonState;
	DWORD m_dwEditbkColor;
	DWORD m_dwEditTextColor;
	int m_iWindowStyls;
	//
	std::wstring	m_sText;
	std::wstring m_sFontId;
	UiRect	m_rcTextPadding;
	UINT	m_uTextStyle;
	//编辑框提示信息
	bool m_bAllowPrompt;
	std::wstring m_sPromptColor;
	std::wstring m_sPromptText;
	//光标相关
	bool m_bNoCaretReadonly;
	bool m_bIsCaretVisiable;
	int	 m_iCaretPosX;
	int  m_iCaretPosY;
	int  m_iCaretWidth;
	int  m_iCaretHeight;
	std::wstring m_sCaretColor;
	nbase::WeakCallbackFlag m_drawCaretFlag;
};

}
#endif // UIEDIT_H

#include "StdAfx.h"
#include "Edit.h"
#include <Windowsx.h>

namespace ui
{
class EditWnd : public Window
{

public:
	EditWnd();

	void Init(EditUI* pOwner);
	RECT CalPos();

	virtual std::wstring GetWindowClassName() const override;
	virtual std::wstring GetSuperClassName() const override;
	virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
	LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

protected:
	virtual void OnFinalMessage(HWND hWnd) override;


protected:
	EditUI* m_pOwner;
	HBRUSH m_hBkBrush;
	bool m_bInit;
};

EditWnd::EditWnd() : 
	m_pOwner(nullptr),
	m_hBkBrush(NULL),
	m_bInit(false)
{
}

void EditWnd::Init(EditUI* pOwner)
{
	m_pOwner = pOwner;
	ui::UiRect rcPos = CalPos();
	UINT uStyle = 0;
	if(m_pOwner->GetWindow()->IsLayeredWindow()) 
	{
		uStyle = WS_POPUP | ES_AUTOHSCROLL | WS_VISIBLE;
		RECT rcWnd = { 0 };
		::GetWindowRect(m_pOwner->GetWindow()->GetHWND(), &rcWnd);
		rcPos.left += rcWnd.left;
		rcPos.right += rcWnd.left;
		rcPos.top += rcWnd.top - 1;
		rcPos.bottom += rcWnd.top - 1;
	}
	else 
	{
		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;
	if( m_pOwner->IsPasswordMode() ) uStyle |= ES_PASSWORD;
	Create(m_pOwner->m_pWindow->GetHWND(), NULL, uStyle, 0, m_pOwner->GetWindow()->IsLayeredWindow(), rcPos);

	HFONT hFont = GlobalManager::GetFont(m_pOwner->GetFont());
	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().c_str());
	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
	LONG styleValue = ::GetWindowLong(m_hWnd, GWL_STYLE);
	styleValue |= pOwner->GetWindowStyls();
	::SetWindowLong(GetHWND(), GWL_STYLE, styleValue);
	::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
	::SetFocus(m_hWnd);
	m_bInit = true;
}

RECT EditWnd::CalPos()
{
	UiRect 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 = GlobalManager::GetTFontInfo(m_pOwner->GetFont())->tm.tmHeight;
	if (lEditHeight < rcPos.GetHeight()) {
		rcPos.top += (rcPos.GetHeight() - lEditHeight) / 2;
		rcPos.bottom = rcPos.top + lEditHeight;
	}
	return rcPos;
}

std::wstring EditWnd::GetWindowClassName() const
{
	return _T("EditWnd");
}

std::wstring EditWnd::GetSuperClassName() const
{
	return WC_EDIT;
}

void EditWnd::OnFinalMessage(HWND hWnd)
{
	m_pOwner->Invalidate();
	// Clear reference and die
	if (m_hBkBrush != NULL) ::DeleteObject(m_hBkBrush);
	m_pOwner->m_pWindow = NULL;
	delete this;
}

LRESULT EditWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	//char szDebug[32];
	//sprintf(szDebug, "uMsg:%d", uMsg);
	//OutputDebugStringA(szDebug);

	LRESULT lRes = 0;
	BOOL bHandled = TRUE;
	if (uMsg == WM_KILLFOCUS) lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
	else if( uMsg == OCM_COMMAND ) 
	{
		OutputDebugStringA("OCM_COMMAND");
		if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
		{
			OutputDebugStringA("EN_CHANGE");
			lRes = OnEditChanged(uMsg, wParam, lParam, bHandled);
		}
		else if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_UPDATE ) {
			OutputDebugStringA("EN_UPDATE");
			RECT rcClient;
			::GetClientRect(m_hWnd, &rcClient);
			::InvalidateRect(m_hWnd, &rcClient, FALSE);
		}
	}
	else if (uMsg == WM_NOTIFY)
	{
		OutputDebugStringA("WM_NOTIFY");
	}
	else if( uMsg == WM_KEYDOWN && TCHAR(wParam) == VK_RETURN ){
		m_pOwner->GetWindow()->SendNotify(m_pOwner, kEventReturn);
	}
	else if( uMsg == WM_KEYDOWN && TCHAR(wParam) == VK_TAB ){
		if (m_pOwner->GetWindow()->IsLayeredWindow()) 
		{
			m_pOwner->GetWindow()->SetNextTabControl();
		}
	}
	else if( uMsg == OCM__BASE + WM_CTLCOLOREDIT  || uMsg == OCM__BASE + WM_CTLCOLORSTATIC ) {
		if (m_pOwner->GetNativeEditBkColor() == 0xFFFFFFFF) return NULL;
		::SetBkMode((HDC)wParam, TRANSPARENT);

		DWORD dwTextColor;
		if (m_pOwner->GetNativeEditTextColor() != 0x000000)
			dwTextColor = m_pOwner->GetNativeEditTextColor();
		else
			dwTextColor = 0xFFFFFFFF;// m_pOwner->GetTextColor();

		::SetTextColor((HDC)wParam, RGB(GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor)));
		if (m_hBkBrush == NULL) {
			DWORD clrColor = m_pOwner->GetNativeEditBkColor();
			m_hBkBrush = ::CreateSolidBrush(RGB(GetBValue(clrColor), GetGValue(clrColor), GetRValue(clrColor)));
		}
		return (LRESULT)m_hBkBrush;
	}
	else bHandled = FALSE;

	if (!bHandled) return Window::HandleMessage(uMsg, wParam, lParam);
	return lRes;
}

LRESULT EditWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
	PostMessage(WM_CLOSE);
	return lRes;
}

LRESULT EditWnd::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);
	OutputDebugString(pstr);

	m_pOwner->m_sText = pstr;
	m_pOwner->GetWindow()->SendNotify(m_pOwner, kEventTextChange);
	return 0;
}


/////////////////////////////////////////////////////////////////////////////////////
//
//
EditUI::EditUI() : 
	m_bInited(false),
	m_pWindow(NULL), 
	m_uMaxChar(255), 
	m_bReadOnly(false),
	m_bPasswordMode(false), 
	m_cPasswordChar(_T('*')), 
	m_uButtonState(0), 
	m_dwEditbkColor(0xFFFFFFFF), 
	m_dwEditTextColor(0x00000000), 
	m_iWindowStyls(0),
	m_bNoCaretReadonly(false),
	m_bIsCaretVisiable(false),
	m_iCaretPosX(0),
	m_iCaretPosY(0),
	m_iCaretWidth(0),
	m_iCaretHeight(0),
	m_drawCaretFlag(),
	m_sFontId(),
	m_sText(),
	m_uTextStyle(DT_LEFT | DT_TOP | DT_END_ELLIPSIS | DT_NOCLIP | DT_SINGLELINE),
	m_rcTextPadding(),
	m_bAllowPrompt(false),
	m_sPromptText(),
	m_sPromptColor()
{
	SetTextPadding(ui::UiRect(4, 3, 4, 3));
	SetBkColor(L"white");
}

std::wstring EditUI::GetType() const
{
	return DUI_CTR_EDIT;
}


void EditUI::DoInit()
{
	if (m_bInited)
		return;
	//创建光标
	CreateCaret(1, (INT)(GlobalManager::GetTFontInfo(GetFont())->tm.tmHeight));

	m_bInited = true;

}
UINT EditUI::GetControlFlags() const
{
	return IsEnabled() && IsAllowTabStop() ? UIFLAG_TABSTOP : UIFLAG_DEFAULT;
}

void EditUI::HandleMessage(EventArgs& event)
{
	if( !IsMouseEnabled() && event.Type > kEventMouseBegin && event.Type < kEventMouseEnd ) {
		if (m_pParent != NULL) m_pParent->HandleMessageTemplate(event);
		else __super::HandleMessage(event);
		return;
	}

	if( event.Type == kEventSetCursor && IsEnabled() )
	{
		::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)));
		return;
	}
	if( event.Type == kEventWindowSize )
	{
		if (m_pWindow != NULL)
		{
			m_pWindow->SetFocusNeeded(this);
		}
	}
	if( event.Type == kEventMouseScrollWheel )
	{
		if( m_pWindow != NULL ) return;
	}
	if( event.Type == kEventSetFocus && IsEnabled() ) 
	{
		ShowCaret(true);

		if(m_pWindow) return;
		m_pWindow = new EditWnd();
		ASSERT(m_pWindow);
		m_pWindow->Init(this);
		OutputDebugStringA("kEventSetFocus");

		Invalidate();
	}
	if( event.Type == kEventKillFocus && IsEnabled() ) 
	{
		ShowCaret(false);
		OutputDebugStringA("kEventKillFocus");
		Invalidate();
	}
	if( event.Type == kEventMouseButtonDown || event.Type == kEventMouseDoubleClick || event.Type == kEventMouseRightButtonDown) 
	{
		if( IsEnabled() ) {
			GetWindow()->ReleaseCapture();
			if( IsFocused() && m_pWindow == NULL )
			{
				m_pWindow = new EditWnd();
				ASSERT(m_pWindow);
				m_pWindow->Init(this);

				if( PtInRect(&m_rcItem, event.ptMouse) )
				{
					int nSize = GetWindowTextLength(m_pWindow->GetHWND());
					if( nSize == 0 ) nSize = 1;
					Edit_SetSel(m_pWindow->GetHWND(), 0, nSize);
				}
				else if (m_pWindow != NULL)
				{

#if 1
int nSize = GetWindowTextLength(m_pWindow->GetHWND());
if (nSize == 0)
nSize = 1;

					Edit_SetSel(m_pWindow->GetHWND(), 0, nSize);

#else
POINT pt = event.ptMouse;
pt.x -= m_rcItem.left + m_rcTextPadding.left;
pt.y -= m_rcItem.top + m_rcTextPadding.top;
::SendMessage(*m_pWindow, WM_LBUTTONDOWN, event.wParam, MAKELPARAM(pt.x, pt.y));
#endif
}
}
}
return;
}
if (event.Type == kEventMouseMove)
{
return;
}
if (event.Type == kEventMouseButtonUp)
{
return;
}
if (event.Type == kEventMouseMenu)
{
return;
}
__super::HandleMessage(event);
}

std::wstring EditUI::GetText() const
{
	return m_sText;
}

void EditUI::SetText(const std::wstring& strText)
{
	m_sText = strText;
	if (m_pWindow != NULL) Edit_SetText(m_pWindow->GetHWND(), m_sText.c_str());
	Invalidate();
}

std::wstring EditUI::GetFont() const
{
	return m_sFontId;
}

void EditUI::SetFont(const std::wstring& strFontId)
{
	m_sFontId = strFontId;
	this->Invalidate();
}
void EditUI::SetEnabled(bool bEnable)
{
	__super::SetEnabled(bEnable);
	if( !IsEnabled() ) {
		m_uButtonState = 0;
	}
}

UiRect EditUI::GetTextPadding() const
{
	return m_rcTextPadding;
}

void EditUI::SetTextPadding(UiRect rc)
{
	DpiManager::GetInstance()->ScaleRect(rc);
	m_rcTextPadding = rc;
	if (this->GetFixedWidth() == DUI_LENGTH_AUTO || this->GetFixedHeight() == DUI_LENGTH_AUTO) {
		this->ArrangeAncestor();
	}
	else {
		this->Invalidate();
	}
}

void EditUI::SetMaxChar(UINT uMax)
{
	m_uMaxChar = uMax;
	if( m_pWindow != NULL ) Edit_LimitText(m_pWindow->GetHWND(), m_uMaxChar);
}

UINT EditUI::GetMaxChar()
{
	return m_uMaxChar;
}

void EditUI::SetReadOnly(bool bReadOnly)
{
	if( m_bReadOnly == bReadOnly ) return;

	m_bReadOnly = bReadOnly;
	if( m_pWindow != NULL ) Edit_SetReadOnly(m_pWindow->GetHWND(), m_bReadOnly);
	Invalidate();
}

bool EditUI::IsReadOnly() const
{
	return m_bReadOnly;
}

void EditUI::SetNumberOnly(bool bNumberOnly)
{
	if( bNumberOnly )
	{
		m_iWindowStyls |= ES_NUMBER;
	}
	else
	{
		m_iWindowStyls &= ~ES_NUMBER;
	}
}

bool EditUI::IsNumberOnly() const
{
	return (m_iWindowStyls & ES_NUMBER) ? true:false;
}

void EditUI::SetLowerCase(bool bLowerCase)
{
	if( bLowerCase )
	{
		m_iWindowStyls |= ES_LOWERCASE;
	}
	else
	{
		m_iWindowStyls &= ~ES_LOWERCASE;
	}
}
bool EditUI::IsLowerCase() const { return (m_iWindowStyls & ES_LOWERCASE) ? true:false; }

void EditUI::SetUpperCase(bool bUpperCase)
{
	if( bUpperCase )
	{
		m_iWindowStyls |= ES_UPPERCASE;
	}
	else
	{
		m_iWindowStyls &= ~ES_UPPERCASE;
	}
}
bool EditUI::IsUpperCase() const { return (m_iWindowStyls & ES_UPPERCASE) ? true:false; }

int EditUI::GetWindowStyls() const 
{
	return m_iWindowStyls;
}

void EditUI::SetPasswordMode(bool bPasswordMode)
{
	if( m_bPasswordMode == bPasswordMode ) return;
	m_bPasswordMode = bPasswordMode;
	Invalidate();
	if( m_pWindow != NULL ) {
		LONG styleValue = ::GetWindowLong(m_pWindow->GetHWND(), GWL_STYLE);
		bPasswordMode ? styleValue |= ES_PASSWORD : styleValue &= ~ES_PASSWORD;
		::SetWindowLong(m_pWindow->GetHWND(), GWL_STYLE, styleValue);
	}
}

bool EditUI::IsPasswordMode() const
{
	return m_bPasswordMode;
}

void EditUI::SetPasswordChar(TCHAR cPasswordChar)
{
	if( m_cPasswordChar == cPasswordChar ) return;
	m_cPasswordChar = cPasswordChar;
	if( m_pWindow != NULL ) Edit_SetPasswordChar(m_pWindow->GetHWND(), m_cPasswordChar);
	Invalidate();
}

TCHAR EditUI::GetPasswordChar() const
{
	return m_cPasswordChar;
}

void EditUI::SetNativeEditBkColor(DWORD dwBkColor)
{
	m_dwEditbkColor = dwBkColor;
}

DWORD EditUI::GetNativeEditBkColor() const
{
	return m_dwEditbkColor;
}

void EditUI::SetNativeEditTextColor( LPCTSTR pStrColor )
{
	if( *pStrColor == _T('#')) pStrColor = ::CharNext(pStrColor);
	LPTSTR pstr = NULL;
	DWORD clrColor = _tcstoul(pStrColor, &pstr, 16);

	m_dwEditTextColor = clrColor;
}

DWORD EditUI::GetNativeEditTextColor() const
{
	return m_dwEditTextColor;
}

void EditUI::SetTextStyle(UINT uStyle)
{
	m_uTextStyle = uStyle;
	this->Invalidate();
}

UINT EditUI::GetTextStyle() const
{
	return m_uTextStyle;
}

void EditUI::SetPos(RECT rc, bool bNeedInvalidate)
{
	__super::SetPos(rc);
	if( m_pWindow != NULL ) {
		RECT rcPos = m_pWindow->CalPos();
		::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left, 
			rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE);        
	}
}

void EditUI::SetVisible(bool bVisible)
{
	__super::SetVisible(bVisible);
	if( !IsVisible() && m_pWindow != NULL ) m_pWindow->SetFocus(NULL);
}

void EditUI::SetInternVisible(bool bVisible)
{
	if( !IsVisible() && m_pWindow != NULL ) m_pWindow->SetFocus(NULL);
}

void EditUI::SetAttribute(const std::wstring& strName, const std::wstring& strValue)
{
	if(strName == _T("readonly")) SetReadOnly(strValue == _T("true"));
	else if(strName ==  _T("numberonly")) SetNumberOnly(strValue == _T("true"));
	else if(strName ==  _T("password")) SetPasswordMode(strValue == _T("true"));
	else if (strName == _T("passwordchar"))
	{
		LPCTSTR pValue = strValue.c_str();
		SetPasswordChar(*pValue);
	}
	else if(strName ==  _T("maxchar")) SetMaxChar(_ttoi(strValue.c_str()));
	else if(strName ==  _T("lowercase")) SetLowerCase(strValue == _T("true"));
	else if(strName ==  _T("uppercase")) SetUpperCase(strValue == _T("true"));
	else if (strName == L"caretcolor") {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		SetCaretColor(pValue);
	}
	else if (strName == _T("promptmode")) {
		if (strValue == _T("true"))
			m_bAllowPrompt = true;
	}
	else if (strName == _T("promptcolor")) {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		m_sPromptColor = pValue;
	}
	else if (strName == _T("prompttext")) SetPromptText(strValue);
	else if (strName == _T("font")) SetFont(strValue);
	else if (strName == _T("text")) SetText(strValue.c_str());
	else if (strName == _T("textpadding")) {
		UiRect rcPadding;
		LPTSTR pstr = NULL;
		rcPadding.left = _tcstol(strValue.c_str(), &pstr, 10);  ASSERT(pstr);
		rcPadding.top = _tcstol(pstr + 1, &pstr, 10);    ASSERT(pstr);
		rcPadding.right = _tcstol(pstr + 1, &pstr, 10);  ASSERT(pstr);
		rcPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
		SetTextPadding(rcPadding);
	}
	//else if(strName ==  _T("nativetextcolor")) SetNativeEditTextColor(pstrValue);
	/*else if(strName ==  _T("nativebkcolor")) {
		if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
		LPTSTR pstr = NULL;
		DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
		SetNativeEditBkColor(clrColor);
	}*/
	else __super::SetAttribute(strName, strValue);
}

void EditUI::SetPromptMode(bool bPrompt)
{
	if (bPrompt == m_bAllowPrompt)
		return;
	m_bAllowPrompt = bPrompt;
	Invalidate();
}

std::wstring EditUI::GetPromptText() const
{
	return m_sPromptText;
}

void EditUI::SetPromptText(const std::wstring& strText)
{
	if (m_sPromptText == strText) return;
	m_sPromptText = strText;

	Invalidate();
}

BOOL EditUI::CreateCaret(INT xWidth, INT yHeight)
{
	m_iCaretWidth = xWidth;
	m_iCaretHeight = yHeight;
	return true;
}

BOOL EditUI::ShowCaret(BOOL fShow)
{
	if (fShow) {
		m_bIsCaretVisiable = true;
		m_drawCaretFlag.Cancel();
		std::function<void()> closure = nbase::Bind(&EditUI::ChangeCaretVisiable, this);
		TimerManager::GetInstance()->AddCancelableTimer(m_drawCaretFlag.GetWeakFlag(), closure, 500, TimerManager::REPEAT_FOREVER);
	}
	else {
		m_bIsCaretVisiable = false;
		m_drawCaretFlag.Cancel();
	}

	Invalidate();
	return true;
}

void EditUI::SetCaretColor(const std::wstring& dwColor)
{
	m_sCaretColor = dwColor;
}

std::wstring EditUI::GetCaretColor()
{
	return m_sCaretColor;
}

RECT EditUI::GetCaretRect()
{
	RECT rc = { m_iCaretPosX, m_iCaretPosY, m_iCaretPosX + m_iCaretWidth, m_iCaretPosY + m_iCaretHeight };
	return rc;
}

BOOL EditUI::SetCaretPos(INT x, INT y)
{
	m_iCaretPosX = x;
	m_iCaretPosY = y;
	//ShowCaret(GetSelText().empty());

	return true;
}

void EditUI::ChangeCaretVisiable()
{
	m_bIsCaretVisiable = !m_bIsCaretVisiable;
	Invalidate();
}

void EditUI::PaintCaret(IRenderContext* pRender, const UiRect& rcPaint)
{
	if (m_bReadOnly && m_bNoCaretReadonly)
		return;

	if (m_bIsCaretVisiable) {
		UiRect rect(m_iCaretPosX, m_iCaretPosY, m_iCaretPosX, m_iCaretPosY + m_iCaretHeight);
		DWORD dwClrColor = 0xff000000;

		if (!m_sCaretColor.empty())
			dwClrColor = this->GetWindowColor(m_sCaretColor);

		pRender->DrawLine(rect, m_iCaretWidth, dwClrColor);
	}
}
void EditUI::SetNoCaretReadonly()
{
	m_bNoCaretReadonly = true;
}

void EditUI::PaintChild(IRenderContext* pRender, const UiRect& rcPaint)
{
	UiRect rcTemp;
	if (!::IntersectRect(&rcTemp, &rcPaint, &m_rcItem)) return;

	PaintCaret(pRender, rcPaint);
}

void EditUI::PaintPromptText(IRenderContext* pRender)
{
	if (m_sText.size() != 0)
		return;

	if (!m_pWindow)
		return;

	std::wstring strPrompt = GetPromptText();
	if (strPrompt.empty() || m_sPromptColor.empty())
		return;

	UiRect rc = this->m_rcItem;
	rc.left += m_rcTextPadding.left;
	rc.right -= m_rcTextPadding.right;
	rc.top += m_rcTextPadding.top;
	rc.bottom -= m_rcTextPadding.bottom;

	DWORD dwClrColor = this->GetWindowColor(m_sPromptColor);
	UINT dwStyle = DT_NOCLIP;
	pRender->DrawText(rc, strPrompt, dwClrColor, m_sFontId, dwStyle, 255, false, false, IsD2DRender());
}

void EditUI::PaintStatusImage(IRenderContext* pRender)
{
	if (IsFocused()) {
		PaintPromptText(pRender);
		return;
	}
	__super::PaintStatusImage(pRender);
	PaintPromptText(pRender);
}

void EditUI::PaintText(IRenderContext* pRender)
{
	if (GetText().empty()) return;

	std::wstring sDrawText = GetText();
	if (m_bPasswordMode)
	{
		std::wstring sTemp = sDrawText;
		sDrawText.empty();
		LPCTSTR pStr = sTemp.c_str();
		while (*pStr != _T('\0')) {
			sDrawText += m_cPasswordChar;
			pStr = ::CharNext(pStr);
		}
	}

	//if (m_bSingleLine)
	//	m_uTextStyle |= DT_SINGLELINE;
	//else
		m_uTextStyle &= ~DT_SINGLELINE;

	ui::UiRect rc = m_rcItem;
	rc.left += m_rcTextPadding.left;
	rc.right -= m_rcTextPadding.right;
	rc.top += m_rcTextPadding.top;
	rc.bottom -= m_rcTextPadding.bottom;

	DWORD dwClrColor = this->GetWindowColor(m_sPromptColor);

	pRender->DrawText(rc, GetText(), dwClrColor, m_sFontId, m_uTextStyle, 255, false, false, IsD2DRender());
}

}

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants