画图板

所属分类:汇编语言
开发工具:Others
文件大小:1761KB
下载次数:0
上传日期:2020-11-01 17:17:02
上 传 者Honordirewolf
说明:  汇编语言实现绘图板,自己看就行了,很有用。
(The assembly language realizes the drawing board, just look at it by yourself, very useful.)

文件列表:
汇编 (0, 2020-07-07)
汇编\doc (0, 2020-07-07)
汇编\doc\choosecolor.png (107861, 2020-07-07)
汇编\doc\choosefont.png (99045, 2020-07-07)
汇编\doc\dialog.png (9343, 2020-07-07)
汇编\doc\font.png (74861, 2020-07-07)
汇编\doc\hatchstyle.png (62330, 2020-07-07)
汇编\doc\linestyle.png (267125, 2020-07-07)
汇编\doc\linestyles.png (66072, 2020-07-07)
汇编\doc\load.png (86182, 2020-07-07)
汇编\doc\paint.png (25345, 2020-07-07)
汇编\doc\report.md (10650, 2020-07-07)
汇编\doc\report.pdf (833074, 2020-07-07)
汇编\doc\save.png (66460, 2020-07-07)
汇编\doc\size.png (25982, 2020-07-07)
汇编\doc\solidinside.png (3577, 2020-07-07)
汇编\exe (0, 2020-07-07)
汇编\exe\PictureEditor.exe (28672, 2020-07-07)
汇编\exe\PictureEditor.pdb (438272, 2020-07-07)
汇编\src (0, 2020-07-07)
汇编\src\PictureEditor (0, 2020-07-07)
汇编\src\PictureEditor\Define.inc (6911, 2020-07-07)
汇编\src\PictureEditor\main.asm (2348, 2020-07-07)
汇编\src\PictureEditor\MenuAndControl.asm (6410, 2020-07-07)
汇编\src\PictureEditor\Painter.asm (12402, 2020-07-07)
汇编\src\PictureEditor\PictureEditor.vcxproj (8243, 2020-07-07)
汇编\src\PictureEditor\PictureEditor.vcxproj.filters (1787, 2020-07-07)
汇编\src\PictureEditor\PictureEditor.vcxproj.user (162, 2020-07-07)
汇编\src\PictureEditor\RCa49504 (5666, 2020-07-07)
汇编\src\PictureEditor\RCb49504 (5666, 2020-07-07)
汇编\src\PictureEditor\res (0, 2020-07-07)
汇编\src\PictureEditor\res\EraserCursor.cur (326, 2020-07-07)
汇编\src\PictureEditor\res\PaintCursor.cur (326, 2020-07-07)
汇编\src\PictureEditor\res\TextCursor.cur (326, 2020-07-07)
汇编\src\PictureEditor\Resource.aps (6168, 2020-07-07)
汇编\src\PictureEditor\resource.h (807, 2020-07-07)
汇编\src\PictureEditor\Resource.rc (7600, 2020-07-07)
汇编\src\PictureEditor\WindowsManager.asm (14596, 2020-07-07)
汇编\src\PictureEditor.sln (1794, 2020-07-07)
... ...

