Newsgroup: it.comp.lang.c++
Titolo: api function / taskmanager

Salve a tutti.
C'e' nessuno che sappia se esiste (e qual e') una funzione api che mi
faccia sapere se la mia applicazione sta girando in piu' di una copia?
grazie in anticipo a tutti per ogni suggerimento!
flavia in alto mare

Se ti interessa solo sapere se l'istanza corrente del tuo programma sia
l'unica nel 
sistema, puoi usare la funzione FindWindow :
HWND FindWindow(LPCTSTR lpszClassName, LPCTSTR lpszWindowName);
Come primo parametro devi passare il nome della classe della finestra
principale della 
tua applicazione (lo stesso che passi al membro lpszClassName della
struttura
WNDCLASS/WNDCLASSEX); come secondo parametro passa pure NULL.
Se il valore di ritorno di questa funzione (di tipo HWND) è NULL allora
nessun'altra
istanza della tua applicazione è correntemente in esecuzione.
Se invece ti interessa sapere quante istanze siano correntemente in
esecuzione
devi scrivere del codice simile al seguente:
char globale_szClassName[] = "MiaApplicazione"; // per esempio
int globale_nIstanze = 0;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{ 
 char szClassName[100];                              // 100 è anche troppo
ma non si sa mai
 GetClassName(hWnd,szClassName,100);    // 100 si riferisce alla 
                                                                  //
dimensione del buffer
                                                                  //
szClassName 
 if(0 == lstrcmp(globale_szClassName,szClassName)) 
 {
  globale_nIstanze += 1;
  .
  .
  .
 }
 return TRUE;                                              // TRUE per
continuare l'enumerazione,
                                                                 // FALSE
per interromperla
}
   .
   .
   .
... WinMain ...
   .
   .
   .
... WindowProcedure ...
{
   .
   .
   .
 EnumWindows((WNDENUMPROC)EnumWindowsProc,0L);
   .
   .
   .
}   
EnumWindows elenca tutte le finestre principali (visibili e non visibili) e
ne passa l'handle
alla funzione callback EnumWindowsProc (che può avere anche un altro nome).
Questa
funzione viene chiamata una volta per ogni finestra elencata.
In questo esempio, all'interno della funzione EnumWindowsProc vengono
eseguite le
seguenti operazioni:
1) Viene allocato un Buffer sufficientemente grande;
2) Dall'handle passato come primo parametro si ricava il nome
    della classe della finestra con la funzione GetClassName;
3) La funzione lstrcmp restituisce 0 se le due stringhe passate
    come parametri sono uguali;
4) Se le stringhe sono uguali incrementa il contatore delle istanze;
5) ritorna TRUE per continuare l'enumerazione;
NOTA: In un altro momento potresti voler usare questo metodo per ricavare
l'handle di 
           una determinata finestra; non appena trovata la finestra non
avrebbe senso
           continuare l'enumerazione; in questo caso sarebbe sufficiente
ritornare FALSE 
           per interromperla immediatamente.
Se vuoi eseguire delle operazioni sulle altre istanze della tua
applicazione puoi
aggiungere delle istruzioni nella funzione EnumWindowsProc; per esempio:
 if(0 == lstrcmp( ... ))
 {
  globale_nIstanze += 1;
  SendMessage(hWnd,...);
 }
Se vuoi, puoi anche salvare tutti gli hWnd in un array globale e farci poi
quello che ti pare.
IMPORTANTE: La funzione EnumWindows rileva anche l'istanza corrente
dell'applicazione, quindi se globale_nIstanze vale 1 significa che non ci
sono altre copie
del tuo programma in esecuzione; globale_nIstanze non dovrebbe mai rimanere
0, ma
con Windows non si può mai dire.

faccia sapere se la mia applicazione sta girando in piu' di una copia?
una funzione specifica non c'e', ci sono per diversi sistemi molto
semplici, quello che uso di solito e' questo:
registri la classe della finestra principale con un nome assegnato da
te e non creato dal framework (MFC o altro), ad esempio in Visual C++
si fa cosi':
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 cs.lpszClass = _T("myAppMainFrame");
 return TRUE;
}
poi alla partenza del programma come prima cosa controlli se esiste
gia' una finestra con quella classe, con il Visual C++ si puo'
aggiungere il codice nella InitInstance() :
CWnd *pWndPrev;
if (pWndPrev = CWnd::FindWindow(_T("myAppMainFrame"),NULL))
	{
	// Esiste gia' un'instanza di questo programma
	}
Se hai il VC5 sull'MSDN trovi un articolo su questo argomento.
Gianpaolo Bottin
- Live Long and Prosper -