immagini e listbox

Salve a tutti,

in una listbox della versione desk
all’ evento CellTextPaint posiziono un’immagine all’inteno di una cell di una determinata row
con il seguente codice:

dim f As FolderItem
dim p as Picture

f = GetFolderItem(“immagine”)
p = f.OpenAsPicture

g.DrawPicture(p,0,0,p.Widthrapporto,p.Heightrapporto,0,0,p.Width,p.Height)

Questo mi permette di proporzionare e posizionare a piacere l’immagine all’interno della cell
Ora però vorrei poterlo fare con un’immagine letta via http://……

Qualcuno sa se esiste un modo per farlo?

Grazie
Enzo

Te lo sconsiglio.
O almeno non direttamente. In questo modo ad ogni invalidate della cella (o refresh) dovrebbe scaricare il file, ma anche il ridimensionamento che fai rallenta (ovviamente di meno)

Ti consiglio ad esempio (per il tuo codice)
metti nel cellTag la picture ridimensionata, se NIL allora scala altrimenti disegna

dim p as picture=me.cellTag(row,column) if p=nil then dim f as folderItem=getFolderItem("immagine") dim nuovaImmagine as picture=picture.open(f) if nuovaImmagine<>nil then p=new picture(nuovaImmagine.width*rapporto, nuovaImmagine.height*rapporto) p.graphics.DrawPicture(0, 0, p.Width, p.Height, 0, 0, nuovaImmagine.width, nuovaImmagine.Height) me.cellTag(row, column)=p end if if p<>nil then g.DrawPicture p, 0, 0

A questo punto fare che l’immagine venga dal web (letta via http) diventa molto simile
In linea di principio potresti fare la stessa cosa e invece di leggere da file leggi da un httpsocket con un get. Ma ti lascio immaginare i tempi di risposta al momento in cui per la prima volta vai a leggere il dato…

La cosa migliore farlo in modo asincrono e una volta letta l’immagine ridimensionarla e poi salvarla nel cellTag e fare l’invalidate della cella

Buon giorno Antonio,
se non ho capito male con l’httpsocket in ogni caso
prima dovrei salvare l’immagine in qualche modo sul disco e poi fare il resto
e questo volevo evitarlo…
Speravo ci fosse un modo per inserire un oggetto HTMLViewer all’interno di una cell e sfruttare LoadURL dell’oggetto

Grazie per il tuo interesse
Saluti
Enzo

Se ci rifletti bene, sarebbe l’oggetto html che caricherebbe l’immagine in modo asincrono e poi la terrebbe in cache, ma in ogni caso la ricaricherebbe (per come funziona un browser web) ad ogni refresh.

Il suggerimento di fare lo stesso con un httpsocket e senza salvare su file, basta che mantieni in memoria l’immagine scaricata e ridimensionata.

Se ti preoccupi dei tempi di download li avresti comunque, se ti preoccupi dell’occupazione in memoria, la avresti comunque…

Salve Antonio,

a forza di provare sembra che qualcosa salti fuori !!

Dai miei test per emerso che:
l’immagine una volta scaricata e ridimensionata deve essere caricata in un array di immagini.
Mentre se (come facevo io) l’immagine viene caricata nel tag della row
la cell la visualizza correttamente ma alla row successiva sparisce l’immagine della row precedente e se leggo il tag lo trovo vuoto…

Come dici tu per tutto molto lento…
Sicuramente sono io a sbagliare qualcosa ma almeno ora funziona !!

Ho fatto anche dei test comparativi usando la tecnica di costruire una sorta di listbox con il gioco di container,
dove nel container riga ho inserito un HTMLViewer a cui faccio leggere l’immagine con LoadPage.
Con questa tecnica la cosa si complica dal punto di vista della gestione
ma la velocit e di popolamento molto interessante
ed di poco inferiore al caricare la stessa lista di record su una listbox standard leggendo le immagini dal disco…

Se prima non sapevo come fare ora non so quale strada conviene prendere…

In ogni caso
ringrazio sempre
per la tua disponibilit nel capire le mie problematiche

Saluti
Enzo

Ciao Enzo,
il caricamento nella tag (cell o row) serve a velocizzare il processo di cella (una volta che hai definito cosa c’ in una listbox ci sono vari momenti in cui questa viene disegnata e di conseguenza chiamati gli eventi cellPaint e backgroundPaint)

Quello che hai osservato non molto diverso da quello che vedi quando carichi in una listbox i dati di un recordset, ad ogni caricamento di un nuovo recordset i vecchi dati vengono rimpiazzati.
Pertanto se vuoi caricare delle immagini che sono separate dai dati (in quanto provengono ad esempio dal web) devi usare una struttura di supporto come un array o meglio ancora un dictionary.

Ad esempio puoi creare un dictionary ed usare come chiave la chiave del record da memorizzare nel rowtag quando carichi il recordset.
Man mano che carichi le immagini vai a popolare il dictionary (chiaveRecord->immagineRidimensionata), e quando disegni (paint) vedi se hai l’immagine relativa con dictImmagini.lookup(chiaveRecord,nil) e se non nil disegni l’immagine.
In pratica il dictionary ti fa da cache.

In questo modo dopo il caricamento delle immagini tutto sar estremamente veloce e fluido e visto che le immagini sono caricate in modo asincrono (httpSocket) anche durante il caricamento tutto rimarr fluido, un po come succede sul web o in altri ambienti dove si utilizzano i meccanismi di cache.

Salve Antonio,
ho ottimizzato per bene il codice seguendo i tuoi consigli.
Senza ombra di dubbio il risultato di molto migliore ora.
La listbox si carica velocemente ed lo stesso evento CellTexPaint che richiama il socket al bisogno.
Grazie molte!!

Sono 2 gli aspetti che ancora non mi soddisfano:

1 il tempo che impiega il socket ( di molto superiore a quanto ci mette un HTMLViewer con loadpage )
2 non riesco a creare da codice un nuovo socket per ogni riga caricata,
perci richiamando sempre lo stesso socket molto velocemente lui restituisce sempre l’ultima richiesta.
Questo fa si che le immagini sulla listbox vengono aggiornate partendo dall’ultima riga visualizzata…

Saluti
Enzo

Ciao Enzo,
per migliorare ulteriormente la cosa puoi utilizzare un array per le richieste e fare il pop da questo per richiamarle (cos verranno richiamate in ordine) e magari utilizzare pi socket per scaricarle in contemporanea (sono asincroni)

… l’ho messo in lista per un prossimo tutorial

Ciao Antonio,
si proprio quello che st tentando di fare io…
Spero di trovare un p di tempo da dedicare alla sperimentazione,
e se vien fuori qualcosa di buono ti aggiorno

Grazie
Enzo