




已阅读5页,还剩42页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
案例四 绘图板4 . 1 程序设计目的绘图操作在日常应用中不可或缺。图形可以用于说明很多无法用言语说明白的问题。本案例将介绍如何使用 C来开发一个绘图程序,该程序基于 GDI+ 类库,具有一些简单的绘图操作功能及图片查看和缩放功能,使用它可以绘制出简单的图形。 4 . 2 程序功能介绍本案例程序实现了对简单图形(如直线、矩形和圆形)进行绘制、移动和旋转等操作;插入图片作为背景;改变绘制画笔的颜色、线宽和样式等;以及将图形存储为自定义格式文件或者图像文件。本案例程序基于工厂的设计模式来编写,可以向程序中添加其他的图形元素,如三角形、多边形、图像等,只需要继承基类 MyItem 并实现其定义的一些方法即可。 4 . 3 架构设计与关键技术介绍431 需求分析和架构设计针对上述介绍过的功能,首先分析一下如何实现图形绘制的功能,并且考虑到图形元素的多样性,为了加强程序的可扩展性,需要利用一些设计模式。与前面的章节不同,本案例及以后的章节所开发的程序没有已有的功能强大的控件可供使用,我们都需要从底层开发,具体到每一个点的绘制。因此,将使用 UML 的图形化描述来替换我们频繁的说教式的方式, UML 图将使用 Rational Rose 来绘制。 1 程序功能分析用例分析我们所需要开发的功能总体上可以分为三类:图形绘制、图形操作和文件操作。图形绘制完成各种图形元素的创建。图形操作完成图形元素绘制完毕后的各种操作,如绘制、选中、移动、旋转等。文件操作完成将绘制的各个图形存储为文件以备以后继续编辑,或者将其存储为图像文件以方便插入其他的文档中。根据上述分析,可以绘制出系统的用例图,如图 4-1 所示。 图4-1 系统用例图2 程序用例分析和实现顺序图由于有非常多的图形元素,肯定会出现考虑不周的情况,所以一定要使程序具有可扩,通过一个统一的接口来使用所有的元素,当需要添加另外的图形元素时,只需继承统一的接口,就可以直接在程序中使用。对于这种情况,很明显可以使用工厂模式来实现,假设一个统一的接口为基类 MyItem ,此类为一个抽象类,定义操作图形需要的方法,图形元素都继承自此类,实现 MyItem 的方法即可。我们可以实现图形创建的顺序图,如图 4-2所示。图4-2 图形创建的顺序图实现由于图形操作有很多种,而其程序功能大致相同,例如,移动图形的顺序图给出如图 4-3所示。图 4-3 移动图形的顺序图打开文件的顺序图实现如图 4-4所示。图 4 -4打开文件的顺序图实现3 程序设计类图经过上面的分析,我们已经对系统的要求和需要实现的功能有了一些了解,下面我们具体进行编码,设计程序需要使用的类,设定基类为 MyItem ,并定义 3 个子类:MyLine 、 MyRectangle 和 MyCirce,分别表示直线、矩形和圆形三种图形。另外需要有创建工厂类 ItemFactory 和表示图形元素类型的类 ItemType,这样就可以得到 系统的类图,如图 4-5 所示。图 4-5 系统类图实现在基类 MyItem 中定义了一些图形操作所需要的抽象方法,如 Draw 、 Erase 等,在相关的子类中实现这些方法,然后直接将子类封装成统一的基类来操作,这样就统一了接口实现,简化了编码。432 程序关键技术介绍下面介绍本案例程序中的关键技术。 1 工厂设计模式简介工厂模式的意图是定义一个用于创建对象的接口,让子类决定实例化哪个类,它使得每一个类的实例化延迟到子类。它适用于下列几种情况:当一个类不知道它所必须创建的对象的类时。当一个类希望由它的子类来指定它所创建的对象时。当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将其中一个帮助子类是代理者这一信息局部化时。图 4-6 给出了该模式的架构图。图 4-6 工厂模式的架构图工厂模式主要有两种不同的情况:第一种情况是, Creator 类是一个抽象类并且不提供它所声明的工厂方法的实现。第二种情况是, Creator 类是一个具体的类而且为工厂方法提供一个默认的实现。也有可能有一个定义了默认实现的抽象类,但这不太常见。第一种情况需要子类来定义实现,因为没有合理的默认实现。它避免了不得不实例化不可预见类的问题。在第二种情况中,具体的 Creator 主要因为灵活性才使用工厂方法。它所遵循的准则是,“用一个独立的操作创建对象,这样子类才能重定义它们的创建方式”。这条准则保证了子类的设计者能够在必要的时候改变父类所实例化的对象的类。2 类的序列化序列化是 .NET 的运行时环境用来支持用户定义类型的流化的机制。它是将对象案例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。序列化的目的是以某种存储形式使自定义对象持久化或者将对象从一个地方传到另一个地方。实质上序列化机制是将类的值转换为一个一般的(即连续的)字节流,然后就可以将该流写到磁盘文件或任何其他流化目标上。而要想实际地写出这个流,就要使用那些实现了 IFormatter 接口的类里的 Serialize 和 Deserialize 方法。.NET 提供了两种序列化的方式,分别对应两个类: BinaryFormatter 和 SoapFormatter 。 BinaryFormatter 使用二进制格式化程序进行序列化。只需创建一个要使用的流和格式化程序的案例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象案例作为参数提供给 BinaryFormatter 调用。类中的所有成员变量(甚至标记为 private 的变量)都将被序列化。而 SoapFormatter 将对象以 XML 格式化,因此能有更好的可移植性,需要注意的是这种序列化方式不能安全地访问私有变量成员,所以需要将私有成员改为公共成员,或者提供合适的公共特性。当需要序列化一个类的时候,只需要简单地在定义类的时候加上自定义属性 Serializable , 然后在序列化或者反序列化的时候调用系统的 Serialize 和 Deserialize 方法即可。需要注意的是在使用 BinaryFormatter 时可以继承 Serilizable 属性,而使用 SoapFormater 时必须为每一个类(包括父类和子类)都定义 Serilizable 属性,而且需要为每一个类都建立一个默认的构造函数。 3GDI+ 绘图方式简介在 GDI+ 中,几乎所有的绘图操作都是在 Graphics 对象上完成的,所有的可绘图对象都可以通过使用 CreateGraphics 方法来获得其 Graphics 对象。 Graphics 对象可以完成多种绘图操作,如绘制直线、矩形、椭圆形、不规则多边形、贝塞尔曲线等,可以绘制图像、文字等对象。具体的绘图方法可以在 Graphics 类的说明中找到,在此不再赘述。4 . 4 程序设计 441 设计界面程序共有 4 个窗体,分别是图像大小设定窗体、画笔线宽选择窗体、画笔样式选择窗体和程序主窗体,下面一一进行介绍。 1 图像大小设定窗体NewPaint.cs此窗体用于设定画布的大小,利用此功能可以设定绘制的图像的大小。另外因为打开的图片文件默认将作为背景图,在画布的大小变化时,此图像也会随之变化,利用此功能可以改变图片的大小。该窗体设计步骤如下:在程序中新建窗体,命名为 NewPaint ,在窗体中添加 3 个 Label 控件、两个 NumbericUpDown 控件和一个 Button 控件,分别命名并设置它们的属性。设置完毕后的界面如图 4-7 所示。表 4-l 是图像大小设定窗体的控件属性列表。图 4-7 图像大小设定窗体界面NewPaint.cs表 4-1 控件对象属性列表对象属性设置值 控件功能Label Text 图像大小Label Text 宽度 Label Text 高度 NumbericUpDown Name nu_Width 表示图像的宽度 MaXimum 20000 NumbericUpDown Name nu_Height 表示图像的高度 Maximum 20000 Button Name Text btnOK 确定单击设定图像大小 2 画笔线宽选择窗体ChooseWidth.cs此窗体用于选择绘制图像时使用的画笔的线宽。设计步骤如下:在程序中新建窗体,命名为 ChooseWidth ,在窗体中添加一个 Label 控件、一个 ComboBox 控件和一个 Button 控件,分别命名并设置它们的属性。设置完毕后的界面如图 4-8 所示。表 4-2 是画笔线宽设定窗体的控件属性列表。图 4-8 画笔线宽选择窗体界面ChooseWidth.cs表 4-2控件对象属性列表对象属性设置值控件功能Label Text 选择线宽ComboboxName comboWidth 表示画笔的线宽DropDownStyleDropdownListButton Name btnOK单击设定画笔线宽Text 确定 3 画笔样式选择窗体ChooseStyle.cs此窗体用于选择绘制图像时使用的画笔的样式。设计步骤如下:在程序中新建窗体,命名为 ChooseStyle ,在窗体中添加一个 Label 控件、一个 ComboBox 控件和一个 Button 控件,分别命名并设置它们的属性。设置完毕后的界面如图 4-9 所示。表 4-3 是画笔样式设定窗体的控件属性列表。图 4-9 画笔样式选择窗体界面ChooseStyle.cs表 4-3 控件对象属性列表对象属性 设置值控件功能Label Text选择样式ComboBoxName comboStyle 表示画笔的样式DropDownStyleDropDownList ButtonName Textbtn0K 确定 单击设定画笔样式 4 程序主窗体PaintForm.cs程序主窗体完成大部分的绘图操作,包括图形的创建、绘制、移动、旋转、文件操作等。程序主窗体设计步骤如下:在程序中新建窗体,命名为 PaintForm ,在窗体中添加一个 MainMenu 控件、一个 ToolBar控件、一个 Panel 控件、一个 StatusBar 控件、一个 OpenFileDialog 控件、一个 SaveFileDialog 控件、一个 ColorDialog 控件,在 Panel 控件中添加一个 PictureBox 控件,为 MainMenu 控件添加菜单项,为 ToolBar 控件添加 4 个工具栏按钮,为 StatusBar 控件添加两个 Panel ,分别命名并设置控件的属性。设置完毕后的界面如图 4-10 所示。表 4-4 是程序主窗体的控件属性列表。图 4-10 程序主窗体界面图PaintForm.cs表 4-4 控件对象属性列表对象属性设置值控件功能 OpenFileDialog Name openFileDialog1 用于打开文件DefaultExt *.pat Filter Painter文件| *. pat |BMP文件| * .bmp | JPG文件| * .jpg |JPEG文件 | *.jpeg |Gif 文件 | *. gifSaveFileDialog Name saveFileDialogl 用于保存文件DefaultExt *.pat FilterPainter文件| *. pat |BMP文件| * .bmp | JPG文件| * .jpg |JPEG文件 | *.jpeg |Gif 文件 | *. gifColorDialogNamecolorDialogl用于选择画笔的颜色PanelName myPanel 用于容纳 PictureBox 控件AutoScrollTruePictureBoxNamemyPicture所有图像的容器StatusBarName myStatus 用于显示系统状态ShowPanelsTrueToolBarName MainToolBar 用于绘制各种图形TextAlign Right ShowToolTipsTrue主窗体的菜单项的设计如图 4-11 所示。由于菜单项太多,在此不一一列举其属性了,读者可以参考下载包中的源代码。图 4-11菜单项界面图442 代码编写 图4-12 Common文件夹文件1 . MyItem 图形基类的设计该类是所有图形元素的基类,定义了所有图形元素必须实现的方法,以及图形元素的行为规范。代码如下: using System;using System.Drawing;namespace Painter.Common/ / ItemBase 的摘要说明。/ Serializablepublic abstract class MyItempublic MyItem()/表示图形被选中后的颜色private Color selectedcolor = Color.Red;public Color SelectedColorgetreturn selectedcolor;setselectedcolor = value;/表示绘制图形所使用的画笔的颜色private Color bordercolor;public Color BorderColorgetreturn bordercolor;setbordercolor = value;/表示绘制图形所使用的画笔的样式private System.Drawing.Drawing2D.DashStyle borderstyle;public System.Drawing.Drawing2D.DashStyle BorderStylegetreturn borderstyle;setborderstyle = value;/表示绘制图形所使用的画笔的线宽private float borderwidth;public float BorderWidthgetreturn borderwidth;setborderwidth = value;/表示此图形是否被选中public bool IsSelected = false;/表示此图形取消选中时是否需要重绘public bool DrawDeSelect = false;/绘制图形方法public abstract void Draw(Graphics g,Color bgColor);/擦除图形方法public abstract void Erase(Graphics g,Color bgColor);/选中图形方法public abstract void Select(Graphics g,Color bgColor);/取消选中图形方法public abstract void DeSelect(Graphics g,Color bgColor);/判断一个点是否在图形上的方法public abstract bool Contains(float x,float y);/旋转图形方法public abstract void Rotate(Graphics g, float cx,float cy,Color bgColor);/移动图形方法public abstract void Move(Graphics g, float ptx_offset,float pty_offset,Color bgColor);/判断一条线段是否包含一个指定的点,/error为误差范围,在此误差范围内的点将都被认为是在线段上public bool LineContains(float x1,float y1,float x2,float y2,float ptx,float pty,float error)float space = 2;if (x1=x2) if (ptxx1-error-space & ptxx1+error+space)&(ptyy2)|(ptyy1&ptyy1-error-space & ptyy1+error+space)&(ptxx2)|(ptxx1&ptxx2) return true;Elsereturn false;elsecoordX1 = x1-y1/slope-error-space;coordX2 = x1-y1/slope+error+space;coordPt = ptx-pty/slope;if (coordPtcoordX2) |(coordPtcoordX1 & coordPtcoordX2) slope = -1/slope;coordX1 = x1-y1/slope;coordX2 = x2-y2/slope;coordPt = ptx-pty/slope;if (coordPtcoordX2)|(coordPtcoordX1 & coordPtcoordX2) return true;return false;/用于围绕一个端点旋转一条直线,按照鼠标的位置取出另一个端点的坐标public PointF RotateLine(float x1,float y1,float cx,float cy,double length)float x2,y2;double angle = Math.Atan(cy-y1)/(cx-x1);x2 = cxx1?x1-(float)(length*Math.Cos(angle):x1+(float)(length*Math.Cos(angle);y2 = cxx1?y1-(float)(length*Math.Sin(angle):y1+(float)(length*Math.Sin(angle);return new PointF(x2,y2);/定义图形类型为枚举类型public enum ItemTypeLine,RectAngle,Circle2MyLine类说明此类实现了绘制一条直线所需要的方法。代码如下:using System;using System.Drawing;using System.Drawing.Drawing2D;namespace Painter.Common/ / Line 的摘要说明。/ Serializablepublic class MyLine : MyItem/分别表示两个端点的坐标private float x1,y1,x2,y2; public float X1getreturn x1;setx1 = value;public float Y1getreturn y1;sety1 = value;public float X2getreturn x2;setx2 = value;public float Y2getreturn y2;sety2 = value;/表示直线的长度private double length = 0;public double Lengthgetif (length = 0) length = Math.Sqrt(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);return length;/构造直线public MyLine(float x1,float y1,float x2,float y2,Color color,float width,DashStyle style)this.X1 = x1;this.Y1 = y1;this.X2 = x2;this.Y2 = y2;this.BorderColor = color;this.BorderWidth = width;this.BorderStyle = style;/绘制直线public override void Draw(Graphics g,Color bgColor)Pen pen = new Pen(this.BorderColor,this.BorderWidth);pen.DashStyle = this.BorderStyle;g.DrawLine(pen,X1,Y1,X2,Y2);if (IsSelected) SolidBrush brush = new SolidBrush(SelectedColor);g.FillEllipse(brush,x1-2,y1-2,4,4);g.FillEllipse(brush,x2-2,y2-2,4,4);else if (DrawDeSelect)SolidBrush brush = new SolidBrush(bgColor);g.FillEllipse(brush,x1-2,y1-2,4,4);g.FillEllipse(brush,x2-2,y2-2,4,4);DrawDeSelect = false;/擦除直线public override void Erase(Graphics g,Color bgColor)Pen pen = new Pen(bgColor,this.BorderWidth);pen.DashStyle = this.BorderStyle;g.DrawLine(pen,X1,Y1,X2,Y2);if (IsSelected) pen.Color = SelectedColor;g.DrawLine(pen,X1,Y1,X2,Y2);else if (DrawDeSelect)pen.Color = BorderColor;g.DrawLine(pen,X1,Y1,X2,Y2);DrawDeSelect = false;/选中直线public override void Select(Graphics g,Color bgColor)IsSelected = true;this.Draw(g,bgColor);/取消选中直线public override void DeSelect(Graphics g,Color bgColor)IsSelected = false;DrawDeSelect = true;this.Draw(g,bgColor);/判断是否包含某个点public override bool Contains(float x, float y)return LineContains(x1,y1,x2,y2,x,y,this.BorderWidth);/旋转直线public override void Rotate(Graphics g, float cx,float cy,Color bgColor)this.Erase(g,bgColor);PointF pt = RotateLine(X1,Y1,cx,cy,Length);X2 = pt.X;Y2 = pt.Y;this.Draw(g,bgColor);/移动直线public override void Move(Graphics g, float ptx_offset, float pty_offset, Color bgColor)this.Erase(g,bgColor);this.X2 += ptx_offset;this.Y2 += pty_offset;this.X1 += ptx_offset;this.Y1 += pty_offset;this.Draw(g,bgColor);3MyRectangle类说明此类实现了绘制一个矩形所需要的方法。代码如下:using System;using System.Drawing;using System.Drawing.Drawing2D;namespace Painter.Common/ / MyRectAngle 的摘要说明。/ Serializablepublic class MyRectAngle : MyItem/分别表示矩形的四个端点的坐标private float x1,y1,x2,y2,x3,y3,x4,y4;public float X1getreturn x1;setx1 = value;public float Y1getreturn y1;sety1 = value;public float X2getreturn x2;setx2 = value;public float Y2getreturn y2;sety2 = value;public float X3getreturn x3;setx3 = value;public float Y3getreturn y3;sety3 = value;public float X4getreturn x4;setx4 = value;public float Y4getreturn y4;sety4 = value;/表示连接第一个端点和第二个端点的边的长度private double l12=0;public double L12getif (l12=0) l12 = Math.Sqrt(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);return l12;/表示连接第一个端点和第三个端点的边的长度private double l13=0;public double L13getif (l13=0) l13 = Math.Sqrt(x3-x1)*(x3-x1)+(y3-y1)*(y3-y1);return l13;/表示连接第一个端点和第四个端点的边的长度private double l14=0;public double L14getif (l14=0) l14 = Math.Sqrt(x4-x1)*(x4-x1)+(y4-y1)*(y4-y1);return l14;/构造函数public MyRectAngle(float x1,float y1,float x3,float y3,Color color,float borderwidth,DashStyle style)this.X1 = x1;this.Y1 = y1;this.X2 = x3;this.Y2 = y1;this.X3 = x3;this.Y3 = y3;this.X4 = x1;this.Y4 = y3;this.BorderColor = color;this.BorderWidth = borderwidth;this.BorderStyle = style;/绘制矩形,由于Graphics提供的会址举行的函数不能够实现旋转的目的,/因此这里实际使用了绘制多变形的方式来绘制矩形。public override void Draw(Graphics g,Color bgColor)Pen pen = new Pen(this.BorderColor,this.BorderWidth);pen.DashStyle = this.BorderStyle;g.DrawPolygon(pen,new PointF new PointF(x1,y1), new PointF(x2,y2), new PointF(x3,y3), new PointF(x4,y4);if (IsSelected) pen.Color = SelectedColor;g.DrawPolygon(pen,new PointF new PointF(x1,y1), new PointF(x2,y2), new PointF(x3,y3), new PointF(x4,y4);else if (DrawDeSelect)pen.Color = BorderColor;g.DrawPolygon(pen,new PointF new PointF(x1,y1), new PointF(x2,y2), new PointF(x3,y3), new PointF(x4,y4);DrawDeSelect = false;/擦除矩形public override void Erase(Graphics g,Color bgColor)Pen pen = new Pen(bgColor,this.BorderWidth);pen.DashStyle = this.BorderStyle;g.DrawPolygon(pen,new PointF new PointF(x1,y1), new PointF(x2,y2), new PointF(x3,y3), new PointF(x4,y4);/选中矩形public override void Select(Graphics g,Color bgColor)IsSelected = true;this.Draw(g,bgColor);/取消选中public override void DeSelect(Graphics g,Color bgColor)IsSelected = false;DrawDeSelect = true;this.Draw(g,bgColor);/判断某个点是否落在矩形的四条边上public override bool Contains(float x, float y)if (LineContains(X1,Y1,X2,Y2,x,y,this.BorderWidth) return true;else if (LineContains(X2,Y2,X3,Y3,x,y,this.BorderWidth) return true;else if (LineContains(X3,Y3,X4,Y4,x,y,this.BorderWidth) return true;else if (LineContains(X4,Y4,X1,Y1,x,y,this.BorderWidth) return true;return false;/旋转矩形public override void Rotate(Graphics g, float cx, float cy ,Color bgColor)this.Erase(g,bgColor);PointF pt3;pt3 = RotateLine(X1,Y1,cx,cy,L13);X3 = pt3.X;Y3 = pt3.Y;double angle34,angle23;angle23 = Math.Acos(L12/L13);angle34 = Math.Acos(L14/L13);double angle13 = Math.Atan(Y3-Y1)/(X3-X1);/ 如果角度在-PI/2PI/2之间if (X3X1) X2 = X1+(float)(L12*Math.Cos(angle13+angle23);Y2 = Y1+(float)(L12*Math.Sin(angle13+angle23);X4 = X1+(float)(L14*Math.Cos(angle13-angle34);Y4 = Y1+(float)(L14*Math.Sin(angle13-angle34);elseX2 = X1-(float)(L12*Math.Cos(angle13+angle23);Y2 = Y1-(float)(L12*Math.Sin(angle13+angle23);X4 = X1-(float)(L14*Math.Cos(angle13-angle34);Y4 = Y1-(float)(L14*Math.Sin(angle13-angle34);this.Draw(g,bgColor);/移动矩形public override void Move(Graphics g, float ptx_offset, float pty_offset, Color bgColor)this.Erase(g,bgColor);this.X4 += ptx_offset;this.Y4 += pty_offset;this.X3 += ptx_offset;this.Y3 += pty_offset;this.X2 += ptx_offset;this.Y2 += pty_offset;this.X1 += ptx_offset;this.Y1 += pty_offset;this.Draw(g,bgColor);4.MyCircle类说明此类实现了绘制一个圆形所需要的方法。代码如下:using System;using System.Drawing;using System.Drawing.Drawing2D;namespace Painter.Common/ / MyCircle 的摘要说明。/ Serializablepublic class MyCircle : MyItem/分别表示圆形外接矩形的对角线的两个端点的坐标private float x1,y1,x2,y2;public float X1getreturn x1;setx1 = value;public float Y1getreturn y1;sety1 = value;public float X2getreturn x2;setx2 = value;public float Y2getreturn y2;sety2 = value;/ 圆心public float XGetreturn (X1+X2)/2;public float Ygetret
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 乡村老人阅读题目及答案
- 现代刑侦推理题目及答案
- 葡萄糖知识培训课件
- 2024译林版八年级英语上册Unit3 单元测试卷及答案(含两套题)
- 2025计时工的劳动合同
- 物权法自考试题及答案
- 2025电气设备采购合同
- 新实英语综合教程(第二册) 课件 U6 China and the World
- 营销师操作规程培训课件
- 2025联营企业合作协议
- 电竞酒店服务礼仪与职业素养培训
- 物业客服管家工作内容培训
- 梅大高速塌方灾害调查评估报告及安全警示学习教育
- 针灸在临床医学中的应用探讨
- 2023年高考英语试卷(新课标Ⅰ卷)含答案解析
- 学生生活全景模板
- 言语语言障碍康复护理
- 无人机装调检修工理论知识考试题及答案
- 统编语文五年级上册第一单元作业设计
- 湖北省2025届高三(9月)起点考试 语文试卷(含答案)
- 2024重庆机场集团公开招聘57人(高频重点提升专题训练)共500题附带答案详解
评论
0/150
提交评论