Newsgroup: it.comp.lang.visual-basic
Titolo: Problema con DLL ActiveX

Vi illustro la situazione
Progetto DLL ActiveX composto da:
- frmCertificati
- modCertificati
- clsCertificati
Nelle proprietà del progetto ho messo come oggetto di avvio Sub Main che non
fa altro che connettersi al DB e aprire il recordset delle
personalizzazioni.
Sub Main()
    Set gWs = DBEngine.Workspaces(0)
    Set gDBcert = gWs.OpenDatabase(App.Path & "\Gestlab.mdb")
    Set rsPersonal = gDBcert.OpenRecordset("SELECT *" _
                                        & " FROM Personal", dbOpenSnapshot)
End Sub
La classe clsCertificati non fa altro che verificare la presenza di alcuni
record e aprire la form:
Public Sub ShowGestCertificati(MySQL As String)
On Error GoTo GestErr
Dim rsSaldi As Recordset
    Set rsSaldi = gDBcert.OpenRecordset(MySQL, dbOpenSnapshot)
    If rsSaldi.RecordCount > 0 Then
        ....
    End If
    frmCertificati.Show vbModal
Exit Sub
GestErr:
    MsgBox Err.Number & ":" & Err.Description, vbOKOnly + vbCritical,
"Classe: clsTrasf"
End Sub
SubApriCertificato()
Da un progetto EXE richiamo la DLL ActiveX così:
Dim MyForm As New Certificati.clsCertificati.
    MyForm.ShowGestCertificati strSQL
    Set MyForm = Nothing
End Sub
Fin qui tutto ok ma la cosa che mi sembra strana è che se richiamo
successivamente la Sub ApriCertificato, la Sub Main del progetto ActiveX non
viene richiamata e il programma esegue come prima istruzione
ShowGestCertificati.
Sono io che con il freddo di questi giorni mi stò rincogl.... oppure mi sono
perso qualche cosa?!
Ciao, Vincenzo

 ha scritto nel messaggio news:35p8h0F...@individual.net...

Negli activex la sub main non si usa mai: devi solo scrivere
sub main
end sub
lasciandola vuota;
Devi invece aggiungere una sub public del tipo "InitDLL" o qualcosa di simile
da chiamare ad ogni nuova istanza dell'asctivex prima di chiamare "ApriCertificato";
nella dichiarazione delle routine bisogna tenere presente la differenza tra "private", "public" e "friend"
e la visibilità (scope in inglese) delle variabili o proprietà dell'oggetto istanziato.
bye bye by salclem2
--
Meglio una Gallina domani che un Uovo oggi!!

 --
Grazie.
Ciao, Vincenzo

 istruzione ShowGestCertificati.
Credo sia normale nei progetti di tipo ActiveX, e per questo motivo dovresti 
evitare di utilizzare Sub Main.
Lascia pure impostato l'oggetto di avvio a "(nessuno)" e richiama la tua 
funzione di inizializzazione all'interno di ogni Class_Initialize delle sole 
classe creabili (per quelle PublicNotCreatable non e' necessario, perche' 
per forza e' stata creata prima un istanza di una classe MultiUse/SingleUse)
Eventualmente definisci un flag globale per indicare se l'inizializzazione 
e' giua' stata fatta, in modo da non ripeterla se hai piu' oggetti creati in 
sequenza; questo in particolare e' utile nei progetti ActiveX EXE di tipo 
"misto" (che possono cioe' essere usati come programmi stand alone ma anche 
richiamati esternamente): in questo caso devi definire anche Sub Main, per 
la modalita' stand alone e sia questa sia i Class_Initialize richiameranno 
la vera funzione di inizializzazione, ma una volta sola a seconda di chi 
arriva per primo.
Alla fine dei conti e' comunque un aggiustamento da pochi minuti...
Ciao
-- 
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown 

 > Progetto DLL ActiveX composto da:
[CUT]
Grazie anche a te Luca. Avevo già risolto con l'aiuto di Salclem2.
Si, in effetti è stato un aggiustamento di 2 minuti!
Ciao, Vincenzo

 lasciandola vuota;
Questa è un'affermazione un po' forte :)
E infatti mi trovo in disaccordo.
Spesso è molto utile utilizzare la sub Main degli ActiveX, per inizializzare
informazioni che poi perdureranno per tutta la vita del progetto.
Nella fattispecie non è questo il caso.
Ciao
--
Qualunque mentecatto può scrivere codice che un computer possa capire.
I buoni programmatori scrivono codice che gli uomini possano capire.
[Martin Fowler]


Occhio che pero' lui suggeriva una routine pubblica da far invocare 
manualmente al client come prima cosa, io parlavo di una funzione privata da 
chiamare solo internamente.
Io preferisco la seconda, che rende la DLL autonoma, ma vedi tu come 
regolarti.


 ha scritto nel messaggio news:35pkucF...@individual.net...

Sono parzialmente d'accordo con Luca.
Mi sembra che sia meglio settare i valori di default e basta nella routine
di inizializzazione di un oggetto (mi riferisco alla Class_Initialize);
quando occorre invece fargli fare un'azione specifica, cioè
qualcosa di avanzato tipo aprire un database, è più pulito inizializzare
con una routine apposta (anche pubblica) perchè lo sviluppatore sa
cosa fargli fare e quando, specialmente quando un oggetto è in grado
di compiere diverse azioni e, in base all'azione attuale so che debbo
inizializzare solo una certa cosa e non altre.
bye bye by salclem2
--


 E infatti mi trovo in disaccordo.
la mia affermazione (che dici essere "un po' forte") deriva dal fatto
che la sub main non viene eseguita in ogni circostanza (nelle dll activex)
e quindi può anche essere esclusa del tutto; invece nel caso di EXE activex
mi pare di ricordare che è opportuno dichiarare la sub main anche se poi la
si lascia vuota.
mi sbaglio?


 mi sbaglio?
Queste mi sembrano affermazioni da "smanettone" (sai, ormai mi sto abituando
a frasi del tipo
"
- facciamo così perchè sennò non funziona
- ma non ha senso, perchè?
- boh.
")
A cosa serve dichiarare una sub se poi la si lascia vuota?
E che cos'è una "circostanza"?
Gli ActiveX vengono caricati in memoria al primo accesso al progetto e in
quell'occasione viene eseguita, se è indicata come oggetto di avvio, la sub
main.
Poi la loro vita prosegue fino alla chiusura dell'applicazione.


 inizializzare solo una certa cosa e non altre.
Personalmente delegherei il problema a una classe specifica.
mmm... mi viene un motto: "ogni problema alla sua classe, una classe per
ogni problema". :)
