如何在图片框中识别地图上的鼠标位置?

时间:2012-03-07 11:31:54

标签: vb.net

我在省级分区的图片框中有一张国家地图。我可以通过在我的pictureBox MouseMove事件上调用以下floodfill函数来填充每个省的鼠标:

Private Structure BITMAPINFOHEADER
    Dim biSize As Integer
    Dim biWidth As Integer
    Dim biHeight As Integer
    Dim biPlanes As Short
    Dim biBitCount As Short
    Dim biCompression As Integer
    Dim biSizeImage As Integer
    Dim biXPelsPerMeter As Integer
    Dim biYPelsPerMeter As Integer
    Dim biClrUsed As Integer
    Dim biClrImportant As Integer
End Structure

''' <summary>
''' API declarations
''' </summary>
''' <param name="hdc"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As IntPtr) As IntPtr
Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As IntPtr, ByRef pBitmapInfo As BITMAPINFOHEADER, ByVal un As Integer, ByRef lplpVoid As IntPtr, ByVal handle As Integer, ByVal dw As Integer) As IntPtr
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal crColor As Integer, ByVal wFillType As Integer) As Integer
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Integer) As IntPtr
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer) As Integer
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As IntPtr) As Integer
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As IntPtr) As Integer
Private Declare Function GdiFlush Lib "gdi32" Alias "GdiFlush" () As Integer
Private Const SRCCOPY = &HCC0020

Public Sub FloodFill(ByRef mbmp As Bitmap, ByVal col As Color, ByVal Pt As Point)
    If mbmp Is Nothing Then Exit Sub
    Dim srcDC As IntPtr = CreateCompatibleDC(IntPtr.Zero)
    Dim dstDC As IntPtr = CreateCompatibleDC(IntPtr.Zero)
    Dim dstBMI As BITMAPINFOHEADER
    With dstBMI
        .biBitCount = 24
        .biHeight = mbmp.Height
        .biSize = System.Runtime.InteropServices.Marshal.SizeOf(dstBMI)
        .biWidth = mbmp.Width
        .biPlanes = 1
    End With
    Dim dstBits As IntPtr
    Dim mbmpGetHbitmap As IntPtr = mbmp.GetHbitmap
    'Select the bitmap into an HDC
    Dim Obmp As IntPtr = SelectObject(srcDC, mbmpGetHbitmap)
    'Create a DIB
    Dim dstBMP As IntPtr = CreateDIBSection(dstDC, dstBMI, 0, dstBits, 0, 0)
    Dim Obmp2 As IntPtr = SelectObject(dstDC, dstBMP)
    'Place our bitmap in the DIB
    BitBlt(dstDC, 0, 0, mbmp.Width, mbmp.Height, srcDC, 0, 0, SRCCOPY)
    GdiFlush()

    'Create a brush to use to FloodFill
    Dim mBrush As IntPtr = CreateSolidBrush(System.Drawing.ColorTranslator.ToOle(col))
    Dim hmm As IntPtr = SelectObject(dstDC, mBrush)
    'Label5.Text = mBrush

    'Fill with color
    ExtFloodFill(dstDC, Pt.X, Pt.Y, GetPixel(dstDC, Pt.X, Pt.Y), 1)
    'Get the bitmap back with the Filled Color
    mbmp = Bitmap.FromHbitmap(dstBMP)

    'Go berserk clearing memory
    'ExtFloodFill has a bad reputation for gobbling up memory
    'if you dont clean up properly
    DeleteObject(mBrush)
    DeleteObject(SelectObject(dstDC, mBrush))
    DeleteObject(SelectObject(dstDC, dstBMP))
    DeleteObject(SelectObject(srcDC, mbmpGetHbitmap))
    DeleteObject(hmm)
    DeleteObject(dstBits)
    DeleteObject(Obmp2)
    DeleteObject(Obmp)
    DeleteObject(dstBMP)
    DeleteDC(dstDC)
    DeleteDC(srcDC)
    mbmpGetHbitmap = Nothing
    hmm = Nothing
    dstBits = Nothing
    Obmp2 = Nothing
    Obmp = Nothing
    dstBMP = Nothing
    dstDC = Nothing
    srcDC = Nothing
    dstBMI = Nothing

End Sub

我唯一需要的就是在鼠标悬停时识别洪水填埋的省份。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

如果您知道地图坐标,则可以检查已定义的矩形列表。

即。一个名称为字符串和矩形的类

所以华盛顿可能是(0,0,100,100) 纽约可能是(100,40,100,100)

然后只需查看对象列表并查看边界 将区域的“名称”返回给用户

如果那是你想要达到的目的。

P.S。我不确定你为什么要使用很多“经典”的blitting / GDI代码,其中.NET框架system.drawing命名空间对你来说可能更好....

dim b as New Bitmap(Width, Height, Imaging.PixelFormat.Format32bppPArgb)
dim g as graphics = graphics.fromimage(b)
g.Clear(Color.White)
g.DrawImage(Bitmap.FromFile("test.jpg"), New Rectangle(0, 0, 100, 100))
PictureBox1.image = b