本例在Visual Studio 2010环境下使用OpenGL,提供一个基本的开发应用程序框架。
第一步:OpenGL基础设置:
1.创建一个单文档的MFC应用程序,命名为TestGL,然后在TestGLView.h头文件中添加以下两条include包含语句:
#include "gl/gl.h"
#include "gl/glu.h"
2.设置程序为静态运行方式
执行菜单命令:项目->属性,弹出属性对话框,选择配置属性->常规->MFC使用->在静态库中使用MFC,然后单击确定。这样做会使程序变得很大,但是它编译生成的可执行程序可以在其他计算机中运行。
3.链接OpenGL库文件
执行菜单命令:项目->属性打开属性对话框,选择配置属性->链接器->常规->附加库路径,输入OpenGL的库文件所在的路径,单击确定。比如我的机子如下:
再选择配置属性->链接器->输入->附加依赖库,在弹出的对话框中输入OpenGL的库文件OpenGL32.lib和glu32.lib,如下:
然后确定结束属性配置。编译运行,如果没有错误则表明配置正确。
第二步:在Visual Studio下用OpenGL绘制三棱锥:
绘制步骤如下:
*通过PIXELFORMATDESCRIPTOR结构设置设备描述表DC的像素格式和属性;
*创建渲染描述表RC,并和DC建立联系;
*使用OpenGL做图;
*释放所占用的资源,包括解除DC和RC的联系,删除RC及其与之关联的DC;
为应用程序添加变量和函数,对相关变量进行初始化,然后在函数中实现DC像素格式设置,RC的创建及其与DC 的关联,图形绘制以及资源释放等功能。
1.添加成员变量和成员函数:
为CTestGLView类添加公共变量:
CClientDC* pDrawDC; // 用于指向当前DC的指针
通过向导自动添加后,会在CTestGLView类的构造函数中将其初始化为NULL:
CTestGLView::CTestGLView()
: pDrawDC(NULL)
{
// TODO: 在此处添加构造代码
}
然后为CTestGLView添加三个公共成员函数:
void DrawGraphics(void);// 用于后续图形绘制
BOOL PixelformatSetting(void); // 用于设置像素格式
void GLSetting(void); // 用于创建渲染描述表
2.添加消息响应函数:
右击CTestGLView类选择属性命令,在属性对话框中选择消息页面。然后选择WM_CREATE消息,单击其后的下拉菜单按钮并选择"<添加>OnCreate"选项,为CTestGLView类添加消息响应函数OnCreate(),如下所示:
此时在TestGLView.cpp文件中可以看到添加消息的消息映射宏ON_WM_CREATE()和对应的OnCreate()函数。该消息响应在建立一个窗体前将被调用,因此可在其中做一些初始设置。
同样的方法添加另外两个消息响应函数:
OnDestroy():响应WM_DESTROY消息,宏为ON_WM_DESTROY(),窗口销毁时响应此函数,因此应该在此释放函数中所占用的资源。
OnSize():响应WM_SIZE消息,宏为ON_WM_SIZE()。改变窗口大小时响应此函数,因此可在此函数中调整视场。
3.为成员函数和消息响应函数添加代码:
1)设置像素格式。在BOOL CTestGLView::PixelformatSetting(void)函数中添加如下代码:
// 用于设置像素格式
BOOL CTestGLView::PixelformatSetting(void)
{
static PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR), //结构体长度
1, //版本
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //在窗口中绘图|支持进行OpenGL调用|双缓存模式
PFD_TYPE_RGBA, //RGBA颜色模式
24, //使用24位颜色
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0,
32, //深度缓冲区大小
0, 0,
PFD_MAIN_PLANE,
0, 0, 0, 0
}; //填充PIXELFORMATDESCRIPTOR像素格式
int ipixelformat;
//获取最佳匹配的像素格式索引
if((ipixelformat = ChoosePixelFormat(pDrawDC->GetSafeHdc(),&pfd)) == 0)
{
MessageBox(_T("Choose pixel format failed!"));
return TRUE;
}
//把DC的像素格式设置成由索引值ipixelformat指向的像素格式
if(SetPixelFormat(pDrawDC->GetSafeHdc(),ipixelformat,&pfd) == FALSE)
{
MessageBox(_T("Set pixel format failed !"));
return FALSE;
}
return TRUE;
}
2).创建渲染描述表:
在函数void CTestGLView::GLSetting(void)中调用PixelformatSetting(void)设置像素格式,然后创建和DC关联的渲染描述表,代码如下:
// 用于创建渲染描述表
void CTestGLView::GLSetting(void)
{
HGLRC hRC; //渲染描述表句柄
pDrawDC = new CClientDC(this); //使pDrawDC指向当前DC
ASSERT(pDrawDC !=NULL); //断言pDrawDC不为空
if(!PixelformatSetting()) //设置像素格式
return;
//创建和当前DC兼容的RC,并和当前DC关联
hRC = wglCreateContext(pDrawDC->GetSafeHdc());
wglMakeCurrent(pDrawDC->GetSafeHdc(),hRC);
}
3).在消息响应函数OnCreate()函数中调用GLSetting()函数,使上述设置生效,代码如下:
int CTestGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
GLSetting(); //该函数用来创建渲染描述表
return 0;
}
4).投影变换和视口变换。
在OnSize()中添加代码设置投影变换和视口变换,如下所示:
void CTestGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(cy>0)
{
glMatrixMode(GL_PROJECTION); //启动投影矩阵,4×4
glLoadIdentity(); //初始化为单位矩阵
gluPerspective(45.0f,cx/cy,0.0f,30.0f); //设置透视投影变换,指定视场
glViewport(0, 0, cx, cy); //设置视场,即定义显示范围
}
RedrawWindow(); //显示更新
}
5).绘制三棱锥:
在void CTestGLView::DrawGraphics(void)函数中,添加代码绘制3个三角形,构成一个三棱锥,如下:
void CTestGLView::DrawGraphics(void)
{
glTranslatef(0.0f, 0.0f, -6.0f); //移动物体到显示区
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //以边线方式绘制三角形
//绘制3个三角形的三个顶点
glBegin(GL_TRIANGLES);
glVertex3f(-0.6f, 0.0f, 0.0f);
glVertex3f(0.6f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.15f, 0.6f);
glVertex3f(-0.6f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.15f, 0.6f);
glVertex3f(0.0f, 0.9f, 0.6f);
glVertex3f(0.0f, 0.9f, 0.6f);
glVertex3f(0.0f, 0.15f, 0.6f);
glVertex3f(0.6f, 0.0f, 0.0f);
glEnd();
}
6).在OnDraw()函数中设置背景并调用DrawGraphics()函数绘制图形。
通常使用CView类的成员函数OnDraw()绘制用户界面,此外还可以在该函数中添加代码完成背景色设置,然后调用DrawGraphics()函数完成绘制。
void CTestGLView::OnDraw(CDC* /*pDC*/)
{
CTestGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
static BOOL bBusy = FALSE; //定义开关变量
//绘制完成后才可以更新缓存
if(bBusy)
return;
bBusy =TRUE;
glClearColor(0.0f, 0.0f, 0.5f, 0.5f); //设置背景颜色
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除深度缓存和颜色缓存
glMatrixMode(GL_MODELVIEW); //启动模型矩阵
glLoadIdentity(); //初始化为单位矩阵
DrawGraphics(); //绘制图形
SwapBuffers(wglGetCurrentDC()); //更新缓存
bBusy=FALSE;
}
7).删除渲染描述表。
在消息响应函数OnDestroy()中删除渲染描述表及其绑定的设备描述表,代码如下:
void CTestGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
HGLRC hRC;
hRC=::wglGetCurrentContext(); //获取当前RC句柄
::wglMakeCurrent(NULL,NULL); //解除当前RC和DC的关联,并把当前RC非当前化
if(hRC)
{
::wglDeleteContext(hRC); //删除RC
}
if(pDrawDC)
{
delete pDrawDC; //删除DC
}
}
编译运行项目,如果没有错,可得结果如下:
4.添加旋转功能:
实现一个交互功能,即单击鼠标开始/停止三棱锥旋转。
1).添加消息响应函数。
为CTestGLView类添加鼠标左键消息WM_LBUTTONDOWN和定时器消息WM_TIME,鼠标左键消息响应函数OnLButtonDown(),宏ON_WM_LBUTTONDOWN()。定时器消息响应函数为OnTimer(),宏ON_WM_TIMER(). 2).为CTestGLView类添加两个共有属性的成员变量,
BOOL bRotate; // 控制图形旋转
float RotateAngle; // 旋转角度
Visual Studio会自动在CTestGLView类的构造函数中将bRotate初始化为FALSE,将RotateAngle初始化为0.手动将bRotate的初始值改为TRUE。
3).在void CTestGLView::OnLButtonDown(UINT nFlags, CPoint point)函数中添加如下代码,通过单击启动/停止定时器,
void CTestGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(bRotate)
{
SetTimer(1,100,NULL); //设置定时器1,100ms触发一次
}
else
{
KillTimer(1); //移除定时器1
}
bRotate = !bRotate; //更新bRotate的值
CView::OnLButtonDown(nFlags, point);
}
4).设置旋转角度。在定时器消息响应函数OnTimer()中添加如下代码,实现每次定时到达时都能将图形旋转10度
void CTestGLView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//若定时器1到达预定时刻,则旋转角度增加10度
if(nIDEvent == 1)
{
RotateAngle += 10.0f;
Invalidate(FALSE); //使当前窗口失效,重新绘制
}
CView::OnTimer(nIDEvent);
}在OnTimer()函数中使用的Invalidate()函数作用是将整个客户区失效,从而被重新绘制,而最终的重绘工作由OnDraw()函数完成。此处用函数Invalidate()函数调用了OnDraw()函数来绘制旋转后的图形。
5).每次按照设置的角度重绘图形。重绘窗口由OnDraw()函数完成,而OnDraw()函数调用DrawGraphics()函数绘制图形。因此在函数DrawGraphics()函数中需添加如下代码:
glRotated(RotateAngle,1.0, 1.0, 1.0); //按设定的角度RotateAngle旋转图形将这句代码放在glTranslatef()函数语句之后。使得每次重绘时将图形绕着从原点指向(1.0,1.0,1.0)的射线旋转RotateAngle的角度,而RotateAngle的值在定时器函数OnTimer()中更新。这样就可以实现每次单击鼠标左键,定时器开始计时,每个100ms后响应定时器消息的函数OnTimer()将RotateAngle的值增加10度,同时Invalidate()函数使界面失效而被重绘,重绘是将图形选择RotateAngle的角度,有时间间隔短,所以看上去就会产生三棱锥旋转的效果。当鼠标在此单击左键时,定时器被取消,图形停止旋转。
参考文献:张俊华.<医学图像三维重建和可视化——VC++实现>.科学出版社
这篇文章是来自园子的,我只是把自己觉得重要的地方,做了更鲜明的标记和解释。
使用Visual Studio 2010可以在项目中添加架构图,项目可以是www.gsm-guard.net、Windows Forms、...,也可以创建单独的Modeling Projects。
可以通过下图方式在项目中添加架构图(菜单栏===>Tools===>New Diagram):
?
?在下面窗口中选择架构图的类型
?
用例图的工具说明:
?
?
1、Actor,参与者/角色,系统的理想用户,通过向系统输入或请求系统输入某些事件来触发系统的执行。包括:
(1)系统用户
(2)其它系统,如:购物网站使用支付宝在线支付,支付完成后再跳转到购物网站处理下一步。
(3)可以运行的进程,如:时间,经过一定时间触发系统某个事件执行。?
总结:可以理解成使用命令的那个角色,可以是整个处理过程的任何一个(可以是client,system,usecase等等),但是在图中更偏重于作为初始点的角色。
?
2、Use Case,用例,
用户与系统的交互,外部可见的系统功能单元。比如像增、删、改、查这样的功能点。?
?
总结:可以认为,我们的用户看到的功能,反过来说就是系统对用户开放的功能。
3、Comment,注释。
4、Association,关联关系,描述参与者与用例之间的关系、通信。
?
?
??
总结:这个是种关系,用来描述参与者与用例之间的关系。注意一段为参与者,另一端是开放的功能,因为抽象抽模型的话,这些用例(usecase)就是这个操作黑盒,对于用户来说的入口,所以就用这个用例代表了黑盒的角色。
5、Dependency,依赖关系,用于链接表示不同版本或变体的子系统/用例,源模型指向目标模型。
总结:这一部分,还是从字面理解比较简单。就是Usecase2的情况,决定了useCase1的情况。就是需要先确定Usecase2,这里并不是调用什么的关系,还是种顺序或者递进的关系。这里要注意与extend的区别,extend是有条件发生,而这里是肯定发生。然后再和include对比,include的usecase不会影响到usecase,只是运作中的一部分。而这里的确是会影响到。再换种方式考虑,可以认为一个东西,通过某种处理方式(也可以不处理),转换到了另一个。读做【非箭头端】依赖【箭头端】
6、Include,包含关系,一个用例用其它更简单的用例来描述,定义行为更为明确的用例。
?
总结:是一个UseCase中
必然包含的功能。有点类似,某一功能的具体流程。读作
【非箭头端】包含了【箭头端】
7、Extend,扩展关系,基础用例的增量扩展,只有满足特定的条件,扩展用例才会被执行。
?
上图中,缴纳罚金只有在比如有车损、租赁超期等情况下才会发生。?
总结:要注意此处的关键语,只有满足特定的条件,扩展用例才会被执行,也就是说有条件执行的,也可以认为是中根据条件更具体的事物。读做【非箭头端】扩展了【箭头端】。
8、Generalization,泛化关系,一般化到特殊化的关系,一个用例可以被特例为一个或多个子用例,子用例表示基用例的特殊形式。
?
总结:对应编程中的继承,就是通例和个例间的关系。【非箭头端】继承了【箭头端】
9、CommentLink:注释链接。
?
MSDN中一个综合一点的例子:
?
??
?更多资料:
UML 用例图:准则?
UML 用例图:参考??
百度百科关于用例图的资料
转载于:https://www.gsm-guard.net/JosephLiu/archive/2011/10/20/2218747.html
计算器和画图板的设计
目录:
计算器设计画图板设计整体总结和分析
前言: 本次应课程要求要用C++设计计算器和画图程序,我会使用Microsoft Visual Studio 2010来完成该窗体应用程序,如果有写的不好的地方希望大家批评指正。
1.计算器设计
结构:
界面设计函数模块设计整体功能实现
首先,我们可以先创建一个一个基于CLR的窗体应用程序。这里我就从零开始讲解,这样大家可以更好的明白,同时自己也可以加深记忆。
我们打开Visual Studio 2010,先打开项目,创建一个CLR窗体应用程序,输入程序名称,选择保存路径,点击确定。如图: 打开项目后,将会出现以下的界面: 我们选择CLR中的窗体用用程序,这里一定要注意,千万别选错,不然就得不到想要的结果了。我这里创建了一个SpecialCalculator 名称,大家也可以创建别的名称,但最好是英文名,这样对编程更有利,也可以帮助大家学习英语。(? ?_?)? 上面都创建好了,我们就出现如下的界面了:
接下来我们来实现整体界面设计,构建一个真正的计算器!!!
1.界面设计
我们都知道,要实现计算器,最基本的就是要有一个计算器的输入框和数字符号按钮,我们用鼠标点击数字、符号和公式,然后再点击=符号,输入框就可以计算出正确的答案。这样我们就实现了一个简单的计算器。
上面提到了输入框,按钮等等,以上我们可以称为组件,我们无非就是在窗体上添加自己想要的组件,然后给每个组件设置监听器,让他们去做不同的事情罢了。 这里我们就要打开关于组件的视图:工具箱||属性 所谓工具箱,就是存放工具的地方。里面包括所有我们要用到的组件,包括按钮,文本框,画图板,菜单栏,单选框等等。我们点击某个组件就可以在界面上进行绘制。如果我们要精确调整,这就涉及到组件的属性,属性自然说组件的特色,比如按钮的大小可以设置,按钮的背景颜色,按钮显示的文字的颜色,按钮的字体,视图的滚条设置等等,大家可以慢慢摸索。
接下来我们都知道组件的使用和属性了,我们可以简单设计一下界面。用到的组件有按钮、如下: 这里省略很多步骤,但这些步骤都一些简单的步骤,比如自己调整按钮的布局,在属性设置编辑框的显示文本,编辑框的滚条设计,还有就是按钮的前景色和背景色的设置。大家慢慢设计就可以制作一个美观的计算器,至于具体这么样大家可以有自己的想法。
2.函数模块设计
上面我们完成一个还算美观的界面,但是计算器是要用来计算的,而上面的按钮现在还只是摆设,我们因该要点击按钮时可以实现显示公式和算出结果。这里就涉及到对每个按钮添加相应的事件,我们可以称之为事件监听机制。 那么怎么实现事件监听呢?这里我们用鼠标双击我们需要添加监听器的组件,如下:
#pragma endregion
//界面
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
//编辑框
private: System::Void textBox1_TextChanged(System::Object^ sender, System::EventArgs^ e) {
}
//标签
private: System::Void label1_Click(System::Object^ sender, System::EventArgs^ e) {
}
//按钮0
private: System::Void button18_Click(System::Object^ sender, System::EventArgs^ e) {
//这里我们让编辑框现实的字符串加上字符0
this->textBox1->Text=this->textBox1->Text+L"0";
}
接下来我们运行程序来看看点击O按钮的效果: 我们这里就完成字符的显示,接下类我们一气呵成,把其他的按钮都实现相应功能,完整的代码如下:
//------------------------------------------------------------------------------------------------------
//按钮0
private: System::Void button18_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"0";
}
//按钮1
private: System::Void button17_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"1";
}
//按钮2
private: System::Void button12_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"2";
}
//按钮3
private: System::Void button9_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"3";
}
//按钮4
private: System::Void button8_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"4";
}
//按钮5
private: System::Void button13_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"5";
}
//按钮6
private: System::Void button16_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"6";
}
//按钮7
private: System::Void button15_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"7";
}
//按钮8
private: System::Void button14_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"8";
}
//按钮9
private: System::Void button7_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"9";
}
//按钮.
private: System::Void button11_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L".";
}
//按钮/
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"/";
}
//按钮+
private: System::Void button6_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"+";
}
//按钮-
private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"-";
}
//按钮*
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"*";
}
//按钮(
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"(";
}
//按钮)
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L")";
}
//按钮Sin
private: System::Void button22_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"Sin";
}
//按钮Cos
private: System::Void button21_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"Cos";
}
//按钮Tan
private: System::Void button20_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"Tan";
}
//按钮In
private: System::Void button19_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"In";
}
//------------------------------------------------------------------------------------------------------
//按钮BackSpace(删除)
private: System::Void button27_Click(System::Object^ sender, System::EventArgs^ e) {
String^ s=this->textBox1->Text;
this->textBox1->Text=s->Remove(s->Length-1);
}
//按钮DelUp(清空)
private: System::Void button28_Click(System::Object^ sender, System::EventArgs^ e) {
String^ s=this->textBox1->Text;
this->textBox1->Text=s->Remove(0);
}
//按钮=输出-----------------------------------
private: System::Void button10_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"=";
//调用计算函数(计算器的核心)
}
};
}
接下来我们键入公式,这里就需要根据公式来计算并显示答案,需要计算器的核心模块,计算函数函数构造:
1.首先,创建一个头文件来放置计算函数来供定义文件调用。 在出现的对话框中选中头文件(.h),并填写文件名,点击确定及创建一个头文件: 接下来就是编写函数代码:
using namespace System;//调用命名空间
//声名函数
String^ eatspaces(String^ str);//1.去掉输入公式中空格的函数
double expr(String^ str);//2.计算器的主函数计算+-
double term(String^ str,int^ index);//计算乘除函数
double number(String^ str,int^ index);//计算每一个数值
String^ extract(String^,int^);//抽取括号字符串函数
String^ exhsm(String^ int^);//取得三角函数字符串的函数
//定义函数-------------------------------------------------------------
//1.去掉输入公式中空格的函数
String^ eatspace(String^ str){
return str->Replace(L" ",L"");//注意第一个参数有空格,第二个没有
}
//这里我们可以简单了解一下Replace函数,这个大家可以去相应文档去查找,它有两个参数
//都是字符或字符串,这里显然是字符,意思是遍历传入的字符串并检查有无出现第一个数
//设置的字符,这个代表空字符,若出现空字符则用""代替,也就是去除。
//2.计算器的主函数,最后计算最基本的+,-
double expr(String^ str){
int^ index(0);//定义一个index指针变量,初始值为0
double value(term(str,index));//声名value双精度变量,以term
//函数作为参数,value可以理解为实时计算的过程值
while(*index
switch(str[*index]){//switch判断语句,按顺序判断传入公示的每一个字符
//+
case'+':
++(*index);
value+=term(str,index);
break;
case'-':
++(*index);
value+=term(str,index);
break;
default:
Console::WriteLine(L"There is an error!!!\n");
}
}
return value;
}
//定义先计算的乘除函数
double term(String^ str,int^ index){
double value(number(str,index));
while(*index
if(L'*'==str[*index]){
++(*index);
value*=number(str,index);
}
else if(L"/"==str[*index]){
++(*index);
value/=number(str,index);
}else{
break;
}
}
return value;
}
//返回每个表达式数字的函数
double number(String^ str,int^ index){
//初始化初值
double value(0.0);
double sign(1.0);
double mtd(0.0);
String^ s2;
//遇到()为特殊情况需要截取括号的内容作为一个表达式重新计算
if(L'('==str[*index]){
++(*index);
String^ substr=extract(str,index);
return expr(substr);
}
if((*index
sign=-1.0;
(*index)++;
}
//Sin,Cos,Tan函数
s2=exhsm(str,index);
if(s2->Length>0){
if(s2=L"Sin"){
mtd=number(str,index);
mtd=Math::Sin(mtd);
return mtd;
}else
if(s2=L"Cos"){
mtd=number(str,index);
mtd=Math::Cos(mtd);
return mtd;
}else
if(s2=L"Tan"){
mtd=number(str,index);
mtd=Math::Tan(mtd);
return mtd;
}
}
//小数点符号
while((*index
value=10.0*value+Char::GetNumericValue(str[(*index)]);
++(*index);
}
if((*index==str->Length||str[*index]!='.')){
return sign*value;
double factor(1.0);
++(*index);
while((*index
factor*=0.1;
value=value+Char::GetNumericValue(str[(*index)])*factor;
++(*index);
}
return sign*value;
}
//取得括号中的表达式的函数
String^ extract(String^ str,int^ index){
int numL(0);
int bufindex(*index);
while(*index
switch(str[*index]){
case')':
if(0==numL){
return str->Substring(bufindex,(*index)++ -bufindex);
}else{
numL--;
break;
}
case'(':
numL++;
break;
}
++(*index);
}
return "0";
}
//取得字符串判断是否为三角函数的函数
String^ exhsm(String^ str,int^ index){
String^ s1="";
while(*index
s1=s1+str[*index];
(*index)++;
return s1;
}
}
//注意:
//上式中的IsDigit是判断该字符是否为十进制数
//上式中的GetNumericValue是将指定的数字 Unicode 字符转换为双精度浮点数
//上式中的Substring是它等于此实例中从 startIndex 开始的长度为 length 子
//字符
//串,如果 startIndex 等于此实例的长度且 length 为零,则为 Empty
既然我们已经搭建好了计算器的主函数,接下来就是要去调用这些函数: 1.首先我们在类视图中去添加include代码,将头文件包含进来: 2.包含了头文件,我的窗体的类程序中就可以访问头文件中的函数了:
//按钮=输出-----------------------------------
private: System::Void button10_Click(System::Object^ sender, System::EventArgs^ e) {
//调用计算函数(计算器的核心)
double result=expr(eatspaces(this->textBox1->Text));//调用计算函数
this->textBox1->Text=this->textBox1->Text+L"="+result.ToString();
//以字符串的形式输出
}
通过上面的步骤,一个简单的计算器基本实现了。 示例:
3.整体功能实现
上面的计算器还有一些功能是不全的,比如指数函数和对数函数没有实现,接下来我们拓展一下功能,实现对指数函数和对数函数的计算:
if (s2== L"Sin")
{
mtd=number(str,index);
mtd=Math::Sin(mtd);
return mtd;
}
if (s2== L"Cos")
{
mtd=number(str,index);
mtd=Math::Cos(mtd);
return mtd;
}
if (s2== L"Tan")
{
mtd=number(str,index);
mtd=Math::Tan(mtd);
return mtd;
}
//对数函数实现代码
if(s2==L"In"){
mtd=number(str,index);
double x=mtd;
double sum=0.0;
int f=1.0;
int flag=1;
double y,y1,t;
long i=1;
if(x<0||x==0){
mtd=0.0;
}
if(x>2){
y=1/x;
flag=-1;
}
else{
y=x;
y=y-1;
y1=y;
t=y;
while((t>=0?t:-t)>=0.000001){
sum+=t;
y1=y1*y;
i++;
f=-1*f;
t=f*y1/i;
}
mtd=flag*sum;
}
return mtd;
}
上面的对数函数代码添加到三角函数这一块比较好,因为这里有一个识别前面的公式,放在这一块比较合适。上面的算法我这里就不用分析,就是用数学里的微积分来计算对数,大家可以自己推导一下。
接下来说一下指数函数的实现:
//平方
private: System::Void button24_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"^2";
}
//立方
private: System::Void button23_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"^3";
}
//指数
private: System::Void button25_Click(System::Object^ sender, System::EventArgs^ e) {
this->textBox1->Text=this->textBox1->Text+L"^";
}
通过如上添加到的代码设置,我们看可以分析一下,指数运算是通过“^”符号来实现的,而且指数运算优先于加减,并且优于乘除,所以我们如果要在指数后面乘以或除以一个数时,我们因该加上括号: 下面展示如何实现指数运算:
if(L'*'==str[*index])
{
++(*index);
value *=number(str,index);
}
else if(L'/'==str[*index])
{
++(*index);
value /=number(str,index);
//指数运算
}else if(L'^'==str[*index]){
++(*index);
value=Math::Pow(value,number(str,index));
}
else
break;
}
由上面代码来看还是比较简单的,我们只要调用Math库里的指数函数就OK了。
现在基本的计算器功能已经实现了。如果大家还有什么问题或有什么想法的可以和我交流。
2.画图板设计
结构:
界面设计画图函数实现整体功能实现
这里我们首先创建一个窗体类项目,同上面创建计算器的一样,这里就不重复了。我这里命名为:SpecialGraphics
首先还是老套路,分析一下,我们要实现一个简单的画图程序,首先要有一些按钮,包含直线,圆等等,我们但我们点击直线,我们在窗体上按下松开鼠标可以画一条直线。
要实现上面的功能,我们需要按钮,画框这些组件,同时我们在画框添加鼠标监听器,实现事件的响应。
1.界面设计
1.首先,我们进行组件的添加和相关属性的设置: 下面我们要进行代码编写,实现对事件的响应: 这里我们整个的画图程序的代码完整的给出来,里面基本都有注释,大家可以参考一下:
#pragma once
namespace SpecialGraphics {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
///
/// Form1 摘要
///
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: 在此处添加构造函数代码
//
PBheight=this->pictureBox1->Height;//获取画板的高度
PBwidth=this->pictureBox1->Width;//获取画板宽度
myImage=gcnew Bitmap(PBwidth,PBheight);//设置画布
g=Graphics::FromImage(myImage);//将位图作为画板
backgroundColor=Color::Black;//背景颜色
g->Clear(backgroundColor);//黑底画布
pictureBox1->Image=myImage;//显示图像
foreColor=Color::White;//画笔颜色
penWeight=1.0;//画笔粗细
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
line_startPoint=gcnew Point();//记录线段首点
buttonString="直线";//默认直线
brush = gcnew SolidBrush(backgroundColor);//初始化笔刷
}
protected:
///
/// 清理所有正在使用的资源。
///
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::Button^ button2;
private: System::Windows::Forms::Button^ button3;
private: System::Windows::Forms::PictureBox^ pictureBox1;
private:
///
/// 必需的设计器变量。
///
System::ComponentModel::Container ^components;
Image^ myImage;//定义一个位图
Graphics^ g;//创建一个画图对象
Pen^ pen;//画笔
float penWeight;//画笔粗细
static int PBheight,PBwidth;//记录画板长宽
String^ buttonString;//按钮类型
Point^ line_startPoint;//记录线段首点
int x1,y1,x2,y2;//坐标
Color backgroundColor,foreColor;//背景色和画笔颜色
Brush^ brush;//笔刷,用于填充图形
private: System::Windows::Forms::MenuStrip^ menuStrip1;
private: System::Windows::Forms::ToolStripMenuItem^ 系统ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 线性ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 颜色ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 编辑ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 插入图片ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 退出ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 细线ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 中线ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 粗线ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 背景颜色ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 画笔颜色ToolStripMenuItem;
private: System::Windows::Forms::ToolStripMenuItem^ 清屏ToolStripMenuItem;
private: System::Windows::Forms::Button^ button4;
private: System::Windows::Forms::Button^ button5;
private: System::Windows::Forms::Button^ button6;
private: System::Windows::Forms::Button^ button7;
private: System::Windows::Forms::Button^ button8;
private: System::Windows::Forms::Button^ button9;
private: System::Windows::Forms::Button^ button10;
private: System::Windows::Forms::ToolStripMenuItem^ 橡皮擦ToolStripMenuItem;
#pragma region Windows Form Designer generated code
///
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
///
void InitializeComponent(void)
{
this->button1 = (gcnew System::Windows::Forms::Button());
this->button2 = (gcnew System::Windows::Forms::Button());
this->button3 = (gcnew System::Windows::Forms::Button());
this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
this->系统ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->插入图片ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->退出ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->线性ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->细线ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->中线ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->粗线ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->颜色ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->背景颜色ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->画笔颜色ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->编辑ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->清屏ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->橡皮擦ToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
this->button4 = (gcnew System::Windows::Forms::Button());
this->button5 = (gcnew System::Windows::Forms::Button());
this->button6 = (gcnew System::Windows::Forms::Button());
this->button7 = (gcnew System::Windows::Forms::Button());
this->button8 = (gcnew System::Windows::Forms::Button());
this->button9 = (gcnew System::Windows::Forms::Button());
this->button10 = (gcnew System::Windows::Forms::Button());
(cli::safe_cast
this->menuStrip1->SuspendLayout();
this->SuspendLayout();
//
// button1
//
this->button1->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button1->Location = System::Drawing::Point(0, 31);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 29);
this->button1->TabIndex = 0;
this->button1->Text = L"直线";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// button2
//
this->button2->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button2->Location = System::Drawing::Point(0, 66);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(75, 29);
this->button2->TabIndex = 1;
this->button2->Text = L"圆";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
//
// button3
//
this->button3->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button3->Location = System::Drawing::Point(0, 101);
this->button3->Name = L"button3";
this->button3->Size = System::Drawing::Size(75, 29);
this->button3->TabIndex = 2;
this->button3->Text = L"椭圆";
this->button3->UseVisualStyleBackColor = true;
this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
//
// pictureBox1
//
this->pictureBox1->BackColor = System::Drawing::Color::Black;
this->pictureBox1->Cursor = System::Windows::Forms::Cursors::Default;
this->pictureBox1->Location = System::Drawing::Point(75, 31);
this->pictureBox1->Name = L"pictureBox1";
this->pictureBox1->Size = System::Drawing::Size(1107, 723);
this->pictureBox1->TabIndex = 3;
this->pictureBox1->TabStop = false;
this->pictureBox1->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseDown);
this->pictureBox1->MouseMove += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseMove);
this->pictureBox1->MouseUp += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseUp);
//
// menuStrip1
//
this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(4) {this->系统ToolStripMenuItem,
this->线性ToolStripMenuItem, this->颜色ToolStripMenuItem, this->编辑ToolStripMenuItem});
this->menuStrip1->Location = System::Drawing::Point(0, 0);
this->menuStrip1->Name = L"menuStrip1";
this->menuStrip1->Size = System::Drawing::Size(1182, 28);
this->menuStrip1->TabIndex = 4;
this->menuStrip1->Text = L"menuStrip1";
//
// 系统ToolStripMenuItem
//
this->系统ToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) {this->插入图片ToolStripMenuItem,
this->退出ToolStripMenuItem});
this->系统ToolStripMenuItem->Name = L"系统ToolStripMenuItem";
this->系统ToolStripMenuItem->Size = System::Drawing::Size(51, 24);
this->系统ToolStripMenuItem->Text = L"系统";
//
// 插入图片ToolStripMenuItem
//
this->插入图片ToolStripMenuItem->Name = L"插入图片ToolStripMenuItem";
this->插入图片ToolStripMenuItem->Size = System::Drawing::Size(138, 24);
this->插入图片ToolStripMenuItem->Text = L"插入图片";
//
// 退出ToolStripMenuItem
//
this->退出ToolStripMenuItem->Name = L"退出ToolStripMenuItem";
this->退出ToolStripMenuItem->Size = System::Drawing::Size(152, 24);
this->退出ToolStripMenuItem->Text = L"退出";
this->退出ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::退出ToolStripMenuItem_Click);
//
// 线性ToolStripMenuItem
//
this->线性ToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(3) {this->细线ToolStripMenuItem,
this->中线ToolStripMenuItem, this->粗线ToolStripMenuItem});
this->线性ToolStripMenuItem->Name = L"线性ToolStripMenuItem";
this->线性ToolStripMenuItem->Size = System::Drawing::Size(51, 24);
this->线性ToolStripMenuItem->Text = L"线性";
//
// 细线ToolStripMenuItem
//
this->细线ToolStripMenuItem->Name = L"细线ToolStripMenuItem";
this->细线ToolStripMenuItem->Size = System::Drawing::Size(108, 24);
this->细线ToolStripMenuItem->Text = L"细线";
this->细线ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::细线ToolStripMenuItem_Click);
//
// 中线ToolStripMenuItem
//
this->中线ToolStripMenuItem->Name = L"中线ToolStripMenuItem";
this->中线ToolStripMenuItem->Size = System::Drawing::Size(108, 24);
this->中线ToolStripMenuItem->Text = L"中线";
this->中线ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::中线ToolStripMenuItem_Click);
//
// 粗线ToolStripMenuItem
//
this->粗线ToolStripMenuItem->Name = L"粗线ToolStripMenuItem";
this->粗线ToolStripMenuItem->Size = System::Drawing::Size(108, 24);
this->粗线ToolStripMenuItem->Text = L"粗线";
this->粗线ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::粗线ToolStripMenuItem_Click);
//
// 颜色ToolStripMenuItem
//
this->颜色ToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) {this->背景颜色ToolStripMenuItem,
this->画笔颜色ToolStripMenuItem});
this->颜色ToolStripMenuItem->Name = L"颜色ToolStripMenuItem";
this->颜色ToolStripMenuItem->Size = System::Drawing::Size(51, 24);
this->颜色ToolStripMenuItem->Text = L"颜色";
//
// 背景颜色ToolStripMenuItem
//
this->背景颜色ToolStripMenuItem->Name = L"背景颜色ToolStripMenuItem";
this->背景颜色ToolStripMenuItem->Size = System::Drawing::Size(138, 24);
this->背景颜色ToolStripMenuItem->Text = L"背景颜色";
this->背景颜色ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::背景颜色ToolStripMenuItem_Click);
//
// 画笔颜色ToolStripMenuItem
//
this->画笔颜色ToolStripMenuItem->Name = L"画笔颜色ToolStripMenuItem";
this->画笔颜色ToolStripMenuItem->Size = System::Drawing::Size(138, 24);
this->画笔颜色ToolStripMenuItem->Text = L"画笔颜色";
this->画笔颜色ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::画笔颜色ToolStripMenuItem_Click);
//
// 编辑ToolStripMenuItem
//
this->编辑ToolStripMenuItem->DropDownItems->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^ >(2) {this->清屏ToolStripMenuItem,
this->橡皮擦ToolStripMenuItem});
this->编辑ToolStripMenuItem->Name = L"编辑ToolStripMenuItem";
this->编辑ToolStripMenuItem->Size = System::Drawing::Size(51, 24);
this->编辑ToolStripMenuItem->Text = L"编辑";
//
// 清屏ToolStripMenuItem
//
this->清屏ToolStripMenuItem->Name = L"清屏ToolStripMenuItem";
this->清屏ToolStripMenuItem->Size = System::Drawing::Size(152, 24);
this->清屏ToolStripMenuItem->Text = L"清屏";
this->清屏ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::清屏ToolStripMenuItem_Click);
//
// 橡皮擦ToolStripMenuItem
//
this->橡皮擦ToolStripMenuItem->Name = L"橡皮擦ToolStripMenuItem";
this->橡皮擦ToolStripMenuItem->Size = System::Drawing::Size(152, 24);
this->橡皮擦ToolStripMenuItem->Text = L"橡皮擦";
this->橡皮擦ToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::橡皮擦ToolStripMenuItem_Click);
//
// button4
//
this->button4->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button4->Location = System::Drawing::Point(0, 164);
this->button4->Name = L"button4";
this->button4->Size = System::Drawing::Size(75, 29);
this->button4->TabIndex = 5;
this->button4->Text = L"细线";
this->button4->UseVisualStyleBackColor = true;
this->button4->Click += gcnew System::EventHandler(this, &Form1::button4_Click);
//
// button5
//
this->button5->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button5->Location = System::Drawing::Point(0, 199);
this->button5->Name = L"button5";
this->button5->Size = System::Drawing::Size(75, 29);
this->button5->TabIndex = 6;
this->button5->Text = L"中线";
this->button5->UseVisualStyleBackColor = true;
this->button5->Click += gcnew System::EventHandler(this, &Form1::button5_Click);
//
// button6
//
this->button6->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button6->Location = System::Drawing::Point(0, 234);
this->button6->Name = L"button6";
this->button6->Size = System::Drawing::Size(75, 29);
this->button6->TabIndex = 7;
this->button6->Text = L"粗线";
this->button6->UseVisualStyleBackColor = true;
this->button6->Click += gcnew System::EventHandler(this, &Form1::button6_Click);
//
// button7
//
this->button7->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button7->Location = System::Drawing::Point(0, 279);
this->button7->Name = L"button7";
this->button7->Size = System::Drawing::Size(75, 29);
this->button7->TabIndex = 8;
this->button7->Text = L"前景色";
this->button7->UseVisualStyleBackColor = true;
this->button7->Click += gcnew System::EventHandler(this, &Form1::button7_Click);
//
// button8
//
this->button8->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button8->Location = System::Drawing::Point(0, 314);
this->button8->Name = L"button8";
this->button8->Size = System::Drawing::Size(75, 29);
this->button8->TabIndex = 9;
this->button8->Text = L"背景色";
this->button8->UseVisualStyleBackColor = true;
this->button8->Click += gcnew System::EventHandler(this, &Form1::button8_Click);
//
// button9
//
this->button9->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button9->Location = System::Drawing::Point(0, 443);
this->button9->Name = L"button9";
this->button9->Size = System::Drawing::Size(75, 29);
this->button9->TabIndex = 10;
this->button9->Text = L"清屏";
this->button9->UseVisualStyleBackColor = true;
this->button9->Click += gcnew System::EventHandler(this, &Form1::button9_Click);
//
// button10
//
this->button10->Font = (gcnew System::Drawing::Font(L"宋体", 9, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point,
static_cast
this->button10->Location = System::Drawing::Point(0, 478);
this->button10->Name = L"button10";
this->button10->Size = System::Drawing::Size(75, 29);
this->button10->TabIndex = 11;
this->button10->Text = L"橡皮擦";
this->button10->UseVisualStyleBackColor = true;
this->button10->Click += gcnew System::EventHandler(this, &Form1::button10_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(8, 15);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::SystemColors::ControlDark;
this->ClientSize = System::Drawing::Size(1182, 753);
this->Controls->Add(this->button10);
this->Controls->Add(this->button9);
this->Controls->Add(this->button8);
this->Controls->Add(this->button7);
this->Controls->Add(this->button6);
this->Controls->Add(this->button5);
this->Controls->Add(this->button4);
this->Controls->Add(this->pictureBox1);
this->Controls->Add(this->button3);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
this->Controls->Add(this->menuStrip1);
this->MainMenuStrip = this->menuStrip1;
this->Name = L"Form1";
this->Text = L"多功能画图板---抽象派画家";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
(cli::safe_cast
this->menuStrip1->ResumeLayout(false);
this->menuStrip1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
//背景颜色
private: System::Void 背景颜色ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
ColorDialog^ colorDialog =gcnew ColorDialog();
// Keeps the user from selecting a custom color.
colorDialog->AllowFullOpen = false ;
// Allows the user to get help. (The default is false.)帮助
colorDialog->ShowHelp = true ;
// Sets the initial color select to the current text color.
//colorDialog->Color = textBox1.ForeColor ;
//上面是一些默认设置可以不用管
if (colorDialog->ShowDialog()==Windows::Forms::DialogResult::OK)
{
//获取所选择的颜色
backgroundColor= colorDialog->Color;
g->Clear(backgroundColor);
this->button8->BackColor=backgroundColor;
pictureBox1->Image=myImage;
}
}
//画笔颜色
private: System::Void 画笔颜色ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
ColorDialog^ colorDialog =gcnew ColorDialog();
// Keeps the user from selecting a custom color.
colorDialog->AllowFullOpen = false ;
// Allows the user to get help. (The default is false.)帮助
colorDialog->ShowHelp = true ;
// Sets the initial color select to the current text color.
//colorDialog->Color = textBox1.ForeColor ;
//上面是一些默认设置可以不用管
if (colorDialog->ShowDialog()==Windows::Forms::DialogResult::OK)
{
//获取所选择的颜色
foreColor=colorDialog->Color;
pen->Color=foreColor;
this->button7->BackColor=foreColor;
pictureBox1->Image=myImage;
}
}
//界面
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
//直线
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
buttonString=L"直线";
}
//圆
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
buttonString=L"圆";
}
//椭圆
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
buttonString=L"椭圆";
}
//---------------------------------------------鼠标事件
//画板的鼠标按下事件
private: System::Void pictureBox1_MouseDown(System::Object^ sender,System::Windows::Forms::MouseEventArgs^ e) {
//记录首点坐标
line_startPoint->X=e->X;
line_startPoint->Y=e->Y;
x1=e->X;
y1=e->Y;
//判断字符串
if(buttonString=="圆"){
pen->Color=foreColor;
g->DrawEllipse(pen,x1-25,y1-25,50,50);
pictureBox1->Image=myImage;
}else
if(buttonString=="椭圆"){
pen->Color=foreColor;
g->DrawEllipse(pen,x1-40,y1-25,80,50);
pictureBox1->Image=myImage;
}
}
//画板的鼠标松开事件
private: System::Void pictureBox1_MouseUp(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {
//判断
if(buttonString=="直线"){
Point^ line_endPoint=gcnew Point();
//记录尾点坐标
line_endPoint->X=e->X;
line_endPoint->Y=e->Y;
pen->Color=foreColor;
g->DrawLine(pen,*line_startPoint,*line_endPoint);
pictureBox1->Image=myImage;
}
}
//画板的鼠标移动事件
private: System::Void pictureBox1_MouseMove(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) {
x1=e->X;
y1=e->Y;
//判断
if(buttonString=="橡皮"){
brush = gcnew SolidBrush(backgroundColor);//初始化笔刷
g->FillRectangle(brush,x1,y1,15,15);
pictureBox1->Image=myImage;
}
}
//清屏
private: System::Void button9_Click(System::Object^ sender, System::EventArgs^ e) {
g->Clear(backgroundColor);
pictureBox1->Image=myImage;
}
//橡皮
private: System::Void button10_Click(System::Object^ sender, System::EventArgs^ e) {
buttonString=L"橡皮";
}
//细线
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=1.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//中线
private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=2.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//粗线
private: System::Void button6_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=3.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//前景色
private: System::Void button7_Click(System::Object^ sender, System::EventArgs^ e) {
ColorDialog^ colorDialog =gcnew ColorDialog();
// Keeps the user from selecting a custom color.
colorDialog->AllowFullOpen = false ;
// Allows the user to get help. (The default is false.)帮助
colorDialog->ShowHelp = true ;
// Sets the initial color select to the current text color.
//colorDialog->Color = textBox1.ForeColor ;
//上面是一些默认设置可以不用管
if (colorDialog->ShowDialog()==Windows::Forms::DialogResult::OK)
{
//获取所选择的颜色
foreColor=colorDialog->Color;
pen->Color=foreColor;
this->button7->BackColor=foreColor;
pictureBox1->Image=myImage;
}
}
//背景色
private: System::Void button8_Click(System::Object^ sender, System::EventArgs^ e) {
ColorDialog^ colorDialog =gcnew ColorDialog();
// Keeps the user from selecting a custom color.
colorDialog->AllowFullOpen = false ;
// Allows the user to get help. (The default is false.)帮助
colorDialog->ShowHelp = true ;
// Sets the initial color select to the current text color.
//colorDialog->Color = textBox1.ForeColor ;
//上面是一些默认设置可以不用管
if (colorDialog->ShowDialog()==Windows::Forms::DialogResult::OK)
{
//获取所选择的颜色
backgroundColor= colorDialog->Color;
g->Clear(backgroundColor);
this->button8->BackColor=backgroundColor;
pictureBox1->Image=myImage;
}
}
//菜单栏设置
//细线
private: System::Void 细线ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=1.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//中线
private: System::Void 中线ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=2.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//粗线
private: System::Void 粗线ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
penWeight=3.0;
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
}
//清屏
private: System::Void 清屏ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
g->Clear(backgroundColor);
pictureBox1->Image=myImage;
}
//橡皮
private: System::Void 橡皮擦ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
buttonString=L"橡皮";
}
//退出
private: System::Void 退出ToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
this->Visible=false;
}
};
}
注意: 1.在上述画图程序中定义全局变量时,应在Form1类中进行,而且不能初始化,否则会报错:
private://Form1类的位置
///
/// 必需的设计器变量。
///
System::ComponentModel::Container ^components;
Image^ myImage;//定义一个位图
Graphics^ g;//创建一个画图对象
Pen^ pen;//画笔
float penWeight;//画笔粗细
static int PBheight,PBwidth;//记录画板长宽
String^ buttonString;//按钮类型
Point^ line_startPoint;//记录线段首点
int x1,y1,x2,y2;//坐标
Color backgroundColor,foreColor;//背景色和画笔颜色
Brush^ brush;//笔刷,用于填充图形
2.在Form1构造函数可以进行初始化:
Form1(void)
{//构造函数模块
InitializeComponent();
//
//TODO: 在此处添加构造函数代码
//
PBheight=this->pictureBox1->Height;//获取画板的高度
PBwidth=this->pictureBox1->Width;//获取画板宽度
myImage=gcnew Bitmap(PBwidth,PBheight);//设置画布
g=Graphics::FromImage(myImage);//将位图作为画板
backgroundColor=Color::Black;//背景颜色
g->Clear(backgroundColor);//黑底画布
pictureBox1->Image=myImage;//显示图像
foreColor=Color::White;//画笔颜色
penWeight=1.0;//画笔粗细
pen=gcnew Pen(foreColor,penWeight);//初始化画笔
line_startPoint=gcnew Point();//记录线段首点
buttonString="直线";//默认直线
brush = gcnew SolidBrush(backgroundColor);//初始化笔刷
}
2.画图函数实现
画图函数这一块其实不是特别难,大家看看Visual C++的文档基本就能够搞定,主要就是要在画图板上添加一些鼠标监听器,鼠标按下、松开、移动等等,以自己的需求而定,上面我也有相应的代码操作。 鼠标监听器文档:
3.整体功能实现
上面基本实现了画图,调整画笔、背景颜色,清屏、橡皮擦等功能。我们其实还可以添加一些别的功能,我的想法是实现插入图片,画一些迭代图形等,大家可以创建一个别的图形。
3.整体总结和分析
上面的两个小程序总体的实现难度不大,关键大家要懂得模仿吧! 建议不要复制粘贴,要自己一行一敲,这样可以加深理解,拿来主义很重要!同时要多去看看文档里的代码的类和成员,以及构造函数,类里面代码我们要抓住核心。
最后,大家如果有什么问题可以和我讨论呀!!!