上一篇文章一个优秀的C#开源绘图软件 DrawTools中详细的介绍了DrawTools的几种演化的较高版本的软件的特色与功能。

这篇文章,将介绍一下这款软件的成名版本, 下载地址DrawTool_Origin.rar

Introduction

DrawTools sample shows how to create a Windows Forms application for drawing graphic objects in a Windows client area using mouse and drawing tools. Drawing tools implemented in this sample are: Rectangle, Ellipse, Line, and Pencil. There are well-known techniques for creating such type of applications, like: interaction with mouse, flicker-free drawing, implementing of drawing and selection tools, objects selection, managing of objects Z-order etc. MFC developers may learn all this stuff from MFC sample DRAWCLI. DrawTools C# program reproduces some of DRAWCLI functionality and uses some design decisions from this sample.

介绍

DrawTools示例告诉你怎么创建一个Windows窗体,来使用鼠标和画图工具在窗体上的可用区域画图。这个示例中实现了以下画图工具:矩形,椭圆形,直线和铅笔。其中有一些众所周知的技术来创建这个程序,比如说:鼠标的交互,无闪烁画图,实现了画图和工具选择,物体选择,控制物体的Z轴次序,等等。MFC开发者可以从DRAWCLI.这个MFC示例中了解到所有这些特性。DrawTools这个C#程序复制了一些DRAWCLI的功能,并且在这个例子中使用了一些设计决定。

DrawTools solution contains two projects: DrawTools Windows Forms application and DocToolkit Class Library. DrawTools implements specific application stuff, and DocToolkit contains some standard classes for file managing.

Main features of the DrawTools solution are described below.

DrawTools解决方案包括两个工程:DrawTools窗体应用程序和DocToolkit类库。DrawTools实现了一些特别的应用程序功能,DocToolkit包含有一些用于文件管理的标准类库。

以下描述了DrawTools 解决方案的主要特点:

  • DrawArea - user control which fills main application window client area. Contains instance of the GraphicsList class. Draws graphic objects, handles mouse input passing commands to GraphicsList.
  • GraphicsList - list of graphic objects. Contains ArrayList of graphic objects. Talks with each graphic object by generic way using DrawObject methods.
  • DrawObject - abstract base class for all graphic objects.
  • DrawRectangle - rectangle graphic object.
  • DrawEllipise - ellipse graphic object.
  • DrawLine - line graphic object.
  • DrawPolygon - polygon graphic object.
  • Tool - abstract base class for all drawing tools.
  • ToolPointer - pointer tool (neutral tool). Contains implementation for selection, moving, resizing of graphic objects.
  • ToolObject - abstract base class for all tools which create new graphic object.
  • ToolRectangle - rectangle tool.
  • ToolEllipse - ellipse tool.
  • ToolLine - line tool.
  • ToolPolygon - polygon tool.
  • DrawArea – 用来填充主程序在窗体上可用区域的用户控件。包括GraphicsList 类的实例。绘制图形对象, 处理鼠标输入,把(鼠标)命令传给GraphicsList。
  • GraphicsList – 图形对象的列表。包括图形对象的ArrayList。通过使用DrawObject类中的方法与其他图形对象通讯
  • DrawObject – 所有图形对象的抽象基类。
  • DrawRectangle – 矩形图形对象。
  • DrawEllipise – 椭圆形图形对象。
  • DrawLine – 直线图形对象。
  • DrawPolygon – 多边形图形对象。
  • Tool – 所有画图工具的抽象基类。
  • ToolPointer – 箭头工具 (中性工具)。包含选择,移动,改变图形对象大小的实现。
  • ToolObject – 所有工具的抽象基类,用来创建新的图形对象。ToolRectangle – 矩形工具。
  • ToolEllipse – 椭圆形工具。
  • ToolLine – 直线工具。
  • ToolPolygon – 多边形工具。

DocToolkit Library

DocToolkit Library contains set of classes which may be used for creation of document-centric Windows Forms applications. Instances of classes exported from the DocToolkit Library are kept in the main form of the DrawTools project and used for general file-related operations.

DocToolkit 类库

DocToolkit类库包含一些类的集合,这些类用来创建文档中心(document-centric)的窗体应用程序。从DocToolkit类库输出的类的实例被保存在DrawTools工程的主窗口中,用作一般的文件操作。

  • DocManager class: Makes file-related operations: open, new, save, updating of the form title, registering of file type for Windows Shell. Built using the article Creating Document-Centric Applications in Windows Forms by Chris Sells.
  • DragDropManager class: Allows to open files dropped from Windows Explorer in Windows Form application.
  • MruManager class: Manages Most Recently Used Files list.
  • PersistWindowState class: Allows to keep last window state in the Registry and restore it when form is loaded. Source: Saving and Restoring the Location, Size and Windows State of a .NET Form By Joel Matthias.
  • DocManager 类: 处理文件操作:打开,新建,保存,更新窗体标题,为Windows Shell注册文件类型。创建这个类引用了Chris Sells文章 Creating Document-Centric Applications in Windows Forms
  • DragDropManager 类: 在Windows Form应用程序中允许你通过拖拽的方式从浏览器(文件浏览器)中打开文件。
  • MruManager 类: 管理大多数最近使用的文件列表。
  • PersistWindowState 类: 允许你把最近一次的窗口状态保存到注册表 ,在窗体载入的时候重新获得。来源: Saving and Restoring the Location, Size and Windows State of a .NET Form By Joel Matthias.

