新建MFC Test项目
文本插入符:
int CTestView::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);
//显示插入符
ShowCaret();
/*m_btn.Create(L"按钮", WS_CHILD | BS_DEFPUSHBUTTON, CRect(0, 0, 50, 50), this, 123);
m_btn.ShowWindow(SW_SHOWNORMAL);*/
return 0;
}
创建图形插入符:
添加Bitmap
【解决方案资源管理器】->【资源文件】->【添加】【资源】
在TestView.h
加入成员函数
CBitmap bitmap;
int CTestView::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);
/*CBitmap bitmap; */
bitmap.LoadBitmap(IDB_BITMAP1);
CreateCaret(&bitmap);
//显示插入符
ShowCaret();
/*m_btn.Create(L"按钮", WS_CHILD | BS_DEFPUSHBUTTON, CRect(0, 0, 50, 50), this, 123);
m_btn.ShowWindow(SW_SHOWNORMAL);*/
return 0;
}
窗口重绘:
在Windows程序运行时,如果程序窗口大小发生变化,窗口会发生重绘,那么窗口中已输入的文字或图形就会被擦除。如果希望输入的内容始终保留在窗口上,就要在响应WM_PAINT消息的函数中将内容再次输出。在MFC应用程序向导产生的视类代码中,给我们提供了一个类似于WM_PAINT消息响应函数的OnDraw函数,当窗口发生重绘时,应用程序框架代码就会调用该函数。
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str(_T("VC++深入编程"));
pDC->TextOut(50,50,str);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str(_T("VC++深入编程"));
pDC->TextOut(50,50,str);
str.LoadString(IDS_STRINGVG);
pDC->TextOut(0,100,str);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CString str(_T("VC++深入编程"));
pDC->TextOut(50,50,str);
//GetTextExtent获取某个特定的字符串在窗口中显示时所占据的宽度和高度
CSize sz = pDC->GetTextExtent(str);
str.LoadString(IDS_STRINGVG);
pDC->TextOut(0,200,str);
//打开路径层
pDC->BeginPath();
pDC->Rectangle(50,50,50+sz.cx,50+sz.cy);
//结束路径层
pDC->EndPath();
//对剪裁区与路径层进行互操作
pDC->SelectClipPath(RGN_DIFF);// RGN_AND
for (int i = 0; i < 300; i += 10)
{
pDC->MoveTo(0,i);
pDC->LineTo(300,i);
pDC->MoveTo(i,0);
pDC->LineTo(i,300);
}
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
字符输入:
void CTestView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
TEXTMETRIC tm;
dc.GetTextMetrics(&tm);
if (0x0d == nChar)//回车符
{
m_strLine.Empty();
m_Cpiont.y = tm.tmHeight;
}
else if(0x08==nChar)//退格符
{
/*按下退格符,应该删除屏幕上位于插入符前面的那个字符,也就是将这个字符磨掉
这个有一定的难度 先用取巧的方法实现(我也不知道 照书实践)
先获取背景色,再设置字符为背景色,再输出一遍返回的字符串数做到抹掉效果*/
//GetBkColor获取背景色 SetTextColor返回文本的先前的颜色
COLORREF clr = dc.SetTextColor(dc.GetBkColor());
dc.TextOut(m_Cpiont.x,m_Cpiont.y,m_strLine);
m_strLine = m_strLine.Left(m_strLine.GetLength()-1);
//CStringT Left(_In_ int nCount) nCountz参数指定个数
//Left返回指定字符串左边指定数目的字符 如"string",nCount=3,则返回"str"
dc.SetTextColor(clr);
}
else
{
m_strLine += (TCHAR)nChar;
}
CSize sz = dc.GetTextExtent(m_strLine);
//插入符横向移动就是输入字符的宽度,其纵向坐标不变;
CPoint pt;
pt.x = m_Cpiont.x + sz.cx;
pt.y = m_Cpiont.y ;
SetCaretPos(pt);
dc.TextOut(m_Cpiont.x,m_Cpiont.y,m_strLine);
CView::OnChar(nChar, nRepCnt, nFlags);
}
字体设置:
void CTestView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
//CFont类专门来设置字体,这个类派生于CGdiObject类 封装了Windows图形设备接口
/*
BOOL CreateFontIndirect(const LOGFONT* lpLogFont);
BOOL CreateFont(int nHeight, int nWidth, int nEscapement,
int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
LPCTSTR lpszFacename);
BOOL CreatePointFont(int nPointSize, LPCTSTR lpszFaceName, CDC* pDC = NULL);
BOOL CreatePointFontIndirect(const LOGFONT* lpLogFont, CDC* pDC = NULL);
*/
CFont font;
font.CreatePointFont(300,_T("华文行楷"),NULL);
CFont *pOldFont = dc.SelectObject(&font);
TEXTMETRIC tm; //TEXTMETRIC字体信息结构体
dc.GetTextMetrics(&tm);
if (0x0d == nChar)//回车符
{
m_strLine.Empty();
m_Cpiont.y = tm.tmHeight;
}
else if(0x08==nChar)//退格符
{
/*按下退格符,应该删除屏幕上位于插入符前面的那个字符,也就是将这个字符磨掉
这个有一定的难度 先用取巧的方法实现
先获取背景色,再设置字符为背景色,再输出一遍返回的字符串数做到抹掉效果*/
//GetBkColor获取背景色 SetTextColor返回文本的先前的颜色
COLORREF clr = dc.SetTextColor(dc.GetBkColor());
dc.TextOut(m_Cpiont.x,m_Cpiont.y,m_strLine);
m_strLine = m_strLine.Left(m_strLine.GetLength()-1);
//CStringT Left(_In_ int nCount) nCountz参数指定个数
//Left返回指定字符串左边指定数目的字符 如"string",nCount=3,则返回"str"
dc.SetTextColor(clr);
}
else
{
m_strLine += (TCHAR)nChar;
}
CSize sz = dc.GetTextExtent(m_strLine);
//插入符横向移动就是输入字符的宽度,其纵向坐标不变;
CPoint pt;
pt.x = m_Cpiont.x + sz.cx;
pt.y = m_Cpiont.y ;
SetCaretPos(pt);
dc.TextOut(m_Cpiont.x,m_Cpiont.y,m_strLine);
dc.SelectObject(font);
CView::OnChar(nChar, nRepCnt, nFlags);
}
字幕变色功能的实现:(卡拉OK字幕平滑效果)