PDA

View Full Version : [VB6] Creazione PlugIn per Applicazioni


leadergl
04-07-2005, 22:04
Raga mi chiedevo se era possibile, ma penso di si, e come si faceva a creare:

1) Una applicazione che potesse essere aspandibile tramite plugin
2) creare plugin per un'applicazione

questo in VB6...non riesco a trovare info su internet...qualcuno ne sa qualcosa?

matpez
04-07-2005, 22:22
Bhe i plug in sono a volte solo delle dll aggiunte che il software riconosce e aggiunge una funzione nel menu... tanto un dll può contenere tutte le cose che contiene un normale progetto per exe, quindi anche le form.

leadergl
04-07-2005, 22:53
e da queste DLL posso far richiamare funzioni che si trovano in altre dll che usa il mio progetto normalmente senza dichiarare nessuna nuova referenza?

matpez
05-07-2005, 09:13
Sinceramente nn ho mai provato a richiamare un dll dentro un'altra dll... fai delle prove e poi fammi sapere...

leadergl
05-07-2005, 12:08
Matpez tu che te ne intendi...sarebbe possibile creare un programma che si "autoespande"?

Una sorta di plugin...ma è diversa la mia idea..tipo un programma che legge da un file di testo delle righe di codice:
if a>b then ...
e le aggiunge al suo codice originario?

nn so se mi son spiegato bene...

matpez
05-07-2005, 12:16
Al suo interno no, perchè dovresti ricompilarlo con il nuovo codice..

...io ho visto i plug in di nero usano delle dll, poi al suo interno va a sapere cosa richiamano, ma sicuramente le form che compaiono dopo aver messo il plug in

leadergl
05-07-2005, 12:20
come facci a far partire la form che sta in un plugin?

tipo io creo una DLL PLUGIN che contine:
FORM
MODULO (è un modulo base che mi serve x l'interfacciamento con un'altra dll che mi permette di collegarmi ad una periferica usb)

ora come faccio dal mio programma a far partire la form di quella DLL?

So come far creare un nuovo menu nel mio programma dove compare, nella lista del menu, il nome per richiamare quella dll...a questo ci posso arrivare :D ...ma poi come faccio a dirgli di far partire la form di quella dll plugin?

matpez
05-07-2005, 12:48
Bhe ma tu devi già prevedere che la tua applicazione avrà dei plug-in, poi il meno lo visualizzi o no a seconda se trovi la dll

Per visualualizzare una form basta che rischiami una funzione del tuo modulo che abbia il comando frmxxx.show

leadergl
05-07-2005, 13:15
Bhe ma tu devi già prevedere che la tua applicazione avrà dei plug-in....

in che senso?

Per visualualizzare una form basta che rischiami una funzione del tuo modulo che abbia il comando frmxxx.show

ah ecco..giusto :p

Brigante
05-07-2005, 14:21
Infatti potresti aggiungere nuove dll che contengono nuove funzioni per il programma, ma come è stato giustamente detto, il programma deve essere stata progettato per ricevere plugin, in modo da poter effettuare le chiamate alle nuove funzioni.

leadergl
05-07-2005, 14:58
Infatti potresti aggiungere nuove dll che contengono nuove funzioni per il programma, ma come è stato giustamente detto, il programma deve essere stata progettato per ricevere plugin, in modo da poter effettuare le chiamate alle nuove funzioni.

eh questo l'ho capito ma questa parte
il programma deve essere stata progettato per ricevere plugin
in pratica in cosa si tradurrebbe?

gli faccio fare la ricerca di tutti i files in una dir e li aggiungo ad un menu? (menu che quindi avra una determinata index...a seconda del numero di elementi e poi faccio tipo:

Private Sub mnuPlugIn_Click(Index As Integer)
'considerando che tutti i plugin avranno un modulo comune
'dove ci sta la funzione "InizializzaForm"

'...che ci metto qui...


End Sub

come lo rendo "PlugIn Ready" :D ?

leadergl
05-07-2005, 15:14
allora...mi sto mentalmente avvicinando...
mi servono:

1) una struttura che mi consenta di salvare alcune informazioni sul PlugIN che sto aggiungendo...tipo:
Type PLUG_STR
Plugin_Path as string
Plugin_Name as string
End Type
così so da dove prendere quel PlugIN
2) un array del tipo PLUG_STR dove conservare le info per ognuno dei plugin trovati
3) una procedura/funzione che quando clicco sull'elemento del menu che verrà creato ed associato all'elemento nell'array di prima mi permetta di creare una referenza al PlugIN giusto...una cosa del tipo:
Public Function CreaReferenza(indice: integer)
...e qui dentro creo la referenza...
...posso creare la referenza ad una dll da qui?...

