home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch12 / Panview2.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-06-16  |  13.1 KB  |  429 lines

  1. VERSION 5.00
  2. Begin VB.Form frmPanview2 
  3.    Caption         =   "Panview2"
  4.    ClientHeight    =   3165
  5.    ClientLeft      =   2550
  6.    ClientTop       =   1800
  7.    ClientWidth     =   3165
  8.    LinkTopic       =   "Form1"
  9.    PaletteMode     =   1  'UseZOrder
  10.    ScaleHeight     =   3165
  11.    ScaleWidth      =   3165
  12.    Begin VB.HScrollBar HScrollBar 
  13.       Height          =   255
  14.       Left            =   0
  15.       TabIndex        =   2
  16.       Top             =   2880
  17.       Width           =   2895
  18.    End
  19.    Begin VB.VScrollBar VScrollBar 
  20.       Height          =   2895
  21.       Left            =   2880
  22.       TabIndex        =   1
  23.       Top             =   0
  24.       Width           =   255
  25.    End
  26.    Begin VB.PictureBox picViewport 
  27.       Height          =   2880
  28.       Left            =   0
  29.       ScaleHeight     =   2820
  30.       ScaleWidth      =   2820
  31.       TabIndex        =   0
  32.       Top             =   0
  33.       Width           =   2880
  34.    End
  35.    Begin VB.Menu mnuFile 
  36.       Caption         =   "&File"
  37.       Begin VB.Menu mnuFileExit 
  38.          Caption         =   "E&xit"
  39.       End
  40.    End
  41.    Begin VB.Menu mnuScale 
  42.       Caption         =   "&Scale"
  43.       Begin VB.Menu mnuScaleZoom 
  44.          Caption         =   "&Zoom"
  45.          Shortcut        =   ^Z
  46.       End
  47.       Begin VB.Menu mnuScaleMag 
  48.          Caption         =   "Full  Scale"
  49.          Index           =   1
  50.          Shortcut        =   ^F
  51.       End
  52.       Begin VB.Menu mnuScaleMag 
  53.          Caption         =   "Magnify 1/2"
  54.          Index           =   20
  55.          Shortcut        =   ^{F2}
  56.       End
  57.       Begin VB.Menu mnuScaleMag 
  58.          Caption         =   "Magnify 1/4"
  59.          Index           =   40
  60.          Shortcut        =   ^{F4}
  61.       End
  62.    End
  63. Attribute VB_Name = "frmPanview2"
  64. Attribute VB_GlobalNameSpace = False
  65. Attribute VB_Creatable = False
  66. Attribute VB_PredeclaredId = True
  67. Attribute VB_Exposed = False
  68. Option Explicit
  69. ' Global max and min world coordinates
  70. ' (including margins).
  71. Private Const DataXmin = 0
  72. Private Const DataXmax = 10
  73. Private Const DataYmin = 0
  74. Private Const DataYmax = 10
  75. ' Set the min and max allowed width and height.
  76. Private Const DataMinWid = 1
  77. Private Const DataMinHgt = 1
  78. Private Const DataMaxWid = DataXmax - DataXmin
  79. Private Const DataMaxHgt = DataYmax - DataYmin
  80. ' The aspect ratio of the viewport.
  81. Private VAspect As Single
  82. ' Current world window bounds.
  83. Private Wxmin As Single
  84. Private Wxmax As Single
  85. Private Wymin As Single
  86. Private Wymax As Single
  87. ' Prevent change events when we are adjusting the
  88. ' scroll bars.
  89. Private IgnoreSbarChange As Boolean
  90. ' Variables used for zooming.
  91. Private Enum DrawingModes
  92.     mode_None
  93.     mode_StartZoom
  94.     mode_Zooming
  95. End Enum
  96. Private DrawingMode As DrawingModes
  97. Private StartX As Single
  98. Private StartY As Single
  99. Private LastX As Single
  100. Private LastY As Single
  101. Private OldMode As Integer
  102. ' Draw a smiley face in the viewport centered
  103. ' around the point (5, 5).
  104. Private Sub DrawSmiley(ByVal pic As PictureBox)
  105. Const PI = 3.14159265
  106. Dim i As Single
  107.     ' Head.
  108.     pic.FillColor = vbYellow
  109.     pic.FillStyle = vbSolid
  110.     pic.Circle (5, 5), 4
  111.     ' Nose.
  112.     pic.FillColor = RGB(0, &HFF, &H80)
  113.     pic.Circle (5, 4.5), 1, , , , 1.5
  114.     ' Eye whites.
  115.     pic.FillColor = vbWhite
  116.     pic.Circle (3.5, 6), 0.75, , , , 1.25
  117.     pic.Circle (6.5, 6), 0.75, , , , 1.25
  118.     ' Pupils.
  119.     pic.FillColor = vbBlack
  120.     pic.Circle (3.7, 6), 0.5, , , , 1.25
  121.     pic.Circle (6.7, 6), 0.5, , , , 1.25
  122.     ' Smile.
  123.     pic.Circle (5, 5), 2.75, , 1.15 * PI, 1.8 * PI
  124.     ' Draw some grid lines to make small scales
  125.     ' easier to understand.
  126.     i = DataXmin + 0.5
  127.     Do While i < DataXmax
  128.         picViewport.Line (i, DataYmin)-(i, DataYmax)
  129.         i = i + 0.5
  130.     Loop
  131.     i = DataYmin + 0.5
  132.     Do While i < DataYmax
  133.         picViewport.Line (DataXmin, i)-(DataXmax, i)
  134.         i = i + 0.5
  135.     Loop
  136. End Sub
  137. ' End a zoom operation early. This happens if the
  138. ' user starts a zoom and the selects another menu
  139. ' item instead of doing the zoom.
  140. Private Sub StopZoom()
  141.     If DrawingMode <> mode_StartZoom Then Exit Sub
  142.     DrawingMode = mode_None
  143.     picViewport.DrawMode = OldMode
  144.     picViewport.MousePointer = vbDefault
  145. End Sub
  146. ' Change the level of magnification.
  147. Private Sub SetScaleFactor(fact As Single)
  148. Dim wid As Single
  149. Dim hgt As Single
  150. Dim mid As Single
  151.     fact = 1 / fact
  152.     ' Compute the new world window size.
  153.     wid = fact * (Wxmax - Wxmin)
  154.     hgt = fact * (Wymax - Wymin)
  155.     ' Center the new world window over the old.
  156.     mid = (Wxmax + Wxmin) / 2
  157.     Wxmin = mid - wid / 2
  158.     Wxmax = mid + wid / 2
  159.     mid = (Wymax + Wymin) / 2
  160.     Wymin = mid - hgt / 2
  161.     Wymax = mid + hgt / 2
  162.     ' Set the new world window bounds.
  163.     SetWorldWindow
  164. End Sub
  165. ' Adjust the world window so it is not too big,
  166. ' too small, off to one side, or of the wrong
  167. ' aspect ratio. Then map the world window to the
  168. ' viewport and force the viewport to repaint.
  169. Private Sub SetWorldWindow()
  170. Dim wid As Single
  171. Dim hgt As Single
  172. Dim xmid As Single
  173. Dim ymid As Single
  174. Dim aspect As Single
  175.     ' Find the size and center of the world window.
  176.     wid = Wxmax - Wxmin
  177.     hgt = Wymax - Wymin
  178.     xmid = (Wxmax + Wxmin) / 2
  179.     ymid = (Wymax + Wymin) / 2
  180.     ' Make sure we're not too big or too small.
  181.     If wid > DataMaxWid Then
  182.         wid = DataMaxWid
  183.     ElseIf wid < DataMinWid Then
  184.         wid = DataMinWid
  185.     End If
  186.     If hgt > DataMaxHgt Then
  187.         hgt = DataMaxHgt
  188.     ElseIf hgt < DataMinHgt Then
  189.         hgt = DataMinHgt
  190.     End If
  191.     ' Make the aspect ratio match the viewport
  192.     ' aspect ratio, VAspect (set in Form_Resize).
  193.     aspect = hgt / wid
  194.     If aspect > VAspect Then
  195.         ' Too tall and thin. Make it wider.
  196.         wid = hgt / VAspect
  197.     Else
  198.         ' Too short and wide. Make it taller.
  199.         hgt = wid * VAspect
  200.     End If
  201.     ' Compute the new coordinates
  202.     Wxmin = xmid - wid / 2
  203.     Wxmax = xmid + wid / 2
  204.     Wymin = ymid - hgt / 2
  205.     Wymax = ymid + hgt / 2
  206.     ' See if we're off to one side.
  207.     If wid > DataMaxWid Then
  208.         ' We're wider than the picture. Center.
  209.         xmid = (DataXmax + DataXmin) / 2
  210.         Wxmin = xmid - wid / 2
  211.         Wxmax = xmid + wid / 2
  212.     Else
  213.         ' Else see if we're too far to one side.
  214.         If Wxmin < DataXmin And Wxmax < DataXmax Then
  215.             ' Adjust to the right.
  216.             Wxmax = Wxmax + DataXmin - Wxmin
  217.             Wxmin = DataXmin
  218.         End If
  219.         If Wxmax > DataXmax And Wxmin > DataXmin Then
  220.             ' Adjust to the left.
  221.             Wxmin = Wxmin + DataXmax - Wxmax
  222.             Wxmax = DataXmax
  223.         End If
  224.     End If
  225.     If hgt > DataMaxHgt Then
  226.         ' We're taller than the picture. Shrink.
  227.         ymid = (DataYmax + DataYmin) / 2
  228.         Wymin = ymid - hgt / 2
  229.         Wymax = ymid + hgt / 2
  230.     Else
  231.         ' See if we're too far to top or bottom.
  232.         If Wymin < DataYmin And Wymax < DataYmax Then
  233.             ' Adjust downward.
  234.             Wymax = Wymax + DataYmin - Wymin
  235.             Wymin = DataYmin
  236.         End If
  237.         If Wymax > DataYmax And Wymin > DataYmin Then
  238.             ' Adjust upward.
  239.             Wymin = Wymin + DataYmax - Wymax
  240.             Wymax = DataYmax
  241.         End If
  242.     End If
  243.     ' Map the world window to the viewport.
  244.     picViewport.ScaleLeft = Wxmin
  245.     picViewport.ScaleTop = Wymax
  246.     picViewport.ScaleWidth = Wxmax - Wxmin
  247.     picViewport.ScaleHeight = Wymin - Wymax
  248.     ' Force the viewport to repaint.
  249.     picViewport.Refresh
  250.     ' Reset the scroll bars.
  251.     IgnoreSbarChange = True
  252.     HScrollBar.Visible = (wid < DataXmax - DataXmin)
  253.     VScrollBar.Visible = (hgt < DataYmax - DataYmin)
  254.     ' The values of the scroll bars will be where
  255.     ' the top/left of the world window should be.
  256.     VScrollBar.Min = 100 * (DataYmax)
  257.     VScrollBar.Max = 100 * (DataYmin + hgt)
  258.     HScrollBar.Min = 100 * (DataXmin)
  259.     HScrollBar.Max = 100 * (DataXmax - wid)
  260.     ' SmallChange moves the world window 1/10
  261.     ' of its width/height.
  262.     VScrollBar.SmallChange = 100 * (hgt / 10)
  263.     VScrollBar.LargeChange = 100 * hgt
  264.     HScrollBar.SmallChange = 100 * (wid / 10)
  265.     HScrollBar.LargeChange = 100 * wid
  266.     ' Set the current scroll bar values.
  267.     VScrollBar.Value = 100 * Wymax
  268.     HScrollBar.Value = 100 * Wxmin
  269.     IgnoreSbarChange = False
  270. End Sub
  271. ' Return to the default magnification scale.
  272. Private Sub SetScaleFull()
  273.     ' Reset the world window coordinates.
  274.     Wxmin = DataXmin
  275.     Wxmax = DataXmax
  276.     Wymin = DataYmin
  277.     Wymax = DataYmax
  278.     ' Set the new world window bounds.
  279.     SetWorldWindow
  280. End Sub
  281. Private Sub Form_Load()
  282.     ' Start at full scale.
  283.     Wxmin = DataXmin
  284.     Wxmax = DataXmax
  285.     Wymin = DataYmin
  286.     Wymax = DataYmax
  287. End Sub
  288. Private Sub Form_Resize()
  289. Dim X As Single
  290. Dim Y As Single
  291. Dim wid As Single
  292. Dim hgt As Single
  293.     ' Fit the viewport to the window.
  294.     X = picViewport.Left
  295.     Y = picViewport.Top
  296.     wid = ScaleWidth - 2 * X - VScrollBar.Width
  297.     hgt = ScaleHeight - 2 * Y - HScrollBar.Height
  298.     picViewport.Move X, Y, wid, hgt
  299.     VAspect = hgt / wid
  300.     ' Place the scroll bars next to the viewport.
  301.     X = picViewport.Left + picViewport.Width + 10
  302.     Y = picViewport.Top
  303.     wid = VScrollBar.Width
  304.     hgt = picViewport.Height
  305.     VScrollBar.Move X, Y, wid, hgt
  306.     X = picViewport.Left
  307.     Y = picViewport.Top + picViewport.Height + 10
  308.     wid = picViewport.Width
  309.     hgt = HScrollBar.Height
  310.     HScrollBar.Move X, Y, wid, hgt
  311.     ' Set the new world window bounds.
  312.     SetWorldWindow
  313. End Sub
  314. ' Move the world window.
  315. Private Sub HScrollBar_Change()
  316.     If IgnoreSbarChange Then Exit Sub
  317.     HScrollBarChanged
  318. End Sub
  319. ' The vertical scroll bar has been moved.
  320. ' Adjust the world window.
  321. Private Sub VScrollBarChanged()
  322. Dim hgt As Single
  323.     hgt = Wymax - Wymin
  324.     Wymax = VScrollBar.Value / 100
  325.     Wymin = Wymax - hgt
  326.     ' Remap the world window.
  327.     IgnoreSbarChange = True
  328.     SetWorldWindow
  329.     IgnoreSbarChange = False
  330. End Sub
  331. ' The horizontal scroll bar has been moved.
  332. ' Adjust the world window.
  333. Private Sub HScrollBarChanged()
  334. Dim wid As Single
  335.     wid = Wxmax - Wxmin
  336.     Wxmin = HScrollBar.Value / 100
  337.     Wxmax = Wxmin + wid
  338.     ' Remap the world window.
  339.     IgnoreSbarChange = True
  340.     SetWorldWindow
  341.     IgnoreSbarChange = False
  342. End Sub
  343. Private Sub mnuFileExit_Click()
  344.     StopZoom    ' If we're zooming, stop it.
  345.     Unload Me
  346. End Sub
  347. ' Change the level of magnification.
  348. Private Sub mnuScaleMag_Click(Index As Integer)
  349.     StopZoom    ' If we're zooming, stop it.
  350.     If Index = 1 Then
  351.         ' Return to full scale.
  352.         SetScaleFull
  353.     ElseIf Index < 10 Then
  354.         ' Magnify by the indicated amount.
  355.         SetScaleFactor CSng(Index)
  356.     Else
  357.         ' Zoom out by 1/(Index \ 10).
  358.         SetScaleFactor 1 / (Index \ 10)
  359.     End If
  360. End Sub
  361. ' Allow the user to select an area to zoom in on.
  362. Private Sub mnuScaleZoom_Click()
  363.     ' Enable zooming.
  364.     picViewport.MousePointer = vbCrosshair
  365.     DrawingMode = mode_StartZoom
  366. End Sub
  367. ' If we are zooming, start the rubberband box.
  368. Private Sub picViewport_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  369.     If DrawingMode <> mode_StartZoom Then Exit Sub
  370.     DrawingMode = mode_Zooming
  371.     OldMode = picViewport.DrawMode
  372.     picViewport.DrawMode = vbInvert
  373.     StartX = X
  374.     StartY = Y
  375.     LastX = X
  376.     LastY = Y
  377.     picViewport.Line (StartX, StartY)-(LastX, LastY), , B
  378. End Sub
  379. ' If we are zooming, continue the rubberband box.
  380. Private Sub picViewport_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  381.     If DrawingMode <> mode_Zooming Then Exit Sub
  382.     ' Erase the old box.
  383.     picViewport.Line (StartX, StartY)-(LastX, LastY), , B
  384.     ' Draw the new box.
  385.     LastX = X
  386.     LastY = Y
  387.     picViewport.Line (StartX, StartY)-(LastX, LastY), , B
  388. End Sub
  389. ' If we are zooming, finish the rubberband box.
  390. Private Sub picViewport_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  391. Dim wid As Single
  392. Dim hgt As Single
  393. Dim mid As Single
  394.     If DrawingMode <> mode_Zooming Then Exit Sub
  395.     DrawingMode = mode_None
  396.     ' Erase the old box.
  397.     picViewport.Line (StartX, StartY)-(LastX, LastY), , B
  398.     LastX = X
  399.     LastY = Y
  400.     ' We're done drawing for this rubberband box.
  401.     picViewport.DrawMode = OldMode
  402.     picViewport.MousePointer = vbDefault
  403.     ' Set the new world window bounds.
  404.     If StartX > LastX Then
  405.         Wxmin = LastX
  406.         Wxmax = StartX
  407.     Else
  408.         Wxmin = StartX
  409.         Wxmax = LastX
  410.     End If
  411.     If StartY > LastY Then
  412.         Wymin = LastY
  413.         Wymax = StartY
  414.     Else
  415.         Wymin = StartY
  416.         Wymax = LastY
  417.     End If
  418.     ' Set the new world window bounds.
  419.     SetWorldWindow
  420. End Sub
  421. Private Sub picViewport_Paint()
  422.     DrawSmiley picViewport
  423. End Sub
  424. ' Move the world window.
  425. Private Sub VScrollBar_Change()
  426.     If IgnoreSbarChange Then Exit Sub
  427.     VScrollBarChanged
  428. End Sub
  429.