Newsgroup: it.comp.lang.visual-basic
Titolo: VB_6_help passaggio di strutture utente da / a procedure public membro di classe

HELP  VB_6.0
qualcuno è a conoscenza se esiste un metodo per AGGIRARE, eventualmente
tramite add-ins capaci di estendere le caratteristiche del linguaggio, il
controllo sintattico che PROIBISCE che una struttura dati utente (TYPE) di
tipo PUBLIC possa essere passata dentro e fuori, come argomento o valore di
ritorno, le procedure pubbliche degli oggetti classe (e forms) ?
E' una limitazione davvero micidiale che talvolta, per strutture di dati
pesanti e molto annidate, vanifica completamente l'efficacia della O.O.P. e
della creazione di classi
Tra l'altro non sono neppure certo di capire la filosofia alla base di
questo limite, visto che per le procedure private il passaggio di oggetti di
tipo utente tra procedure interne alla classe è implementato e lo è anche
nelle routine pubbliche/private dei moduli.BAS
ciao e grazie
Soviet-Mario

nelle routine pubbliche/private dei moduli.BAS
Visual Basic si basa su COM, quindi vuole praticamente solo oggetti
COM.
-- 
ciao,
hal

 hal

 ritorno, le procedure pubbliche degli oggetti classe (e forms) ?
[SNIP]
Come suggerisce il messaggio di errore in compilazione, gli UDT possono
essere utilizzati in funzioni di classe pubbliche purche' il tipo stesso sia
dichiarato come pubblico in un modulo *di classe* pubblico (uno qualunque,
non necessariamante quello che ne fa uso) e non in un modulo BAS.
Questo implica che in un progetto EXE standard non puoi utilizzarli, perche'
non puoi definire classi pubbliche, mentre puoi in un tutti gli altri
progetti di tipo ActiveX (EXE\DLL ecc.).
Come accennava hal (anche se non c'entra molto la pochezza OOP di VB6) puoi
comunque vedere se vale la pena trasformare questi tipi in classi; gli UDT
hanno alcuni contesti dove sono quasi imprescindibili, uno su tutti la
lettura/scrittura immediata di strutture da file, viceversa per esporre
informazioni all'esterno, al di la' dell'ingombro a video(!), le classi
vincono a mani basse in flessibilita', riutilizzo e robustezza.
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown


Sono d'accordo com hal. Ho risolto proprio ieri notte questo stesso problema
con la soluzione delle classi. E adesso sono più tranquillo xè non sono il
solo ad aver avuto questa idea. Per quanto riguarda riempire il progetto con
tanti file *.cls, considera che Java (ops!), definito uno tra i migliori
programmi OOP, funziona "esclusivamente" con questo sistema: una classe per
struttura.
Ciao Haxl
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 progetti di tipo ActiveX (EXE\DLL ecc.).
Già, infatti per assurdo puoi definire i tuoi UDT in una dll activex in un
modulo di classe pubblico (multiuse o globalmultiuse) e tramite riferimento
a questa DLL puoi usare l'UDT tranquillamente in tutta la tua app.
Quindi puoi predere in considerazione il fatto di creare una DLL activeX
tipo:
MyTypes.dll
 +--- MyTypes.PublicTypes.cls
        +--- Public Type MyType
Ciao
--
Math Parser : 
http://www.neodatatype.net
Sito Comune : 
http://www.it-lang-vb.net


Ma  GRAAAAAAAAANDE  !
Oh, sarà pure assurdo come dici ma questo trick è davvero notevole.
L'unico problema che mi resta in ogni caso da gestire è definire i tipi
utente in un progetto ed usarli a posteriori in un progetto diverso.
Quindi suppongo che se voglio esporre i tipi utente durante lo sviluppo del
progetto che funge da "client" non posso tenere aperto l'altro progetto
("server") in VB, ma dovrei averlo già compilato in una DLL binaria, giusto
?
pls conferma
Grazie delle dritte
Ciao
Soviet-Mario


 ?
Niente affatto.
Puoi includere il progetto della tua dll al gruppo di progetti.
1) Apri il tuo progetto.
2) Menu file --> aggiungi progetto, aggiungi la dll.
3) Assicurati che la dll abbia tra le proprietà del progetto la
compatibilità binaria con la versione referenziata dal progetto iniziale: in
questo modo VB rimappa il riferimento alla dll con un riferimento al
progetto.
C'è anche un'altra alternativa ma per i tuoi scopi non è molto utile.


Salve.
Questa mattina ho applicato l'idea condivisa da hal1961:
ho creato una classe con all'interno la struttura di tipo privato(unico tipo
consentito), ho istanziato una variabile per leggere un file binario a
blocchi(record) e ho dotato la classe di tante proprietą quanti sono i campi
della struttura: Class_Initialize() mi apre il file, legge un blocco,
inizializza le proprietą della classe. Risolto: struttura incapsulata nella
classe e possibilitą di leggere tutti i campi dall'esterno.
Ciao. Haxl



ok, tanto ce ne avanza così !
Ciao
Soviet-Mario


 quelli della lista coi segni di spunta) ?
