Vb6 反向注水:测试点是否位于区域内

Vb6 反向注水:测试点是否位于区域内,vb6,gdi,flood-fill,Vb6,Gdi,Flood Fill,我有一个带大图的图片盒: 在此图片框中,使用ExtFloodFill()API为各个区域着色 Private Declare Function ExtFloodFill Lib "GDI32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long 洪水填充开始的X和Y坐标位于必须填充的区域中的某个位置,但不在精确的中心,或者所有

我有一个带大图的图片盒:

在此图片框中,使用
ExtFloodFill()
API为各个区域着色

Private Declare Function ExtFloodFill Lib "GDI32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long
洪水填充开始的X和Y坐标位于必须填充的区域中的某个位置,但不在精确的中心,或者所有区域的偏移量相同,并且两个区域的形状或大小也不相同。(这就是为什么我们喜欢填海)

现在,我希望用户通过单击图片并使用与他们单击的区域对应的特定操作的坐标来与图片进行交互

为此,我使用
\u MouseDown()
事件:

Private Sub picfat_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
  Dim lngIndex As Long
  lngIndex = CheckClick(mobjDet, x, y)
  If lngIndex > -1 Then
    With mobjDet(lngIndex)
      .lngStat = 2 - .lngStat
      SendCmd "det swico " & CStr(lngIndex) & "=" & CStr(.lngStat), wskDet
    End With 'mobjDet(lngIndex)
  End If
End Sub
调用
CheckClick()
以确定单击的区域:

Private Function CheckClick(obj() As FC_DET, sngX As Single, sngY As Single) As Long
  Dim lngObj As Long
  Dim lngIndex As Long
  Dim sngWidth As Single, sngHeight As Single
  sngWidth = 15
  sngHeight = 15
  lngIndex = -1
  For lngObj = 0 To UBound(obj)
    With obj(lngObj)
      If sngWidth > 0 Then
        If sngX > .sngX Then
          If sngX < .sngX + sngWidth Then
            If sngY > .sngY Then
              If sngY < .sngY + sngHeight Then
                lngIndex = .lngIndex
                Exit For
              End If
            End If
          End If
        End If
      End If
    End With 'obj(lngObj)
  Next lngObj
  CheckClick = lngIndex
End Function
Private Function CheckClick(obj()作为FC_DET,sngX作为Single,sngY作为Single)尽可能长
昏暗的长廊
暗指数和长指数一样
暗SNG宽为单色,浅SNG宽为单色
sngWidth=15
sngHeight=15
lngIndex=-1
对于lngObj=0至UBound(obj)
带obj(lngObj)
如果sngWidth>0,则
如果sngX>.sngX,则
如果sngX<.sngX+sngWidth,则
如果sngY>那么.sngY
如果sngY<.sngY+sngHeight,则
lngIndex=.lngIndex
退出
如果结束
如果结束
如果结束
如果结束
如果结束
以'obj(lngObj)结束
下一个印度政府
CheckClick=lngIndex
端函数
此时,我在原始X和Y坐标的右下角使用了一个15x15像素的正方形,如果用户单击这些坐标,它将正常工作

如果洪水填充的X和Y坐标位于小正方形的左上角,则15x15正方形适用于图中的小正方形,但情况并非如此,正如您所看到的,还有其他形状以及小正方形

我想做的是:

  • 使用
    \u MouseDown()
    事件中的X和Y坐标
  • 从洪水填充开始,循环浏览我的X和Y坐标列表
  • 确定哪个泛光填充起点对应于MouseDown事件的X和Y坐标
[编辑]

例如:

  • 在我的图片中,黄色泛光填充的中心是500160(在白色正方形和矩形之间的黄色区域)。其坐标为
    mobjDet(6).sngX
    mobjDet(6).sngY
  • 用户单击白色矩形上方黄色区域的某个位置,例如495,53处
  • 如何将_MouseDown()事件的X和Y与泛洪填充udt的索引(6)耦合

这样我就可以找出用户在图片中单击的区域。

过去我做过类似的事情,最适合我的方法是创建一个UDT数组。每个UDT都保存了调用我的绘图API所需的所有信息(例如,
color
x1
x2
y1
y2
)。当我必须渲染屏幕时,我只是在我的数组中循环,然后画出我所有的项目。当用户单击我的hdc时,我会再次循环以找到使用相同坐标的匹配UDT,该坐标还包含附加信息,如
id
,等等

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type DrawItem
    Id As Long
    Name As String
    ' etc...

    tRect As RECT
End Type

Private DrawItems() As DrawItem
另外,由于FloodFill实际上不可能跟踪填充的内容,我建议您使用更多的ridgid API(如FillRect)手动绘制图形这意味着您将拥有UDT中所绘制内容的完整边界(上、下、左、右),以便您可以查看鼠标单击是否在该矩形内。

下面是绘制矩形的API。您还需要使用CreateSolidBrush函数创建一个“笔刷”

Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
此外,我喜欢将我正在绘制的任何东西(例如,PictureBox)的
ScaleMode
1-Twip
(无用)更改为
3-Pixel
,因此我不必经常乘以或除以15

希望这有帮助


作为最后一点,如果你真的被洪水淹没了,我能推荐的最好方法就是使用

Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long

…它可以返回鼠标单击的x和y坐标处的像素颜色。然后,您可以测试颜色以(希望)匹配您需要的颜色。

过去我做过类似的事情,最适合我的方法是创建一个UDT数组。每个UDT都保存了调用我的绘图API所需的所有信息(例如,
color
x1
x2
y1
y2
)。当我必须渲染屏幕时,我只是在我的数组中循环,然后画出我所有的项目。当用户单击我的hdc时,我会再次循环以找到使用相同坐标的匹配UDT,该坐标还包含附加信息,如
id
,等等

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type DrawItem
    Id As Long
    Name As String
    ' etc...

    tRect As RECT
End Type

Private DrawItems() As DrawItem
另外,由于FloodFill实际上不可能跟踪填充的内容,我建议您使用更多的ridgid API(如FillRect)手动绘制图形这意味着您将拥有UDT中所绘制内容的完整边界(上、下、左、右),以便您可以查看鼠标单击是否在该矩形内。

下面是绘制矩形的API。您还需要使用CreateSolidBrush函数创建一个“笔刷”

Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
此外,我喜欢将我正在绘制的任何东西(例如,PictureBox)的
ScaleMode
1-Twip
(无用)更改为
3-Pixel
,因此我不必经常乘以或除以15

希望这有帮助


作为最后一点,如果你真的被洪水淹没了,我能推荐的最好方法就是使用

Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long

…它可以返回鼠标单击的x和y坐标处的像素颜色。然后,您可以测试颜色以(希望)匹配您需要的颜色。

使用GDI,您可以使用。这些要求您定义区域
'API
Private Const SRCCOPY = &HCC0020

Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long