我们在消息响应变量中添加如下代码:AfxMessageBox(“HelloWord!”);运行程序!当我们在用户区中双击键盘左键时,我们可以提到效果(如图5)。我们在完成双击鼠标左键这个事件后,Windows便会发出WM_LBUTTONDBLCLK这条消息。我们的程序收到这个消息后,就会跳转到键盘左键双击的消息响应变量内,执行上面的代码。同样的,我们可以添加其他的消息响应函数,如键盘左键按下,抬起,鼠标挪动等(WM_LBUTTONUP、WM_LBUTTONDOWN、WM_MOUSEMOVE等)。我们程序就是在这样的消息响应制度下运行的。图52.4资源在ResoureView里,我们可以编辑对话框、菜单、工具条、快捷键等资源。点开Menu,可以提到一个ID为IDR_MAINFRAME的菜单。ID是一个标示,实际上是一个无符号整型常量,每一个资源在程序中都有一个唯一的ID号。双击IDR_MAINFRAME,在右面的视口中双击帮助左侧的实线框,弹出菜单属性,在Caption中键入“画图”,并将其关闭。双击画图菜单下边出现虚线框,在caption中输入“画线”后将其关闭。
双击画线mfc画图板,在跳出的菜单属性中ID栏的ID_MENUITEM32775改成ID_MENUITEM_LINE。同样方式在建一个“画圆”菜单项。注意:每个资源对应一个ID号,ID号的命名全部用小写字母,且要符合匈牙利命名法。我们为新的菜单项名字,如果我们选取了Pop-up,生成的菜单就也有下级子菜单;如果没有选择,菜单就没有下级菜单。我们相同可以在ClassWizard中为我们生成的菜单添加响应。在ClassWizard中的ObjectIDs中选中菜单的ID号,Messages中选取COMMOND,然后点击AddFunction。这样,我们就为新建的菜单添加了单击的响应,我们同样可以点击EditCode编辑消息响应变量。2.5设备环境CDC是设备环境类的子类直接由CObject派生。是GDI的关键元素,它代表了生物设备。每一个C++设备环境对象都有相对应Windows设备环境,并借助一个32位类型的HDC句柄来标志。CDC类的虚拟性使我们可以很易于的做到编写同时适用于多种设施的代码。使用CDC类可以使我们的作图不用关心设备的弊端。CClientDC和CWindowDC是显示设备环境类,都是由CDC派生而来,区别在于CClientDC是窗口的用户区不包含边框、标题栏和菜单栏,(0,0)指客户区域的左上角。
CWindowDC的(0,0)指整个屏幕的左上角,这意味着我们可以在显示器的任意地方绘图,包括窗口边框、标题栏和菜单栏等等。CWindowDC一般应用在框架窗口,而不是视图窗口。CDC对象被建立后一定要在靠谱的之后将它删除掉,如果忘掉了卸载设备环境对象则会导致存储丢失。在每次绘图前,我们要获得设施环境,我们可以使用CDC*GetDC()变量来获得设施环境。在绘图完成后,使用voidReleaseDC(CDC*pDC)变量释放设备环境。第3章简易画图板的制做3.1设计目的设计一个单文档类型的MFCAppWizard(exe)项目,工程取名为:Graphic。此程序将推动简单的绘图功能,包括点、直线、矩形、椭圆、扇形和连续线的勾画。并且能推动绘图的控制,包括线宽、线型和样式的设定,图形的保存和打开以及笔刷的使用。3.2总体设计设计图如图6简易画图板简易画图板文件绘图笔刷打开保存点直线矩形椭圆扇形连续线设置样式简洁笔刷位图蒙版透明图层线宽线型图63.3详细设计首先,新建一个单文档类型的MFCAppWizard(exe)项目,工程取名为:Graphic。为此程序添加一个子菜单,菜单名称为“绘图”,并为其添加六个菜单项,分别用来控制不同图形的绘制。
当用户选取其中的一个菜单项后,程序将依照当前的选用进行相应图形的绘制。添加的六个菜单项的ID及名称如表1所示。然后分别为这六个菜单项添加命令响应,本程序让视类(CGraphicView)对很多菜单命令进行响应,这六个响应变量的名称分别如表1所示。表1添加的菜单项菜单项ID菜单项名称菜单项命令响应变量IDM_DOT点OnDotIDM_LINE直线OnLineIDM-RECTANGLE矩形OnRectangleIDM_ELLIPSE椭圆OnEllipseIDM_SHANXING扇形OnShanxingIDM_LIANXUXIAN连续线OnLianxuxian在程序运行之后,当用户点击某个菜单项时,应该把用户的选用保存出来,以便之后的绘图操作使用。因此在CGraphicView类中添加一个私有数组m_nDrawType;用来储存用户的选取,该数组的定义如下所述:private:UINTm_nDrawType;接着,在视类的构造数组中将此函数初始化为0,程序代码如下:CGraphicView::CGraphicView(){//TODO:addconstructioncodeherem_nDrawType=0;}利用switch/case子句,来分别完成相应图形的重绘。

当用户选取【绘图】菜单下的不同子菜单项时,将数组m_nDrawType设置为不同的值。程序代码如下:voidCGraphicView::OnDot(){//TODO:Addyourcommandhandlercodeherem_nDrawType=1;}voidCGraphicView::OnLine(){//TODO:Addyourcommandhandlercodeherem_nDrawType=2;}voidCGraphicView::OnRectangle(){//TODO:Addyourcommandhandlercodeherem_nDrawType=3;}voidCGraphicView::OnEllipse(){//TODO:Addyourcommandhandlercodeherem_nDrawType=4;}voidCGraphicView::OnShanxing(){//TODO:Addyourcommandhandlercodeherem_nDrawType=5;}voidCGraphicView::OnLianxuxian(){//TODO:Addyourcommandhandlercodeherem_nDrawType=6;}3.3.1点、直线、矩形、椭圆的绘制对于直线、矩形和半圆,在勾画时都可有两点来确认其图形。
当光标左击时得到一个点,当键盘左键按住时得到另外一个点。为视类CGraphicView分别捕获鼠标左键按下和弹起这两个消息。另外当键盘左键按下时,需要将光标当前按下点保存,因此我们为CGraphicView再提高一个CPoint类型的私有成员数组:m_ptOrigin,在视类的构造函数中将此数组初始化为0。在光标按下消息响应变量中,保存该点,代码如下:voidCGraphicView::OnLButtonDown(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefaultm_ptOrigin=point;//保存鼠标按下得到点,也是绘制一个点CView::OnLButtonDown(nFlags,point);}在键盘左键弹起消息响应变量中实现绘图,代码如下:voidCGraphicView::OnLButtonUp(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefault//创建并获得设备描述CClientDCdc(this);switch(m_nDrawType){case1:dc.SetPixel(point,RGB(255,0,0));/*绘制点*/break;case2:/*绘制直线*/dc.MoveTo(m_ptOrigin);/*读取MoveTo函数移动到原点*/dc.LineTo(point);/*读取LineTo函数绘制到终点。
*/break;case3:/*绘制矩形*/dc.Rectangle(CRect(m_ptOrigin,point));break;case4:/*绘制椭圆*/dc.Ellipse(CRect(m_ptOrigin,point));break;CView::OnLButtonUp(nFlags,point);}在上述程序中,设置一个点,用到的函数是SetPixel,这也有CDC类的一个成员原则,该变量的生命方式如下:COLORREFSetPixel(POINTpoint,COLORREFcrColor);该变量是在选定的点设定一个像素。其中第一个参数(point)是指定的点,第二个参数(crColor)是选定的样式。在程序中设置的形状在系统样式表中可能不存在,但系统会选用一种和这个样式最接近的底色。RGB是一个宏,它有三个参数,分别代表红、绿、蓝三种肤色的值。这三个参数BYTE类型,取值范围为0~255。RGB(0,0,0)是黑色,RGB(255,255,255)是橙色,将这三个分量设置变成0~255之间的任意值,从而得到各种不同的颜色。这里的RGB(255,0,0)是蓝色。
绘制线段时,首先读取MoveTo函数移动到原点,然后读入LineTo函数重绘到终点。绘制矩形时使用Rectangle函数,该变量声明方式为:BOOLRectangle(LPCRECTlpRect);该变量有一个指向Crect对象的参数,后者可以借助两个点来构造。需要留意的是该变量应该的是指向Crect对象的指针,而上述代码中传递的却是Crect对象,但运行编译时也能顺利借助,运行时也不会报错,这是为什么呢?我们明白C系列的语言都是强类型语言,如果种类不匹配的话,需要进行强制类型转化。但这里为什么没有进行这样的强制类型转化程序也可以借助呢?实际上,Crect类提供了这样一个成员变量:重载LPCRECT操作符,其作用是将Crect转换为LPCRECT类型。因此,当在程序中给Rectangle函数的参数实参时,如果它发现该参数是一个Crect对象,它还会隐式地调用LPCRECT操作符,将Crect类型的对象转化为LPRECT类型。因此,在给变量传递参数时,如果我们提到的释放的数值类型和所应该的类别不匹配,但编译和运行都恰当的状况时,就要想想这其中的动因了。当然,有的状况下可能是很多类别之间本来就可以互相转化,例如short类型和int类型。
之后参数是对象类的话,就要考量了,它选用的对象的构造方式进行的隐式转化,还是有其他重载的操作符。当用户选取椭圆菜单项时,调用Ellipes函数重绘一个椭圆。3.3.2连续线和扇形的绘制Windows系统为我们提供了一个绘图程序,在该程序中,利用画笔可以勾画连续的笔触,下面我们设计描绘连续线和弧形。为了勾勒连续的腰线,首先要得到线条的起点,这在上面已经推动。然后还要捕获鼠标移动过程中的每一个点,这可以借助捕获鼠标移动消息(WM_MOUSEMOVE)来谋求。在此消息响应函数中,在依次捕获的各个点之间绘制一条条比较短的直线,从而就可以勾画出一条连续的纹路。遵照这一模式,我们起初增加程序的用途。首先为视类降低鼠标移动消息(WM_MOUSEMOVE)的响应函数(OnMouseMove)。这样,只要鼠标在应用程序窗口中移动时都会处于到这个消息响应函数中。但这并不是我们所期待的,我们期望在键盘左键按下后起初绘图。因此,我们还要有一个函数来表示键盘左键是否按下这一状况,然后在鼠标移动消息响应函数中对这一数组进行判定。当此函数为真,即键盘左键已经按下去,我们起初绘图。于是,为视类添加一个BOOL型的私有数组m_bDraw,当键盘左键按下去时,此变量为真;当键盘左键弹起时,此变量为假,这时,我们就不再描绘线条了。

该数组在视类头文件中的定义代码如下:Private:BOOLm_bDraw;接出来在视类的构造数组中,将此函数初始化为FALSE。m_bdraw=FALSE;当鼠标左键按下去时,在视类的OnLButtonDown函数中将此数组初始化为TRUE。m_bdraw=TRUE;当鼠标左键弹起时,在视类的OnLButton函数中将此数组初始化为假。m_bdraw=FALSE;然后在OnMouseMove函数中首先对m_bdraw变量进行判定,如果其值为真,说明鼠标左键已经按下来了,这时就可开始进行画线操作。还有一点还要切记,因为每绘制一条直线后,下次需要从这条线段的终点开始继续绘制。因此,绘制完当前线段后,应该设置直线的起点,将当前线段的终点作为下一条直线的起点,程序代码如下:voidCGraphicView::OnMouseMove(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefault{//创建并获得设备描述CClientDCdc(this);//创建宽度为1的虚线红色画笔CPenpen(PS_SOLID,1,RGB(255,0,0));//把创建的画笔选入设备描述CPen*pOldpen=dc.SelectObject(&pen);if(m_bDraw==true){dc.MoveTo(m_ptOrigin);dc.LineTo(point);//修改线段的起点m_ptOrigin=point;}//恢复设备描述dc.SelectObject(pOldpen);CView::OnMouseMove(nFlags,point);}如果在前面绘制连续色块的程序中,保持每段小线段的起点不变,即以光标左键按下时的起点为起点不变,分别绘制到鼠标移动点的线段,这时还会出现弧形的效果。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-120024-2.html
成功了
日子没法过了
从没听说过会作词作曲