MFC的坐标系

合集下载

mfc控件位置调整和坐标确定

mfc控件位置调整和坐标确定

mfc控件位置调整和坐标确定的方法(几个相关的函数)在mfc工程中控件或者窗口位置的调整是经常遇到的,特别是基于对话框的工程。

位置的调整包括坐标、长度和宽度的变化,一般在窗口类的OnSize函数中实现。

控件位置的调整涉及的函数有:GetWindowRect()、ScreenToClient()、GetClientRect()、MoveWindow()或SetWindowPos(),功能意义如下:GetWindowRect():获得窗口在屏幕上的矩形坐标,调整控件位置时必须首先获得该屏幕坐标;ScreenToClient():转换屏幕坐标到客户区坐标,如果为子窗口,转换后坐标为相对于父窗口的坐标,若为独立窗口,转换后客户区左上坐标为(0,0);调整子窗口时这一步也是必须的;GetClientRect():获得窗口客户区坐标,左上坐标永远为(0,0);MoveWindow():调整控件到指定位置;SetWindowPos():调整控件的位置,该函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:控件位置调整涉及的参变量有:主窗口的cx、cy坐标、参考点坐标。

相对于调整位置时调用的函数,变量稍许复杂些。

cx、cy 坐标为主窗口的宽和高,有OnSize的参数给出,为窗口控件调整提供了变化的范围,所有的控件为了能够正常显示都不能超出这个范围。

其实在开发过程中较难和重要的是参考控件的选择,其位置相对于主窗口来说必须好确定。

常用的策略:1.选择主窗口上位置不随窗口大小变化的控件为参考;2.选择主窗口上控件的宽或者高固定的控件;3.选择与主窗口满足固定坐标关系的控件;4.选择主窗口上控件位置或者高宽容易确定的控件。

以上四种策略可在实际开发中作为参考!不管遇到什么的情况,一定要清楚:选择一个。

兄弟机坐标系宏变量

兄弟机坐标系宏变量

兄弟机坐标系宏变量
"兄弟机坐标系"一般指的是数控机床上的坐标系。

数控机床通
常有多种坐标系,包括机床坐标系、工件坐标系和工具坐标系等。

这些坐标系可以通过宏变量来进行控制和管理。

宏变量是数控系统中用来存储数据和控制程序执行的一种特殊
变量。

在数控编程中,宏变量可以用来存储坐标系的偏移量、工件
尺寸、刀具补偿值等信息。

通过宏变量,操作人员可以方便地对坐
标系进行调整和管理,从而实现加工过程中的精确控制。

在数控编程中,宏变量的应用非常广泛。

通过合理地设置和运
用宏变量,可以实现复杂零件的加工,提高加工效率和精度。

同时,宏变量还可以用于编写通用的数控程序,从而实现程序的复用和标
准化。

总之,兄弟机坐标系和宏变量在数控加工中都扮演着非常重要
的角色。

合理地管理和运用宏变量,可以帮助操作人员更好地控制
和管理坐标系,实现高效精确的加工。

MFC的坐标系

MFC的坐标系

MFC的坐标系建立以左上角为原点,X轴和Y轴为1000的坐标我们可以用以下代码:void CTtView::OnDraw(CDC* pDC){CTtDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rect;GetClientRect(&rect);pDC->SetMapMode(MM_ANISOTROPIC);pDC->SetViewportOrg(0,0);pDC->SetViewportExt(rect.right,rect.bottom);pDC->SetWindowOrg(0,0);pDC->SetWindowExt(1000,1000);pDC->MoveTo(50,50);pDC->LineTo(50,950);pDC->LineTo(950,950);pDC->LineTo(50,50);}代码分析:1. GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect 中2. 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式3. 通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点4. 通过pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,1000);来确定逻辑坐标下和设备坐标下的尺寸对应关系5. 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同6. 坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的方向和视口的方向相同,即X轴向右为正,Y轴向下为正。

mfc teechart曲线坐标

mfc teechart曲线坐标

在MFC中,使用TeeChart控件绘制曲线图时,需要设置曲线的坐标系、坐标轴和数据系列等参数。

以下是一个示例代码,演示如何使用TeeChart控件绘制曲线图并显示坐标轴:在MFC资源编辑器中添加一个TeeChart控件,命名为“m_chart_RDE”。

在控件的事件处理程序中,获取控件的CSeries对象和CAxes对象,并设置曲线的坐标系、坐标轴和数据系列等参数。

示例代码如下:cpp// 获取控件的CSeries对象和CAxes对象CSeries* pSeries = (CSeries*)m_chart_RDE.Series(0);CAxes* pAxis = (CAxes*)m_chart_RDE.get_Axis();// 设置坐标轴的相关参数CAxis& leftAxis = pAxis->get_Left();leftAxis.put_Automatic(FALSE); // 关闭自动大小leftAxis.put_Maximum(30); // 设置最大值leftAxis.put_Increment(0); // 设置增量leftAxis.put_StartPosition(0); // 设置最小值开始的位置,百分比leftAxis.put_EndPosition(50); // 设置最大值结束的位置,百分比// 设置数据系列的相关参数pSeries->put_MarkerStyle(ms_MarkerStyleCircle); // 设置标记样式为圆形pSeries->put_MarkerSize(3); // 设置标记大小为3pSeries->put_LineWidth(2); // 设置线条宽度为2在主界面的.cpp文件中添加#include"CSeries",并书写绘制曲线的代码。

示例代码如下:cpp// 绘制曲线图CSeries mycs0 = (CSeries)m_chart_RDE.Series(0);for(int i=0; i<100; i++) {mycs0.AddNullXY(i,2*i+10,NULL); // 添加数据点,X轴为i,Y轴为2*i+10}通过以上代码,可以绘制出一个简单的曲线图,并显示X轴和Y轴的坐标轴。

运算机图形学MFC画图模式逻辑坐标系和设备坐标系解析

运算机图形学MFC画图模式逻辑坐标系和设备坐标系解析