normalmente per creare una referenza si fa, ad esempio:

Public NUOVADLL as New NOMEREFERENZA

ma in questo caso come si fa?

matpez
05-07-2005, 18:31
Ecco a te un bel esempio.. miraccomando segui quello che ti dico:

La cartella Exe contiene tutto quello che serve a te, prima di tutto come qlc ActiveX che si rispetti lo devi registrare, quindi trascina la dll sopra a regsvr32

Una volta fatto questo ricorda che la registrazione viene fatta nella path in cui sti trova, se sposti la path, rinomini o fai cose varie va riregistrata...

A questo punto, prendi la dll e la metti dove vuoi tu, magari sul desktop, lasciando l'eseguibile senza la sua dll... lancialo e premi il bottone, dovrebbe segnalarti un messaggio di errore, cioè che nn trova il tuo plug-in ...

Adesso chiuedi tutto, metti la tua dll assieme all'exe e lo rilanci, premendo sul pulsante si aprirà una form completamente a se stante dal progetto, unica caratteristica che si chiude con la form che lo ha lanciato (giustamente)


Fai queste prove e poi guarda i sorgenti, così ti fai un idea più chiara di tutta la faccenda! :Prrr:

leadergl
05-07-2005, 20:20
come al solito impeccabile :D

sei un mito...grazie a te ho imparato tante cose sul VB :D

(P.S. x caso hai un cellulare motorola? se si...dammi sta soddisfazione...vedi i miei progressi in VB6..vai su http://www.leadergl.net e scaricati il FlexEditor 9.5F ...mi piacerebbe sapere che ne pensi :D )

leadergl
05-07-2005, 22:32
Matpez ho problemi con la compilazione del codice....nel senso che nn riesco a creare l'exe...mi dice libreria non trovata...

inoltre come faccio nel caso in cui ho più PlugIn? Tu hai impostato:

Dim mcPlugIn As Plug_In.Class1


Set mcPlugIn = New Plug_In.Class1
Call mcPlugIn.EditaLabel
Set mcPlugIn = Nothing

ma come faccio a sapere se il nome assegnato al plugin è proprio "Plug_In"? se l'utente gli da un nome differente?

matpez
05-07-2005, 22:49
Bhe, inanzitutto per compilare devi impostare nelle referenze le dll usate dal tuo programma, poi come seconda cosa per impostare + plugin basta che fai + dll hehehe :ciapet:

Per quanto riguarda il nome, di solito un utente non dovrebbe toccare i nomi dei componenti di un programma, ma tanto la dll anche se si chiama con un nome diverso, lui usa il nome dell'applicazione con cui hai compilato la dll. :Prrr:

Per il resto, come ti avevo già detto, fai un pochettino di prove, paciocca un pochetto, fai tentativi, altrimenti ci sentiamo domani per ulteriori informazioni :)

Notte :oink:



PS: pultroppo ho tutti sony-ericsson :cry:

matpez
05-07-2005, 22:53
Forse io ho corso troppo, ma tu hai mai creato una dll, sai cos'è la compatibilità binaria?

Va bhe, cmq se nn lo sai te lo dico domani, adesso sono stanco e domani si lavora tutto il giorno attaccato a sto piffero di VB ehehhehe :cool:

byebye

leadergl
05-07-2005, 22:56
Forse io ho corso troppo, ma tu hai mai creato una dll, sai cos'è la compatibilità binaria?

Va bhe, cmq se nn lo sai te lo dico domani, adesso sono stanco e domani si lavora tutto il giorno attaccato a sto piffero di VB ehehhehe :cool:

byebye


si, creato Dll....ma non so cosa sia la "compatibilità binaria" o magari non so che si chiama così...ok...domani mi illumini ;) :p

matpez
06-07-2005, 08:00
La compatabilità binaria è quella compilazione che ti permette di mantenere la compatibilità con la dll che avevi fatto prima.

