CEdit有一个函数SetLimitText,设置允许在文本框中输入的字符的最大数量,这个函数的限制是把中文字符当作一个字节来处理。
如果要把汉字当作两个字节处理,需要派生一个编辑框类CCheckEdit。重载OnChar函数,在此函数中处理。
void CCheckEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//判断是否按住CTRL键
SHORT nVK = GetKeyState(VK_CONTROL) ;
CString strText = L"";
GetWindowText(strText);
int nAOldLen = (int)strlen(CW2A(strText));
//...
int nWFirstSel = LOWORD(GetSel());
int nWLastSel = HIWORD(GetSel());
CString strLeft = strText.Left(nWFirstSel);
CString strRight = strText.Right(strText.GetLength() - nWLastSel);
//还能允许写入多少字节
int nADiscLen = GetLimitText() - ((int)strlen(CW2A(strLeft)) + (int)strlen(CW2A(strRight)));
if (nVK < 0)//CTRL按下,高位为1,即为负数
{
switch (nChar)
{
case 1://CTRL + A
{
SetSel(0,strText.GetLength(),0);
break;
}
case 3://CTRL + C
{
Copy();
break;
}
case 22://CTRL + V
{
if (nADiscLen == 0)
{
break;
}
//获得剪切板数据
OpenClipboard();
HANDLE hData = GetClipboardData(CF_TEXT);
char *pData = (char *)GlobalLock(hData);
std::string strTemp = pData;
GlobalUnlock(hData);
CloseClipboard();
//获得可写入的文本
std::basic_string<char> substring = strTemp.substr(0,nADiscLen);
//由于输入点可能不在文本结尾,需要重新组合文本
CString strSubString = CA2W(substring.c_str());
if (strRight.GetLength() == 0)
{
strText.Format(_T("%s%s"),strLeft,CA2W(substring.c_str()));
}
else
{
strText.Format(_T("%s%s%s"),strLeft,strSubString,strRight);
}
SetWindowText(strText);
SetSel(strText.GetLength() - strRight.GetLength(),strText.GetLength() - strRight.GetLength());
break;
}
case 24://CTRL + X
{
Cut();
break;
}
case 26://CTRL + Z
{
if (CanUndo())
{
Undo();
}
break;
}
default:
{
break;
}
}
}
else
{
switch (nChar)
{
case VK_BACK:
{
return CEdit::OnChar(nChar, nRepCnt, nFlags);
}
default:
{
if (nChar > 127)
{
//输入了汉字
if(nADiscLen >= 2)
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
else
{
if(nADiscLen >= 1)
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
}
}
}
}
至此,把之前的两个CEdit派生类与此类合并,就能实现一个使用起来比较方便的文本编辑框类了。