MFC画图映射模式:咱们需要先清楚几个概念:客户区坐标:应用程序的客户区,左上角(0,0)屏幕坐标:包括整个屏幕坐标,(0,0);屏幕坐标用在WM_MOVE消息中(关于非子窗口)和下面的Windows函数中:CreateWindow和MoveWindow(都关于非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint和SetBrushOrg中。

用函数ClientToScreen和ScreenToClient能够将客户区域坐标转换成屏幕区域坐标,或反之。

全窗口坐标:一个程序的整个窗口,包括题目条。

菜单。

转动条和窗口框,(0,0).利用GetWindowDC取得的窗口设备环境,能够将逻辑单位转换成窗口坐标。

逻辑坐标系:设备坐标系:窗口坐标:视口坐标:数据显示和图形绘制并非是在屏幕上直接进行的,而是第一将图形绘制到一个具有逻辑坐标系的虚拟窗口中,然后在依照预先设置好的映射模式,将虚拟窗口中的图形或图像映射到屏幕或打印机等设备中。

虚拟的窗口叫窗口window,显示图像的设备确实是视口viewport.绘制图像的进程:先绘制到虚拟窗口(逻辑坐标)―――(映射模式)―――屏幕或打印机等设备(设备坐标)逻辑原点:逻辑坐标原点算作是窗口中的一个固定的点,通过该点引出两条坐标线,成立逻辑坐标系,长度单位和正方向通过setmapmode()来设置。

窗口原点:只是逻辑坐标系中一个可变点,那个点通过SetWindowOrg来设置。

设备原点:设备坐标原点可看做在视口的一个固定点,关于屏幕而言,它对应于左上角点,通过那个点成立设备坐标系,长度单位像素x 、y向下视口原点:视口原点是设备坐标系中的一个可变的点,那个点的坐标能够通过SetViewOrg 来设置。

逻辑坐标系和设备坐标系的联系:是通过窗口原点和视口原点联系的,当图像各点从逻辑坐标系向设备坐标系映射时,依照坐标之间的换算关系,换算成图像各点在设备坐标中相关于视口原点的位置,实现坐标映像。

mfc+opengl画几何图形,屏幕坐标与OpenGl坐标关系。

mfc+opengl画几何图形,屏幕坐标与OpenGl坐标关系。

mfc+opengl画几何图形,屏幕坐标与OpenGl坐标关系。

MFC和OpenGL一起画几何图形可以使绘图更简单和有效。

使用MFC和OpenGL绘制几何图形时,屏幕坐标系与OpenGL坐标系有一定的关系。

MFC使用屏幕坐标系来定位图形,而OpenGL使用OpenGL坐标系,它基于3D空间对象,但在使用绘图功能时来定位图形,所以它们之间有一
定的关系。

屏幕坐标系是以用户屏幕左上角的点作为原点,且屏幕方向的X,Y轴
的正方向是右、下方向的,简单的来说它就是用窗口内显示的坐标系。

而OpenGL坐标系是一个三维坐标系,它相对于屏幕坐标系的原点有一
定的偏移,它的坐标轴的方向与屏幕的坐标轴是正交的。

在MFC和OpenGL联合绘制几何图形时,需要把屏幕坐标系中的坐标全
部转换为OpenGL坐标系中的坐标,才能在屏幕上正确的显示图形。


个转换需要根据OpenGL空间中的不同位置和方向来进行转换,从而实
现准确的转换,从而使得MFC和OpenGL联合绘制几何图形更加有效。

Windows MFC CDC中的坐标

Windows MFC CDC中的坐标

pDC->SetWindowOrg((int)x0,(int)y0); //SetWindowOrg是设置设备上下文的窗口初始位置。 //它和设备上下文窗口一起说明了GDI如何将逻辑坐标中的点映射到实际设备坐标中。 //换言之,它们说明了GDI如何将逻辑坐标转换为设备坐标。 pDC->SetWindowExt((int)Width, (int)Height); //设置窗口的X和Y范围(Extent)。 //窗口和设备上下文窗口说明了GDI如何将逻辑坐标中的点映射到实际设备坐标中。 //换言之,它们说明了GDI如何将逻辑坐标转换为设备坐标。
鼠标位置
CRect rect; m_Picture.GetWindowRect(&rect); // 获取控件在屏幕里的位置和大小,以像素为单位 ScreenToClient(&rect); // 把控件的位置转换到当前程序窗体的坐标,以像素为单位 // 鼠标事件里的坐标是应用程序窗体的,指示的位置是窗体的坐标 // 此时的rect中(left,top)是控件左上角在应用程序窗体中的位置 point.Offset(-rect.left, -rect.top);//point是鼠标事件中的位置 // 把鼠标在程序窗体中的位置转换到控件中的位置
RECT rect; GetClientRect(&rect); // 获得绘制区域的设备坐标范围,原点在左上角。 // 该函数获取窗口客户区的坐标,以像素为单位。 // 客户区坐标指定客户区的左上角和右下角。 此左上角坐标为(0,0) // 设置视窗的原点(与用户原点对应) pDC->SetViewportOrg(10, rect.bottom-10); pDC->SetViewportExt(rect.right-20, -rect.bottom+20);

MFC的坐标系

MFC的坐标系

关于MFC的坐标系MFC和VC++ 2008-08-11 17:08:06 阅读108 评论0 字号:大中小订阅建立以左上角为原点,X轴和Y轴为1000的坐标我们可以用以下代码:void CTtView::OnDraw(CDC* pDC){CTtDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rect;GetClientRect(&rect);pDC->SetMapMode(MM_ANISOTROPIC);pDC->SetViewportOrg(0,0);pDC->SetViewportExt(rect.right,rect.bottom);pDC->SetWindowOrg(0,0);pDC->SetWindowExt(1000,1000);pDC->MoveTo(50,50);pDC->LineTo(50,950);pDC->LineTo(950,950);pDC->LineTo(50,50);}代码分析:1. GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect中2. 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式3. 通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点4. 通过pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,1000);来确定逻辑坐标下和设备坐标下的尺寸对应关系5. 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同6. 坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的方向和视口的方向相同,即X轴向右为正,Y轴向下为正。

7. 如果将显示模式改为MM_ISOTROPIC,那么X轴单位和Y轴单位一定相同,感兴趣的读者可以自己使一下。

mfc的二位坐标系缩放

mfc的二位坐标系缩放

mfc的二位坐标系缩放MFC(Microsoft Foundation Class)是Microsoft提供的开发框架,用于开发Windows平台上的应用程序。

二维坐标系缩放是指在二维平面上对坐标进行放大或缩小的操作,可以用来实现图形的缩放、平移等功能。

在MFC中,可以通过一些函数和方法来实现二维坐标系的缩放。

下面我们将详细介绍如何在MFC中实现二维坐标系的缩放功能。

首先,在MFC框架中,可以通过重写绘图框架(如CView类)的OnDraw函数来进行绘图操作。

在OnDraw函数中,可以使用CDC (Device Context)类来进行绘图操作。

对于二维坐标系的缩放,我们可以通过修改绘图操作时的坐标系来实现。

具体的步骤如下:1.获取绘图设备的宽度和高度。

可以使用CDC类的GetWindowExt 函数来获取绘图设备的宽度和高度。

int width, height;CDC* pDC = GetDC();width = pDC->GetWindowExt().cx;height = pDC->GetWindowExt().cy;2.设置缩放比例。

我们可以通过修改绘图操作时坐标系的缩放比例来实现缩放功能。

缩放比例可以是一个浮点数,表示放大或缩小的倍数。

float scaleX, scaleY;scaleX = 2.0; // x轴放大两倍scaleY = 1.5; // y轴放大1.5倍3.缩放绘图设备的坐标系。

