Subject Re: Display Images on the form from a local imagefolder
From Mervyn Bick <invalid@invalid.invalid>
Date Fri, 22 Sep 2023 10:29:57 +0200
Newsgroups dbase.getting-started
Attachment(s) seek_fish1.wfm

On 2023/09/22 06:13, AGOSTINHO wrote:
> Following Mervin Bick adive that's not recommended  to  save images to tables.
>
....

> I added a character field named "imagefolder" to my fish4.dbf file and wrote the image files name to this particular record "C:\Users\HOME_PC\Desktop\blueangelfish.png"
>
> Dropped an image controle  from the componed pallete  to the form
> and have programmed an onNavigate function into the form.
>
> this.IMAGE1 = new IMAGE(this)
>     with (this.IMAGE1)
>        height = 4.84
>        left = 73.1111
>        top = 3.96
>        width = 17.8889
>     endwith
>
> function form_onNavigate(nWorkArea)
>               local cImageFileName
>               // Assuming I have a field in my table that contains image file paths
>              cImageFileName = form.fish41.rowset.fields["imagefolder"]
>              // Image control's ImageFile property to display the image
>            this.image1 = cImageFileName
>    return
>


Firstly, workareas are created when a table is USE'd with XDML.
Workareas don't exist when OODML query objects are used.  One can mix
XDML and OODML table access in a form if one is very careful but it is
NOT a good idea as it can lead to major problems.  Stick with OODML.

You need to use the onNavigate event handler of the rowset created by
the query object to tell the image control which image to display.

The syntax for displaying an image file in an image object is

       dataSource = 'FILENAME "whatever.jpg"'

No event handler executed by a query or a rowset understands the concept
"form".  One needs to use this.parent.parent in event handlers executed
by the rowset.

'this' refers to the rowset
'this.parent' refers to the query
'this.parent.parent' refers to the form.

  function rowset_onNavigate(type, nRows)
    cImageFileName = this.fields["imagefolder"].value
    this.parent.parent.image1.dataSource = 'FILENAME  "'+cImagefile+["]
    return

This has not been tested but it should work.  It will, however, only
work if the image files are in the same folder as your program.  If you
haven't set the image control's datasource in the constructor code to
access the first image in the table you will need to use the form's
onOpen event handler to do this.

  function form_onOpen
    cImageFileName = form.fish41.rowset.fields["imagefolder"].value
    form.image1.dataSource = 'FILENAME  "'+cImagefile+["]
    return

It is better programming practice to keep the image files in a separate
folder with the path in one field of the table and the file name in
another.  To display a file means combining the path and the filename.
Having trailing blanks for the file name is not a problem but they must
be removed from the path.  One can provide the path as a variable and
only save the file name to the table but I prefer to include the path in
a separate field.

A revised version of your test form is attached.

Mervyn.











if file ('fish_mb.dbf')
  drop table fish_mb
endif  
if not file('fish_mb.dbf')
   copy table :dbasesamples:fish to fish_mb
endif
cDir = set('dire')
nDir_len = len(cDir)+10
cPath = cDir+'\jpg_path'
cmd = 'alter table fish_mb add jpg_path char('+nDir_len+') , add jpg_name char(10)'
&cmd
try  
   cmd = 'md '+cDir+'\jpg_path'
   &cmd
catch(exception e)
endtry
cSafety = set('safety')
set safety off
q = new query()
q.sql = 'select * from fish_mb'
q.active = true
n = 1
do while not q.rowset.endofset
   cFish = 'fish'+n+'.jpg'
   cmd = 'q.rowset.fields["fish image"].copyToFile("'+cPath+'\'+cFish+'")'
   &cmd
   q.rowset.fields['jpg_path'] .value = cPath
   q.rowset.fields['jpg_name'].value = cFish
   n++
   q.rowset.next()
enddo
q.active= false
set safety  &cSafety

** END HEADER -- do not remove this line
//
// Generated on 2023-09-22
//
parameter bModal
local f
f = new SEEK_FISH1Form()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class SEEK_FISH1Form of FORM
   with (this)
      onOpen = class::FORM_ONOPEN
      height = 16.0
      left = 50.1429
      top = -0.2273
      width = 55.2857
      text = ""
   endwith

   this.FISH_MB1 = new QUERY(this)
   with (this.FISH_MB1)
      left = 25.0
      top = 4.0
      width = 6.0
      height = 1.0
      sql = 'select * from "FISH_MB.dbf" where lower(name)  like lower(:ag)'
      params["ag"] = "%"
      active = true
   endwith

   with (this.FISH_MB1.rowset)
      onNavigate = class::ROWSET_ONNAVIGATE
   endwith

   this.GRID1 = new GRID(this)
   with (this.GRID1)
      dataLink = form.fish_mb1.rowset
      height = 6.16
      left = 2.3333
      top = 5.72
      width = 50.5556
   endwith

   this.ENTRYFIELD1 = new ENTRYFIELD(this)
   with (this.ENTRYFIELD1)
      onKey = class::ENTRYFIELD1_ONKEY
      height = 1.76
      left = 24.1111
      top = 12.76
      width = 24.1111
      value = ""
   endwith

   this.IMAGE1 = new IMAGE(this)
   with (this.IMAGE1)
      height = 4.0
      left = 4.7143
      top = 0.4545
      width = 17.1429
      dataSource = form.fish_mb1.rowset.fields["fish image"]
   endwith

   this.TEXTLABEL1 = new TEXTLABEL(this)
   with (this.TEXTLABEL1)
      height = 1.76
      left = 0.7778
      top = 12.76
      width = 18.6667
      text = "Search Fish By Name"
   endwith

   this.IMAGE2 = new IMAGE(this)
   with (this.IMAGE2)
      height = 4.0
      left = 32.8571
      top = 0.4545
      width = 17.1429
   endwith

   this.rowset = this.fish_mb1.rowset

   function ENTRYFIELD1_onKey(nChar, nPosition,bShift,bControl)
      form.FISH_MB1.params['ag'] = '%'+this.value+'%'
      try
         form.FISH_MB1.requery()
      catch(exception e)
         form.FISH_MB1.requery()
      endtry
      form.image1.dataSource = form.FISH_MB1.rowset.fields["fish image"]
      form.image2.dataSource = 'FILENAME  "'+trim(form.FISH_MB1.rowset.fields['jpg_path'].value)+'\'+form.FISH_MB1.rowset.fields['jpg_name'].value+'"'
      return

   function form_onOpen()
      //Display image for first record when form opens
      form.image2.dataSource = 'FILENAME  "'+trim(form.FISH_MB1.rowset.fields['jpg_path'].value)+'\'+form.FISH_MB1.rowset.fields['jpg_name'].value+'"'
      return

   function rowset_onNavigate(type, nRows)
      this.parent.parent.image2.dataSource = 'FILENAME  "'+trim(this.fields['jpg_path'].value)+'\'+this.fields['jpg_name'].value+'"'
      return

endclass