L’esempio allegato contiene un’applicazione MFC, che mostra l’utilizzo delle API descritte nell’articolo precedente. Si tratta di una
Dialog che consente di visualizzare un file di testo all’interno di una
edit-box multiline. Una volta aperto il file, possiamo provare a modificarlo con un’altra applicazione, per esempio
Blocco Note. Salvando il file su
Blocco Note, la nostra applicazione riceve la notifica del cambiamento e chiede se si intende ricaricare il file.
Dopo l’apertura del file, chiamiamo la funzione
FindFirstChangeNotification e memorizziamo l’
handle restituito in una variabile membro della classe,
m_hChange. Subito dopo avviamo il thread, che si metterà in attesa di eventuali cambiamenti al nostro file:
<span style="font-size:1.0em">
// Funzione Thread
UINT ThreadFunc(LPVOID pParam)
{ THREADPARMS* ptp = (THREADPARMS*) pParam;
HWND hWnd = ptp->hWnd;
HANDLE hChange = ptp->hChange;
delete ptp;
if ( hChange == INVALID_HANDLE_VALUE )
{ return -1;
}
while ( 1 )
{ ::WaitForSingleObject(hChange, INFINITE);
::SendMessage(hWnd, WM_USER_FILE_MODIFIED, (WPARAM)0, (LPARAM)0);
::FindNextChangeNotification(hChange);
}
return 0;
}
</span>
Per attendere che un oggetto kernel diventi segnalato, si usa la funzione
WaitForSingleObject:
<span style="font-size:1.0em">
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds );
</span>
Il primo parametro è un
handle di un oggetto kernel; nel nostro caso, si tratta di un oggetto di notifica dei cambiamenti sui file. Il secondo parametro dice al sistema per quanto tempo (in millisecondi) vogliamo attendere. Noi abbiamo utilizzato il valore
INFINITE e, dunque, attendiamo finché l’oggetto non diventi segnalato. Se si vuole specificare un tempo massimo di attesa, la funzione va chiamata nel modo seguente :
<span style="font-size:1.0em">
WaitForSingleObject(hChange, 10000); // Attendiamo per max dieci secondi
</span>
In questo caso, se l’oggetto non diventa segnalato entro dieci secondi, il sistema sveglia il thread e gli consente di proseguire l’esecuzione.
WaitForSingleObject restituisce uno dei seguenti valori:
- WAIT_OBJET_0: l’oggetto ha raggiunto lo stato segnalato;
- WAIT_TIMEOUT: l’oggetto non ha raggiunto lo stato segnalato entro il tempo specificato nel parametro dwMilliseconds;
- WAIT_ABANDONED: l’oggetto mutex ha raggiunto lo stato segnalato in seguito al suo abbandono;
- WAIT_FAILED: si è verificato un errore.