可以使用CDC类的ScaleViewportExt 函数来缩放绘图设备的坐标系。

pDC->ScaleViewportExt(scaleX, scaleY, scaleX, scaleY);这个函数的四个参数分别表示x轴的缩放比例、y轴的缩放比例、x轴的原点位置和y轴的原点位置。

在这里,我们将原点位置也按照相同比例进行缩放。

4.根据缩放后的坐标系进行绘图。

在进行绘图操作时,坐标的位置也需要进行相应的缩放操作。

MFC映射模式

MFC映射模式

MFC映射模式所谓映射模式,说白了就是坐标系。

在默认情况下,Windows所绘图像单位为像素,这是因为设备环境用了默认的映射模式MM_TEXT,所以如下语句所绘图形为长和宽都为200像素的方块:pDC->Rectangle(CRect(0,0,200,200));那么我们要绘制一个长和宽都是4厘米的方块该怎么做呢?这就必须改变设备环境的默认映射模式为MM_HIMETRIC,它的图像单位为1/100mm,而不是像素了。

它的y轴方向和MM_TEXT 的相反,它的向下为递减的,因此用如下语句就可以绘出4×4cm的方块了:pDC->SetMapMode( MM_HIMETRIC);pDC->Rectangle(CRect(0,0,4000,-4000));下面我们再来了解一下Windows都提供了哪些映射模式。

1、MM_TEXT映射模式这种模式下,绘图单位为像素,x轴向右递增,y轴向下递增,我们可以用CDC的SetViewPortOrg和SetWindowOrg函数来改变坐标原点的位置,下面的代码就是把坐标原点设在了(100,100)处,画了一个200×200像素的方块,此时逻辑坐标点(100,100)被映射到了设备坐标点(0,0)处,下一篇的滚动窗口使用的就是这种变换。

Void CmyView::OnDraw( CDC *pDC ){pDC->SetMapMode(MM_TEXT);pDC->SetWindowOrg(Cpoint(100,100));pDC->Rectangle(CRect(100,100,200,200));}2、固定比例映射模式Windows提供了一组非常重要的固定比例影视模式,所有这种模式都遵循x轴向右递减,y 轴向下递减的规则,而且我们无法将其改变。

固定比例模式之间唯一的差别就在于实际的比例因子。

下表列出了影视模式和比例因子的对应情况:映射模式逻辑单位MM_LOENGLISH0.01英寸MM_HIENGLISH0.001英寸MM_LOMETRIC0.1mm MM_HIMETRIC0.01mm MM_TWIPS1/1440英寸MM_TWIPS模式常用于打印机。

MFC界面坐标获取转换及区域获取

MFC界面坐标获取转换及区域获取

MFC界面坐标获取转换及区域获取MFC界面坐标获取/转换及区域获取MFC界面相关常用方法整理:坐标点----CPoint:CPoint构造方法:CPoint();CPoint( int initX, int initY );CPoint(POINT initPt );CPoint( SIZE initSize );CPoint(DWORD dwPoint );参数:initXSpecifies the value of the x member of CPoint.initYSpecifies the value of the y member of CPoint.initPtPOINT structure orCPoint that specifies the values used to initializeCPoint.initSizeSIZE structureor CSize that specifiesthe values used to initialize CPoint.dwPointSets the x member to the low-order word of dwPoint and the ymember to the high-order word of dwPoint.光标----GetCursorPos/SetCursorPosGetCursorPos函数功能:该函数检取光标的位置,以屏幕坐标表示。

函数原型:BOOL GetCursorPos(LPPOlNTIpPoint);参数:IpPoint:POINT结构指针,该结构接收光标的屏幕坐标。

返回值:如果成功,返回值非零;如果失败,返回值为零。

若想获得更多错误信息,请调用GetLastError函数。

备注:1.光标的位置通常以屏幕坐标的形式给出,它并不受包含该光标的窗口的映射模式的影响。

该调用过程必须具有对窗口站的WINSTA_READATTRIBUTES访问权限。

如何在MFC对话框中绘制直角坐标

如何在MFC对话框中绘制直角坐标

如何在MFC对话框中绘制直角坐标有时为了对采集数据进行显示, 需要在界面中显示直角坐标, 主要操作均在OnPaint函数中完成, 下面就简单的讲解下如何实现:1. 添加static静态文本框到对话框上, 并修改其ID为IDC_MYSTATIC2. 在对话框的申明文件即CXXXDlg.h文件中定义变量:CWnd *pWnd; //获取控件窗口类指针3. 在其cpp实现文件中的OnInitDialog()函数中获取:pWnd = GetDlgItem(IDC_MYSTATIC);4. 在OnPaint()中的代码如下:void CXXXDlg::OnPaint(){CPaintDC dc(this); // device context for paintingCString str;int i, j;int x, y;//强制更新绘图, 不可少, 否则绘图会出错//使static控件区域无效pWnd->Invalidate();//更新窗口, 此时才真正向系统发送重绘消息, 没有这句你可以试下, 绝对出问题pWnd->UpdateWindow();CDC *pDC = pWnd->GetDC(); //获取控件的CDC 指针pDC->Rectangle(0, 0, 380, 390); //画一个矩形框CPen *pPenRed = new CPen(); //创建画笔对象pPenRed ->CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); //红色画笔CPen *pPen = NULL;//选中当前红色画笔,并保存以前的画笔CGdiObject *pOldPen = pDC ->SelectObject(pPenRed); pDC ->MoveT o(20, 20); //绘制坐标轴pDC ->LineTo(20, 360); //竖起轴pDC ->LineTo(360, 360); //水平轴//写X轴刻度值for(i = 0; i <= 10; i ++){str.Format("%d", i);pDC ->TextOut(17 + 30 * i, 365, str);//绘制X轴刻度pDC ->MoveT o(i * 30 + 20, 360);pDC ->LineTo(i * 30 + 20, 355);}//写Y轴刻度值for(i = 1; i <= 10; i ++){str.Format("%d", i);pDC ->TextOut(2, 360 - 30 * i - 5, str);//绘制Y轴刻度pDC ->MoveT o(25, 360 - 30 * i);pDC ->LineTo(20, 360 - 30 * i);}//绘制X箭头pDC ->MoveT o(350, 357);pDC ->LineTo(360, 360);pDC ->LineTo(350, 363);//绘制Y箭头pDC ->MoveT o(17, 30);pDC ->LineTo(20, 20); //绘制左边箭头pDC ->LineTo(23, 30); //绘制右边箭头//恢复以前的画笔pDC ->SelectObject(pOldPen);delete pPenRed;if(pPen != NULL)delete pPen;ReleaseDC(pDC);}效果见下图(因为以前做过相关的东西, 就直接贴出来了, 并没有单独的图片, 看下效果就可以):。

MFC编程

MFC编程

