Newsgroup: it.comp.programmare
Titolo: Aiutino in Visual C++

Ciao,
per la tesi sto facendo un programma in Visual C++, non sono del settore
strettamente informatico e non riesco a fare alcune cose. Per esempio:
- fatto partire il mio programma in Visual C++, clickando su un bottone
"Avvia" si manda in esecuzione una mia routine che ci mette molto tempo per
girare. Durante l'esecuzione c'č bisogno di controllare ogni tanto se
l'utente ha clickato su un bottone "interrompi" che č sul dialog. Come posso
fare? Che funzione si usa?
- Dopo avviata la routine, se clicko sul desktop o su un'altra finestra, il
dialog del mio programma non viene piů aggiornato, cioč rimane "congelato"
allo stato in cui si trova in quel momento. Perché? Come si fa a far
aggiornare automaticamente la finestra?
Grazie mille a chi mi risponde. E' importante.
Ciao
Mauro

Mauro wrote:
 > - fatto partire il mio programma in Visual C++, clickando su un bottone
 > "Avvia" si manda in esecuzione una mia routine che ci mette molto 
tempo per
 > girare. Durante l'esecuzione c'č bisogno di controllare ogni tanto se
 > l'utente ha clickato su un bottone "interrompi" che č sul dialog. 
Come posso
 > fare? Che funzione si usa?
 > - Dopo avviata la routine, se clicko sul desktop o su un'altra 
finestra, il
 > dialog del mio programma non viene piů aggiornato, cioč rimane 
"congelato"
 > allo stato in cui si trova in quel momento. Perché? Come si fa a far
 > aggiornare automaticamente la finestra?
E' un problema ben noto, ma non c'e' una soluzione standard; soprattutto 
non c'č una soluzione preconfezionata in Visual C++.
La soluzione piu' brillante, secondo me, e' far eseguire la routine di 
elaborazione in un thread diverso da quello dell'interfaccia utente. Una 
variante di questa soluzione consiste nel far eseguire la routine di 
elaborazione a un processo diverso da quello dell'interfaccia utente.
Queste soluzioni, tuttavia, sono di complessita' eccessiva per chi non 
sia a conoscenza delle problematiche della programmazione concorrente.
Una soluzione piu' abbordabile consiste nella cosiddetta pompa di 
messaggi secondaria ("secondary message pump").
In ambiente Microsoft Windows, consiste nel chiamare periodicamente 
PeekMessage per controllare se sono arrivati messaggi nella coda. Se e' 
arrivato un messaggio, questo va smistato alla finestra di competenza, 
che lo elaborera'.
La routine associata al pulsante "interrompi" impostara' un flag.
Tale flag deve essere controllato nella routine di elaborazione.
Il codice da usare e' il seguente:
#include <windows.h>
// Nelle dichiarazioni.
bool interrupted = false;
MSG msg;
HWND hwnd;
// Dentro un loop non troppo stretto.
if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
   if (interrupted) return;
}
// Nella routine associata al pulsante "interrompi".
interrupted = true;
Un problema consiste nel fatto che la chiamata a PeekMessage pur 
richiedendo un tempo brevissimo per un essere umano, dell'ordine del 
microsecondo, richiede un tempo enorme per una CPU d'oggigiorno. Quindi 
se la chiamata viene fatta troppo spesso, rallenta il programma.
Inoltre, tutti i comandi che non risultano compatibili con 
l'elaborazione devono essere disabilitati o comunque non devono agire.
Spero sia d'aiuto.
-- 
	Carlo Milanesi
 
http://digilander.libero.it/carlmila

 non c'è una soluzione preconfezionata in Visual C++.
