Newsgroup: it.comp.programmare.win32
Titolo: UpdateData da un thread

NT4 VC++5.
Ho un Dialog associato ad operazioni molto pesanti che non
si ridisegna, per cui chiamo un therad parallelo e li
eseguo le operazioni pesanti (questo per consentire che
il dialog si ridisegni quando altre finestre lo coprono).
Questo funziona benissimo.
Oggi pero` vorrei chiamare la UpdateData nel thread, tramite
un puntatore. Ma questo mi procura solo noie, perche`
ricevo sempre delle eccezioni al momento della chiaata!!!!
Come posso fare ad aggioranre gli edit sul dialog quando
la stringa associata a loro cambia????
Ciao e grazie.
Michele.

la stringa associata a loro cambia????
Posti uno o piu' messaggi definiti da te nella coda del thread UI con
::PostThreadMessage. Sul Richter ("Programmazione avanzata in windows")
dovresti trovare maggiori dettagli, se non ricordo male. Ho comunque
utilizzato questo metodo in un programma che funziona ininterrottamente da
mesi.
Ciao
Gian Michele Bertoni
homepage: 
http://space.tin.it/computer/gbertoni

...


Va bene qualsiasi messaggio???
Se non ho capito male, tu hai un thread UI che si occupa del Dialog (e'
quello di "default" creato dal processo) e un thread che hai creato per fare
delle elaborazioni "parallele". All'interno di quest'ultimo thread cambiano
delle variabili che dovrebbero riflettersi su degli elementi dell'UI.
Ipotizziamo una comunicazione monodirezionale dal "worker thread" al thread
UI.
Bene, con  ::PostThreadMessage puoi inviare al thread UI un messaggio
(qualsiasi) con lo scopo di far aggiornare l'UI. Se guardi bene il flusso
del programma ti devi assicurare che non ci possa mai essere accesso
contemporaneo a delle zone di memoria da parte dei due thread. Quindi,
mettiamo che il "worker thread" aggiorni una stringa: devi essere sicuro che
il thread UI non acceda alla stessa stringa. Il che puo' avvenire o perche'
il flusso del programma non lo consente o perche' usi le sezioni critiche o
altri sistemi (p.e. metti in pausa il "worker thread" con degli eventi o dei
semafori). In ogni caso, una volta che ti sei assicurato che i due thread
non accedono alla stessa variabile, mandando un messaggio dal "worker
thread" fai in modo che sia il thread UI a compiere tutto il lavoro per
mostrare il contenuto di quella variabile senza incasinare tutto (come ho
gia' detto, possono esserci dei problemi ad accedere a zone di memoria nello
stesso momento).
La materia e' indubbiamente un minimo complicata. Se vuoi adottare queste
tecniche DEVI procurarti il Richter altrimenti rischi di perdere un sacco di
tempo in tentativi che magari ti danno solo l'illusione di funzionare.
Spero di esserti stato utile


Ho capito.
La teoria l'ho senz'altro capita.
Ora mi naca la pratica, ma mi rendo conto
che sto chiedendo troppo.
Ma sicome chiedere e` lecito, e rispondere e` .....
Mi definisco un messaggio:
       #define NULL_MESSAGE      WM_USER + 1
poi nella InitDialog assegno il valore di una
variabile globale:
       dwUIThread = GetCurrentThreadId();
poi nel thread di calcolo, dopo aver modificato le
variabili membro del dialogo, faccio:
       ::PostThreadMessage (dwUIThread, WM_USER, 0, 0);
(Ti assicuro che non c'e` conflitto sulla memoria).
Ma il dialogo non si aggiorna.
Penso perche` non viene gestito il WM_USER+1.
Ma come posso gestirlo??
Dico bene?
Ciao e grazie smisuratamente.
Michele.

Dico bene?
Ottimo! Per aggiungere messaggi definiti da te il metodo e' il seguente (ed
e' piuttosto manuale):
1) Nella dichiarazione della classe derivata da CDialog inserisci i
prototipi delle funzioni che gestiranno i tuoi messaggi:
 // Generated message map functions
 //{{AFX_MSG(CTuoDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnAggiornaUI(); // questa e' la tua funzione !!!
 //}}AFX_MSG
2) Nell'implementazione aggiungi i tuoi messaggi
BEGIN_MESSAGE_MAP(CTuoDlg, CDialog)
 ON_MESSAGE(NULL_MESSAGE, OnAggiornaUI)
 //{{AFX_MSG_MAP(CTuoDlg)
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
3) Intercetti (se necessario) i tuoi messaggi nella PreTranslateMessage:
BOOL CTuoDlg::PreTranslateMessage(MSG* pMsg)
{
 // TODO: Add your specialized code here and/or call the base class
 if (pMsg->message == NULL_MESSAGE)
    {
        // Call the function to handle this message
  OnAggiornaUI();
        // Tell MFC no more processing is needed
        return TRUE;
 } else {
        // Call MFC to have it continue processing the message
        return CDialog::PreTranslateMessage(pMsg);
 }
}
4) Implementi CTuoDlg::OnAggiornaUI()
Ciao


Michele.
Saluti
  Mardy
--
Per rispondere, togliere NVN dal mio indirizzo.
Usare sempre e comunque la massima cortesia.

Grazie 1000 a tutti.
Sono riuscito con un SendMessage, che aspetta fino a
quando non e` stato processato il messaggio.
Michele.