思路
1.刚开始想做这个内容的时候,第一想法就是派生CEdit的子类,在子类中处理控件的 EN_UPDATE 事件–就是在当中判断输入的文字是否修改了你的固定文本,如果修改了则重新处理文本恢复固定文本内容在设置回编辑框。
但这个方法有个问题,子控件处理EN_UPDATE事件后,父窗口就无法获取到该消息(如果父窗口不需要处理该消息的话可选择该方法)。
2.因为我这边父窗口需要处理该消息,且两个内容不能合并(也不推荐合并,要不然 该子类只能对于这个父窗口唯一使用)。
3.所以我就在想不可编辑的话,从编辑入手截取编辑消息做处理。
对文本编辑无非就:删除 增加
而对于删除增加文本的内容是靠,鼠标光标位置确定的,所以在删除增加文本的时候判断鼠标光标位置去判断是否可以编辑
代码实现
1.继承CEdit 重写子类
2.重写EN_UPDATE 事件方法:
//.h
afx_msg void OnEnUpdate();
//.cpp
//控件重写 EN_UPDATE 事件的方法
BEGIN_MESSAGE_MAP(子类, CEdit)
ON_CONTROL_REFLECT(EN_UPDATE, &子类::OnEnUpdate)
END_MESSAGE_MAP()
//。。。
void 子类::OnEnUpdate()
{
//在这里就可以使用获取字符串然后对字符串进行处理啦
//只要文本内容被修改后都会触发此事件可以设置一个标记去判断是否修改
}
3.截取编辑消息方法
(1)鼠标键盘的回退格删除消息/左移右移鼠标光标消息(这几个都是键盘消息一起处理)
(2)鼠标点击移动光标事件
//.h
//捕获按键消息
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//左击事件
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//左双击事件
afx_msg void OnLButtonDblClk(UINT nFlags,CPoint point);
//保存无法编辑文本内容
CString m_Text;
//.cpp
void 子类::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (VK_BACK == nChar || VK_LEFT == nChar || VK_RIGHT == nChar)
{
CString strText;
GetWindowText(strText);
//是否包含不可编辑文本
if (strText.Find(m_Text) != -1)
{
int nStart;
int nEnd;
GetSel(nStart, nEnd);
//相等就是未选择文本时
if (nStart == nEnd)
{
int limLength = m_Text.GetLength();
int curLength = strText.GetLength();
if (nStart == limLength) //说明现在光标所在位置为不可编辑文本的末尾,不可删除,不可移动光标进去,直接return
if (VK_LEFT == nChar || VK_BACK == nChar)
return;
//光标位置在补课编辑文本内容中,移动光标到文本尾端
else if (nStart < limLength)
SetSel(curLength, curLength);
}
}
else
{
SetWindowText(m_Text);
return;
}
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void 子类::OnLButtonDown(UINT nFlags, CPoint point)
{
//先执行左击事件(使其他可编辑文本能正常编辑)然后判断左击事件后光标是否在不可编辑文本中
__super::OnLButtonDown(nFlags, point);
int nStart;
int nEnd;
GetSel(nStart, nEnd);
if (nStart == nEnd)
{
CString strText;
GetWindowText(strText);
int limLength = m_Text.GetLength();
int curLength = strText.GetLength();
if (nStart < limLength)
SetSel(curLength, curLength);
}
}
void 子类::OnLButtonDblClk(UINT nFlags, CPoint point)
{
//先执行默认双击事件(使其他可编辑文本能正常编辑),再去判断鼠标光标位置
__super::OnLButtonDblClk(nFlags, point);
int nStart;
int nEnd;
GetSel(nStart, nEnd);
CString strText;
GetWindowText(strText);
int limLength = m_Text.GetLength();
int curLength = strText.GetLength();
if (nStart < limLength || nEnd < limLength)
SetSel(curLength, curLength);
}