home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH4 / SRC / CONTRAST.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-01-03  |  21.8 KB  |  683 lines

  1. VERSION 4.00
  2. Begin VB.Form ContrastForm 
  3.    Caption         =   "Contrast"
  4.    ClientHeight    =   4110
  5.    ClientLeft      =   960
  6.    ClientTop       =   1470
  7.    ClientWidth     =   8010
  8.    Height          =   4800
  9.    Left            =   900
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   274
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   534
  14.    Top             =   840
  15.    Width           =   8130
  16.    Begin VB.HScrollBar RangeSBar 
  17.       Enabled         =   0   'False
  18.       Height          =   255
  19.       LargeChange     =   16
  20.       Left            =   4080
  21.       Max             =   256
  22.       Min             =   1
  23.       TabIndex        =   5
  24.       Top             =   3120
  25.       Value           =   1
  26.       Width           =   3930
  27.    End
  28.    Begin VB.PictureBox HistPict 
  29.       AutoRedraw      =   -1  'True
  30.       Height          =   2775
  31.       Left            =   4080
  32.       ScaleHeight     =   181
  33.       ScaleMode       =   3  'Pixel
  34.       ScaleWidth      =   258
  35.       TabIndex        =   4
  36.       Top             =   0
  37.       Width           =   3930
  38.    End
  39.    Begin VB.PictureBox FromSwin 
  40.       Height          =   3855
  41.       Left            =   0
  42.       ScaleHeight     =   253
  43.       ScaleMode       =   3  'Pixel
  44.       ScaleWidth      =   245
  45.       TabIndex        =   2
  46.       Top             =   0
  47.       Width           =   3735
  48.       Begin VB.PictureBox FromPict 
  49.          AutoRedraw      =   -1  'True
  50.          AutoSize        =   -1  'True
  51.          Height          =   1905
  52.          Left            =   0
  53.          ScaleHeight     =   123
  54.          ScaleMode       =   3  'Pixel
  55.          ScaleWidth      =   88
  56.          TabIndex        =   3
  57.          Top             =   0
  58.          Width           =   1380
  59.       End
  60.    End
  61.    Begin VB.HScrollBar FromHBar 
  62.       Enabled         =   0   'False
  63.       Height          =   255
  64.       Left            =   0
  65.       TabIndex        =   1
  66.       Top             =   3840
  67.       Width           =   3765
  68.    End
  69.    Begin VB.VScrollBar FromVBar 
  70.       Enabled         =   0   'False
  71.       Height          =   3855
  72.       Left            =   3720
  73.       TabIndex        =   0
  74.       Top             =   0
  75.       Width           =   255
  76.    End
  77.    Begin VB.Label RangeLabel 
  78.       Height          =   255
  79.       Left            =   4080
  80.       TabIndex        =   6
  81.       Top             =   2805
  82.       Width           =   3975
  83.    End
  84.    Begin MSComDlg.CommonDialog FileDialog 
  85.       Left            =   3840
  86.       Top             =   0
  87.       _Version        =   65536
  88.       _ExtentX        =   847
  89.       _ExtentY        =   847
  90.       _StockProps     =   0
  91.       CancelError     =   -1  'True
  92.    End
  93.    Begin VB.Menu mnuFile 
  94.       Caption         =   "&File"
  95.       Begin VB.Menu mnuFileLoad 
  96.          Caption         =   "&Load..."
  97.          Shortcut        =   ^L
  98.       End
  99.       Begin VB.Menu mnuFileSep2 
  100.          Caption         =   "-"
  101.       End
  102.       Begin VB.Menu mnuFileExit 
  103.          Caption         =   "E&xit"
  104.       End
  105.    End
  106. Attribute VB_Name = "ContrastForm"
  107. Attribute VB_Creatable = False
  108. Attribute VB_Exposed = False
  109. Option Explicit
  110. Dim SysPalSize As Integer
  111. Dim NumStaticColors As Integer
  112. Dim StaticColor1 As Integer
  113. Dim StaticColor2 As Integer
  114. Dim LogPal As Integer
  115. Dim bytes() As Byte
  116. Dim wid As Long
  117. Dim hgt As Long
  118. Dim origpal(0 To 255) As PALETTEENTRY
  119. Dim newpal(0 To 255) As PALETTEENTRY
  120. Dim IndexCounts(0 To 255) As Long
  121. Dim ValueCounts(0 To 255) As Long
  122. Dim SettingRange As Boolean
  123. Dim DarkestIndex As Integer
  124. Dim BrightestIndex As Integer
  125. Dim DarkestValue As Integer
  126. Dim BrightestValue As Integer
  127. ' ************************************************
  128. ' Adjust the colors in the image so they span the
  129. ' indicated range of color values.
  130. ' This routine assumes the ValueCounts and origpal
  131. ' arrays are filled in. It updates the logical
  132. ' palette but does not update these arrays.
  133. ' ************************************************
  134. Sub AdjustContrast(pic As Control, Range As Integer)
  135. Dim factor As Single
  136. Dim offset As Integer
  137. Dim i As Integer
  138. Dim status As Long
  139. Dim val As Integer
  140.     factor = Range / (BrightestValue - DarkestValue)
  141.     offset = (256 - Range) / 2 - factor * DarkestValue
  142.     ' Remap the values in the logical palette.
  143.     For i = StaticColor1 + 1 To StaticColor2 - 1
  144.         val = origpal(i).peRed * factor + offset
  145.         If val < 0 Then
  146.             val = 0
  147.         ElseIf val > 255 Then
  148.             val = 255
  149.         End If
  150.         
  151.         With newpal(i)
  152.             .peRed = val
  153.             .peGreen = val
  154.             .peBlue = val
  155.             .peFlags = PC_NOCOLLAPSE
  156.         End With
  157.     Next i
  158.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, newpal(StaticColor1 + 1))
  159.     i = RealizePalette(pic.hdc)
  160. End Sub
  161. ' ************************************************
  162. ' Return the index of the nonstatic gray closest
  163. ' to the given value (assuming the non-static
  164. ' colors are a gray scale created by
  165. ' MatchGrayPalette).
  166. ' ************************************************
  167. Function NearestNonstaticGray(c As Integer) As Integer
  168. Dim dgray As Single
  169.     If c < 0 Then
  170.         c = 0
  171.     ElseIf c > 255 Then
  172.         c = 255
  173.     End If
  174.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  175.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  176. End Function
  177. ' ************************************************
  178. ' Count the number of pixels with each palette
  179. ' index.
  180. ' ************************************************
  181. Sub CountIndexes()
  182. Dim X As Integer
  183. Dim Y As Integer
  184. Dim idx As Integer
  185.     ' Start from scratch.
  186.     For X = 0 To SysPalSize - 1
  187.         IndexCounts(X) = 0
  188.     Next X
  189.     ' Count the indexes.
  190.     For Y = 1 To hgt
  191.         For X = 1 To wid
  192.             idx = bytes(X, Y)
  193.             IndexCounts(idx) = IndexCounts(idx) + 1
  194.         Next X
  195.     Next Y
  196.     ' Find the brightest and darkest indexes and
  197.     ' their values.
  198.     For DarkestIndex = 0 To SysPalSize - 1
  199.         If IndexCounts(DarkestIndex) > 0 Then Exit For
  200.     Next DarkestIndex
  201.     With origpal(DarkestIndex)
  202.         DarkestValue = (CInt(.peRed) + .peGreen + .peBlue) / 3
  203.     End With
  204.     For BrightestIndex = SysPalSize - 1 To 0 Step -1
  205.         If IndexCounts(BrightestIndex) > 0 Then Exit For
  206.     Next BrightestIndex
  207.     With origpal(BrightestIndex)
  208.         BrightestValue = (CInt(.peRed) + .peGreen + .peBlue) / 3
  209.     End With
  210. End Sub
  211. ' ************************************************
  212. ' Count the brightness values.
  213. ' ************************************************
  214. Sub CountValues()
  215. Dim i As Integer
  216. Dim val As Integer
  217. Dim brightval As Integer
  218. Dim darkval As Integer
  219.     ' Start from scratch.
  220.     For i = 0 To SysPalSize - 1
  221.         ValueCounts(i) = 0
  222.     Next i
  223.     ' Add up the values.
  224.     '
  225.     ' For each palette index i, with brightness
  226.     ' val, there are IndexCounts(i) pixels with
  227.     ' that brightness.
  228.     For i = 0 To SysPalSize - 1
  229.         With newpal(i)
  230.             val = (CInt(.peRed) + .peGreen + .peBlue) / 3
  231.         End With
  232.         ValueCounts(val) = ValueCounts(val) + IndexCounts(i)
  233.     Next i
  234.     ' Find the brightest and darkest values.
  235.     With newpal(DarkestIndex)
  236.         darkval = (CInt(.peRed) + .peGreen + .peBlue) / 3
  237.     End With
  238.     With newpal(BrightestIndex)
  239.         brightval = (CInt(.peRed) + .peGreen + .peBlue) / 3
  240.     End With
  241.     RangeLabel.Caption = "Range:" & _
  242.         Str$(brightval - darkval + 1) & " (" & _
  243.         Str$(darkval) & " -" & Str$(brightval) & ")"
  244.     SettingRange = True
  245.     RangeSBar.Value = brightval - darkval + 1
  246.     SettingRange = False
  247. End Sub
  248. ' ***********************************************
  249. ' Load the indicated file and prepare to work
  250. ' with its palette.
  251. ' ***********************************************
  252. Sub LoadFromPict(fname As String)
  253. Dim i As Integer
  254.     On Error GoTo LoadFileError
  255.     FromPict.Picture = LoadPicture(fname)
  256.     On Error GoTo 0
  257.     FromHBar.Enabled = False
  258.     FromVBar.Enabled = False
  259.     RangeSBar.Enabled = False
  260.     DoEvents
  261.     MatchGrayPalette FromPict
  262.     FromPict.Move 0, 0
  263.     ResetScrollBars
  264.     RangeSBar.Enabled = True
  265.     ' Make the new and original palettes match.
  266.     For i = 0 To SysPalSize - 1
  267.         newpal(i) = origpal(i)
  268.     Next i
  269.     ' Count the pixels with each palette index.
  270.     CountIndexes
  271.     ' Display the current histogram.
  272.     ShowHistogram
  273.     Caption = "Contrast [" & fname & "]"
  274.     Exit Sub
  275. LoadFileError:
  276.     Beep
  277.     MsgBox "Error loading file " & fname & "." & _
  278.         vbCrLf & Error$
  279.     Exit Sub
  280. End Sub
  281. Private Sub Form_Unload(Cancel As Integer)
  282.     End
  283. End Sub
  284. ' ************************************************
  285. ' Present a message indicating the pixel's palette
  286. ' index and color value.
  287. ' ************************************************
  288. Private Sub FromPict_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  289.     If X > wid Or Y > hgt Then Exit Sub
  290.     With newpal(bytes(X, Y))
  291.         MsgBox "Palette index:" & Str$(bytes(X, Y)) & _
  292.             vbCrLf & "Red:  " & Str$(.peRed) & _
  293.             vbCrLf & "Green:" & Str$(.peGreen) & _
  294.             vbCrLf & "Blue: " & Str$(.peBlue)
  295.     End With
  296. End Sub
  297. ' ***********************************************
  298. ' Load the control's palette so it matches the
  299. ' the system palette. Remap any of the image's
  300. ' pixels that use static colors to non-static
  301. ' colors.
  302. ' Set the following module global variables.
  303. '   LogPal      Image logical palette handle.
  304. '   origpal()  Image logical palette entries.
  305. '   wid         Width of image.
  306. '   hgt         Height of image.
  307. '   bytes(1 To wid, 1 To hgt)
  308. '               Image pixel values.
  309. ' ***********************************************
  310. Sub MatchColorPalette(pic As Control)
  311. Dim sys(0 To 255) As PALETTEENTRY
  312. Dim i As Integer
  313. Dim bm As BITMAP
  314. Dim hbm As Integer
  315. Dim status As Long
  316. Dim X As Integer
  317. Dim Y As Integer
  318. Dim clr As Integer
  319.     ' Make sure pic has the foreground palette.
  320.     pic.ZOrder
  321.     i = RealizePalette(pic.hdc)
  322.     DoEvents
  323.     ' Get the system palette entries.
  324.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  325.             
  326.     ' Make the logical palette as big as possible.
  327.     LogPal = pic.Picture.hPal
  328.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  329.         Beep
  330.         MsgBox "Error resizing logical palette.", _
  331.             vbExclamation
  332.         Exit Sub
  333.     End If
  334.     ' Blank the non-static colors.
  335.     For i = 0 To StaticColor1
  336.         origpal(i) = sys(i)
  337.     Next i
  338.     For i = StaticColor1 + 1 To StaticColor2 - 1
  339.         With origpal(i)
  340.             .peRed = 0
  341.             .peGreen = 0
  342.             .peBlue = 0
  343.             .peFlags = PC_NOCOLLAPSE
  344.         End With
  345.     Next i
  346.     For i = StaticColor2 To 255
  347.         origpal(i) = sys(i)
  348.     Next i
  349.     i = SetPaletteEntries(LogPal, 0, SysPalSize, origpal(0))
  350.     ' Insert the non-static colors.
  351.     For i = StaticColor1 + 1 To StaticColor2 - 1
  352.         origpal(i) = sys(i)
  353.         origpal(i).peFlags = PC_NOCOLLAPSE
  354.     Next i
  355.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, origpal(StaticColor1 + 1))
  356.     ' Realize the new palette.
  357.     i = RealizePalette(pic.hdc)
  358.     ' Get the image pixels.
  359.     hbm = pic.Image
  360.     status = GetObject(hbm, BITMAP_SIZE, bm)
  361.     wid = bm.bmWidthBytes
  362.     hgt = bm.bmHeight
  363.     ReDim bytes(1 To wid, 1 To hgt)
  364.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  365.     ' Remap any pixels using static colors.
  366.     For Y = 1 To hgt
  367.         For X = 1 To wid
  368.             clr = bytes(X, Y)
  369.             If clr <= StaticColor1 Or clr >= StaticColor2 Then
  370.                 With sys(clr)
  371.                     bytes(X, Y) = _
  372.                         NearestNonstaticColor( _
  373.                         .peRed, .peGreen, .peBlue)
  374.                 End With
  375.             End If
  376.         Next X
  377.     Next Y
  378.     ' Update the image's pixel values.
  379.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  380.     pic.Refresh
  381. End Sub
  382. ' ***********************************************
  383. ' Load the control's palette so the non-static
  384. ' colors are grays. Map the logical palette to
  385. ' match the system palette. Convert the image to
  386. ' use the non-static grays.
  387. ' Set the following module global variables.
  388. '   LogPal      Image logical palette handle.
  389. '   origpal()  Image logical palette entries.
  390. '   wid         Width of image.
  391. '   hgt         Height of image.
  392. '   bytes(1 To wid, 1 To hgt)
  393. '               Image pixel values.
  394. ' ***********************************************
  395. Sub MatchGrayPalette(pic As Control)
  396. Dim sys(0 To 255) As PALETTEENTRY
  397. Dim i As Integer
  398. Dim bm As BITMAP
  399. Dim hbm As Integer
  400. Dim status As Long
  401. Dim X As Integer
  402. Dim Y As Integer
  403. Dim gray As Single
  404. Dim dgray As Single
  405. Dim c As Integer
  406. Dim clr As Integer
  407.     ' Make sure pic has the foreground palette.
  408.     pic.ZOrder
  409.     i = RealizePalette(pic.hdc)
  410.     DoEvents
  411.     ' Get the system palette entries.
  412.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  413.         
  414.     ' Get the image pixels.
  415.     hbm = pic.Image
  416.     status = GetObject(hbm, BITMAP_SIZE, bm)
  417.     wid = bm.bmWidthBytes
  418.     hgt = bm.bmHeight
  419.     ReDim bytes(1 To wid, 1 To hgt)
  420.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  421.     ' Make the logical palette as big as possible.
  422.     LogPal = pic.Picture.hPal
  423.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  424.         Beep
  425.         MsgBox "Error resizing logical palette.", _
  426.             vbExclamation
  427.         Exit Sub
  428.     End If
  429.     ' Blank the non-static colors.
  430.     For i = 0 To StaticColor1
  431.         origpal(i) = sys(i)
  432.     Next i
  433.     For i = StaticColor1 + 1 To StaticColor2 - 1
  434.         With origpal(i)
  435.             .peRed = 0
  436.             .peGreen = 0
  437.             .peBlue = 0
  438.             .peFlags = PC_NOCOLLAPSE
  439.         End With
  440.     Next i
  441.     For i = StaticColor2 To 255
  442.         origpal(i) = sys(i)
  443.     Next i
  444.     i = SetPaletteEntries(LogPal, 0, SysPalSize, origpal(0))
  445.     ' Insert the non-static grays.
  446.     gray = 0
  447.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  448.     For i = StaticColor1 + 1 To StaticColor2 - 1
  449.         c = gray
  450.         gray = gray + dgray
  451.         With origpal(i)
  452.             .peRed = c
  453.             .peGreen = c
  454.             .peBlue = c
  455.         End With
  456.     Next i
  457.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, origpal(StaticColor1 + 1))
  458.     ' Recreate the image using the new colors.
  459.     For Y = 1 To hgt
  460.         For X = 1 To wid
  461.             clr = bytes(X, Y)
  462.             With sys(clr)
  463.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  464.             End With
  465.             bytes(X, Y) = NearestNonstaticGray(c)
  466.         Next X
  467.     Next Y
  468.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  469.     ' Realize the gray palette.
  470.     i = RealizePalette(pic.hdc)
  471.     pic.Refresh
  472. End Sub
  473. ' ************************************************
  474. ' Return the index of the nonstatic color closest
  475. ' to the given color value.
  476. ' ************************************************
  477. Function NearestNonstaticColor(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As Integer
  478. Dim best_i As Integer
  479. Dim best_dist As Long
  480. Dim dist As Long
  481. Dim dr As Long
  482. Dim dg As Long
  483. Dim db As Long
  484. Dim i As Integer
  485.     best_dist = 1000000
  486.     For i = StaticColor1 + 1 To StaticColor2 - 1
  487.         With origpal(i)
  488.             dr = r - .peRed
  489.             dg = g - .peGreen
  490.             db = b - .peBlue
  491.             dist = dr * dr + dg * dg + db * db
  492.         End With
  493.         If best_dist > dist Then
  494.             best_i = i
  495.             best_dist = dist
  496.         End If
  497.     Next i
  498.     NearestNonstaticColor = best_i
  499. End Function
  500. ' ************************************************
  501. ' Create a brightness histogram for the image.
  502. ' ************************************************
  503. Sub ShowHistogram()
  504. Dim i As Integer
  505. Dim maxy As Single
  506. Dim yscale As Single
  507.     RangeLabel.Caption = ""
  508.     RangeLabel.Refresh
  509.     HistPict.Cls
  510.     HistPict.Refresh
  511.     ' Count the brightness values.
  512.     CountValues
  513.     ' **********************
  514.     ' * Display the output *
  515.     ' **********************
  516.     For i = 0 To SysPalSize - 1
  517.         If maxy < ValueCounts(i) Then _
  518.             maxy = ValueCounts(i)
  519.     Next i
  520.     If maxy <> 0 Then
  521.         yscale = -HistPict.ScaleHeight / maxy
  522.     Else
  523.         yscale = 0
  524.     End If
  525.     maxy = HistPict.ScaleTop + HistPict.ScaleHeight
  526.     For i = 0 To SysPalSize - 1
  527.         HistPict.Line (i + 1, maxy)-Step(0, ValueCounts(i) * yscale)
  528.     Next i
  529. End Sub
  530. ' ***********************************************
  531. ' Set the Max and LargeChange properties for the
  532. ' image scroll bars.
  533. ' ***********************************************
  534. Sub ResetScrollBars()
  535.     ' FromHBar.
  536.     FromHBar.Value = 0
  537.     If FromSwin.ScaleWidth >= FromPict.Width Then
  538.         FromHBar.Enabled = False
  539.     Else
  540.         FromHBar.Max = FromPict.Width - FromSwin.ScaleWidth
  541.         FromHBar.LargeChange = FromSwin.ScaleWidth
  542.         FromHBar.Enabled = True
  543.     End If
  544.     ' FromVBar.
  545.     FromVBar.Value = 0
  546.     If FromSwin.ScaleHeight >= FromPict.Height Then
  547.         FromVBar.Enabled = False
  548.     Else
  549.         FromVBar.Max = FromPict.Height - FromSwin.ScaleHeight
  550.         FromVBar.LargeChange = FromSwin.ScaleHeight
  551.         FromVBar.Enabled = True
  552.     End If
  553. End Sub
  554. ' ***********************************************
  555. ' Give the form and all the picture boxes an
  556. ' hourglass cursor.
  557. ' ***********************************************
  558. Sub WaitStart()
  559.     MousePointer = vbHourglass
  560.     FromPict.MousePointer = vbHourglass
  561.     HistPict.MousePointer = vbHourglass
  562.     DoEvents
  563. End Sub
  564. ' ***********************************************
  565. ' Restore the mouse pointers for the form and all
  566. ' the picture boxes.
  567. ' ***********************************************
  568. Sub WaitEnd()
  569.     MousePointer = vbDefault
  570.     FromPict.MousePointer = vbDefault
  571.     HistPict.MousePointer = vbDefault
  572. End Sub
  573. Private Sub Form_Load()
  574.     ' Make sure the screen supports palettes.
  575.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  576.         Beep
  577.         MsgBox "This monitor does not support palettes.", _
  578.             vbCritical
  579.         End
  580.     End If
  581.     ' Get system palette size and # static colors.
  582.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  583.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  584.     StaticColor1 = NumStaticColors \ 2 - 1
  585.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  586.     ' Remove the borders from FromPict.
  587.     FromPict.BorderStyle = vbTransparent
  588.     ' Make sure FromPict has control.
  589.     FromPict.ZOrder
  590. End Sub
  591. ' ***********************************************
  592. ' Make the picture as large as possible.
  593. ' ***********************************************
  594. Private Sub Form_Resize()
  595. Const GAP = 4
  596. Dim hgt As Single
  597. Dim wid As Single
  598.     If WindowState = vbMinimized Then Exit Sub
  599.         
  600.     hgt = ScaleHeight - FromHBar.Height - 1
  601.     wid = ScaleWidth - FromVBar.Width - 1 - _
  602.         GAP - HistPict.Width
  603.     ' Place FromSwin and its scroll bars.
  604.     FromSwin.Move 0, 0, wid, hgt
  605.     FromVBar.Move _
  606.         FromSwin.Left + FromSwin.Width + 1, _
  607.         0, FromVBar.Width, hgt
  608.     FromHBar.Move _
  609.         FromSwin.Left, FromSwin.Height + 1, _
  610.         wid
  611.     ' Place HistPict.
  612.     HistPict.Move FromVBar.Left + FromVBar.Width + GAP, 0
  613.     RangeLabel.Move HistPict.Left, RangeLabel.Top
  614.     RangeSBar.Move HistPict.Left, RangeSBar.Top
  615.     ' Set the scroll bar limits.
  616.     ResetScrollBars
  617. End Sub
  618. ' ***********************************************
  619. ' Move FromPict within FromSwin.
  620. ' ***********************************************
  621. Private Sub FromHBar_Change()
  622.     FromPict.Left = -FromHBar.Value
  623. End Sub
  624. ' ***********************************************
  625. ' Move FromPict within FromSwin.
  626. ' ***********************************************
  627. Private Sub FromHBar_Scroll()
  628.     FromPict.Left = -FromHBar.Value
  629. End Sub
  630. ' ***********************************************
  631. ' Load a new image file.
  632. ' ***********************************************
  633. Private Sub mnuFileLoad_Click()
  634. Dim fname As String
  635.     ' Allow the user to pick a file.
  636.     On Error Resume Next
  637.     FileDialog.filename = "*.BMP;*.ICO;*.RLE;*.WMF;*.DIB"
  638.     FileDialog.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  639.     FileDialog.ShowOpen
  640.     If Err.Number = cdlCancel Then
  641.         Exit Sub
  642.     ElseIf Err.Number <> 0 Then
  643.         Beep
  644.         MsgBox "Error selecting file.", , vbExclamation
  645.         Exit Sub
  646.     End If
  647.     On Error GoTo 0
  648.     fname = Trim$(FileDialog.filename)
  649.     FileDialog.InitDir = Left$(fname, Len(fname) _
  650.         - Len(FileDialog.FileTitle) - 1)
  651.     ' Load the picture.
  652.     WaitStart
  653.     LoadFromPict fname
  654.     WaitEnd
  655. End Sub
  656. ' ***********************************************
  657. ' End the application. (See also the QueryUnload
  658. ' event.)
  659. ' ***********************************************
  660. Private Sub mnuFileExit_Click()
  661.     Unload Me
  662. End Sub
  663. ' ***********************************************
  664. ' Move FromPict within FromSwin.
  665. ' ***********************************************
  666. Private Sub FromVBar_Change()
  667.     FromPict.Top = -FromVBar.Value
  668. End Sub
  669. ' ***********************************************
  670. ' Move FromPict within FromSwin.
  671. ' ***********************************************
  672. Private Sub FromVBar_Scroll()
  673.     FromPict.Top = -FromVBar.Value
  674. End Sub
  675. ' ************************************************
  676. ' Adjust the image's contrast.
  677. ' ************************************************
  678. Private Sub RangeSBar_Change()
  679.     If SettingRange Then Exit Sub
  680.     AdjustContrast FromPict, RangeSBar.Value
  681.     ShowHistogram
  682. End Sub
  683.