win32汇编使用GDI+入门教程之九

效果图:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;win32汇编使用GDI+入门教程之九

;上一教程我们学了如何画出扇形和饼形,这一教程研究一下如何画贝塞尔曲线。

;调用GdipDrawBezierI函数,其中主要的是参数中的坐标数组

;其核心问题在于各个点的坐标值,以下例子的坐标值是随意写的,主要是展示怎么画,如果实用的话,计算坐标值则是另外的话题了。

;以下的例子画了二次曲线和三次曲线,更多次的以此类推

;以下代码在64位的win7系统编译通过,直接复制进RadAsm可编译运行;

;注意注释部分在编译时可以删除,不然容易出错。重要部分加备注。

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 使用 nmake 或下列命令进行编译和链接:

; ml /c /coff FirstWindow.asm

; Link /subsystem:windows FirstWindow.obj

.386

.model flat, stdcall

option casemap:none

include windows.inc

include user32.inc

include kernel32.inc

include gdiplus.inc

includelib gdiplus.lib

includelib user32.lib

includelib kernel32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; GdiplusStartupInput结构在gdiplus头文件里面没有定义,这里我们自已定义

GdiplusStartupInput STRUCT

GdiplusVersion DWORD ? ; 设置为1

DebugEventCallback DWORD ? ; 调试回调,通常为NULL

SuppressBackgroundThread DWORD ? ; 是否抑制后台线程

SuppressExternalCodecs DWORD ? ; 是否抑制外部编解码器

GdiplusStartupInput ENDS

; ==============================================

; 数据段

; ==============================================

.data?

hInstance HINSTANCE ?

CommandLine LPSTR ?

gdiplusToken dd ? ;实例变量,每个实例的意思相当于浏览器里打开的每个页面,这里相当于画室

pGraphics dd ? ;画布变量,有画布,才能在上面写或画或涂

.data

ClassName db "GdiplusShapesDemo",0

AppName db "WIN32汇编下使用GDI+ 绘制贝塞尔曲线",0

UnitPixel equ 2 ;设为2就是单位参数是像素,而不是英寸或其它什么的标准

.code

; ==============================================

; 窗口过程

; ==============================================

WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

local @ps:PAINTSTRUCT

local @hdc:HDC

local @startupInput:GdiplusStartupInput

local @pPen:DWORD ;画笔变量

local points10:POINT ;三次贝塞尔曲线需要10个点,所以定义一个POINT结构数组

.if uMsg == WM_CREATE

; 初始化GDI+

mov @startupInput.GdiplusVersion, 1

mov @startupInput.DebugEventCallback, NULL

mov @startupInput.SuppressBackgroundThread, FALSE

mov @startupInput.SuppressExternalCodecs, FALSE

invoke GdiplusStartup, addr gdiplusToken, addr @startupInput, NULL

.elseif uMsg == WM_PAINT

invoke BeginPaint, hWnd, addr @ps

mov @hdc, eax

invoke GdipCreateFromHDC, @hdc, addr pGraphics ;在设备上,即屏幕上创建画布

invoke GdipCreatePen1, 099000080h, 40400000h, UnitPixel, addr @pPen ;创建海军蓝色画笔,40400000h是3.0的值,即3个像素宽的画笔

;关开色彩值,这是ARGB值,就是网上查到的十六进制值,在这个值前面加上0,再加上透明度

;比如前面的099FF7F50h,0是汇编编译的要求,99是0.6的透明度,如果是FF,则是不透明的,FF7F50是珊瑚色的十六进制值

;画二次曲线

invoke GdipDrawBezierI, pGraphics, @pPen,

80, 150, ; 起点 P0

147, 50, ; 控制点1 Q1

213, 50, ; 控制点2 Q2

280, 150 ; 终点 P3

;画三次曲线

; 设置曲线控制点(波浪形)

; 第1段曲线:点0-3

mov dword ptr points, 80 ; P0.x

mov dword ptr points+4, 400 ; P0.y

mov dword ptr points+8, 70 ; P1.x

mov dword ptr points+12, 300 ; P1.y

mov dword ptr points+16, 120 ; P2.x

mov dword ptr points+20, 300 ; P2.y

mov dword ptr points+24, 170 ; P3.x

mov dword ptr points+28, 400 ; P3.y

; 第2段曲线:点3-6(继续)

mov dword ptr points+32, 180 ; P4.x