MFC编程先认识一下MFC中的一些和绘图有关的结构体和类1.点(1)点结构POINT点数据结构POINT用来表示一点的x、y坐标:typedef struct tagPOINT {LONG x;LONG y;} POINT;(2)点类CPoint点类CPoint为一个没有基类的独立类,封装了POINT结构,有成员变量x和y其构造函数有5种:CPoint( );CPoint( int initX, int initY );CPoint( POINT initPt );CPoint( SIZE initSize );CPoint( LPARAM dwPoint );// 低字设为x、高字设为yCPoint类还定义了4个平移和设置函数:void Offset(int xOffset, int yOffset);void Offset(POINT point);void Offset(SIZE size);void SetPoint(int X, int Y);CPoint类还重载了+、-、+=、-=、==、!=等运算符来支持CPoint对象和CPoint、POINT、SIZE对象之间的运算。

2.大小(1)大小结构SIZE大小(size尺寸)结构SIZE用来表示矩形的宽cx和高cy:typedef struct tagSIZE {LONG cx;LONG cy;} SIZE(2)大小类CSize大小类CSize也为一个没有基类的独立类,封装了SIZE结构,有成员变量cx和cy其构造函数也有5种:CSize( );CSize( int initCX, int initCY );CSize( SIZE initSize );CSize( POINT initPt );CSize( DWORD dwSize ); // 低字设为cx、高字设为cyCSizet类也重载了+、-、+=、-=、==、!=等运算符来支持CSize对象和CSize、POINT、SIZE、RECT对象之间的运算3.矩形(1)矩形结构RECT矩形结构RECT定义了矩形的左上角与右下角的坐标:typedef struct tagRECT {LONG left;LONG top;LONG right;LONG bottom;} RECT;(2)矩形类CRect矩形类CRect也为一个没有基类的独立类,封装了RECT结构,有成员变量left、top、right 和bottom其构造函数有6种:CRect( );CRect( int l, int t, int r, int b );CRect( const RECT& srcRect );CRect( LPCRECT lpSrcRect );CRect( POINT point, SIZE size );CRect( POINT topLeft, POINT bottomRight );CRect类重载了=,+、-,+=、-=,==、!=,&、|,& =、|=等运算符来支持CRect对象和CRect、POINT、SIZE、RECT对象之间的运算。

mfc对话框画三维矩阵

mfc对话框画三维矩阵

mfc对话框画三维矩阵摘要:一、引言二、MFC对话框概述1.MFC对话框简介2.MFC对话框与普通对话框的区别三、MFC对话框画三维矩阵1.对话框背景的绘制2.控件的绘制3.坐标系的转换4.绘制三维矩阵的实现四、MFC对话框画三维矩阵的应用1.数据可视化2.三维模型展示3.科学计算的可视化五、结论正文:一、引言在MFC(Microsoft Foundation Class)中,对话框是一种常用的窗口类型,可以用于显示和编辑数据。

然而,在实际应用中,我们常常需要对数据进行三维展示,这就需要对话框具备画三维矩阵的功能。

本文将详细介绍如何在MFC对话框中画出三维矩阵。

二、MFC对话框概述1.MFC对话框简介MFC对话框是MFC中一种特殊的窗口,通常用于显示和编辑数据。

它与普通对话框的区别在于,MFC对话框可以包含多种控件,如列表框、编辑框等,以满足不同的数据展示和编辑需求。

2.MFC对话框与普通对话框的区别MFC对话框与普通对话框的主要区别在于,MFC对话框是MFC框架类,而普通对话框是Windows API中的对话框。

MFC对话框可以自定义外观和行为,而普通对话框则相对固定。

此外,MFC对话框提供了更丰富的控件和更强大的功能。

三、MFC对话框画三维矩阵1.对话框背景的绘制在MFC对话框中,要画出三维矩阵,首先需要绘制对话框的背景。

这可以通过重载对话框的OnPaint()方法实现。

在OnPaint()方法中,可以调用CDC::SetPixel()方法来绘制背景颜色。

2.控件的绘制在对话框中,除了背景,还需要绘制各种控件,如列表框、编辑框等。

这可以通过重载控件的OnDraw()方法实现。

在OnDraw()方法中,可以调用CDC::DrawControl()方法来绘制控件。

3.坐标系的转换在绘制三维矩阵时,需要将三维坐标系转换为对话框上的二维坐标系。

这可以通过计算控件的相对位置和大小实现。

首先,需要获取控件的客户区域,然后计算该区域在对话框上的位置和大小。

MFC绘图中关于坐标映射的说明

MFC绘图中关于坐标映射的说明

窗口和视口原点的改变以及与设备坐标的关系关于SetWindowOrg使用说明示例:把设备坐标的原点(视口)映射到逻辑坐标的(X, Y)处。

绘图代码如下dc.SetWindowOrg(20,20);//将(20,20)作为设备环境的原点;dc.MoveTo(20,20);//这个点对应设备环境(对话框客户区的原点)原点dc.LineTo(200,200);由于GDI绘图使用的是逻辑坐标,故等同于将逻辑坐标(20,20)看成设备环境(对话框客户区)的原点:即设备环境的原点等同于逻辑坐标的(20,20)。

这条线与在未改变窗口的原点之前,与dc.MoveTO(0,0,);dc.LineTO(180,180);效果等同将代码改成如下CPaintDC dc(this); // device context for paintingCPen pen(PS_SOLID,2,RGB(255,0,0));CPen* pOldPen = dc.SelectObject(&pen);dc.MoveTo(0,0);dc.LineTo(160,160);dc.SelectObject(pOldPen);dc.SetWindowOrg(20,20);//将(20,20)作为设备环境的原点;dc.MoveTo(20,20);//这个点对应设备环境(对话框客户区的原点)原点dc.LineTo(200,200);可以很明显的看到在未改变窗口坐标原点之前与改变窗口坐标原点之后的对比,它们的起点相同,实例3CPaintDC dc(this); // device context for paintingCPen pen(PS_SOLID,2,RGB(255,0,0));CPen* pOldPen = dc.SelectObject(&pen);dc.SetWindowOrg(-20,-20);//将(-20,-20)作为设备环境的原点,当然坐标依然是X轴向右为正,Y轴向下为正dc.MoveTo(-10,-10);dc.LineTo(200,200);2. 关于SetViewportOrg :是把逻辑坐标的原点(窗口)映射到设备坐标的(X, Y)处CPaintDC dc(this); // device context for paintingCPen pen(PS_SOLID,2,RGB(255,0,0));CPen* pOldPen = dc.SelectObject(&pen);dc.SetViewportOrg(20,20);//逻辑原点点(0,0)映射成设备点(20,20)dc.MoveTo(-10,-10);dc.LineTo(200,200);代码改成如下dc.MoveTo(0,0);dc.LineTo(200,200);dc.SelectObject(pOldPen);dc.SetViewportOrg(20,20);//逻辑点(0,0)对应设备点(20,20)dc.MoveTo(0,0);dc.LineTo(200,200);需要明确指出的是任意一点进行平移旋转,1. 确定AB 线,作为向量AB ,把A 点作为参考点,平移至(0,0),然后A (Xa,Ya )------→A ’(0,0)B (Xb,Yb)--------→B ’(Xb-Xa,Yb-Ya)2. 将向量AB 旋转方向与Y 轴正半轴相同 Y 轴正半轴向量(0,1)求解旋转角Cos = (Yb-Ya)/(sqrt((Xb-Xa)* (Xb-Xa) +(Yb-Ya)*(Yb- Ya)))3. 得到角度后旋转向量AB 线旋转,就得到了与Y 轴平行AB ‘线,作为导航线旋转公式 设P (x ,y ),逆时针旋转 jiao 为P ‘(X ’,Y ’)X ’ = xcos - ysinY ’= xsin + ycos拖拉机空间坐标按照前面的步骤 先平移同样的单位,在进行旋转这样进行坐标转换之后的缺陷在于,A点作为原点,AB即为Y轴,通过A点垂直于AB的直线为X轴如图所示如果拖拉机的坐标出现在画阴影线区域,则及时转换后坐标也是不能显示到绘图区域,所以以通过AB点的两条互相垂直的直线为边界,地块只能位于非阴影区域,否则转化的到的坐标在绘制时是显示不出来的。