La compatabilità binaria ti permette di non dovere tutte le volte ricreare l'eseguibile che utilizza la tua dll, altrimenti che caxxo serve avere una dll? heeheh

Per esempio se tu nella dll avessi tutti i calcoli per un software che fa paghe, poi esce l'euro e tu senza sbatterti più di tanto a ricompilare tutti i sorgenti di chissà quanti programmi, basta che ricompili la dll con la dovuta conversione in euro. Ma se nn avessi la compatibilità allora il lavoro sarebbe vano, perchèi tuo exe non ti riconoscerebbero più la libreria.

Per parlare un po' più tecnicamente, tu sai che nel registro ci sono degli identificativi di classe, quelli che sono fatti così: {000214EE-0000-0000-C000-000000000046}, praticamente quello è un identificativo che gli oggetti come le dll creano al momento della registrazione tramite il regsvr32 o tramite il setup del tuo software quando registra i componenti.
Se tu non hai la compatibilità lui ogni volta che compili ti ricrea un CLSID e quindi il tuo exe non trova il riferimento nel registro, se tu hai la compatibilità (dove possibile) lui riutilizza lo stesso CLSID e quindi i tuo exe sia da te che dall'utente funzionano dandogli la tua dll aggiornata e senza nemmeno avere più il bisogno di registrarla.

Detto questo che è solo un aiuto per utilizzare le dll, cerca di fare funzionare e di capire il mio esempio, dato che da me funziona e poi se hai altri dubbi gli esponi.

ciaoooooooooooooo :p

leadergl
06-07-2005, 08:34
Ottima informazione...mi hai fatto scoprire una cosa nuova :D

Ed ho anche compilato il tuo progetto...solo che rimane la domanda:
1) "nel caso chi crea la DLL cambia il nome del progetto come faccio a farla identificare dal programma?"

2) (poi ci sarebbe questa) io vorrei fare una cosa di questo tipo:
<ul type=disc><li>Analizzo la directory "Plugin" in cerca delle DLL
<li>A seconda del numero di DLL creo un menu dinamico che mi contenga un nome (diverso) per ogni DLL
<li> Quando uno clicca sul nome della DLL si apre la form corrispondente
</ul>

ecco quello che mi chiedo è...avendo tutti nomi uguali come faccio a distinguere le varie dll?

matpez
06-07-2005, 09:05
Ma è qui che ti sbagli, sbagli il modo di pensare...

Una dll di quel genere è un ActiveX, e quindi va registrata e quindi già non pottresti basarti sul fatto di cercare le dll come se fossiano file, perchè nn si comportano come file.

Come già detto, il tuo programma già deve supportare tutti i tuoi plug-in, o almeno mettendola più facilemente, devi già prevedere quanti plug in vuoi fare, poi che li fai piano piano dopo che l'exe è già sul "mercato" è un altro conto. Ma quando fai un software c'è sempre un analisi, non si comincia mai scrivendo la prima riga e poi pensando alla cosa da fare dopo, ma bisogna sapere ed avere un percorso ben preciso per fare un bel lavoro, in meno tempo e soprattutto più ottimizzato.

Quindi tu devi giocare sul fatto che ti dia errore quando istanzi il tuo plug-in, li fai quello che vuoi, puoi nascondere il menu volendo, ma il tuo menu è già stato progettato con il codice per lanciare il tuo plug-in.

Tornando alla tua prima domanda, il nome della dll è un bel problema! Dentro a VB lui prende il nome dell'Applicazione che gli hai impostato alla tua dll, e quindi dentro a VB lo sai che si chiama come hai impostato tu, es: Plug_In ... e quindi li nn è un problema, il problema ma li nn ci puoi fare NULLA è che se un pirla ti rinomina, elimina o sposta una dll dalla tua cartella dove l'hai posizionata il tuo programma nn avrà più il plugin, ma se ci pensi bene, se cancelli una dll di sistema da system32, nn so poi se ti parte più il pc senza dare nessun problema. :oink:

leadergl
06-07-2005, 14:37
una domanda...programmi come ad esempio FireFox che permettono di estendere le loro funzionalità tramite plugin funzionano molto più dinamicamente o mi sbaglio?

non credo ci sia una limitazione sul numero di plugin caricabili o sul nome da dargli...io vorrei una cosa tipo quella ma che quando poi eseguo la plugin mi si apre una sorta di programma a parte, come hai fatto tu con la form....

è possibile arrivare ad una cosa del genere?

matpez
06-07-2005, 18:39
Bhe questo nn lo so, ma sicuramente FF nn è fatto in VB :)


PS: ma dove si caricano i plugin in firefox ?

leadergl
06-07-2005, 21:14
Bhe questo nn lo so, ma sicuramente FF nn è fatto in VB :)

PS: ma dove si caricano i plugin in firefox ?

qui: https://pfs.mozilla.org/plugins/

71104
06-07-2005, 23:16
ecco quello che mi chiedo è...avendo tutti nomi uguali come faccio a distinguere le varie dll? il fatto è che sti plugin li devi caricare a runtime con LoadLibrary e GetProcAddress, anche perché se non fai così il tuo programma non è realmente espandibile perché le dll che carica sono sempre le stesse; se invece le carichi con LoadLibrary hai la possibilità di fare un algoritmo che (ad esempio) carica tutte le dll che trova in una apposita directory per i tuoi plugin, così ogni volta che installi un nuovo plugin nella dir (cioè semplicemente ce lo copi) non appena avvii il programma ce l'hai dentro.

leadergl
07-07-2005, 07:20
il fatto è che sti plugin li devi caricare a runtime con LoadLibrary e GetProcAddress, anche perché se non fai così il tuo programma non è realmente espandibile perché le dll che carica sono sempre le stesse; se invece le carichi con LoadLibrary hai la possibilità di fare un algoritmo che (ad esempio) carica tutte le dll che trova in una apposita directory per i tuoi plugin, così ogni volta che installi un nuovo plugin nella dir (cioè semplicemente ce lo copi) non appena avvii il programma ce l'hai dentro.

diciamo che un piccolo esempio non guaterebbe :D

Mi son letto cosa fa ognuna di queste due API:

LoadLibrary
The LoadLibrary function maps the specified executable module into the address space of the calling process.

VB4-32,5,6
Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long



Parameter Information

· lpLibFileName
Points to a null-terminated string that names the executable module (either a .DLL or .EXE file).


mentre l'altra:

GetProcAddress
The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.

VB4-32,5,6
Declare Function GetProcAddress Lib "kernel32" Alias "GetProcAddress" (ByVal hModule As Long, ByVal lpProcName As String) As Long


Parameter Information

· hModule
Identifies the DLL module that contains the function. The LoadLibrary or GetModuleHandle function returns this handle.

· lpProcName
Points to a null-terminated string containing the function name, or specifies the function’s ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.

Return Values
If the function succeeds, the return value is the address of the DLL’s exported function.

ora come faccio ad usare questo per poi eseguire la mia dll?

71104
07-07-2005, 15:05
con LoadLibrary carichi la dll nel tuo processo (ti viene restituito un HMODULE, corrispondente al suo base address); con GetProcAddress invece ottieni un puntatore ad una sua funzione: GetProcAddress prende in ingresso l'HMODULE che identifica la tua dll e il nome della funzione che vuoi caricare (se la dll è scritta in C++ occhio alla decorazione dei nomi). se ad es. stabilisci che i tuoi plugin devono esportare una funzione che si chiama "PluginEntry" (nome inventato), basta che dopo aver caricato la libreria con LoadLibrary chiami GetProcAddress passandogli l'HMODULE che hai ottenuto e "PluginEntry", e ottieni l'indirizzo della funzione PluginEntry pronta da chiamare.
per caricare numerosi plugin leggendoli da una directory basta che fai ad esempio un array di strutture dati ognuna delle quali contiene l'HMODULE del plugin caricato e l'indirizzo della PluginEntry; le dimensioni dell'array corrispondono semplicemente al numero di plugin validi contenuti nella apposita directory, quindi direi che l'array deve crescere dinamicamente a mano a mano che carichi sti plugin. l'esempio te lo posso fare solo in C, o al limite in Pascal: io di BASIC conosco solo il QBasic :D

leadergl
07-07-2005, 16:05
L'esempio in C mi sta bene...quello che non capisco è come fare ad esare il "puntatore" che mi viene restituito dalla procedura "GetProcAddress".