No, attenzione.
Referenziata significa che la dll compare nei riferimenti del progetto (Menu
Progetto-->Riferimenti).
Il punto (3) significa che se il tuo progetto mio_exe.vbp referenzia
mia_dll.dll, per effettuare il debug di mia_dll.vbp puoi aggiungere questo
al progetto mio_exe.vbp, e poi per dire che mia_dll.vbp corrisponde a
mia_dll.dll (in realtà "corrisponde" è una grossa semplificazione) devi
andare nelle proprietà del progetto mia_dll.vbp e nella voce "Compatibilità
binaria" indicare mia_dll.dll.
Chiaro? ;)


 più codice.
si. Anche se mi sono accorto di poter evitare le funzioni globali di
conversione a tipi standard (tipo a byte array) inglobandole come membri
pubblici .... anche se devo passare un istanza di oggetto che non è
ovviamente  *.THIS  scrivendo un codice molto inelegante tipo :
Dim ClsObj As New SomeClassType
Dim Temp() As Byte
Temp() = ClsObj.CnvToByteArray(ClsObj)
in questo caso il ClsObj a sinistra dell'operatore di selezione membro resta
del tutto vano e inutilizzato (e i membri interni referenziabili col nome
"plain" non sono mai nominati), mentre viene usata solo l'istanza passata
esplicitamente come argomento (coincidente .... tiè !)
per fare qualcosa tipo
Public Function CnvToByteArray(ClsObj As SomeClassType) as Byte()
Redim Bytes(0 to ConstClassSize - 1) As Byte
copymemory (Bytes(0), ClsObj, ConstClassSize)
CnvToByteArray = Bytes()
End Function
lo so, è pesante assegnare la matrice temporanea .... ma il VB 6 seguita a
darmi errori in statement del tipo  "Exit Function Bytes" con restituzione
diretta di matrice ... boh
cmq, come vedi, l'unico modo per fare in modo che la routine membro veda il
suo THIS dall'interno e tuttavia come un tutt'uno monolitico (anche per
salvarsi su disco) è ripassare una reference fingendo di ricevere un altra
istanza (di nuovo Tiè ! al VB) .... oddio, non ho ancora provato ma non vedo
perché non dovrebbe girare.
dai, già che ci sei dammi ancora qualche dritta quando hai tempo
ciao
Soviet


 classe e possibilità di leggere tutti i campi dall'esterno.
ecco come per il medesimo problema si trovano soluzioni diverse ....
La mia idea (meno incapsulante ma che richiede poco codice) era stata invece
:
togliere del tutto la struttura interna UDT
tradurre ogni membro dell'UDT in una variabile membro pubblica
(ma sarebbe anche potuta essere privata, se ti serviva l'incapsulamento)
scrivere funzioni membro che richiedono esplicitamente un parametro del
medesimo tipo della classe cui appartengono
se tu scrivi codice tipo
obj_1.DiskWrite(obj_2)
e dentro DiskWrite non referenzi nessun membro col nome "plain" ma solo
tramite :  obj_2.membro_1,  obj_2.membro_2,  obj_2.membro_n
o scrivi  Put Handle, , Obj_2
ecco che tratti la classe come un blocco ed aggiri l'invisibilità del
puntatore interno all'istanza (THIS)
E penso che si possa anche scrivere
obj_2.DiskWrite(obj_2)
nel qual caso, riferendosi le variabili "plain" e quelle referenziate
tramite DOT alla medesima istanza, puoi sia usare le componenti interne per
scopi locali, sia scrivere / leggere da disco in blocco
Di nuovo preciso che non ho ancora testato a fondo .... ma mi stupirei se
non funzionasse
Ciao
Soviet


 End Function
Questa non l'ho capita... perchč a questo punto non usare direttamente
ClsObj in questo modo?
Temp() = ClsObj.CnvToByteArray()
che alla .net diventerebbe piů semplicemente
Temp() = ClsObj.ToByteArray()
Per inciso, sempre come direbbero i .nettiani nota che gli UDT sono "value
type" mentre le classi sono "reference type".
Il che significa che per fare una copia di un UDT ti basta fare
struttura1 = struttura2
Con le classi devi farti un'altra funzione del tipo:
Set obj2 = obj1.Copy()
Public function Copy as MyClass
    Set Copy = new MyClass
    Copy.MyMember = ...
    ...
End function
P.S.: Occhio al quoting la prossima volta.
Ciao



Cioè ? Cos'ho cannato ???? Non devo togliere i pezzi "datati" ?
:-0


 Cioè ? Cos'ho cannato ???? Non devo togliere i pezzi "datati" ?
appunto :)
Mi hai lasciato interi blocchi con 4 ">"
Cerca qualche articolo a riguardo su google.


 Mi hai lasciato interi blocchi con 4 ">"
ah vabbeh .... ma non era lungo cmq   :_(
Mo' mi ritiro in meditazione e metabolizzo tutti i suggerimenti avuti
passo e chiudo temporaneamente
ciao
Soviet


 memoria .... boh ? Mica comprime i dati, no ?
Sai che mi fai venire il dubbio?
Può essere che in realtà non siano "impacchettati", anche se dubito, per via
che la CopyMemory funziona.
Comunque per vedere lo spazio occupato da una struttura devi usare Len e non
LenB, tant'è che quando ci sono le struttura dell'API che richiedono la
dimensione della struttura si fa sempre Len(my_type).