实例详解:MFC坐标轴实现

实例详解:MFC坐标轴实现

实例详解:MFC坐标轴实现需求:MFC坐标轴实现-----最好有步骤啊,刚刚才接触C++和MFC啊。

MFC怎样在特定区域建⽴坐标轴,x轴⾃适应,y轴有固定范围,最好有⽹格。

解决思路:VC 内存绘图,不闪屏,具体代码如下:// 先上传代码,在.h ⽂件中:#pragma once#include <afxtempl.h>#define TEXT_AREA_WIDTH (60) ///< ⽂字区宽度,单位像素#define X_AXIS_GRAD (600) ///< X 轴刻度值#define Y_AXIS_GRAD (50) ///< X 轴刻度值class My_Draw : public CStatic{// 构造/析构函数public:My_Draw();virtual ~My_Draw();public:struct{unsigned char Show_Max_Grid :1; // 是否显⽰⼤⽹格unsigned char Show_Min_Grid :1; // 是否显⽰⼩⽹格unsigned char Draw_Enable :1; // 放⼤/缩⼩使能位unsigned char Draw_Line_Choice :1; // 线被选择unsigned char LButton_Down_Flag :1; // ⿏标左键按下标志unsigned char LButton_Up_Flag :1; // ⿏标左键弹起标志unsigned char LButton_Double_Down_Flag :1; // ⿏标左键双击按下标志}Bool_Flag;unsigned int TextAreaWidth;int xAxisGrad,yAxisGrad;unsigned short xMaxGrad,xMinGrad;unsigned short yMaxGrad,yMinGrad;int Limit_Min,Limit_Max;POINT Mouse_Current_Point; // ⿏标当前坐标POINT Button_Down_Point; // 记录⿏标左键按下时的坐标POINT LButton_Double_Down_Point; // 记录⿏标左键双击按下的坐标POINT Old_LButton_Double_Down_Point;// 画笔列表CPen* pBrack; // ⿊⾊画笔CPen* pBlue; // 蓝⾊画笔CPen* pYellow; // 黄⾊画笔CPen* pGren; // 绿⾊画笔CPen* pPink; // 紫⾊画笔CPen* pRed; // 红⾊画笔CPen* pGray; // 灰⾊画笔CRect Draw_Size;CDC memDC;CBitmap memBitmap;CBitmap* pOldBmp;unsigned short SheetMaxH;CWnd *pWnd;void Draw();void Drawing(CDC *pDC); // 绘制图表void Draw_xAxis(CDC *pDC);void Draw_yAxis(CDC *pDC);void Draw_Cross_Cursor(CDC *pDC);void My_Draw::SaveBmpToFile();protected:afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);DECLARE_MESSAGE_MAP()};// .CPP ⽂件中:#include "stdafx.h"#include "Draw_Static_Text.h"#include "conio.h"#include "direct.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// 构造函数My_Draw::My_Draw(){Bool_Flag.Show_Max_Grid = false;Bool_Flag.Show_Min_Grid = false;Bool_Flag.Draw_Enable = false;Bool_Flag.Draw_Line_Choice = false;Bool_Flag.LButton_Down_Flag = false;Bool_Flag.LButton_Up_Flag = false;Bool_Flag.LButton_Double_Down_Flag = false;TextAreaWidth = TEXT_AREA_WIDTH;xAxisGrad = X_AXIS_GRAD;yAxisGrad = Y_AXIS_GRAD;pBrack = new CPen(); // ⿊⾊画笔pBlue = new CPen(); // 蓝⾊画笔pYellow = new CPen(); // 黄⾊画笔pGren = new CPen(); // 绿⾊画笔pRed = new CPen(); // 红⾊画笔pPink = new CPen(); // 紫⾊画笔pGray = new CPen(); // 灰⾊画笔pBrack->CreatePen(PS_SOLID,1,RGB(0,0,0));pBlue->CreatePen(PS_SOLID,1,RGB(0,0,255));pYellow->CreatePen(PS_SOLID,1,RGB(155,125,0));pGren->CreatePen(PS_SOLID,1,RGB(0,255,0));pRed->CreatePen(PS_SOLID,1,RGB(255,0,0));pPink->CreatePen(PS_SOLID,1,RGB(255,0,255));pGray->CreatePen(PS_DOT,1,RGB(145,105,105));#ifdef _DEBUGAllocConsole();_cprintf("Debuging....\r\n");#endif}// 析构函数My_Draw::~My_Draw(){delete pBrack; // ⿊⾊画笔delete pBlue; // 蓝⾊画笔delete pYellow; // 黄⾊画笔delete pGren; // 绿⾊画笔delete pRed; // 红⾊画笔delete pPink; // 紫⾊画笔delete pGray; // 灰⾊画笔}BEGIN_MESSAGE_MAP(My_Draw, CStatic)ON_WM_LBUTTONDOWN()ON_WM_MOUSEMOVE()ON_WM_LBUTTONUP()ON_WM_LBUTTONDBLCLK()END_MESSAGE_MAP()void My_Draw::SaveBmpToFile() // 保存图表为 Bmp 图⽚{CFileDialog dlg(false,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "位图⽂件(*.bmp)|*.bmp|",NULL);if (dlg.DoModal()!= IDOK) return;CString filename = dlg.GetFileName() + ".bmp";// 获取绘制坐标的⽂本框this->GetClientRect(&Draw_Size); // 获取窗⼝⼤⼩CDC *pDC = this->GetDC(); // 获取 dcthis->Invalidate();this->UpdateWindow();//内存绘图memDC.CreateCompatibleDC(pDC);memBitmap.CreateCompatibleBitmap(pDC,Draw_Size.right,Draw_Size.bottom);pOldBmp = memDC.SelectObject(&memBitmap);memDC.BitBlt(Draw_Size.left,Draw_Size.top,Draw_Size.right,Draw_Size.bottom,pDC,0,0,SRCCOPY); Drawing(&memDC); // 绘制坐标BITMAP bmp;memBitmap.GetBitmap(&bmp); // 获得位图信息FILE *fp;fopen_s(&fp,filename, "w+b");BITMAPINFOHEADER bih = {0}; // 位图信息头bih.biBitCount = bmp.bmBitsPixel; // 每个像素字节⼤⼩bih.biCompression = BI_RGB;bih.biHeight = bmp.bmHeight; // ⾼度bih.biPlanes = 1;bih.biSize = sizeof(BITMAPINFOHEADER);bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight; // 图像数据⼤⼩bih.biWidth = bmp.bmWidth; // 宽度BITMAPFILEHEADER bfh = {0}; // 位图⽂件头bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // 到位图数据的偏移量bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight; // ⽂件总的⼤⼩bfh.bfType = (WORD)0x4d42;fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp); // 写⼊位图⽂件头fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp); // 写⼊位图信息头byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight]; // 申请内存保存位图数据GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Draw_Size.Height(), p, (LPBITMAPINFO) &bih, DIB_RGB_COLORS); //获取位图数据 fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp); // 写⼊位图数据delete [] p;fclose(fp);memDC.SelectObject(pOldBmp);memDC.DeleteDC(); // 释放 DcmemBitmap.DeleteObject();}void My_Draw::Draw(){this->Invalidate();this->UpdateWindow();this->GetClientRect(&Draw_Size); // 获取窗⼝⼤⼩CDC *pDC = this->GetDC(); // 获取 dc//内存绘图memDC.CreateCompatibleDC(pDC);memBitmap.CreateCompatibleBitmap(pDC,Draw_Size.right,Draw_Size.bottom);pOldBmp = memDC.SelectObject(&memBitmap);memDC.BitBlt(Draw_Size.left,Draw_Size.top,Draw_Size.right,Draw_Size.bottom,pDC,0,0,SRCCOPY);Drawing(&memDC); // 绘制坐标pDC->BitBlt(Draw_Size.left,Draw_Size.top,Draw_Size.right,Draw_Size.bottom,&memDC,0,0,SRCCOPY);memDC.SelectObject(pOldBmp);memDC.DeleteDC();memBitmap.DeleteObject();ReleaseDC(pDC);}void My_Draw::Drawing(CDC *pDC){pDC->SelectObject(pBrack); // 选择当前画笔颜⾊pDC->Rectangle(0,0,Draw_Size.Width(),Draw_Size.Height()); // 设定绘制范围//绘出⽂字pDC->SetTextColor(RGB(0,25,255));pDC->SetBkMode(TRANSPARENT);pDC->TextOutA(5,180,"输");pDC->TextOutA(5,200,"出");pDC->TextOutA(5,220,"电");pDC->TextOutA(5,240,"压");pDC->TextOutA(11,260,"|");pDC->TextOutA(5,280,"单");pDC->TextOutA(5,300,"位");pDC->TextOutA(3,320,"(V)");pDC->TextOutA(Draw_Size.Width()/2-40,Draw_Size.Height()-20,"⾏程--单位 (%)");SheetMaxH = Draw_Size.Height()-TextAreaWidth;Draw_xAxis(pDC);Draw_yAxis(pDC);Draw_Cross_Cursor(pDC);ReleaseDC(pDC);}void My_Draw::Draw_xAxis(CDC *pDC){CString StrScale; // 转换刻度字符串存放点unsigned short drawCount; // 画王格计数unsigned short temp;unsigned int girdSize;//绘制x轴坐标pDC->MoveTo(TextAreaWidth,SheetMaxH);pDC->LineTo(Draw_Size.Width(),SheetMaxH);//绘制箭头pDC->LineTo(Draw_Size.Width()-10,SheetMaxH-5);pDC->MoveTo(Draw_Size.Width(),SheetMaxH);pDC->LineTo(Draw_Size.Width()-10,SheetMaxH+5);//绘制x轴刻度drawCount = 0;if(xAxisGrad > Draw_Size.Width()){xAxisGrad/=10;girdSize = 10;}elsegirdSize = 1;xMaxGrad = int((Draw_Size.Width() - TextAreaWidth) / xAxisGrad);for(int i=TextAreaWidth; i<=Draw_Size.Width(); i+=xMaxGrad){pDC->SelectObject(pBrack);pDC->MoveTo(i,SheetMaxH);if(xMaxGrad<2)temp = xMaxGrad*100;elsetemp = xMaxGrad*10;if((i-TextAreaWidth)%temp==0){pDC->LineTo(i,SheetMaxH+10); // 整数刻度,绘制长刻度//输出对应的⽂本if(drawCount < 100){//pDC->SelectObject(font1); //选择当前字体StrScale.Format(" %d", drawCount*girdSize);pDC->SetTextColor(RGB(25, 155, 12));pDC->TextOutA(i-10, SheetMaxH+10, StrScale); //修正⽂本显⽰坐标 3位数内,显⽰⽅式if(Bool_Flag.Show_Max_Grid){pDC->SelectObject(pGray); //使⽤虚线灰⾊画笔pDC->MoveTo(i,SheetMaxH);pDC->LineTo(i,20);}}else{StrScale.Format(" %d", drawCount*girdSize);pDC->TextOutA(i-12, SheetMaxH+10, StrScale); //修正⽂本显⽰坐标 4位数内,显⽰⽅式if(Bool_Flag.Show_Max_Grid){pDC->SelectObject(pGray); //使⽤虚线灰⾊画笔pDC->MoveTo(i, SheetMaxH);pDC->LineTo(i, 20);}}}else{pDC->LineTo(i,SheetMaxH+5); //⼩数刻度,绘制短刻度}drawCount++;}ReleaseDC(pDC);}void My_Draw::Draw_yAxis(CDC *pDC){unsigned int drawCount;CString StrScale; //转换刻度字符串存放点drawCount = 0;//绘制y轴坐标pDC->MoveTo(TextAreaWidth, SheetMaxH);pDC->LineTo(TextAreaWidth, 10);//绘制箭头pDC->LineTo(TextAreaWidth-5, 20);pDC->MoveTo(TextAreaWidth, 10);pDC->LineTo(TextAreaWidth+5, 20);yMaxGrad = int(SheetMaxH / yAxisGrad);for(int i=SheetMaxH; i>=20; i-=yMaxGrad){pDC->SelectObject(pBrack);StrScale.Format("%d", drawCount / 10);pDC->MoveTo(TextAreaWidth, i);if(drawCount % 10==0){pDC->LineTo(TextAreaWidth-10, i); //整数刻度,绘制长刻度if(Bool_Flag.Show_Max_Grid){pDC->SelectObject(pGray); //使⽤实线灰⾊画笔pDC->MoveTo(TextAreaWidth, i);pDC->LineTo(Draw_Size.Width()-10, i);}pDC->SetTextColor(RGB(255, 0, 0));pDC->TextOutA(TextAreaWidth-25, i-6, StrScale+"V"); //输出对应的⽂本}else{pDC->LineTo(TextAreaWidth-5, i); //⼩数刻度,绘制短刻度}drawCount++;}ReleaseDC(pDC);}void My_Draw::Draw_Cross_Cursor(CDC *pDC){int m_intVoltage;int m_intAngle;// ⼗字光标和显⽰坐标信息if(Bool_Flag.LButton_Double_Down_Flag){if((LButton_Double_Down_Point.x > TextAreaWidth)&&(LButton_Double_Down_Point.x < Draw_Size.Width())&&(LButton_Double_Down_Point.y > 20)&&(LButton_Double_Down_Point.y < SheetMaxH)){if(Bool_Flag.Draw_Line_Choice)pDC->SelectObject(pGren);elsepDC->SelectObject(pRed);pDC->MoveTo(LButton_Double_Down_Point.x, 1);pDC->LineTo(LButton_Double_Down_Point.x, SheetMaxH-1);pDC->MoveTo(TextAreaWidth+1, LButton_Double_Down_Point.y);pDC->LineTo(Draw_Size.Width()-1,LButton_Double_Down_Point.y);Old_LButton_Double_Down_Point = LButton_Double_Down_Point;m_intVoltage = yAxisGrad;m_intVoltage = (SheetMaxH - LButton_Double_Down_Point.y)/m_intVoltage; m_intVoltage /= 10;m_intAngle = xAxisGrad;m_intAngle = (LButton_Double_Down_Point.x - TextAreaWidth)/m_intAngle; #ifdef _DEBUG_cprintf("Voltage = %0.2f,Angle = %0.2f\r\n",xAxisGrad,m_intAngle);#endifUpdateData(FALSE);}}if(Bool_Flag.LButton_Down_Flag){pDC->SelectObject(pBrack);pDC->MoveTo(Button_Down_Point);pDC->LineTo(Mouse_Current_Point.x,Button_Down_Point.y);pDC->MoveTo(Mouse_Current_Point.x,Button_Down_Point.y);pDC->LineTo(Mouse_Current_Point);pDC->MoveTo(Mouse_Current_Point);pDC->LineTo(Button_Down_Point.x,Mouse_Current_Point.y);pDC->MoveTo(Button_Down_Point.x,Mouse_Current_Point.y);pDC->LineTo(Button_Down_Point);}ReleaseDC(pDC);}void My_Draw::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调⽤默认值Mouse_Current_Point = point;if(Bool_Flag.Draw_Line_Choice){Limit_Min = point.x - 5;Limit_Max = point.x + 5;LButton_Double_Down_Point = point;}if((Bool_Flag.LButton_Down_Flag)||(Bool_Flag.LButton_Up_Flag))Draw();CStatic::OnMouseMove(nFlags, point);}void My_Draw::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调⽤默认值if((Bool_Flag.LButton_Double_Down_Flag)&&(point.x >= Limit_Min)&&(point.x <= Limit_Max)){if(Bool_Flag.Draw_Line_Choice)Bool_Flag.Draw_Line_Choice = FALSE;elseBool_Flag.Draw_Line_Choice = TRUE;LButton_Double_Down_Point = point;}else{if((Bool_Flag.LButton_Down_Flag == FALSE)&&(Bool_Flag.Draw_Line_Choice == FALSE)){Bool_Flag.LButton_Down_Flag = true;Button_Down_Point = point;}}Draw();CStatic::OnLButtonDown(nFlags, point);}void My_Draw::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调⽤默认值if(Bool_Flag.LButton_Down_Flag){Bool_Flag.LButton_Up_Flag = true;Bool_Flag.LButton_Down_Flag = FALSE;Draw();}CStatic::OnLButtonUp(nFlags, point);}void My_Draw::OnLButtonDblClk(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调⽤默认值LButton_Double_Down_Point = point;Limit_Min = LButton_Double_Down_Point.x - 5;Limit_Max = LButton_Double_Down_Point.x + 5;Bool_Flag.LButton_Double_Down_Flag = TRUE;Draw();CStatic::OnLButtonDblClk(nFlags, point);}程序运⾏效果图现在说明⼀下1. 新建⼀个 MFC 应⽤程序2. 选择“基于对话框”3. 添加⼀个 “Picture 控件”4. 为控件添加⼀个变量 my_Graw5. 将源⽂件包含进来,并在 My_ClassDlg.h 中包含 #include "My Draw.h"6. 在 My_ClassDlg.h 头⽂件中将刚才声明的 Picture 控件变量 CStatic my_Graw ; 改成 My_Draw my_Graw;7. 在 My_ClassDlg.cpp ⽂件 void CMy_ClassDlg::OnPaint() 尾部添加 my_Graw.Draw();8. 编译运⾏。

