概述:
我们按照前面文章根据向导创建项目。
1 创建插入符
由于插入符是在创建窗口后并且做我们用户操作前需要使用。所以我们将插入符的创建放在OnCreate函数中即WM_CRATE信号。
int CInsertFuView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);//获取字体信息,以便光标开始前与其它软件写入一样
CreateSolidCaret(tm.tmAveCharWidth / 8, tm.tmHeight);//创建插入符,CreateSolidCaret继承于CWnd,所以可以直接调用
ShowCaret();//显示
return 0;
}
结果:
2 写字
上面只是能将光标自适应大小放在开头,但是并不能将键盘按下的字符记录。所以下面开始写字。
目标:左键按下哪里,就在哪里开始输入字符。
2.1 写字思路
- 1)左键按下事件,记录起始坐标。
- 2)这是用户开始键盘输入,所以键盘事件,定义一个成员字符串变量CString,记录每次输入的单个字符。
- 3)由于每次左键按下都有重新输入,所以需要情况上次的字符,即左键按下事件清空字符。
2.2 代码
1)左键按下事件:
void CInsertFuView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SetCaretPos(m_beginWritePoint);//让光标随着左键移动
//记录鼠标左键按下开始输入字符坐标
m_beginWritePoint = point;
//每次按下将字符串情空
m_contentStr.Empty();
CView::OnLButtonDown(nFlags, point);
}
2)键盘事件
/*OnChar为键盘按下的回调函数*/
void CInsertFuView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_contentStr += (TCHAR)nChar;
//显示每次输入的字符串
CClientDC dc(this);
CSize s = dc.GetTextExtent(m_contentStr);
int x = m_beginWritePoint.x + s.cx;
int y = m_beginWritePoint.y;
SetCaretPos(CPoint(x,y));//让光标在字符串末尾
dc.TextOutW(m_beginWritePoint.x, m_beginWritePoint.y, m_contentStr);//显示每次输入的字符串
CView::OnChar(nChar, nRepCnt, nFlags);
}
结果可以看到,去到哪里点到哪里,并且光标可以放在最后。
3 换行与退格
3.1 换行的思路
3.2 退格的思路
利用背景色将字体全部覆盖,然后将字符串减1,最后恢复原来背景显示字符串。
具体步骤为:
//1 获取背景色
//2 设置写字的颜色,即将上面背景图颜色设置
//3 重写白色并且将字符串最后一个字符扔掉
//4 恢复颜色,否则会出现按下一个退格后字符串显示被颜色覆盖掉
将上面的键盘事件换成下面即可:
void CInsertFuView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_contentStr += (TCHAR)nChar;
//显示每次输入的字符串
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);//获取字体信息,以便光标开始前与其它软件写入一样
//换行
if (nChar == VK_RETURN) {
//1 清空字符串
m_contentStr.Empty();
//2 更新Y坐标,但是差字体的宽度,需要重新获取字符串的信息
m_beginWritePoint.y = m_beginWritePoint.y + tm.tmHeight;
}
else if (nChar == VK_BACK) {//退格
//1 获取背景色
COLORREF color = dc.GetBkColor();
//2 设置写字的颜色,即将上面背景图颜色设置
COLORREF oldcolor = dc.SetTextColor(color);
//3 重写白色并且将字符串最后一个字符扔掉
dc.TextOutW(m_beginWritePoint.x, m_beginWritePoint.y, m_contentStr);
//m_contentStr = m_contentStr.Left(m_contentStr.GetLength() - 1);
m_contentStr = m_contentStr.Left(m_contentStr.GetLength() - 2);
//4 恢复颜色,否则会出现按下一个退格后字符串显示被颜色覆盖掉
dc.SetTextColor(oldcolor);
}
else {
m_contentStr += (TCHAR)nChar;
}
CSize s = dc.GetTextExtent(m_contentStr);
int x = m_beginWritePoint.x + s.cx;
int y = m_beginWritePoint.y;
SetCaretPos(CPoint(x,y));//让光标在字符串末尾
dc.TextOutW(m_beginWritePoint.x, m_beginWritePoint.y, m_contentStr);//显示每次输入的字符串
CView::OnChar(nChar, nRepCnt, nFlags);
}