--- typora-root-url: ./ --- ## PictureEditor # 汇编与编译原理大作业 ### 1. 开发环境 #### windows10下VS2017+masm32 + 常规 > windows SDK版本:**10.0.17134.0** + 常规 > 平台工具集:**Visual Studio 2017 (V141)** + 链接器> 附加库目录:**~/masm32/bin;** 链接器 > 系统 > 子系统: **窗口(/SUBSYSTEM:WINDOWS)** + Microsoft Macro Assemble > General > **~/masm32/include;** ### 2.实现原理 - 整体框架 - 基于老师上课讲的Win32框架 - 通过处理WM_COMMAND事件来响应菜单操作,更改当前绘图模式 - 通过处理单击事件(这里用的是WM_LBUTTONUP)来进行取点 - 通过综合处理WM_LBUTTONDOWN,WM_LBUTTONUP,WM_MOUSEMOVE事件来实现画笔和橡皮 - 每次触发绘图操作时保存数据,然后调用InvalidateRect函数来触发绘图操作。处理WM_PAINT事件来绘制 + 创建窗口 - 用CreatePopupMenu函数创建窗口,用AppendMenu绑定对应的文字描述和模式 + 框架画图 + 实现了直线、矩形、三角形(分上下)、多边形 + 直线可调整类型,PS_SOLID(实线), PS_DASH(段线),PS_DOT(点线), PS_DASHDOT(线、点),.... 等共6种 + 直线可调整粗细,调用GetDlgItemInt函数输入直线粗细值,调整粗细 + 直线可调整颜色,通过选择颜色可修改PenColor + 矩形,确定两个点以对角的两点,画出四条直线 + 三角形,原理同矩形 + 多边形:每选中一个点,就连出一条新线。然后判断当前最新选中的点是否和初始点足够接近,如果足够接近就结束取点,闭合绘制。 + 图形 + 实现了矩形、三角形、多边形、椭圆,用GDI自带的函数绘制 + 其外边距默认借用前面框架直线的设置 + 内部填充可选颜色 + 内部填充可选类型,有实心,(斜)交叉,左右斜线,竖/平线 + 截图如下,有画笔绘制,各种线,各种线框,各种图形,橡皮擦,文字 ![paint](doc/paint.png) ![](doc/hatchstyle.png) + 文本 + 调用IDialogBoxParam创建输入文本窗口,获取文本 + 字体 IHandleFont函数实现 > 1. 定义全局变量CurrentFont,为HFONT句柄,存储当前的字体; > 2. 使用ChooseFont函数调用字体选择对话框,将选择的字体存入句柄; > 3. 当进行文本构建时,直接将CurrentFont作为句柄选择(SelectObject)进入当前HDC(ps.hdc); > 4. CurrentFont作为全局句柄变量无需Delete。 > 5. 截图: + 颜色 + 颜色:IHandleColor函数实现, > 1. 存在两种颜色,PenColora和BrushColor,分别作为全局DWORD存储。 > 2. 使用ChooseColor调用颜色选择对话框,将对应的颜色存入 > 3. 当需要绘制时,通过CreatePen或者CreateSolidBrush/CreateHatchBrush创建对应的hPen或者hBrush句柄。SelectObject选择进入当前HDC(ps.hdc) > 4. 当前创造的句柄需要Delete(DeleteObject)。 + 颜色截图 橡皮大小和线宽度选择 - 线宽度:IHandlePainterSize函数实现,橡皮大小:IHandleEraserSize函数实现 > 1. 通过对话框DialogBoxParam输入大小 > 2. 使用GetDlgItemInt获取输入的整数,并且进行范围判断 > 3. 当需要绘制时,通过CreatePen创建对应线宽的hPen句柄。SelectObject选择进入当前HDC(ps.hdc) > 4. 当前创造的句柄需要Delete(DeleteObject)。 > 5. 在使用橡皮擦的时候,把对应大小的正方形区域用NULL_PEN绘制 - 截图 ![dialog](doc/dialog.png) ![size](doc/size.png) 文件保存 + 文件保存:IHandleModeChange()内直接实现 > 1. 支持将画布内容保存为BMP图片格式; > 2. 认识到BMP图片格式文件由位图文件头、信息头、调色板和位图数据四部分组成; > 3. 通过CreateCompatibleBitmap、CreateCompatibleDC、SelectObject、BitBlt等多个函数将窗口中的位图信息转移到自己创建的环境中的位图上,再通过GetObject函数即可获取到位图信息,再利用GetDIBits函数将位图信息转移到分配的内存中区; > 4. 根据位图信息中像素、色深等信息完成位图文件头、信息头和调色板相关数据计算,同时给文件头和信息头赋上合适的值; > 5. 通过CreateFile和WriteFile函数即可完成文件的创建和信息的传入 文件读取 + 文件读取:IHandleModeChange()内直接实现 > 1. 通过LoadImage函数载入bmp图片文件; > 2. 再通过BitBlt将位图信息传输到窗口,即可对以前保存的文件进行进一步绘制; ![load](doc/load.png) ![save](doc/save.png) ### 3. 难点和创新点 - 如何实现画笔操作? > 画笔操作,实际是画线。 > > 当鼠标按下时,进入绘制状态。收起时,退出绘制状态。 > > 在绘制时,每次触发到WM_MOUSEMOVE事件时,都从先前的鼠标位置画线到当前位置,然后把当前位置作为新的先前鼠标位置。逻辑如下 > > ```assembly > mov edx, CurrentX > mov ebx, CurrentY > mov ecx, CurrentMode > .IF MouseStatus == 1 > .IF ecx == IDM_MODE_DRAW ;画线 > ;更新画线位置 > .IF EndX == 0 ;第一次画线 > mov StartX, edx > .ELSE > mov eax, EndX > mov StartX, eax > .ENDIF > > .IF EndY == 0 ;第一次画线 > mov StartY, ebx > .ELSE > mov eax, EndY > mov StartY, eax > .ENDIF > > mov EndX, edx > mov EndY, ebx > INVOKE InvalidateRect, hWnd, ADDR WorkRegion,0 > .ELSEIF ecx == IDM_MODE_ERASE ;擦除 > INVOKE InvalidateRect, hWnd, ADDR WorkRegion, 0 > .ENDIF > .ENDIF > ``` > > 其中StartX/Y,EndX/Y是绘制函数的画线起止点。 > > 如果没有记录先前的鼠标位置,就从当前位置画线到当前位置。否则从先前位置画线到当前位置。 - 如何实现绘制线/线框/多边形? > 直线,矩形,三角形,椭圆只需要两个点确定,而多边形需要n个点才能确定。因此,我仿照C++的不定长数组,通过一个很大的数组+长度记录,实现了点列数据结构。 > > 当鼠标按下时,进入绘制状态。收起时,退出绘制状态。 > > 在绘制时,每次触发到WM_MOUSEMOVE事件时,都从先前的鼠标位置画线到当前位置,然后把当前位置作为新的先前鼠标位置。逻辑如下 > > ```assembly > ;当前使用的点信息 > CurrentPointNum DWORD 0 > CurrentPointListX DWORD 100 DUP(?) > CurrentPointListY DWORD 100 DUP(?) > ``` > > 每处理一个单击事件,就存一个点。 > > 如果是绘制直线,矩形,三角形,椭圆,就存到2个点触发绘制函数,绘制完毕设置点数量为0 > > 如果是绘制多边形,就每存一个点,判断和第一个点的距离。当足够接近,就触发绘制函数,绘制完毕设置点数量为0 > > 绘制线框时,通过已有点的数据算出其他点的数据,然后相当于一下画多条线。 > > 绘制图形时,用汇编GDI的自带函数进行绘制。 > > ```assembly > INVOKE Rectangle, hdc, CurrentX, CurrentY, ebx, edx > INVOKE Ellipse, hdc, edx, ecx, ebx, eax > INVOKE Polygon, hdc, ADDR CurrentPointList, CurrentPointNum > ``` + 选择颜色后如何赋给直线以及填充区域? > 这需要对于handle句柄以及DC设备上下文有一定的了解 > > 在绘图时,需要传输DC的句柄hDc至绘图函数中,这样绘图才会成功呈现在当前设备上 > > 于是,hDc添加多个可选内容,如Brush, Pen, Erase, Bitmap等,以此来调整画图的模式 > > 对于直线来说,Pen可以通过CreatePen创造; > > 对于填充区来说,Brush通过调用CreateSolidBrush/CreateHatchBrush创造 > > ```assembly > invoke CreatePen, PenStyle, PenWidth, PenColor ;返回句柄hPen到eax > invoke CreateSolidBrush, BrushColor > invoke CreateHatchBrush, HatchStyle, BrushColor;返回句柄hBrush到eax > ``` > > 接着,我们将句柄传入到hDc当中即可 > > ```assembly > invoke SelectObject, hDc, eax ;此时eax存储在对应的句柄,若想传入多个对象到DC,则需重复多次。 > ``` > > 最终,通过传输hdc到画图函数中,会自动进行颜色等的改变 > > ```assembly > invoke DeleteObject,hPen;此外,必须Delete掉新创造的句柄,否则会出现一些奇怪的错误 > ``` + 如何获取窗口中的位图信息? > 这需要用到win32多个函数的帮助; > > 首先要考虑如何能够将窗口的位图信息移出来编程可以使用的数据; > > 通过CreateCompatibleBitmap、CreateCompatibleDC可以创建一个新的位图和上下文环境; > > 再通过SelectObject即可将新创建的位图移到新创建的上下文环境中; > > GetDC可以获取窗口句柄,BitBlt即可通过该句柄将其位图信息覆盖新创建的位图,达到取出位图信息的功能; > > GetObject则通过该位图信息获得BITMAP形式的信息加以利用; > > 而GetDIBits函数最后将位图信息直接移到分配的内存中,这样就可以直接输出位图信息了。 ### 4. 小组分工 #### 1. 沈冠霖: 1. 基本框架 2. 基本的上方菜单 3. 能画线,擦除,绘制基本图形,绘制文字 4. 修改光标 #### 2. 张小健: 1. 实现选择字体,文字大小,字体,(暂无颜色)。 2. 选择颜色:填充颜色和线条颜色 3. 选择填充模式:实心等多种模式 4. 设置线条宽度,线条类型 #### 3. 邓坤恬 1. 文件的保存 2. 文件的读取 ### 5.代码结构 Define.inc --常量和各种函数定义 main.asm --窗口主程序 Painter.asm --各种绘图程序 MenuAndControl.asm --菜单和控制部分,包括菜单建立和对话框程序 WindowsManager.asm --各种事件处理,包括绘图事件,WM_COMMAND事件,鼠标事件,存/读事件,修改绘图模式事件 Resource.rc--资源文件,资源本身放到res文件夹里 ### 6.参考资料 GDI文档 http://www.yfvb.com/help/gdiplus/index.htm?page=gdipdrawline.htm Windows API文档 https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list 对话框使用 https://blog.csdn.net/qq_22***2239/article/details/51203396 一个demo程序 https://github.com/nero19960329/DrawingTool/blob/master/Main.asm

近期下载者

相关文件


收藏者