《C++开发GIS系统》第4章 与绘图操作有关的MFC类及操作

《C++开发GIS系统》第4章 与绘图操作有关的MFC类及操作

实时的将图形绘制到屏幕上。如果用CPaintDC类对象完 成同样的工作,只能发出消息让屏幕上包含这条直线 的区域重画,以把这条直线绘制到屏幕上。当然,重 画区域内的其他图形元素同时也被重画。
4.1.3 绘图类的使用方法
(1)CDC类 因为CDC类不能用窗口对象指针初始化对象,所以一般 不直接创建对象,但经常用来建立一个内存设备描述 对象,创建方法如下:
4.1.1 绘图类简介
(1)CDC类 CDC类是CObject类的一个派生类,CDC类是所有绘图类 的基类。CDC类定义了一个设备描述对象。CDC类提 供了对设备描述对象进行操作的成员函数,以及对与 窗口客户区有关的显示区进行操作的成员函数。通过 CDC类及其派生类创建的对象,可以利用CDC类的所 有成员函数完成图形的绘制工作。CDC类提供的成员 函数,可以用于对设备描述对象进行的操作、绘图工 具的使用、图形设备界面(GDI)的选择,以及颜色 和调色板的操作。它提供的成员函数还用于取得和设 置绘图属性、映像方式、视口和窗口范围的操作、坐 标的转换、区域的使用、剪取、画线,以及绘制图形、
CDC dc;
(2)CPaintDC类 CPaintDC类一般用在窗口类的OnPaint函数中,可采取如 下代码创建一个CPaintDC类对象:
CPaintDC dc(this);
以上代码创建了一个CPaintDC类对象dc,并用当前的窗 口对象指针this对对象进行了初始化。CClientDC类和
通过本篇的学习,引导读者能够从理论和技 术上掌握基本矢量图形系统的设计方法, 掌握MFC应用程序的设计技术。
本章各小节目录
4.1 绘图类 4.2 绘图设备类 4.3 坐标映射方式 4.4 窗口和视口 4.5 其他绘图类操作函数