Handling of Windows controls state at application idle time

Every Windows Forms application has a number of controls like menu items, buttons, toolbar buttons etc. Depending on current situation and user commands, these controls may have different states: enabled/disabled, checked/unchecked, visible/invisible etc. Every user action may change this state. Setting of controls' state in every message handler may be error-prone. Instead of this, it is better to manage controls' state in some function which is called after every user action. MFC has the great ON_UPDATE_COMMAND_UI feature which allows to update toolbar buttons' state at application idle time. Such a feature may be implemented also in .NET programs.

在程序空闲的时候操作Windows的控件状态

每一个Windows窗体应用程序都会有许多控件,比如说菜单项,按钮,工具栏按钮等等。根据当前状态和用户的命令,这些控件可能有不同的状态:enabled/disabled,checked/unchecked, visible/invisible 等等。用户的每一个操作可能改变这些状态。在每一个消息句柄中改变控件的状态可能导致错误。取而代之的方法是,在用户每一个操作后调用一些函数,在这些函数中管理控件的状态。MFC有一个很好的特性叫ON_UPDATE_COMMAND_UI它允许在应用程序的空闲时间更新工具栏按钮的状态。这个特性也可以在.NET程序中实现。

Consider the situation when user clicks the Rectangle toolbar button. This button should be checked, and previously active tool should be unchecked. Rectangle button message handler doesn't change form controls' state, it just keeps current selection in some variable. Idle message handler selects active tool and unselects inactive tool.

考虑一下这种情形:当用户点击工具栏上的Rectangle按钮,这个按钮就要显示为被选中,前一个激活的工具就要显示为没选中。Rectangle按钮的消息句柄并没有改变窗体控件的状态,它只是在一些变量中保存了当前的选择。空闲的消息句柄选择激活的工具,取消未激活工具的选择。

private void Form1_Load(object sender, System.EventArgs e)
{
    // Submit to Idle event to set controls state at idle time
    Application.Idle += new EventHandler(Application_Idle);
}

private void Application_Idle(object sender, EventArgs e)
{
    SetStateOfControls();
}

