要实现字符的输入,也就是当用户在键盘按下某个字符按键后,要把该字符输出到窗口上,这就需要程序捕获键盘按下消息(WM_CHAR消息);将每次输入的字符都先存储到一个单独的字符串中,每当按下新的字符时,都先将字符加到字符串中,然后再在窗口当前插入符的位置把这个字符串重新输出一次。
1.首先让CTextView类捕获WM_CHAR消息,生成消息响应函数
2.接着为CTextView类添加一个成员变量: CString m_strLine,用来存储单独的字符串
3.在CTextView类的构造函数中将变量m_strLine初始化为空
CTextView::CTextView() { // TODO: add construction code here m_strLine=""; }
4.如果用鼠标单击窗口中某个位置,那么插入符就应该移动到该位置,随后输入的字符都应该在此位置处向后输出,需要为CTextView类捕获鼠标左键按下消息(WM_LBUTTONDOWN消息),生成相应的消息响应函数,在该消息响应函数中利用CWnd类的SetCaretPos函数来将插入符移动到鼠标左击处
void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCaretPos(point); CView::OnLButtonDown(nFlags, point); }
5.当鼠标单击窗口中的新位置时,插入符会移动到该位置,那么之后输入的字符应该在该位置向后输出,而之前存储在字符串变量m_strLine中的已输入并在原位置输出过的字符在m_strLine重新刷新输出时不应在新位置再次输出,因此,在插入符移动到鼠标点击的新位置时,要将m_strLine中的已有字符串内容清空。可以利用CString类中的Empty函数实现:
void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCaretPos(point); m_strLine.Empty(); CView::OnLButtonDown(nFlags, point); }
6.每次鼠标单击时,需要捕获的键盘按下消息应在当前鼠标点击后插入符移动到的该坐标位置,为CTextView类添加成员变量:CPoint m_ptOrigin,来保存该坐标位置,以便在消息响应函数OnChar中使用;在CTextView类的构造函数中将该成员变量初始化为0;在鼠标左键按下消息的响应函数OnLButtonDown中保存当前鼠标点击的坐标位置
CTextView::CTextView() { // TODO: add construction code here m_strLine=""; m_ptOrigin=0; }
void CTextView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default SetCaretPos(point); m_strLine.Empty(); m_ptOrigin=point; CView::OnLButtonDown(nFlags, point); }
7.按下回车键后,插入符应换到下一行,这时就需要清空之前保存在字符串m_strLine中的内容,并获取插入符在下一行的新位置,随后的输入按键捕获及字符串的输出应从该新位置向后输出;利用已保存的当前插入点的纵坐标加上当前字体的高度,就可以得到回车后该新位置的纵坐标,利用CDC类的GetTextMetrics函数即可获得当前设备描述表中字体的高度信息;而换行后的横坐标,均为一行的起始位置0;
8.按下退格键(Backspace键)时,应该删除位于插入符前面的那个字符,同时插入符的位置应回退一个字符;解决方法就是,在用户按下退格键的瞬间,将文本的颜色设置为与客户区背景色相同,将文本输出一次,然后从保存了输入字符的字符串变量m_strLen中将要删除的字符删除,再把文本的颜色设置回原来的颜色,再将字符串文本输出;
获取背景色:CDC类的GetBkColor函数
设置文本颜色:CDC类的SetTextColor函数
实现从字符串中删除一个字符:先利用CString类的GetLength函数获得指定字符串中的字符个数n;再利用CString类中的Left函数指定只显示原字符串中从左向右的字符个数n-1
void CTextView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); //获取当前设备描述表中的字体信息 TEXTMETRIC tm; dc.GetTextMetrics(&tm); //回车符的ASCII码十六进制值为0x0d;退格键的ASCII码十六进制值为0x08 if(0x0d==nChar){ //回车键的换行处理 m_strLine.Empty(); //清空字符串变量m_strLine中已有的字符 m_ptOrigin.y+=tm.tmHeight; //已保存的当前插入点的纵坐标加上当前字体的高度即为换行后该新位置的纵坐标 }else if(0x08==nChar){ //退格键的删除处理 COLORREF clr=dc.SetTextColor(dc.GetBkColor()); //先将文本颜色设置为与客户区背景色相同 dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine); //将文本输出一次 m_strLine=m_strLine.Left(m_strLine.GetLength()-1); //删除插入符之前的一个字符 dc.SetTextColor(clr); //再把文本的颜色设置为原来的颜色 }else{ //如果捕获的键盘输入不是回车键或退格键,则将该输入字符添加到字符串变量m_strLine m_strLine+=nChar; } CSize sz=dc.GetTextExtent(m_strLine); //得到客户区显示的字符串的宽度和高度 CPoint pt; pt.x=m_ptOrigin.x+sz.cx; //将插入符的横坐标移动到已输出字符串的后面 pt.y=m_ptOrigin.y; //插入符的纵坐标不变 SetCaretPos(pt); //设置插入符的坐标位置 dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine); //刷新输出修改后的字符串 CView::OnChar(nChar, nRepCnt, nFlags); }