My prior post showed how to use an array of PictureBox controls to display multiple photographs on a form. Now we’ll do something similar, but instead of using the PictureBox control, which is a little bit heavyweight, we can just draw directly onto the form.

This code uses a foxpro table of already created thumbnails (see Create thumbnails of all your digital photos in a single table) as a source. The Foxpro memo field is automagically an array of bytes, from which we can create a memory stream, which can be used by the Bitmap constructor.

 

Note how the Paint event is passed a ClipRectangle which indicates what subset of the form needs to be painted.

 

For some reason, the Rectangle’s Left property is readonly, so we have to set the Location property.

 

Try changing the DoubleBuffered property and move a small window around over the form to force parts to redraw.

 

Next post: do it on a Fox form.

 

 

Imports System.Data.OleDb

Public Class Form1

    Dim xpix As Integer = 8

    Dim ypix As Integer = 8

    Dim aPic(xpix, ypix) As PictureBox

    Dim dt As New DataTable

    Dim PixPath As String = "d:\pictures\"

    Dim PicPageIndex As Integer = 0

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim da As New OleDb.OleDbDataAdapter("Select fullname,thumb from pixthumb where LEFT(fullname,7)='2006\08'", _

            "provider=vfpoledb.1;data source=" + PixPath + "pixthumb.dbf")

        da.Fill(dt)

        Me.WindowState = FormWindowState.Maximized

        Me.DoubleBuffered = True   ' Try changing this: move a small window around on top of the form to force Paint msgs to see

    End Sub

 

    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

        Dim x, y As Integer

        Dim r As New Rectangle

        Dim w, h As Integer

        Dim loc As New Point

        For y = 0 To ypix - 1

            For x = 0 To xpix - 1

                w = Me.Width / xpix

                h = Me.Height / ypix

                r.Width = w

                r.Height = h

                loc.X = x * w

                loc.Y = y * h

                r.Location = loc

                If r.IntersectsWith(e.ClipRectangle) Then

                    Dim nIndex As Integer = PicPageIndex + y * ypix + x

                    If nIndex >= 0 And nIndex >= dt.Rows.Count Then

                        e.Graphics.FillRectangle(Brushes.AntiqueWhite, r)

                    Else

                        Dim ThumbBytes() As Byte = dt.Rows(nIndex).Item(1)

                        Dim ostream As New IO.MemoryStream(ThumbBytes)

                        Dim bm As New Bitmap(ostream)

                        e.Graphics.DrawImage(bm, r)

                    End If

                End If

            Next

        Next

    End Sub

    Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress

        Select Case Char.ToUpper(e.KeyChar)

            Case "Q"    'Quit

                End

            Case "N"

                If PicPageIndex < dt.Rows.Count Then

                    PicPageIndex += (xpix - 1) * (ypix - 1)

                End If

            Case "P"

                If PicPageIndex > 0 Then

                    PicPageIndex -= (xpix - 1) * (ypix - 1)

                End If

        End Select

        Me.Invalidate()

    End Sub

 

    Private Sub Form1_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd

        Me.Invalidate()

    End Sub

End Class