|
|
Title | Use a small map window to let the user view a larger picture |
Keywords | map, map window, drag, key, scrollbars, thumbnail |
Categories | Controls |
|
|
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.ScaleWidth
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, _
120
Width = picMap.Left + picMap.Width + 120 + Width - _
ScaleWidth
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, _
picMap.ScaleMode)
DrawBox
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
DrawBox
picImage.Left = new_x
picImage.Top = new_y
DrawBox
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.
|
|
|
|
|
|