Newsgroup: it.comp.programmare.win32
Titolo: thread e MFC

Come si usano i thread con le MFC ?
Volevo fare una cosa del tipo seguente (refresh automatico):
  - apro una finestra di dialogo modale che presenta alcuni pushbutton.
  - uno di questi fa aprire una ulteriore dialog box (modeless)
    che mostra i dati in arrivo  dalla seriale.
Avevo pensato di creare un thread che legge dalla seriale e invia cio' che
legge alla dialog box modeless.
Pero' sembra che il corpo del thread debba essere una funzione  C e non
un membro di una classe. Ho provato a "fare il furbo" con
una cosa del tipo seguente
void CMyCOMM2Dlg::OnCom2() //chiamata alla pressione di un
                            //pushbutton
{
	// TODO: Add your control notification handler code here
	if(!commPorts[COM2]) commPorts[COM2]=new RS232(this);
     _beginthread(DisplayCommData,8192,commPorts[COM2]);
 
}
commPorts e' un array di puntatori a
RS232 (la classe associata alla finestra di dialogo
che mostra i dati dalla seriale). All'interno
del costruttore di RS232 ci sono la Create e la ShowWindow.
Il codice di DisplayCommData e'
void DisplayCommData(void *RS232Win){
	RS232 *winToBeRendered=(RS232 *)RS232Win;
     winToBeRendered->RetrieveData();
}
RetrieveData e' una funzione del tipo sotto riportato
void RS232::RetrieveData()
{
         <rintraccia dati dalla seriale>	
     	UpdateData(FALSE);
}
Il problema e' che fallisce una assert, ovvero la
		ASSERT(pMap != NULL);
in CWnd::AssertValid()
Invece se la chiamata a RetrieveData la metto direttamente
in RS232::OnCom2, non ci sono problemi, pero' per
fare un refresh devo premere il bottone.
Qualche suggerimento ?
Grazie,
Marco Guidi

 un membro di una classe.
Esatto. In genere il sistema utilizzato per aggirare il problema č passare
come parametro al thread il puntatore alla classe e dichiarare la funzione
del thread come friend all'interno della classe per permettergli di accedere
ai dati membro della classe.
Lorenzo

Per il passaggio del puntatore ok, ma che la funzione sia friend no!!
dichiarando la funzione friend si ottiene un accoppiamento elevato con
il rischio di dover riscrivere la funzione ogni volta che cambia la
struttura interna della classe cui questa e' legata (una Dialog in
questo caso).
Se si vuole fornire un accesso controllato ai membri di una classe
bisogna, in generale, scrivere le due funzioni Get/Set di modo da
permettere di leggere/assegnare i valori al membro lasciando alla
classe stessa il compito di reperire e maneggiare l'informazione.
Pare che con Visual Studio.NET, il Visual C++ verra' arricchito da
alcuni costrutti atti a semplificare questo meccanismo grazie
all'introduzione del concetto di proprieta', caratteristica presente
da tempo nel mondo VCL.
Ciao, Davide.

 da tempo nel mondo VCL.
a propo' di proprietaa......
non so se hai letto il thread "come si fa il casting da un
puntatore_a_metodo a un'altro?" del 23*06*2001 20.06 su
it.comp.lang.c++ (dubito, l'ultimo post risale ad aprile... :-)) ma
io mi sto scannando per inventare un sistema simile.
come si può fare con il C++ (con MSVC++)?
le VCL usano il C++ standard o si aiutano con qualche sotterfugio
interno del compilatore?
pleaze help me >:o)
ciao
xaero

 da tempo nel mondo VCL.
a propo' di proprietaa......


E' passato un po di tempo da quando usavo Delphi, attualmente non l'ho
nemmeno sotto mano, per cui non posso andare a curiosare nei
sorgenti... :.-((
in Delphi, e' possibile scrivere una "procedure" ed associarla ad una
classe dicendo che si tratta di una "procedure of object"
il modificatore "of object" dice al compilatore di generare una member
finction piuttosto che una funzione spaiata.
Come sai bene, la principale differenza tra una funzione membro ed una
normale funzione e' che la prima possiede un parametro implicito che
rappresenta un puntatore all'istanza della classe sulla quale viene
chiamata (this), mentre la seconda no.
Nel mondo Delphi, esiste il concetto di TMethod,, ovvero le
funzioni/procedure "of object" sono talmente tipizzate che e'
possibile vederle come TMethod.
il tipo TMethod, possiede due membri, sono come due puntatori, uno
punta al corpo della funzione e l'altro alla struttura dati che
contiene le informazioni accessorie non associate alle normali
funzioni.
L'idea generale e' questa.
Non ricordo con esattezza ma forse con i TMethod lavoravano grazie
anche all'RTTI, che in Delphi e' ben implementato e "wrappa" ogni
entita' fornendo per essa tutta una serie di informazioni o punti
d'accesso.
Forse ho dimenticato/sbagliato qualcosa, e' da mesi che ho lasciato
stare Delphi in favore del Visual C++.
Davide.

 questo caso).
Beh... se cambio la struttura interna della classe dovrò cambiare tutte le
funzioni membro della classe affette dalle modifiche... siccome la funzione
friend è alla stregua di una funzione membro, è corretto ed accettabile che
sia legata in profondità alla struttura della classe. Infatti la funzione
membro non dovrebbe parlare con la classe tramite la sua interfaccia, ma
dovrebbe manipolarne direttamente i dati.
Lorenzo