mfc 贝塞尔曲线

mfc 贝塞尔曲线

MFC(Microsoft Foundation Class)是一组用于开发Windows桌面应用程序的C++类库。

在MFC中,您可以使用贝塞尔曲线来创建平滑曲线或路径。

贝塞尔曲线是一种数学曲线,通常用于绘制平滑的曲线或路径,其中包括四个控制点:起点、终点以及两个控制点。

以下是在MFC中使用贝塞尔曲线的基本步骤:1. **包含MFC头文件**:首先,在您的MFC应用程序中包含必要的头文件。

通常,您需要包含`afxwin.h`和`afxext.h`等头文件。

2. **创建CPoint对象**:为了定义贝塞尔曲线,您需要创建四个`CPoint`对象来表示起点、终点以及两个控制点。

```cppCPoint startPoint(x1, y1); // 起点坐标CPoint endPoint(x2, y2); // 终点坐标CPoint controlPoint1(x3, y3); // 控制点1坐标CPoint controlPoint2(x4, y4); // 控制点2坐标```3. **使用CDC对象绘制贝塞尔曲线**:MFC中的CDC(Device Context)对象用于绘制图形。

您可以使用CDC对象的`PolyBezier`方法来绘制贝塞尔曲线。

```cppCDC* pDC = GetDC(); // 获取设备上下文对象pDC->PolyBezier(startPoint, controlPoint1, controlPoint2, endPoint);ReleaseDC(pDC); // 释放设备上下文对象```上述代码使用`PolyBezier`方法绘制了一个贝塞尔曲线,其中`startPoint`是起点,`endPoint`是终点,`controlPoint1`和`controlPoint2`是控制点。

