1、確認是否是隨光標第一次輸出文本
//當文檔出圖隨光標第一次輸入時
if(m_ptCaret==m_ptWriteCaret)
{
//回車的情況
if(0x0d==nChar)
{
m_ptCaret.y+=tm.tmHeight;
m_ptCaret.x=0;
//以行爲單位保存輸入的字符串
m_strAarray.Add(m_strLine);
m_strLine.Empty(); //清空字體數組;
m_IsCaretEnter=0;
}
else if(0x08==nChar)
//退格鍵的實現
{
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//將輸出顏色設置爲背景色
dc->TextOut(0,m_ptCaret.y,m_strLine); //已背景色輸出文字
m_strLine=m_strLine.Left(m_strLine.GetLength()-1);//減少一個文字後付給str
dc->SetTextColor(clr); //將字體顏色設置爲原有顏色
dc->TextOutA(0,m_ptCaret.y,m_strLine);//再次輸出;
}
else
m_strLine+=(char)nChar; //將字體自加到字符串中
//將光標隨着字符輸入的移動而移動
sz=dc->GetTextExtent(m_strLine); //獲取字符串的整體形狀信息
pt.x=0+sz.cx;
pt.y=m_ptCaret.y;
//}
SetCaretPos(pt); //將插入符設置在字符串的末尾
//IsLeft=0;
//輸出文字
dc->TextOut(0,m_ptCaret.y,m_strLine);
//收集座標,給插入符的最後位置
m_ptCaret=pt;
//保存輸入文字的最後位置
m_ptWriteCaret=pt;
m_ptOrgCaret=pt;//將本次輸入的位置保留
3、在鼠標重新點擊後插入輸入
//在插入位置繼續輸入
if(m_ptOrgCaret==m_ptCaret)
{
//插入回車的情況
if(0x0d==nChar)
{
strLeft=m_strLeft; //獲取原有左邊的字符
strRight=m_strRight;//獲取原有右邊的字符
//strLeft+=(char)nChar;//增加新的文字
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//將輸出顏色設置爲背景色
int Row=m_strAarray.GetSize();//獲取元素的個數
CPoint ptPoint=CPoint(0,0);
//將原有輸出全部擦除
for(int i=0;i<Row;i++)
{
dc->TextOutA(ptPoint.x,ptPoint.y,m_strAarray.GetAt(i));
ptPoint.y+=tm.tmHeight;
}
dc->SetTextColor(clr);//換回原有顏色;
//以行爲單位保存輸入的字符串
m_strAarray.SetAtGrow(iRow,m_strLeft);//把插入符左邊的文字重新付給第iRow行
CString strAppend;
strAppend=m_strAarray.GetAt(Row-1);//先把左後一行的字符串暫時附到外面
//從倒數第二個開始向前每一個元素都想後移動一位
for(int i=Row-2;i>iRow;i--)
m_strAarray.SetAtGrow(i,m_strAarray.GetAt(i+1));
m_strAarray.SetAtGrow(iRow+1,strRight);//插入符右邊的字符串移動到下一個元素中;
m_strAarray.Add(strAppend);//把最後一個元素增加到末尾
//輸出全部集合類;
ptPoint=CPoint(0,0);
for(int i=0;i<=Row;i++)
{
CString strLook;
strLook=m_strAarray.GetAt(i);
dc->TextOutA(0,ptPoint.y,m_strAarray.GetAt(i));
ptPoint.y+=tm.tmHeight;//輸出完一行後插入符位置下移一行;
}
m_ptWriteCaret.y=ptPoint.y;
m_ptWriteCaret.x=(dc->GetTextExtent(m_strAarray.GetAt(Row))).cx;
//設置插入符的顯示位置
ptPoint.y=(iRow+1)*tm.tmHeight;
ptPoint.x=0;
SetCaretPos(ptPoint);
//將strLeft、strRight恢復原值;
strLeft.Empty();
strLeft=m_strLeft;
strRight.Empty();
strRight=m_strRight;
m_IsCaretEnter=1;
//設置文字輸出的位置
}
else
{
strLeft=m_strLeft; //獲取原有左邊的字符
strRight=m_strRight;//獲取原有右邊的字符
strLeft+=(char)nChar;//增加新的文字
m_strLeft=strLeft; //把左邊新的字符付給全局變量
}
}
4、在插入位置繼續輸入文字
else
{
int iNum=m_ptCaret.x/tm.tmAveCharWidth;//獲取插入符位於本行第幾個字之間
strLeft=strLine.Left(iNum);//獲取操作符左邊的文字
strRight=strLine.Right(strLine.GetLength()-iNum);
strLeft+=(char)nChar;//獲取新輸入的字符;
}
5、顯示所需的輸出
//擦除原有輸出;
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//獲取窗口背景色
dc->TextOut(0,m_ptCaret.y,strLine);//已背景色輸出全部文字
dc->SetTextColor(clr);//重新設置字體顏色
//設置新的光標位置
CSize szStr1=dc->GetTextExtent(strLeft);//獲取輸出左邊字及新輸入的文字寬度
pt.x=szStr1.cx;//將值付給光標
pt.y=m_ptCaret.y;
SetCaretPos(pt);//設置光標;
//將字符串內容合併
strLine.Empty();
strLine=strLeft+strRight;//將正行文字組合在一起;
dc->TextOutA(0,pt.y,strLine);//輸出文字;
m_strLeft=strLeft;
m_strRight=strRight;
m_ptCaret=pt;
m_ptOrgCaret=m_ptCaret;//將本次輸入的位置保留
m_strAarray.SetAtGrow(iRow,strLine);//將新的字符串覆蓋原字符串
m_strLine=strLine;
總:在nChar下代碼的總體。其中涉及回車和回格邏輯還不成熟
void CNoteBookView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
CDC *dc;
dc=GetDC(); //獲取DC句柄
CString str;
CSize sz;
CPoint pt;
TEXTMETRIC tm; //保存字體信息
dc->GetTextMetrics(&tm); //獲取DC中的字體信息
CString strChar;
int IsLeft=0; //左鍵標誌位;
//當文檔出圖隨光標第一次輸入時
if(m_ptCaret==m_ptWriteCaret)
{
//回車的情況
if(0x0d==nChar)
{
m_ptCaret.y+=tm.tmHeight;
m_ptCaret.x=0;
//以行爲單位保存輸入的字符串
m_strAarray.Add(m_strLine);
m_strLine.Empty(); //清空字體數組;
m_IsCaretEnter=0;
}
else if(0x08==nChar)
//退格鍵的實現
{
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//將輸出顏色設置爲背景色
dc->TextOut(0,m_ptCaret.y,m_strLine); //已背景色輸出文字
m_strLine=m_strLine.Left(m_strLine.GetLength()-1);//減少一個文字後付給str
dc->SetTextColor(clr); //將字體顏色設置爲原有顏色
dc->TextOutA(0,m_ptCaret.y,m_strLine);//再次輸出;
}
/*//左鍵
else if(0x1B==nChar)
{
CString strR;
strR=m_strLine.Right(1);
CSize str=dc->GetTextExtent(strR);
pt.x=(dc->GetTextExtent(m_strLine)).cx-str.cx;
pt.y=m_ptCaret.y;
IsLeft=1;
}*/
else
m_strLine+=(char)nChar; //將字體自加到字符串中
//if(IsLeft==0)
//{
//將光標隨着字符輸入的移動而移動
sz=dc->GetTextExtent(m_strLine); //獲取字符串的整體形狀信息
pt.x=0+sz.cx;
pt.y=m_ptCaret.y;
//}
SetCaretPos(pt); //將插入符設置在字符串的末尾
//IsLeft=0;
//輸出文字
dc->TextOut(0,m_ptCaret.y,m_strLine);
//收集座標,給插入符的最後位置
m_ptCaret=pt;
//保存輸入文字的最後位置
m_ptWriteCaret=pt;
m_ptOrgCaret=pt;//將本次輸入的位置保留
}
//在已輸入的文字中間添加
else
{
//獲取插入符所在行及所在行信息
int iRow=m_ptCaret.y/tm.tmHeight;//獲取光標所在的是第幾行
CString strLine;
strLine=m_strAarray.GetAt(iRow);//獲取本行的字符串
CSize sz=dc->GetTextExtent(strLine); //獲取本行字符串的矩形距離
CString strLeft;
CString strRight;
//在插入位置繼續輸入
if(m_ptOrgCaret==m_ptCaret)
{
//插入回車的情況
if(0x0d==nChar)
{
strLeft=m_strLeft; //獲取原有左邊的字符
strRight=m_strRight;//獲取原有右邊的字符
//strLeft+=(char)nChar;//增加新的文字
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//將輸出顏色設置爲背景色
int Row=m_strAarray.GetSize();//獲取元素的個數
CPoint ptPoint=CPoint(0,0);
//將原有輸出全部擦除
for(int i=0;i<Row;i++)
{
dc->TextOutA(ptPoint.x,ptPoint.y,m_strAarray.GetAt(i));
ptPoint.y+=tm.tmHeight;
}
dc->SetTextColor(clr);//換回原有顏色;
//以行爲單位保存輸入的字符串
m_strAarray.SetAtGrow(iRow,m_strLeft);//把插入符左邊的文字重新付給第iRow行
CString strAppend;
strAppend=m_strAarray.GetAt(Row-1);//先把左後一行的字符串暫時附到外面
//從倒數第二個開始向前每一個元素都想後移動一位
for(int i=Row-2;i>iRow;i--)
m_strAarray.SetAtGrow(i,m_strAarray.GetAt(i+1));
m_strAarray.SetAtGrow(iRow+1,strRight);//插入符右邊的字符串移動到下一個元素中;
m_strAarray.Add(strAppend);//把最後一個元素增加到末尾
//輸出全部集合類;
ptPoint=CPoint(0,0);
for(int i=0;i<=Row;i++)
{
CString strLook;
strLook=m_strAarray.GetAt(i);
dc->TextOutA(0,ptPoint.y,m_strAarray.GetAt(i));
ptPoint.y+=tm.tmHeight;//輸出完一行後插入符位置下移一行;
}
m_ptWriteCaret.y=ptPoint.y;
m_ptWriteCaret.x=(dc->GetTextExtent(m_strAarray.GetAt(Row))).cx;
//設置插入符的顯示位置
ptPoint.y=(iRow+1)*tm.tmHeight;
ptPoint.x=0;
SetCaretPos(ptPoint);
//將strLeft、strRight恢復原值;
strLeft.Empty();
strLeft=m_strLeft;
strRight.Empty();
strRight=m_strRight;
m_IsCaretEnter=1;
//設置文字輸出的位置
}
else if(0x08==nChar)
//退格鍵的實現
{
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//將輸出顏色設置爲背景色
dc->TextOut(0,m_ptCaret.y,m_strLine); //已背景色輸出文字
m_strLine=m_strLine.Left(m_strLine.GetLength()-1);//減少一個文字後付給str
dc->SetTextColor(clr); //將字體顏色設置爲原有顏色
dc->TextOutA(0,m_ptCaret.y,m_strLine);//再次輸出;
}
else
{
strLeft=m_strLeft; //獲取原有左邊的字符
strRight=m_strRight;//獲取原有右邊的字符
strLeft+=(char)nChar;//增加新的文字
m_strLeft=strLeft; //把左邊新的字符付給全局變量
}
}
//在新位置插入
else
{
int iNum=m_ptCaret.x/tm.tmAveCharWidth;//獲取插入符位於本行第幾個字之間
strLeft=strLine.Left(iNum);//獲取操作符左邊的文字
strRight=strLine.Right(strLine.GetLength()-iNum);
strLeft+=(char)nChar;//獲取新輸入的字符;
}
if(m_IsCaretEnter==0)
{
//擦除原有輸出;
COLORREF clr=dc->SetTextColor(dc->GetBkColor());//獲取窗口背景色
dc->TextOut(0,m_ptCaret.y,strLine);//已背景色輸出全部文字
dc->SetTextColor(clr);//重新設置字體顏色
//設置新的光標位置
CSize szStr1=dc->GetTextExtent(strLeft);//獲取輸出左邊字及新輸入的文字寬度
pt.x=szStr1.cx;//將值付給光標
pt.y=m_ptCaret.y;
SetCaretPos(pt);//設置光標;
//將字符串內容合併
strLine.Empty();
strLine=strLeft+strRight;//將正行文字組合在一起;
dc->TextOutA(0,pt.y,strLine);//輸出文字;
m_strLeft=strLeft;
m_strRight=strRight;
m_ptCaret=pt;
m_ptOrgCaret=m_ptCaret;//將本次輸入的位置保留
m_strAarray.SetAtGrow(iRow,strLine);//將新的字符串覆蓋原字符串
m_strLine=strLine;
}
}
CView::OnChar(nChar, nRepCnt, nFlags);
}