效果图:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;win32汇编使用GDI+入门教程之八
;上一教程我们学了如何画出圆弧,这个教程我们研究一下扇形和饼形是如何画的。
;这里要说明,扇形属于一个椭圆的一部分,而椭圆则在一个矩形里,而矩形由左上角的坐标、长度、高度决定的。
;当然这个扇形是标准的话,则属于正圆的一部分,而正圆则在一个正方形里。这个逻辑要搞明白来,这样才能理解所调用的GdipDrawPieI函数的参数意思
;GdipDrawPieI函数的参数有8个,分别是GdipDrawArcI(画布,画笔,边界矩形左上角X坐标,边界矩形左上角Y坐标,椭圆的宽度,椭圆的高度,x轴和弧的起点之间的角度,弧线起始点和终点之间的角度)
;这个角度是按顺时针方向设定的,比如0度在3点钟位置,90度在6点钟位置,180度在9点钟位置,270度在12点钟位置
;会画扇形了,就可以按扇形的逻辑拼成饼形
;以下的例子画了圆弧和饼形
;以下代码在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 @pBrush1:DWORD ;画刷变量
local @pBrush2:DWORD
local @pBrush3:DWORD
local angle45:REAL4
local angle90:REAL4 ;单精度浮点数(REAL4)的IEEE 754格式,角度值90度的变量,它是浮点数
local angle135:REAL4
local angle180:REAL4
local angle225:REAL4
local angle270:REAL4
local angle315:REAL4
local angle360:REAL4
.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, 099FF7F50h, 40400000h, UnitPixel, addr @pPen ;创建珊瑚色画笔,40400000h是3.0的值,即3个像素宽的画笔
invoke GdipCreateSolidFill, 0FF4682B4h, addr @pBrush1 ; 创建钢蓝色画刷
invoke GdipCreateSolidFill, 0FFC71585h, addr @pBrush2 ; 创建紫罗兰红色画刷
invoke GdipCreateSolidFill, 0FF2E8B57h, addr @pBrush3 ; 创建海洋绿色画刷
;关开色彩值,这是ARGB值,就是网上查到的十六进制值,在这个值前面加上0,再加上透明度
;比如前面的099FF7F50h,0是汇编编译的要求,99是0.6的透明度,如果是FF,则是不透明的,FF7F50是珊瑚色的十六进制值
mov dword ptr [angle45], 42340000h
mov dword ptr [angle90], 42B40000h ;42B40000h是90.0,这个有小数点,即浮点数的值,也即90度的十六进制值,下面的以此类推
mov dword ptr [angle135], 43070000h
mov dword ptr [angle180], 43340000h
mov dword ptr [angle225], 43610000h
mov dword ptr [angle270], 43870000h
mov dword ptr [angle315], 439D0000h
mov dword ptr [angle360], 43B40000h
;画线框扇形,从225度开始,画90度,就相当于画四分之一个圆
invoke GdipDrawPieI, pGraphics, @pPen, 50, 100, 150, 150, angle225, angle90
;画填充扇形
invoke GdipFillPieI, pGraphics, @pBrush1, 200, 100, 150, 150, angle225, angle90
;画线框饼形
invoke GdipDrawPieI, pGraphics, @pPen, 70, 300, 100, 100, angle315, angle270
;画填充饼形,三个不同颜色,就用三个不同颜色的扇形拼起来
invoke GdipFillPieI, pGraphics, @pBrush1, 230, 300, 100, 100, angle315, angle90
invoke GdipFillPieI, pGraphics, @pBrush2, 230, 300, 100, 100, angle45, angle90
invoke GdipFillPieI, pGraphics, @pBrush3, 230, 300, 100, 100, angle135, angle90
invoke GdipDeletePen, @pPen ;删除画笔
invoke GdipDeletePen, @pBrush1 ;删除画刷
invoke GdipDeletePen, @pBrush2
invoke GdipDeletePen, @pBrush3
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




