GDI 区域检测与边框宽度的关系
https://blog.csdn.net/xiaoyao961/article/details/148657777
GDI+ 中与 CreateEllipticRgn/CreatePolygonRgn 对应的函数
在 GDI+ 中,区域 (Region) 的创建和操作与 GDI 有不同的接口。GDI+ 提供了更高级的对象模型,以下是与 GDI 中 CreateEllipticRgn
和 CreatePolygonRgn
对应的 GDI+ 函数:
1. 对应 CreateEllipticRgn 的 GDI+ 函数
在 GDI+ 中创建椭圆区域,使用 GdipCreateRegion
和 GdipAddEllipseToRegion
函数:
' GDI+ API 声明
Private Declare Function GdipCreateRegion Lib "gdiplus" (ByRef region As Long) As Long
Private Declare Function GdipAddEllipseToRegion Lib "gdiplus" (ByVal region As Long, ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single) As Long
Private Declare Function GdipDeleteRegion Lib "gdiplus" (ByVal region As Long) As Long
Private Declare Function GdipIsVisiblePoint Lib "gdiplus" (ByVal region As Long, ByVal x As Single, ByVal y As Single, ByVal graphics As Long) As Long
' 创建椭圆区域示例
Dim hRegion As Long
Dim graphics As Long
' 创建空区域
GdipCreateRegion hRegion
' 添加椭圆到区域
GdipAddEllipseToRegion hRegion, 50, 50, 100, 100 ' 椭圆边界框
' 使用区域...
' 释放资源
GdipDeleteRegion hRegion
2. 对应 CreatePolygonRgn 的 GDI+ 函数
在 GDI+ 中创建多边形区域,使用 GdipCreatePath
和 GdipAddPathPolygon
函数:
' GDI+ API 声明
Private Declare Function GdipCreatePath Lib "gdiplus" (ByVal fillMode As Long, ByRef path As Long) As Long
Private Declare Function GdipAddPathPolygon Lib "gdiplus" (ByVal path As Long, ByVal points As Long, ByVal count As Long) As Long
Private Declare Function GdipCreateRegionFromPath Lib "gdiplus" (ByVal path As Long, ByRef region As Long) As Long
Private Declare Function GdipDeletePath Lib "gdiplus" (ByVal path As Long) As Long
' 点结构定义
Private Type GdiplusPoint
X As Single
Y As Single
End Type
' 创建多边形区域示例
Dim hPath As Long
Dim hRegion As Long
Dim points(2) As GdiplusPoint ' 三角形3个点
' 初始化点数据
points(0).X = 50
points(0).Y = 50
points(1).X = 150
points(1).Y = 50
points(2).X = 100
points(2).Y = 150
' 创建路径
GdipCreatePath 0, hPath ' 0 = FillModeAlternate
' 添加多边形到路径
GdipAddPathPolygon hPath, VarPtr(points(0)), 3
' 从路径创建区域
GdipCreateRegionFromPath hPath, hRegion
' 使用区域...
' 释放资源
GdipDeletePath hPath
GdipDeleteRegion hRegion
3. GDI+ 区域与 GDI 区域的转换
如果需要在 GDI 和 GDI+ 区域之间转换,可以使用以下方法:
' GDI+ 区域转 GDI 区域
Private Declare Function GdipGetRegionData Lib "gdiplus" (ByVal region As Long, ByVal bufferSize As Long, buffer As Any) As Long
Private Declare Function ExtCreateRegion Lib "gdi32" (lpXform As Any, ByVal nCount As Long, ByVal lpRgnData As Long) As Long
' GDI 区域转 GDI+ 区域
Private Declare Function GdipCreateRegionFromHrgn Lib "gdiplus" (ByVal hrgn As Long, ByRef region As Long) As Long
4. 性能和功能对比
功能 | GDI 方法 | GDI+ 方法 |
---|---|---|
创建椭圆区域 | CreateEllipticRgn | GdipCreateRegion + AddEllipse |
创建多边形区域 | CreatePolygonRgn | GdipCreatePath + AddPathPolygon |
区域操作 | CombineRgn | GdipCombineRegions |
区域包含点检测 | PtInRegion | GdipIsVisiblePoint |
抗锯齿支持 | 不支持 | 支持 |
复杂路径支持 | 有限 | 完整支持 (贝塞尔曲线等) |
5. 完整示例:使用 GDI+ 创建圆形区域并检测鼠标位置
' GDI+ API 声明
Private Declare Function GdipStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Function GdipShutdown Lib "gdiplus" (ByVal token As Long) As Long
Private Declare Function GdipCreateRegion Lib "gdiplus" (ByRef region As Long) As Long
Private Declare Function GdipAddEllipseToRegion Lib "gdiplus" (ByVal region As Long, ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single) As Long
Private Declare Function GdipDeleteRegion Lib "gdiplus" (ByVal region As Long) As Long
Private Declare Function GdipIsVisiblePoint Lib "gdiplus" (ByVal region As Long, ByVal x As Single, ByVal y As Single, ByVal graphics As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hdc As Long, ByRef graphics As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As Long) As Long
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private gdiplusToken As Long
Private hRegion As Long
Private hGraphics As Long
Private Sub Form_Load()
Dim gdiplusInput As GdiplusStartupInput
' 初始化 GDI+
gdiplusInput.GdiplusVersion = 1
GdipStartup gdiplusToken, gdiplusInput
' 创建图形对象
GdipCreateFromHDC Me.hdc, hGraphics
' 创建圆形区域
GdipCreateRegion hRegion
GdipAddEllipseToRegion hRegion, 100, 100, 200, 200 ' 圆心(200,200),半径100
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim pixelX As Single, pixelY As Single
Dim isInside As Long
' 转换为像素坐标
pixelX = X / Screen.TwipsPerPixelX
pixelY = Y / Screen.TwipsPerPixelY
' 检测点是否在区域内
isInside = GdipIsVisiblePoint(hRegion, pixelX, pixelY, hGraphics)
If isInside <> 0 Then
Me.Caption = "鼠标在圆形内"
Else
Me.Caption = "鼠标在圆形外"
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
' 释放资源
GdipDeleteRegion hRegion
GdipDeleteGraphics hGraphics
GdipShutdown gdiplusToken
End Sub
总结
GDI+ 提供了更强大、更灵活的区域操作功能,虽然接口与 GDI 不同,但可以实现相同的功能,并且支持更多高级特性(如抗锯齿、复杂路径)。在需要高性能或复杂图形处理时,推荐使用 GDI+ 方法。