Displaying an Image in a Form: Problem with Code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • BASSPU03
    New Member
    • Oct 2007
    • 55

    Displaying an Image in a Form: Problem with Code

    (Using Access 2003 on Windows XP.)

    I'm using the following code from http://www.databasedev .co.uk/image-form.html to display an image using an image control in my main form (frmVetted). This code is for the "Add Image" command button:

    Code:
    Private Sub cmdAddImage_Click()
        On Error GoTo cmdAddImage_Err
        Dim strFilter As String
        Dim lngflags As Long
        Dim varFileName As Variant
    
        strFilter = "All Files (*.*)" & vbNullChar & "*.*" _
                  & vbNullChar & "All Files (*.*)" & vbNullChar & "*.*"
    
        lngflags = tscFNPathMustExist Or tscFNFileMustExist _
                   Or tscFNHideReadOnly
    
        varFileName = [b] tsGetFileFromUser( _ [/b]
                      fOpenFile:=True, _
                      strFilter:=strFilter, _
                      rlngflags:=lngflags, _
                      strDialogTitle:="Please choose a file...")
    
        If IsNull(varFileName) Then
        Else
            Me![memPropertyPhotoLink] = varFileName
            Forms![frmVetted].Form.Requery
        End If
    
    cmdAddImage_End:
        On Error GoTo 0
        Exit Sub
    
    cmdAddImage_Err:
        Beep
        MsgBox Err.Description, , "Error: " & Err.Number _
                                & " in file"
        Resume cmdAddImage_End
    End Sub
    The code works fine if I delete an image, so I haven't posted the code for the delete button. However, the add image code stops here:

    Code:
    varFileName = tsGetFileFromUser( _
    ...which is in bold above. Apparently, it worked for the programmer on that site. I changed all the relevant areas to reflect my own DB, but now I'm getting on error that I have no clue how to fix. Any ideas? Thanks in advance.
  • Rabbit
    Recognized Expert MVP
    • Jan 2007
    • 12517

    #2
    You haven't told us what the error is.

    Comment

    • BASSPU03
      New Member
      • Oct 2007
      • 55

      #3
      Originally posted by Rabbit
      You haven't told us what the error is.
      Sorry, I thought I was clear but I missed this one indispensable thing:

      Compile error: Sub or Function not defined.

      Thanks.

      Comment

      • Rabbit
        Recognized Expert MVP
        • Jan 2007
        • 12517

        #4
        Then that means it doesn't know where tsGetFileFromUs er() is located. If it's not in a non form code module and it's not in the same form code module as where it's called from, then it won't be able to see that function.

        Comment

        • BASSPU03
          New Member
          • Oct 2007
          • 55

          #5
          Originally posted by Rabbit
          Then that means it doesn't know where tsGetFileFromUs er() is located. If it's not in a non form code module and it's not in the same form code module as where it's called from, then it won't be able to see that function.
          OK, so I added this module to use the Common Dialog API:

          Code:
          Option Compare Database
          
          Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _
          "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
          
          Private Type OPENFILENAME
              lStructSize As Long
              hwndOwner As Long
              hInstance As Long
              lpstrFilter As String
              lpstrCustomFilter As String
              nMaxCustFilter As Long
              nFilterIndex As Long
              lpstrFile As String
              nMaxFile As Long
              lpstrFileTitle As String
              nMaxFileTitle As Long
              lpstrInitialDir As String
              lpstrTitle As String
              flags As Long
              nFileOffset As Integer
              nFileExtension As Integer
              lpstrDefExt As String
              lCustData As Long
              lpfnHook As Long
              lpTemplateName As String
          End Type
          
          Function LaunchCD(strform As Form) As String
              Dim OpenFile As OPENFILENAME
              Dim lReturn As Long
              Dim sFilter As String
              OpenFile.lStructSize = Len(OpenFile)
              OpenFile.hwndOwner = strform.Hwnd
              sFilter = "All Files (*.*)" & Chr(0) & "*.*" & Chr(0) & _
                "JPEG Files (*.JPG)" & Chr(0) & "*.JPG" & Chr(0)
              OpenFile.lpstrFilter = sFilter
              OpenFile.nFilterIndex = 1
              OpenFile.lpstrFile = String(257, 0)
              OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
              OpenFile.lpstrFileTitle = OpenFile.lpstrFile
              OpenFile.nMaxFileTitle = OpenFile.nMaxFile
              OpenFile.lpstrInitialDir = "C:\"
              OpenFile.lpstrTitle = "Choose a File..."
              OpenFile.flags = 0
              lReturn = GetOpenFileName(OpenFile)
                  If lReturn = 0 Then
                      MsgBox "No file was selected", vbInformation, _
                        "Select a file using the Common Dialog DLL"
                   Else
                      LaunchCD = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))
                   End If
          End Function
          It's clear that "tsGetFileFromU ser" doesn't reference the name of this module's function "GetOpenFileNam e". I tried changing it and it still gives the same error. I only have a month of Access/VB programming under my belt, so a layman's explanation would be appreciated. Thanks.

          Comment

          • Rabbit
            Recognized Expert MVP
            • Jan 2007
            • 12517

            #6
            tsGetFileFromUs er() looks to be a user created function as I've never heard of it. So I would look over the original source code where you're getting this from because that's where it should be.

            Comment

            • ADezii
              Recognized Expert Expert
              • Apr 2006
              • 8834

              #7
              Originally posted by BASSPU03
              OK, so I added this module to use the Common Dialog API:

              Code:
              Option Compare Database
              
              Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _
              "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
              
              Private Type OPENFILENAME
                  lStructSize As Long
                  hwndOwner As Long
                  hInstance As Long
                  lpstrFilter As String
                  lpstrCustomFilter As String
                  nMaxCustFilter As Long
                  nFilterIndex As Long
                  lpstrFile As String
                  nMaxFile As Long
                  lpstrFileTitle As String
                  nMaxFileTitle As Long
                  lpstrInitialDir As String
                  lpstrTitle As String
                  flags As Long
                  nFileOffset As Integer
                  nFileExtension As Integer
                  lpstrDefExt As String
                  lCustData As Long
                  lpfnHook As Long
                  lpTemplateName As String
              End Type
              
              Function LaunchCD(strform As Form) As String
                  Dim OpenFile As OPENFILENAME
                  Dim lReturn As Long
                  Dim sFilter As String
                  OpenFile.lStructSize = Len(OpenFile)
                  OpenFile.hwndOwner = strform.Hwnd
                  sFilter = "All Files (*.*)" & Chr(0) & "*.*" & Chr(0) & _
                    "JPEG Files (*.JPG)" & Chr(0) & "*.JPG" & Chr(0)
                  OpenFile.lpstrFilter = sFilter
                  OpenFile.nFilterIndex = 1
                  OpenFile.lpstrFile = String(257, 0)
                  OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
                  OpenFile.lpstrFileTitle = OpenFile.lpstrFile
                  OpenFile.nMaxFileTitle = OpenFile.nMaxFile
                  OpenFile.lpstrInitialDir = "C:\"
                  OpenFile.lpstrTitle = "Choose a File..."
                  OpenFile.flags = 0
                  lReturn = GetOpenFileName(OpenFile)
                      If lReturn = 0 Then
                          MsgBox "No file was selected", vbInformation, _
                            "Select a file using the Common Dialog DLL"
                       Else
                          LaunchCD = Trim(Left(OpenFile.lpstrFile, InStr(1, OpenFile.lpstrFile, vbNullChar) - 1))
                       End If
              End Function
              It's clear that "tsGetFileFromU ser" doesn't reference the name of this module's function "GetOpenFileNam e". I tried changing it and it still gives the same error. I only have a month of Access/VB programming under my belt, so a layman's explanation would be appreciated. Thanks.
              If you are accessing this Function from outside of the Module in which it is contained, then it must be declared Publically as in:
              [CODE=vb]Public Declare Function GetOpenFileName Lib "comdlg32.d ll" Alias _
              "GetOpenFileNam eA" (pOpenfilename As OPENFILENAME) As Long[/CODE]

              Comment

              • BASSPU03
                New Member
                • Oct 2007
                • 55

                #8
                OK, so I went back to the source and found that the module was different. I was using a generic Common Dialog API from a Microsoft Knowledge Base help file instead of the module from the sample database I modeled, which is here: http://www.databasedev.co.uk/downloads/imagepath.zip

                The tutorial for it is here: http://www.databasedev.co.uk/image-form.html

                The problem now is that the ImageFrame control doesn't display the picture when I click "Add Image." When I click "Delete Image," it shows the "No Picture Available" default picture I have, but it sticks to the image control for each record instead of changing like it should.

                The "Add Image" button is working partially. When I click it, the Common Dialog API opens, I choose my file, and then the path appears in a corresponding textbox (memPropertyPho toLink), as desired. However, even though I have the ImageFrame image control, it doesn't show the picture.

                The codes are long enough to make this post long, so, instead, if someone's willing to look at this part of my DB, I can e-mail a sanitized version. Please PM me if you're willing and able. I'd attach it except that the file size limit for a .zip file is 97.7KB and I can only get it down to 140KB or so, even though it's compacted and zipped.

                Comment

                • BASSPU03
                  New Member
                  • Oct 2007
                  • 55

                  #9
                  The codes are long enough to make this post long, so, instead, if someone's willing to look at this part of my DB, I can e-mail a sanitized version.
                  ADezii, thank you for offering to check out my DB. I tried it on for size and it fits! I don't know what all the VB code represents in general, but I can make sense of it. I can see that you inserted the Me![ImageFrame].Picture = varFileName code right below the Me![memPropertyPhot oLink] = varFileName and that it works great. However, I'm having two follow-up issues:

                  1) The picture doesn't remain stored when I close and open the form. I tried adding an ImageFrame field (Type: Memo) in the corresponding table to store the varFileName, but that didn't work.
                  2) The picture stays the same for every record. How would I get it to change for each and to default to No Image Available until an image is selected?

                  I'll post the results on the forum!
                  Thanks,
                  Benito

                  Comment

                  • smorrison64
                    New Member
                    • Dec 2007
                    • 7

                    #10
                    I don't know if this will help but I was having the same problem and I used code from the sample Northwind database.

                    [code=vb]Option Compare Database
                    Option Explicit
                    Dim path As String

                    Private Sub AddPicture_Clic k()
                    ' Use the Office File Open dialog to get a file name to use
                    ' as an employee picture.
                    getFileName
                    End Sub

                    Private Sub Form_RecordExit (Cancel As Integer)
                    ' Hide the errormsg label to reduce flashing when navigating
                    ' between records.
                    errormsg.Visibl e = False
                    End Sub

                    Private Sub RemovePicture_C lick()
                    ' Clear the file name for the employee record and display the
                    ' errormsg label.
                    Me![ImagePath] = ""
                    hideImageFrame
                    errormsg.Visibl e = True
                    End Sub

                    Private Sub Form_AfterUpdat e()
                    ' Requery the ReportsTo combo box after a record has been changed.
                    ' Then, either show the errormsg label if no file name exists for
                    ' the employee record or display the image if there is a file name that
                    ' exists.
                    Me!ReportsTo.Re query
                    On Error Resume Next
                    showErrorMessag e
                    showImageFrame
                    If (IsRelative(Me! ImagePath) = True) Then
                    Me![ImageFrame].Picture = path & Me![ImagePath]
                    Else
                    Me![ImageFrame].Picture = Me![ImagePath]
                    End If
                    End Sub

                    Private Sub ImagePath_After Update()
                    ' After selecting an image for the employee, display it.
                    On Error Resume Next
                    showErrorMessag e
                    showImageFrame
                    If (IsRelative(Me! ImagePath) = True) Then
                    Me![ImageFrame].Picture = path & Me![ImagePath]
                    Else
                    Me![ImageFrame].Picture = Me![ImagePath]
                    End If
                    End Sub
                    Private Sub Form_Current()
                    ' Display the picture for the current employee record if the image
                    ' exists. If the file name no longer exists or the file name was blank
                    ' for the current employee, set the errormsg label caption to the
                    ' appropriate message.
                    Dim res As Boolean
                    Dim fName As String

                    path = CurrentProject. path
                    On Error Resume Next
                    errormsg.Visibl e = False
                    If Not IsNull(Me!Photo ) Then
                    res = IsRelative(Me!P hoto)
                    fName = Me![ImagePath]
                    If (res = True) Then
                    fName = path & "\" & fName
                    End If

                    Me![ImageFrame].Picture = fName
                    showImageFrame
                    Me.PaintPalette = Me![ImageFrame].ObjectPalette
                    If (Me![ImageFrame].Picture <> fName) Then
                    hideImageFrame
                    errormsg.Captio n = "Picture not found"
                    errormsg.Visibl e = True
                    End If
                    Else
                    hideImageFrame
                    errormsg.Captio n = "Click Add/Change to add picture"
                    errormsg.Visibl e = True
                    End If

                    End Sub

                    Sub getFileName()
                    ' Displays the Office File Open dialog to choose a file name
                    ' for the current employee record. If the user selects a file
                    ' display it in the image control.
                    Dim fileName As String
                    Dim result As Integer
                    With Application.Fil eDialog(msoFile DialogFilePicke r)
                    .Title = "Select Employee Picture"
                    .Filters.Add "All Files", "*.*"
                    .Filters.Add "JPEGs", "*.jpg"
                    .Filters.Add "Bitmaps", "*.bmp"
                    .FilterIndex = 3
                    .AllowMultiSele ct = False
                    .InitialFileNam e = CurrentProject. path
                    result = .Show
                    If (result <> 0) Then
                    fileName = Trim(.SelectedI tems.Item(1))
                    Me![ImagePath].Visible = True
                    Me![ImagePath].SetFocus
                    Me![ImagePath].Text = fileName
                    Me![FirstName].SetFocus
                    Me![ImagePath].Visible = False
                    End If
                    End With
                    End Sub

                    Sub showErrorMessag e()
                    ' Display the errormsg label if the image file is not available.
                    If Not IsNull(Me!Photo ) Then
                    errormsg.Visibl e = False
                    Else
                    errormsg.Visibl e = True
                    End If
                    End Sub

                    Function IsRelative(fNam e As String) As Boolean
                    ' Return false if the file name contains a drive or UNC path
                    IsRelative = (InStr(1, fName, ":") = 0) And (InStr(1, fName, "\\") = 0)
                    End Function

                    Sub hideImageFrame( )
                    ' Hide the image control
                    Me![ImageFrame].Visible = False
                    End Sub

                    Sub showImageFrame( )
                    ' Display the image control
                    Me![ImageFrame].Visible = True
                    End Sub[/code]
                    Last edited by Denburt; Dec 5 '07, 04:14 PM. Reason: Code Tags

                    Comment

                    • ADezii
                      Recognized Expert Expert
                      • Apr 2006
                      • 8834

                      #11
                      Originally posted by BASSPU03
                      ADezii, thank you for offering to check out my DB. I tried it on for size and it fits! I don't know what all the VB code represents in general, but I can make sense of it. I can see that you inserted the Me![ImageFrame].Picture = varFileName code right below the Me![memPropertyPhot oLink] = varFileName and that it works great. However, I'm having two follow-up issues:

                      1) The picture doesn't remain stored when I close and open the form. I tried adding an ImageFrame field (Type: Memo) in the corresponding table to store the varFileName, but that didn't work.
                      2) The picture stays the same for every record. How would I get it to change for each and to default to No Image Available until an image is selected?

                      I'll post the results on the forum!
                      Thanks,
                      Benito
                      You have basically 2 Options here:
                      1. You can store the Path to the Image Files within the Database, then dynamically load the Image into the Image Control for each Record in the Form's Current() Event. This will incur no overhead but you must store the Images in a Folder.
                      2. You can store the actual Graphic Images themselves into a Bound OLE Object Field. This approach, however, will drastically increase the size of the Database.
                      3. Let me know what you would like to do, and I'll walk you through the process.

                      Comment

                      • BASSPU03
                        New Member
                        • Oct 2007
                        • 55

                        #12
                        Originally posted by ADezii
                        [*] You can store the Path to the Image Files within the Database, then dynamically load the Image into the Image Control for each Record in the Form's Current() Event. This will incur no overhead but you must store the Images in a Folder.
                        I've opted for the 1st option, ADezii. I took smorrison64's suggestion and tried the Northwind example. It appears to be working quite well. I'm sorry if I wasted your time, ADezii, but I appreciate all your help. I did learn a lot dissecting both your and smorrison64's suggested codes.

                        Consequently, I'll add something I learned: I was getting an error at line 92:

                        Code:
                        With Application.FileDialog(msoFileDialogFilePicker)
                        It's explained here: http://www.pcreview.co.uk/forums/thread-1147567.php. If you try to add a reference with your code already open, the "references ..." option might be unavailable. Close all code windows, open your form in design view, open the code screen, and it should be available then. I added "Microsoft Office 12.0 Object Library" and the dialog box opened up when I clicked "Add/Change" to select an image.

                        Thanks, all.

                        Comment

                        • ADezii
                          Recognized Expert Expert
                          • Apr 2006
                          • 8834

                          #13
                          Originally posted by BASSPU03
                          I've opted for the 1st option, ADezii. I took smorrison64's suggestion and tried the Northwind example. It appears to be working quite well. I'm sorry if I wasted your time, ADezii, but I appreciate all your help. I did learn a lot dissecting both your and smorrison64's suggested codes.

                          Consequently, I'll add something I learned: I was getting an error at line 92:

                          Code:
                          With Application.FileDialog(msoFileDialogFilePicker)
                          It's explained here: http://www.pcreview.co.uk/forums/thread-1147567.php. If you try to add a reference with your code already open, the "references ..." option might be unavailable. Close all code windows, open your form in design view, open the code screen, and it should be available then. I added "Microsoft Office 12.0 Object Library" and the dialog box opened up when I clicked "Add/Change" to select an image.

                          Thanks, all.
                          It's always a Team effort here at TheScripts.

                          Comment

                          • BASSPU03
                            New Member
                            • Oct 2007
                            • 55

                            #14
                            Oh, I do have a slight issue, though: When I select my picture and it appears, the default text ("Click Add/Change to add image") remains over the image until I go to the next record. When I come back, it's gone. smorrison's (Northwind's, rather) code above tells this default text to become invisible after the image is selected, so I'm not sure why it stays until I change records. Any thoughts?

                            Comment

                            • ADezii
                              Recognized Expert Expert
                              • Apr 2006
                              • 8834

                              #15
                              Originally posted by BASSPU03
                              Oh, I do have a slight issue, though: When I select my picture and it appears, the default text ("Click Add/Change to add image") remains over the image until I go to the next record. When I come back, it's gone. smorrison's (Northwind's, rather) code above tells this default text to become invisible after the image is selected, so I'm not sure why it stays until I change records. Any thoughts?
                              Try inserting this line of code between Lines 107 and 108, then see what happens.
                              [CODE=vb]errormsg.Visibl e = False[/CODE]

                              Comment

                              Working...