public void SetStateOfControls()
{
    // Select active tool
    tbPointer.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
    tbRectangle.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
    tbEllipse.Pushed  = (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
    tbLine.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
    tbPolygon.Pushed = (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);

    menuDrawPointer.Checked = 
                      (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
    menuDrawRectangle.Checked = 
                      (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
    menuDrawEllipse.Checked = 
                      (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
    menuDrawLine.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
    menuDrawPolygon.Checked = 
                      (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);

    // 
}

// Rectangle tool is selected
private void CommandRectangle()
{
     drawArea.ActiveTool = DrawArea.DrawToolType.Rectangle;
}

Hit Test

DrawObject class has virtual HitTest function which detects whether point belongs to graphic object:

Hit Test

DrawObject 类有一个叫HitTest的虚拟函数,用来侦测是否Point属于图形对象。

public virtual int HitTest(Point point)
{
    return -1;
}

Derived classes use virtual PointInObject to make hit test. This function is called from HitTest. DrawRectangle class implements this function by a simple way:

继承类使用虚拟的PointInObject来做点击测试。这个函数调用自HitTestDrawRectangle类使用了一种简单的方法实现了这个函数:

protected override bool PointInObject(Point point)
{
    return rectangle.Contains(point);
    // rectangle is class member of type Rectangle
}

DrawLine implementation of this function is more complicated:

DrawLine对这个函数的实现更加复杂:

protected override bool PointInObject(Point point)
{
    GraphicsPath areaPath;
    Pen areaPen;
    Region areaRegion;

    // Create path which contains wide line
    // for easy mouse selection
    AreaPath = new GraphicsPath();
    AreaPen = new Pen(Color.Black, 7);
    AreaPath.AddLine(startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
        // startPoint and EndPoint are class members of type Point
    AreaPath.Widen(AreaPen);

    // Create region from the path
    AreaRegion = new Region(AreaPath);

    return AreaRegion.IsVisible(point);
}

DrawPolygon function works by the same way, but AreaPath contains all lines in the polygon.

DrawPolygon函数使用了同样的方法,但是AreaPath包含了多边形的所有线。

Serialization

GraphicList class implements ISerializable interface which allows to make binary serialization of the class object. DrawObject class has two virtual functions which are used for serialization:

序列化

GraphicList类实现了ISerializable接口,这个接口用作类对象的二进制序列化。DrawObject类有两个虚函数用来做序列化。

public virtual void SaveToStream(SerializationInfo info, int orderNumber)
{
    // 
}

public virtual void LoadFromStream(SerializationInfo info, int orderNumber)

DrawTools(画图工具)原始版本的更多相关文章

  1. 当前不会命中断点。源代码与原始版本不同 (VS2012)

    遇到“当前不会命中断点.源代码与原始版本不同”的问题. 在网上查的类似: 一般studio会提示将“工具”,“选项”,“调试”,“要求源文件与原始版本完成匹配”去掉勾.但是这个配置去掉治标不治本,错误 ...

  2. arcgis 画图工具

    arcgis 4.x系列JavaScript API在4.4及以前的版本对画图工具(Draw)是不支持的,自4.5版本后才提供Draw的类.相关连接:https://developers.arcgis ...

  3. 配置ESP8266 NONOS SDK时由于工具链版本差异引发的故障

    前几天部署ESP8266_NONOS_SDK时遇到了一个看似奇怪的问题,描述如下: examples例程可以通过编译,但烧写到ESP8266模块后,程序无法正常运行,编译和烧写的相关配置均无误.在bo ...

  4. 使用Canvas制作画图工具

      前  言 JRedu canvas是HTML5中重要的元素之一,canvas元素使用JavaScript在网页上绘制图像,画布是一个矩形区域,我们可以控制其每一个元素,并且canvas拥有多种的绘 ...

  5. Ubuntu 16.10 安装KolourPaint 4画图工具

    KolourPaint 4画图工具简单实用,可以绘画.视频处理和图标编辑: • 绘画:绘制图表和“手绘” • 视频处理:编辑截图和照片;应用特效 • 图标编辑:绘画剪贴和标识透明化 1.在Ubuntu ...

  6. 用Canvas制作简单的画图工具

    今天用Canvas制作了一个画图工具,非常简单,功能也不是很多,主要有背景网格,画线,画圆,画矩形和画圆角矩形,也用到了canvas的一些基本知识,在这里一一列举. 1.线段的绘制: 如何绘制真正的1 ...

  7. Flex 中画图工具(drawTool)失效

    做项目的时候画图工具突然失效,解决了半天都不行,最后将画图结束的函数map_drawEndHandler写在方法里面的时候,运行却能够画图了,不知道是什么原理,比较头疼,左思右想,都感觉有点怪怪的,虽 ...

  8. 推荐ubuntu下的画图工具

    今天发现ubuntu下面也有类似于windows画图的画图工具,功能也比较强大,支持各种格式的图片,也有各种工具,非常方便,安装的方法是: sudo apt-get install kolourpai ...

  9. windows“画图”工具用法

    图片编辑工具不少,photoshop功能强大,但是并不是那么容易掌握.而且,倘若一个简单的图片处理问题就使用这么强大的工具,有点“杀鸡焉用牛刀”的意思,要知道只打开photoshop就需要一段等待时间 ...

随机推荐

  1. NOI 2004 郁闷的出纳员(平衡树)

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  2. 《苹果开发之Cocoa编程》挑战2 创建一个数据源 练习

    <苹果开发之Cocoa编程>第4版 P87 创建一个to-do list应用程序,在文本框中输入任务.当用户单击Add按钮时,添加字符串到一个变长队列,新任务就出现在list的末尾. 关键 ...

  3. ExtJS控件样式修改及美化

    Extjs项目对富客户端开发提供了强有力的支持,甚至改变了前端的开发方式,使得开发变得更加趋向于“面向组件”.对界面的美化而言,也是根本性的改变.普通的网页美工面对extjs项目根本无法下手,需要脚本 ...

  4. Linux应用程序的地址布局

    转载自:http://blog.csdn.net/embedded_hunter http://www.360doc.com/content/12/0405/00/1671317_200882538. ...

  5. 基于theano的深度卷积神经网络

    使用了两个卷积层.一个全连接层和一个softmax分类器. 在测试数据集上正确率可以达到99.22%. 代码参考了neural-networks-and-deep-learning #coding:u ...

  6. ToDictionary,ToLookup

    这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...

  7. php开发memcached

    一.memcached 简介 memcached是高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度.提高可扩展 性.它可以应对任意 ...

  8. C++多继承

    1.继承的三种方式: 公有继承(public),私有继承(private),保护继承(protected)三种继承方式的说明,如下表所示: 特征 公有继承 保护继承 私有继承 公有成员变成 派生类的公 ...

  9. EDIUS分别输出视频和音频的教程

    使用EDIUS剪辑好视频之后渲染输出文件时,为什么视频和音频分别出,而不是一起呢?这个问题很可能会让一些新手困惑不已,到底是什么原因呢?又要如何设置才能让输出的文件视音频一体呢?下面,小编将来和大家探 ...

  10. CI框架3.0关于session的设置改动及存数据库的使用方法

    Session的设置跟之前有点不一样 我们来看看2.0版本中的设置是什么样子的: $config['sess_cookie_name']= 'test_session'; $config['sess_ ...