What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleUse a small map window to let the user view a larger picture
Keywordsmap, map window, drag, key, scrollbars, thumbnail
This is a remarkably responsive and easy-to-use interface for displaying large pictures.

The program displays a large picture in a PictureBox named picImage. That control is inside another PictureBox named picViewport. The program moves picImage within picViewport to display different parts of the image. Normally you might use scrollbars to let the user move around the image.

This example draws a smaller "map" version of the image in the PictureBox picMap. The Form_Load event handler arranges the controls and uses PaintPicture to draw a small version of the big picture into the map.

It sets the map control's ScaleMode so it matches the dimensions of the larger picture. That means the point (X, Y) on the map image corresponds to the same point (X, Y) on the larger image.

When all is ready, the routine calls DrawBox to draw a "thumbnail" on the map image showing what part of the big image is visible.

Private Sub Form_Load()
    ' Size things.
    picMap.Width = picImage.ScaleWidth / 4 + picMap.Width - _
    picMap.Height = picImage.ScaleHeight / 4 + _
        picMap.Height - picMap.ScaleHeight
    picViewport.Width = picImage.ScaleWidth / 2 + _
        picMap.Width - picMap.ScaleWidth
    picViewport.Height = picImage.ScaleHeight / 2 + _
        picMap.Height - picMap.ScaleHeight

    picViewport.Move 120, 120
    picMap.Move picViewport.Left + picViewport.Width + 120, _
    Width = picMap.Left + picMap.Width + 120 + Width - _
    Height = picViewport.Top + picViewport.Height + 120 + _
        Height - ScaleHeight

    picMap.AutoRedraw = True
    picMap.PaintPicture picImage.Picture, _
        0, 0, picMap.ScaleWidth, picMap.ScaleHeight, _
        0, 0, picImage.ScaleWidth, picImage.ScaleHeight
    picMap.DrawMode = vbInvert

    ' Set the thumbnail's coordinates to match the
    ' picture's dimensions.
    picMap.ScaleWidth = picImage.ScaleWidth
    picMap.ScaleHeight = picImage.ScaleHeight

    ' Remember how wide the box's edges are.
    m_MapEdge = picMap.ScaleX(picMap.DrawWidth, vbPixels, _

End Sub
Subroutine DrawBox dras a box on the map image showing what part of the main image is visible. The area visible is determined by the size of the viewport PictureBox and the position of picImage inside picViewport.
' Draw a box showing what part of the picture is visible.
Private Sub DrawBox()
    picMap.Line (-picImage.Left, _
        -picImage.Top)-Step(picViewport.ScaleWidth - _
        m_MapEdge, picViewport.ScaleHeight - m_MapEdge), , B
End Sub
The last thing you need to understand is how the program lets the user move the map's thumbnail. When the user presses the mouse down on the map image, its MouseDown event handler executes. It first checks the the user is clicking inside the thumbnail. Then it sets m_DraggingBox = True to indicate that a drag is in progress. It also records the mouse's current position.

The map's MouseMove event handler determines how far the mouse has moved and adds that distance to the main image's position. If the result would move the image out of the viewable area, the program moves it back. Next the program calls DrawBox to erase the current thumbnail (all this drawing is in Invert mode so redrawing the box erases it), updates the main image's position, and then draws the new thumbnail.

The MouseUp event handler simply sets m_DraggingBox = False to indicate that the drag is finished.

' Start dragging the viewing area.
Private Sub picMap_MouseDown(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    ' Make sure the mouse is in the box.
    If X < -picImage.Left Or Y < -picImage.Top Or _
        X > -picImage.Left + picViewport.ScaleWidth - _
            m_MapEdge Or _
        Y > -picImage.Top + picViewport.ScaleHeight - _
            picMap.DrawWidth - m_MapEdge _
            Then Exit Sub

    m_DraggingBox = True

    m_StartX = X
    m_StartY = Y
End Sub

' Continue dragging the viewing area.
Private Sub picMap_MouseMove(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
Dim new_x As Single
Dim new_y As Single

    If Not m_DraggingBox Then Exit Sub

    new_x = picImage.Left + m_StartX - X
    If new_x > 0 Then
        new_x = 0
    ElseIf new_x < -(picImage.Width - _
        picViewport.ScaleWidth) Then
        new_x = -(picImage.Width - picViewport.ScaleWidth)
    End If

    new_y = picImage.Top + m_StartY - Y
    If new_y > 0 Then
        new_y = 0
    ElseIf new_y < -(picImage.Height - _
        picViewport.ScaleHeight) Then
        new_y = -(picImage.Height - picViewport.ScaleHeight)
    End If

    picImage.Left = new_x
    picImage.Top = new_y

    m_StartX = X
    m_StartY = Y
End Sub

' Stop dragging the viewing area.
Private Sub picMap_MouseUp(Button As Integer, Shift As _
    Integer, X As Single, Y As Single)
    m_DraggingBox = False
End Sub
Instead of drawing the thumbnail in Invert mode, you could draw it with red lines or using some other color that contrasts well with the map image. You would then erase the box using a stored image of the original map.
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.