文本的基本操作
1——插入符
i:什么时候创建插入符?
在窗口创建之后,才能创建插入符,没有窗口就没有办法创建插入符
所以应该在Oncreate函数之中,并在窗口之后
创建插入符函数CreateSolidCaret();
CWnd::CreateSolidCaret
void CreateSolidCaret( int nWidth, intnHeight );
两个参数为0时,都是系统指定的相匹配,但如何设置两个参数ii:插入符要跟着字体大小来改变
就是要和文本相匹配,就是设置上面的两个参数
MFC提供一一个函数
CDC::GetTextMetrics
BOOL GetTextMetrics( LPTEXTMETRIC lpMetrics ) const
这是的参数是Points to the TEXTMETRIC structure that receives the metrics.(指向接受文本度量的TEXTMETRIC的结构体)
结构体里边用到两个成员
int tmAveCharWidth;//取字符的平均宽度即可
int tmHeight;
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
CClientDC dc(this);
TEXTMETRIC tr;
dc.GetTextMetrics(&tr);
CreateSolidCaret(tr.tmAveCharWidth/8, tr.tmHeight); //要在窗口创建完成之后,创建插入符,但是显示不出来
}
但是这样编译,运行之后,插入符没有显示出来,是因为CreateSolidCaret成员函数在任何情况下,不管系统自己的
符号,会自动销毁先前插入符号参量,一旦被创建,符号就会自动隐藏,要显示符号,一定要调用函数ShowCaret
CWnd::ShowCaret
void ShowCaret( );它是在字符当前的位置在屏幕上显示出来,一旦被显示出来,它就会自动更新
这个成员函数仅当它有在当前的形态并且没 有被多次的连续地隐藏,才能显示符号,没果它不属于
所在的窗口,就不会显示……
2——如何创建图形插入符?
肯定要加载一幅位图,可以自己创建,也可以加载,但要注意的是:
申请位图的对象应该是所在类(就是要在其中创建位图的类)的成员变量,而不能是
局部变量,因为与资源有关的对象,如果它在一函数内就是它局部变量,当函数终止时,
这个与资源有关对象的生命周期也同时结束,就会发生析构,从而也会把它相关的资源
同时销毁
创建位图插入符函数
CWnd::CreateCaret
void CreateCaret( CBitmap* pBitmap);
它创建一个新的系统符号的形状,并且宣称对符号的所有权
bitmap.LoadBitmap(IDB_BITMAP1);
CClientDC dc(this);
CreateCaret(&bitmap);
ShowCaret();
3——文字的输出
i:::::::当窗口生成时,也就是从无到有的这个过程,会发生WM_PAINT这个消息,让窗口进行一次重绘
窗口的大小变化就会发生窗口的重绘,重绘会把文字给擦除掉,那么如果要把文字保存的窗口之上,就
要在响应WM_PAINT消息时,将文字再次输出 。
在VIEW类中,它提供了一个函数OnDraw(),可以在此设一断点,当窗口生成时,就会执行该函数,被
应用程序的框架所调用。所以在这个函数的实现
文字一定需要CString类。这个类没有基类,它是由长度可变的字符序列组成,不用管它内存的分配。
它的构造函数中,可以用一个对象构造一个CString。然后再用一个CDC类的成员函数TextOut对字符串
进行输出。
当然还有可以通过字符串的ID的加载,进行字符串的输出。其中字符串的ID是在资源视图中String Table(字串表)中
来进行编辑。
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CString str;
str="我正在学习MFC的文本!";
pDC->TextOut(100,50,str);
CString str1;
str1.LoadString(IDS_STRING);
pDC->TextOut(200,100,str1);
}
ii:::::::密闭的区域
有两个函数BeginPath() 和 EndPath()
BeginPath()功能,在设备上下文中打开一个路径区域,在一个路径区域打开之后,应用程序可以调用GDI(图形设备接口)
画图函数在区域内进行工作(可以是画图),应用程序通过调用EndPath()关闭密闭区域。
可以画一个矩形区域,其左上角可以确定,就是文本的起始点,但是右下角的横坐标=文本的起点+字符串的宽度;
纵坐标=文本的起点的纵坐标+字符串的高度;得到字符串的信息(屏幕上显示时的)的一个函数为
GetTextExtent
CDC::GetTextExtent
CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
CSize GetTextExtent( const CString& str ) const;
Return
这是有一个CSize类,它的一个构造函数 CSize( int initCX , int initCY );
密闭区域要和CDC函数SelectClipPath()相互作用才能有效果。
这个函数参数可以选择
RGN_DIFF
这是一个新的剪切区域 包括了当前的剪切区域,但是当前路径除外
代码:
void CTestView::OnDraw(CDC* pDC)
{
CTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CString str;
str="我正在学习MFC的文本!";
pDC->TextOut(100,50,str);
CSize sz=pDC->GetTextExtent(str);
//但做没有什么显示的,它是与SelectClipPath()函数之间的互操作,才有看得到作用
pDC->BeginPath();
pDC->Rectangle(100,50,100+sz.cx,50+sz.cy);
pDC->EndPath();
pDC->SelectClipPath(RGN_DIFF);
CString str1;
str1.LoadString(IDS_STRING);
pDC->TextOut(200,100,str1);
CSize sm=pDC->GetTextExtent(str1);
//但做没有什么显示的,它是与SelectClipPath()函数之间的互操作,才有看得到作用
pDC->BeginPath();
pDC->Rectangle(200,100,200+sm.cx,100+sm.cy);
pDC->EndPath();
pDC->SelectClipPath(RGN_DIFF);
for(int i=0;i<=400;i+=12)
{
pDC->MoveTo(0,i);
pDC->LineTo(400,i);
pDC->MoveTo(i,0);
pDC->LineTo(i,400);
}
}
效果: