Newsgroup: it.comp.programmare.win32
Titolo: [VC++] Message Map

Cari lettori ho un particolare problema che non riesco a risolvere, ho
realizzato una dll che contiene alcune classi per poterle riutilizzare in
altri progetti senza prendermi la briga di portarmi dietro i sorgenti.
Premesso che le classi incluse nel progetto funzionano correttamente.
All'interno di alcune classi implemento la MessageMap attraverso
"DeclareMessageMap", che mi serve per gestire i messaggi della dialog.
Compilando la dll insieme al progetto ottengo il seguente messaggio di
errore:
error LNK2005: "protected: virtual struct AFX_MSGMAP const *
__thiscall CModelessMain::GetMessageMap(void)const "
(?GetMessageMap@CModelessMain@@MBEPBUAFX_MSGMAP@@XZ) already defined in
ImageManager.obj
In pratica sembra che la messageMap sia dichiarata più
di una volta, ma come fare ad ereditare tale mappa senza ridichiarla?
Vi
ringrazio anticipatamente.
Adriano Basile
--------------------------------
Inviato via 
http://usenet.iol.it


Forse la message map è stata definita in maniera erronea mente.
Dove è specificata la macro BEGIN_MESSAGE_MAP (nel file cpp)
le classi sono corrette ?
L'espansione dell macro è la seguente:
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
 const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \
  { return &baseClass::messageMap; } \
 const AFX_MSGMAP* theClass::GetMessageMap() const \
  { return &theClass::messageMap; } \
 AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
 { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; \
 AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
 { \
#else
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
 const AFX_MSGMAP* theClass::GetMessageMap() const \
  { return &theClass::messageMap; } \
 AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
 { &baseClass::messageMap, &theClass::_messageEntries[0] }; \
 AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
 { \
#endif
quindi stando al tuo errore tu dovresti aver dichiarato:
BEGIN_MESSAGE_MAP(CModelessMain, classse_base)
e ti ritrovi la seguente funzione:
const AFX_MSGMAP* CModelessMain::GetMessageMap() const
  { return &CModelessMain::messageMap; }
che il compilatore trova già definita nell'ImageManager.obj.
Quindi, sei sicuro di non aver sbagliato il nome delle classi nella
definizione della mappa dei messaggi ?
Non stai utilizzando calssi diverse ma assegnandogli lo stesso nome ?
E' l'unica cosa che mi viene in mente.
Ciao
Porlock

Porlock
--------------------------------
Inviato via 
http://usenet.iol.it
 


Dunque vediamo se ho capito.
1) Hai un progetto che funziona correttamente dove sono incluse tutte le
classi.
2) Vuoi togliere delle classi dal progetto per portarle in una DLL.
3) Hai fatto la DLL, ma quando compili il progetto di partenza dove hai
tolto le classi ed hai istruito il linker ad agganciarsi alla dll ottieni il
seguente errore:
error LNK2005: "protected: virtual struct AFX_MSGMAP const *
__thiscall CModelessMain::GetMessageMap(void)const "
(?GetMessageMap@CModelessMain@@MBEPBUAFX_MSGMAP@@XZ) already defined in
ImageManager.obj
Se questo è lo scenario, la cosa non torna perché il progetto originale
linka ImageManager.obj e non dovrebbe.
Piuttosto dovrebbe linkare il file punto lib della DLL (ad esempio
ImageManager.obj).
Da' un'occhiata ai settaggi del linker.
Oppure non hai eliminato dal progetto le classi che hai spostato sulla DLL.
Ciao
Porlock.

Porlock.


 scelta corretta?
Intanto che tipo di DLL hai creato ?
Per esportare classi devi creare un Extension DLL.
Questa DLL deve ovviamente includere nel progetto i files .h e .cpp relativi
alle classi.
Per rendere esportabile una classe devi (nel file .h) dichiarare quanto
segue:
class AFX_EXT_CLASS miaclasse
{
// bla bla bla bla
}
Nel progetto che andrà ad utilizzare la Dll, sarà sufficiente includere il
file .h della classe che intendi utilizzare e si dovrè inserire nella voce
sopra menzionata (Object library modules) il file .lib (con il percorso se è
necessario) della DLL.
Se la DLL si chiama miadll quando viene compilata vengono generati diversi
file tra cui:
miadll.dll che è la dll vera e propria
miadll.lib che la libreria che <spiega> cosa esporta.
E poi basta, si compila e non dovrebbero esserci errori.
Ciao
Porlock

Porlock
Tutto compreso, ma non
risolvo ancora il problema, la mia impressione è che la mappa messaggi sia
statica e quindi non derivabile attraverso la AFX_EXT_CLASS o qualcosa di
simile. Comunque ovviamente ti ringrazio per tutto l'aiuto e colgo
l'occasione per chiederti se puoi indicarmi un testo dove reperire maggiori
informazioni, io possiedo un libro Apogeo VC++, il libro Microsoft
"Programmazione Avanzata VC6" quello di Scott Wingo, ma nessuno dei due mi
aiuta nell'attuale problema.
Ti ringrazio nuovamente
Adriano


 aiuta nell'attuale problema.
Se aspetti martedì ti posso dare qualche indicazione più precisa dei libri
da cui ho iniziato.
Devo dire però che le cose più interessanti le ho imparate col debugger del
Visual C++ "entrando" direttamente nei sorgenti.
Ciao
Porlock


volevo dire:
Devo dire però che le cose più interessanti le ho imparate col debugger del
Visual C++ "entrando" direttamente nei sorgenti di MFC.
Ecco cmq i testi che ho a disposizione:
David J. Kruglinski - Inside Visual C++ - Microsoft Press
Jeff Prosise - Programming Windows 95 with MFC - Microsoft Press
Kate Gregory - Programmare in Visual C++ 4.2 - Apogeo
Sul valore di questi libri non ti so dire molto in realtà, poiché io li ho
utilizzati soprattutto come base di consultazione all'inizio del mio
apprendistato con MFC, poi li ho totalmente abbandonati.
Ribadisco che le cose più interessanti le ho imparate consultando MSDN e col
debugger del VC++ entrando nei sorgenti MFC.
Ciao
Porlock

Visual C++
"entrando" direttamente nei sorgenti.
Ti ringrazio per le segnalazioni,
ho letto i tre libri di sfuggita ma non vanno oltre quello che so fare,
anche se mi aiuterebbero ad affinare i miei sorgenti. Quello che vorrei č
capire un po' di programmazione avanzata. Ma questa č un'altra storia.
Ti ringrazio tantissimo.
Ciao 
adriano


 di una volta, ma come fare ad ereditare tale mappa senza ridichiarla?
La mappa viene ereditata senza ridichiararla, poiché la classe che eredita
CModelessMain che è CImageManagerDlg avrà
DECLARE_MESSAGE_MAP() nel file imagemanagerdlg.h
e
BEGIN_MESSAGE_MAP(CImageManagerDlg, CModelessMain) nel file
imagamanagerdlg.cpp
[CUT]
Spero che riusciamo ad arrivare alla conclusione.
Ciao
Porlock.

imagamanagerdlg.cpp
sì, ho fatto così.
Comunque dopo le estenuanti
prove, che poi sul mio pc durano anni mi sto arrendendo al fatto di copiare
i files in ogni mio progetto ed usare le classi in modo normale. Visto che
prima in quel modo funzionava.
Ti ringrazio anticipatamente, torno a
fare le ultime prove.
Ciao Adriano



Ok, spero che riusciamo a venire a capo di questo bizzarro.
Ciao
Porlock.

 
Lo spero anch'io, parecchio rassegnato ma lo spero anch'io.
Grazie Mille comunque.
Adriano