站群seo技巧,网站开发界面设计用什么工具,福州百度分公司,做婚纱的网站GDI32中用PtInRegion检测坐标是否在图形区域内#xff1a; 如果画了一个矩形,外边框线条粗细是10像素,检测区域时只能在第6像素开始才能反应,鼠标移动到边框线的1-5像素时,检测鼠标未在矩形区域
您遇到的问题是由于 GDI 中区域 (Region) 的定义与边框 (Stroke) 的渲染方式不同…GDI32中用PtInRegion检测坐标是否在图形区域内 如果画了一个矩形,外边框线条粗细是10像素,检测区域时只能在第6像素开始才能反应,鼠标移动到边框线的1-5像素时,检测鼠标未在矩形区域
您遇到的问题是由于 GDI 中区域 (Region) 的定义与边框 (Stroke) 的渲染方式不同导致的。这是 GDI 绘图系统的一个常见特性需要特别处理。
问题原因分析 区域 (Region) vs 边框 (Stroke) CreateRectRgn 创建的区域是填充区域不包含边框边框是绘制在区域边缘外部的默认情况下不被视为区域的一部分 边框宽度的影响 当您设置边框宽度为 10 像素时这 10 像素是从区域边缘向外扩展的区域本身的边界并没有改变因此PtInRegion只检测填充区域 坐标系统差异 区域使用整数坐标而边框渲染可能使用亚像素精度这种差异可能导致视觉上的边框与实际区域边界不一致
解决方案
方法一创建包含边框的扩展区域vb API声明
Private Declare Function CreateRectRgn Lib gdi32 (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CombineRgn Lib gdi32 (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Function PtInRegion Lib gdi32 (ByVal hRgn As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function DeleteObject Lib gdi32 (ByVal hObject As Long) As LongPrivate Const RGN_OR 2 区域合并操作Private Sub CreateExtendedRegion(ByVal left As Long, ByVal top As Long, ByVal right As Long, ByVal bottom As Long, ByVal borderWidth As Long, ByRef hRegion As Long)Dim hFillRgn As LongDim hBorderRgn As Long 创建填充区域hFillRgn CreateRectRgn(left, top, right, bottom) 创建扩展区域包含边框hBorderRgn CreateRectRgn(left - borderWidth, top - borderWidth, _right borderWidth, bottom borderWidth) 合并两个区域hRegion CreateRectRgn(0, 0, 1, 1) 创建临时区域CombineRgn hRegion, hFillRgn, hBorderRgn, RGN_OR 释放临时区域DeleteObject hFillRgnDeleteObject hBorderRgn
End Sub 使用示例
Private Sub Form_Load()Dim hRegion As LongDim borderWidth As LongborderWidth 10 创建包含10像素边框的区域CreateExtendedRegion 100, 100, 300, 200, borderWidth, hRegion 现在可以使用这个区域进行鼠标检测 PtInRegion(hRegion, x, y) 将包含边框区域
End Sub方法二分别检测填充区域和边框区域vb
Private Sub MouseInBorderOrFill(ByVal x As Long, ByVal y As Long, ByVal left As Long, ByVal top As Long, ByVal right As Long, ByVal bottom As Long, ByVal borderWidth As Long, ByRef inBorder As Boolean, ByRef inFill As Boolean) 检测是否在填充区域内inFill (x left And x right And y top And y bottom) 检测是否在边框区域内If Not inFill TheninBorder (x left - borderWidth And x right borderWidth And _y top - borderWidth And y bottom borderWidth) And _Not inFillElseinBorder FalseEnd If
End Sub 使用示例
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)Dim pixelX As Long, pixelY As LongDim inBorder As Boolean, inFill As BooleanpixelX X / Screen.TwipsPerPixelXpixelY Y / Screen.TwipsPerPixelY 检测鼠标是否在矩形(100,100,300,200)的填充区域或边框(宽度10)内MouseInBorderOrFill pixelX, pixelY, 100, 100, 300, 200, 10, inBorder, inFillIf inFill ThenMe.Caption 鼠标在填充区域内ElseIf inBorder ThenMe.Caption 鼠标在边框区域内ElseMe.Caption 鼠标在区域外End If
End Sub方法三使用 GDI 进行精确检测
GDI 提供了更精确的区域检测功能可以直接包含边框 GDI API声明
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 Declare Function GdipCreatePen1 Lib gdiplus (ByVal color As Long, ByVal width As Single, ByVal unit As Long, ByRef pen As Long) As Long
Private Declare Function GdipCreatePath Lib gdiplus (ByVal fillMode As Long, ByRef path As Long) As Long
Private Declare Function GdipAddPathRectangle Lib gdiplus (ByVal path As Long, ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single) As Long
Private Declare Function GdipIsVisiblePathPoint Lib gdiplus (ByVal x As Single, ByVal y As Single, ByVal path As Long, ByVal pen As Long, ByVal graphics As Long) As Long
Private Declare Function GdipDisposePath Lib gdiplus (ByVal path As Long) As Long
Private Declare Function GdipDisposePen Lib gdiplus (ByVal pen As Long) As LongPrivate Const UnitPixel As Long 2Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)Dim pixelX As Single, pixelY As SingleDim hGraphics As LongDim hPath As LongDim hPen As LongDim isVisible As LongpixelX X / Screen.TwipsPerPixelXpixelY Y / Screen.TwipsPerPixelY 创建GDI图形对象GdipCreateFromHDC Me.hdc, hGraphics 创建路径和笔GdipCreatePath 0, hPath 0 FillModeAlternateGdipCreatePen1 HFF0000, 10, UnitPixel, hPen 10像素宽的笔 添加矩形到路径GdipAddPathRectangle hPath, 100, 100, 200, 100 检测点是否在路径(包括边框)上isVisible GdipIsVisiblePathPoint(pixelX, pixelY, hPath, hPen, hGraphics)If isVisible 0 ThenMe.Caption 鼠标在矩形(包括边框)内ElseMe.Caption 鼠标在矩形外End If 释放资源GdipDisposePath hPathGdipDisposePen hPenGdipDeleteGraphics hGraphics
End Sub性能考虑
扩展区域方法性能较高但需要额外管理区域对象分别检测方法简单直接适合小型应用GDI 方法最精确但性能开销较大适合对精度要求高的场景
根据您的具体需求选择合适的方法可以有效解决边框检测问题。