mov dword ptr points+36, 300 ; P4.y

mov dword ptr points+40, 230 ; P5.x

mov dword ptr points+44, 300 ; P5.y

mov dword ptr points+48, 280 ; P6.x

mov dword ptr points+52, 400 ; P6.y

; 第3段曲线:点6-9

mov dword ptr points+56, 330 ; P7.x

mov dword ptr points+60, 500 ; P7.y

mov dword ptr points+64, 380 ; P8.x

mov dword ptr points+68, 300 ; P8.y

mov dword ptr points+72, 330 ; P9.x

mov dword ptr points+76, 300 ; P9.y

; 绘制多段贝塞尔曲线

; GdipDrawBeziersI(graphics, pen, points, count)

; count: 点的总数(必须是3n+1,其中n是曲线段数)

invoke GdipDrawBeziersI, pGraphics, @pPen, addr points, 10 ; 3段曲线需要10个点

invoke GdipDeletePen, @pPen ;删除画笔

invoke GdipDeleteGraphics, pGraphics ;删除画布

invoke EndPaint, hWnd, addr @ps

.elseif uMsg == WM_DESTROY

; 清理资源

invoke GdiplusShutdown, gdiplusToken ;删除实例

invoke PostQuitMessage, 0

.else

invoke DefWindowProc, hWnd, uMsg, wParam, lParam

ret

.endif

xor eax, eax

ret

WndProc endp

; ==============================================

; 主程序入口

; ==============================================

start:

invoke GetModuleHandle, NULL

mov hInstance,eax

invoke GetCommandLine

mov CommandLine,eax

invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT

invoke ExitProcess, eax

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

LOCAL wc:WNDCLASSEX

LOCAL msg:MSG

LOCAL hwnd:HWND

mov wc.cbSize,SIZEOF WNDCLASSEX

mov wc.style, CS_HREDRAW or CS_VREDRAW

mov wc.lpfnWndProc, OFFSET WndProc

mov wc.cbClsExtra,NULL

mov wc.cbWndExtra,NULL

push hInstance

pop wc.hInstance

mov wc.hbrBackground,COLOR_WINDOW

mov wc.lpszMenuName,NULL

mov wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION

mov wc.hIcon,eax

mov wc.hIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW

mov wc.hCursor,eax

invoke RegisterClassEx, addr wc

invoke CreateWindowEx,NULL, ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,100,100,400,600, NULL,NULL,hInst, NULL

mov hwnd,eax

invoke ShowWindow, hwnd,CmdShow

invoke UpdateWindow, hwnd

.while TRUE

invoke GetMessage, ADDR msg,NULL,0,0

.break .if (!eax)

invoke TranslateMessage, ADDR msg

invoke DispatchMessage, ADDR msg

.endw

mov eax,msg.wParam

ret

WinMain endp

end start

相关推荐
广州灵眸科技有限公司2 小时前
xfce桌面触摸校准:基于灵眸科技EASY-EAl-Orin-Nano
数据库·windows·科技
王维同学8 小时前
[原创][Windows C++]LSA 认证、安全与通知包的注册表枚举
c++·windows·安全
YCOSA20258 小时前
雨晨 Windows 11 IOT 企业版 LTSC 24H2 轻装 2合1 26100.8968
windows·物联网
汤姆yu9 小时前
CodeGeeX 4完整安装与实操使用全指南
人工智能·windows·ai·智能体·视频模型
吐了啊取名字太难11 小时前
美颜系统AI修图本地跑并支持Mac、win、安卓、iOS不卡顿
android·人工智能·windows·数码相机·mac·ai编程
筱羽_筱羽13 小时前
VS2022 编译SOEM
windows·visualstudio·soem
love530love15 小时前
【排障实录】GPT Desktop (Codex) 开启 WSL 智能体模式后无法启动?手把手教你修复
人工智能·windows·gpt·agent
WangWei_CM15 小时前
Session Manager 的 BootExecute、SetupExecute 与 Execute 多字符串解析
windows
寒水馨16 小时前
Windows 11下载、安装openclaw-v2026.7.1(附安装包OpenClawCompanion-Setup-x64.exe)
windows·大模型·开源软件·ai助手·openclaw·个人ai·中文版
sukalot16 小时前
windows网络适配器驱动开发-为多个 Windows 版本生成 WiFiCx 驱动程序
windows·驱动开发