4. **刷新窗口**:如果在视图或对话框中进行绘制,通常需要在绘制之后调用`Invalidate`或`InvalidateRect`来请求重绘窗口,以使绘制的曲线可见。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于MFC的坐标系MFC和VC++ 2008-08-11 17:08:06 阅读108 评论0 字号:大中小订阅
建立以左上角为原点,X轴和Y轴为1000的坐标
我们可以用以下代码:
void CTtView::OnDraw(CDC* pDC)
{
CTtDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect rect;
GetClientRect(&rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetViewportOrg(0,0);
pDC->SetViewportExt(rect.right,rect.bottom);
pDC->SetWindowOrg(0,0);
pDC->SetWindowExt(1000,1000);
pDC->MoveTo(50,50);
pDC->LineTo(50,950);
pDC->LineTo(950,950);
pDC->LineTo(50,50);
}
代码分析:
1. GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect中
2. 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式
3. 通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点
4. 通过pDC->SetViewportExt(rect.right,rect.bottom);和
pDC->SetWindowExt(1000,1000);来确定逻辑坐标下和设备坐标下的尺寸对应关系
5. 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同
6. 坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的方向和视口的方向相同,即X轴向右为正,Y轴向下为正。

7. 如果将显示模式改为MM_ISOTROPIC,那么X轴单位和Y轴单位一定相同,感兴趣的读者可以自己使一下。

(二)建立以视窗中心为原点的坐标
用如下代码:
void CTtView::OnDraw(CDC* pDC)
{
CTtDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CRect rect;
GetClientRect(&rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetViewportOrg(rect.right/2,rect.bottom/2);
pDC->SetViewportExt(rect.right,rect.bottom);
pDC->SetWindowOrg(0,0);
pDC->SetWindowExt(1000,-1000);
pDC->MoveTo(150,150);
pDC->LineTo(-150,-200);
pDC->LineTo(150,-150);
pDC->LineTo(150,150);
}
代码分析:
1. 用 pDC->SetViewportOrg(rect.right/2,rect.bottom/2); 设置视口的原点。

2. 用pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,-1000);来确定设备坐标和逻辑坐标的单位对应关系。

3. 因为逻辑窗范围和视口范围的符号不一致,纵坐标取反,所以Y轴向上为正。

参考资料:/VC-a154643.htm
1、添加工具栏资源ID为IDR_TOOLBAR
2、在对话框的类定义中加:
CToolBar m_ToolBar;
3、在OnInitDialog中或其它合适的消息响应中加如下代码:(函数可查看MSDN)
m_ToolBar.Create(this); //创建工具栏
m_ToolBar.LoadToolBar(IDR_TOOLBAR);//加载工具栏
//得出控件条大小.
CRect rect;
CRect rectNow;
GetClientRect(rect);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rec tNow);
//放置控件条位置
CPoint ptOffset(rectNow.left-rect.left,rectNow.top-rect.top);
CRect rcChild;
CWnd* pwndChild=GetWindow(GW_CHILD);
while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild,FALSE);
pwndChild=pwndChild->GetNextWindow();
}
//调整对话框尺寸
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right+=rect.Width()-rectNow.Width();
rcWindow.bottom+=rect.Height()-rectNow.Height();
MoveWindow(rcWindow, FALSE);
//控件条定位
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
//对框居中
CenterWindow();
4、手工添加处理函数
afx_msg void OnBtnXXX();//消息响应函数声明
ON_COMMAND(ID_BTN_XXX/*工具按钮ID*/,OnBtnXXX/*函数名*/)//消息映射
void CXXXDlg::OnBtnXXX(){}//消息处理函数
打开对话框打开多个文件
CString temp;
int i=0;
POSITION pos;
CFileDialog dlg(TRUE,"","");
//下面一行是设置打开文件对话框——使之可以打开多个文件
TCHAR *pszFile = new TCHAR[MAX_PATH*MAX_PATH];
memset(pszFile,0,sizeof(TCHAR)*MAX_PATH*MAX_PATH);
dlg.m_ofn.lpstrFile = pszFile;
dlg.m_ofn.nMaxFile = MAX_PATH*MAX_PATH;
dlg.m_ofn.Flags = OFN_ALLOWMULTISELECT|OFN_EXPLORER|OFN_ENABLEHOOK; if(dlg.DoModal()==IDOK)
{
//把起首位置赋值给pos
pos=dlg.GetStartPosition();
//把打开的多个文件名赋值给fname数组
while(pos!=NULL)
{
fname[i]=dlg.GetNextPathName(pos);
i++;
}
temp.Format("%d",i);
temp="一共打开了"+temp+"个文件";
AfxMessageBox(temp);
}。

相关文档
最新文档