GetProcAddress ha in uscita un valore LONG...come lo uso? mi serve un altra funzione a cui passare questo valore e che mi esegue la funzione della mia DLL?

leadergl
07-07-2005, 16:23
AHHHH forse ho capito...allora...vediamo un po!

Prima, ad esempio in un modulo, dichiaro una procedura tipo le chiamate alle API di Windows in questo modo:

Private Declare Function AvviaPlugIN Lib "miaDll" Alias "AvviaPlugINA" (variabili) As Long
poi tramite le funzioni:

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long

posso verificare se quella funzione (AvviaPlugIN) è realmente presente nella mia dll e se presente mi basterà fare:
AvviaPlugIN
ed automaticamente partirà il tutto.

Il problema potrebbe essere nel nome della DLL ma questo lo potrei ricavare dal nome fisico della mia DLL giusto?

Il secondo problema verrebbe che in questo modo avrei una sola DLL caricabile a meno che non creo una procedura dove metto la dichiarazione della funzione...(sempre se si può fare) tipo:

Public Sub AvviaDLL(nome_dll as string)
Dim esiste_funct as boolean

Private Declare Function AvviaPlugIN Lib nome_dll Alias "AvviaPlugINA" (variabili) As Long

Esiste_funct=...chiamo la procedura che verifica l'esistenza...
if esiste_funct then AvviaPlugIN
End Sub
l'errore che posso ricevere da questa procedura è che dichiaro più volte la stessa funzione...ma credo sia risolvibile con un "On Error Resume Next"...oppure una volta avviata la funzione dovrei eliminare dalla memoria la sua dichiarazione....è possibile?

ditemi se mi sto avvicinando...

Questa la funzione per verificare l'esistenza di una funzione in una dll:

Private Function Esiste_funct(ByVal ModuleName As String, ByVal ProcName As String) As Boolean
Dim hModule As Long
Dim lpProc As Long
Dim FreeLib As Boolean

'carichiamo il modulo
hModule = LoadLibrary(ModuleName)
FreeLib = True

'se il modulo è caricato allora verifichiamo
'se la procedura esiste
If hModule Then
lpProc = GetProcAddress(hModule, ProcName)
Esiste_funct = (lpProc <> 0)
End If

'scarichiamo la libreria dalla memoria
If FreeLib Then Call FreeLibrary(hModule)
End Function

leadergl
07-07-2005, 16:34
tra le altre cose posso anche dichiarare:
Private Declare Function AvviaPlugIN Lib "miaDll.dll" Alias "AvviaPlugINA" (variabili) As Long

quindi risolverei un problema...

rimarrebbe questo:
l'errore che posso ricevere da questa procedura è che dichiaro più volte la stessa funzione...ma credo sia risolvibile con un "On Error Resume Next"...oppure una volta avviata la funzione dovrei eliminare dalla memoria la sua dichiarazione....è possibile?

xkè nn sono troppo sicuro che si possa fare come ho detto nella parte evidenziata...

leadergl
08-07-2005, 13:06
ehi mi sto avvicinando?

71104
08-07-2005, 14:08
ehi mi sto avvicinando? ehm, non lo so se ti stai avvicinando perché sei andato in 70mila direzioni diverse :D
cmq tornando alla GetProcAddress: non ti era chiaro come dovevi usare il risultato; be', fisicamente devi solo usarlo in una CALL, quel LONG contiene l'indirizzo della funzione che devi chiamare; memorizzalo in un puntatore a funzione con un cast e poi chiama la funzione tramite il puntatore. più chiaro di così... :mc:

leadergl
08-07-2005, 14:51
ehm, non lo so se ti stai avvicinando perché sei andato in 70mila direzioni diverse :D
cmq tornando alla GetProcAddress: non ti era chiaro come dovevi usare il risultato; be', fisicamente devi solo usarlo in una CALL, quel LONG contiene l'indirizzo della funzione che devi chiamare; memorizzalo in un puntatore a funzione con un cast e poi chiama la funzione tramite il puntatore. più chiaro di così... :mc:


con codice pratico si farebbe come? :D

leadergl
09-07-2005, 09:06
la GetProcAddress mi restituisce sempre 0...xkè?
l'altra invece mi da un valore...