Newsgroup: it.comp.lang.c++
Titolo: DoEvents in C++ ?

Buongiorno,
sono un neofita del c++
per cui abbiate pazienza se la mia domanda è banale :
Da quanto ho capito, per attivare le funzioni presenti nella MESSAGE_MAP è
necessario uscire da ogni altra funzione restituendo così il controllo al
sistema.
Purtroppo, in certi casi, il fatto di non poter lasciare 'in sospeso' una
situazione complica parecchio l'impostazione del programma;
per cui vi chiedo :
Esiste in c++ un modo per intercettare eventi restando all'interno di cicli
e funzioni ??
Grazie

e funzioni ??
Da quanto credo di capire, il tuo ambiente di lavoro è: VC++/ MFC/Win.
In tal caso, all'interno del ciclo (o della funzione) potresti inserire una chiamata a
Sleep().
Di seguito posto la documentazione relativa. Essendo una tecnica comunemente usata in
Windows, può essere utile ad altri. Ad ogni modo, domande su una specifica piattaforma
andrebbero fatte su NG specifici di quella piattaforma. Avrai maggiori possibilità di
ottenere risposte ai quesiti.
Andrea
Sleep
The Sleep function suspends the execution of the current thread for a specified interval.
VOID Sleep(
  DWORD dwMilliseconds   // sleep time in milliseconds
);
Parameters
dwMilliseconds
Specifies the time, in milliseconds, for which to suspend execution. A value of zero
causes the thread to relinquish the remainder of its time slice to any other thread of
equal priority that is ready to run. If there are no other threads of equal priority ready
to run, the function returns immediately, and the thread continues execution. A value of
INFINITE causes an infinite delay.
Return Values
This function does not return a value.
Remarks
A thread can relinquish the remainder of its time slice by calling this function with a
sleep time of zero milliseconds.
You have to be careful when using Sleep and code that directly or indirectly creates
windows. If a thread creates any windows, it must process messages. Message broadcasts are
sent to all windows in the system. If you have a thread that uses Sleep with infinite
delay, the system will deadlock. Two examples of code that indirectly creates windows are
DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use
MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.
QuickInfo
  Windows NT: Requires version 3.1 or later.
  Windows: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winbase.h.
  Import Library: Use kernel32.lib.
See Also
Processes and Threads Overview, Process and Thread Functions, MsgWaitForMultipleObjects,
MsgWaitForMultipleObjectsEx, SleepEx

[........................]
Esatto: l'ambiente è msVC++5/ MFC/ Win98.
Ho provato ad utilizzare la funzione Sleep() che in effetti sospende
l'esecuzione del programma, però non riesco a intercettare i messaggi di
sistema relativi al mio stesso thread: quando passo con il cursore sulla mia
finestra, questo diventa una clessidra e la sua attività non è rilevata
nella MESSAGE_MAP.
Avendo fino a 'ieri' programmato in Visual Basic, ho cercato di utilizzare
la funzione Sleep() un po' come utilizzavo la chiamata DoEvents in VB,
sperando che le due fossero analoghe, ma evidentemente non è così.
Nei pochi programmi C++ che ho scritto fin'ora avevo utilizzato il seguente
sistema :
1) Nella funzione  'afx_msg void C??Wnd::OnTimer(UINT ID)'  inserivo una
chiamata ad una funzione 'C??Wnd::main()' che gestiva il mio programma.
2) Periodicamente uscivo da ''C??Wnd::main()' e di conseguenza si attivava
la MESSAGE_MAP
Certo è un sistema scomodo e 'primitivo' ma è il più semplice che ho
trovato.
Forse nel mio messaggio precedente sono stato troppo generico e quindi
inevitabilmente frainteso: forse la funzione Sleep() non è quella che cerco?
Forse non la ho implementata nel modo giusto?
Nella Doc di Ms ho anche trovato una quantità di funzioni che hanno a che
fare con Threads, Events, Messages .... E' una giungla di soluzioni
possibili e temo di essermi smarrito.
Se qualcuno avesse tempo e voglia di fornirmi qualche indicazione utile
gliene sarei davvero molto grato, se no grazie lo stesso :)
Ciao _sng_

Se sei in una fase di elaborazione il ciclo dei messaggi gestito da MFC non è più attivo perchè l'esecuzione è nella tua parte di programma. Per fare in modo che ti arrivino nuovamente i messaggi di Windows deve rifare la parte del ciclo dei messaggi.
Cioè devi chiamare
PeekMessage() che ti estrae un messaggio dalla coda (se ce n'e' uno)
DispatchMessage() che spedisce il messaggio alla tua funzione di gestione (che poi e' di MFC ma che mappa le tue)
In mezzo se serve TranslateMessage(), TranslateAccelerators(), IsDialogMessage(). Guarda l'help.
Problema: in questo modo l'intero programma diventa attivo (voci di menù, pulsanti, etc.) per cui devi disattivare quello che non si può fare. In ogni ciclo che hai dovresti fare una cosa del genere.
Soluzione alternativa: sposta il tuo ciclo di elaborazione (quello che blocca i messaggi) in un altro thread. E' semplice, funziona bene e non appesantisce l'esecuzione. Guarda CreateThread(). Quando l'elaborazione è terminata il thread può spedire un messaggio all'applicazione (è uno dei tanti metodi).
Problema: sicuramente dovrai disattivare qualche cosa e magari sincronizzarne altre. Windows ha una ottima gestione dei semafori, etc.
Ciao
Antonio Donatiello

[.......]
Non sai quanto mi hai aiutato !! Sei stato gentilissimo.
Per il momento ho usato Peek/DispatchMessage().
Prossimamente cercherò di utilizzare più threads (e la funzione sleep()).
Avrei altre mille domande,
ma forse è meglio se prima cerco un buon libro su MFC/WIN :)
Grazie ancora a tutti.
_sng_
[citazione del momento]
"Quel che non è Dato è perso" ?

Forse però c'è un'alternativa migliore.
MS in una technical note nel VC++ illustra l'uso di PumpMessage, funzione
non documentata di CWnd. Dice che va usata per smistare i messaggi in una
situazione come la tua per ottenere tutte lefunzionalità normalmente
implementate dal framework MFC dietro le quinte.
Vedi la documentazione di VC però facendo una ricerca(sono andato a
memoria).
---
Livio Cavallo
(God is real unless declared as integer)

 wrote in message
7m2vcn$hdt$3...@nslave1.tin.it...

Interessante, ho trovato qualcosa all'url
http://www-courses.cs.uiuc.edu/~deandrsn/mfc
In effetti è molto simile al DoEvents di VB e sembra anche molto semplice e
immediata, .
PumpMessage() fa parte di CWinThread per cui forse non dovrebbe essere
accessibile se chiamata da C*Wnd (io non ci sono riuscito, ma non è un
grande problema) comunque in C*App funziona, e sicuramente può tornare utile
(soprattutto se uno sta smanettando alla 'bell'è meglio').
Ciao e grazie.
_sng_
[citazione adattata]
"Quando il saggio indica la luna lo sciocco guarda il dito ...e poi le
stelle"