Newsgroup: it.comp.programmare.win32
Titolo: Salvataggio del client

Salve,
sono nuovo nella programmazione per Windows, utilizzo Visual C++ 6.0 SP3 e
le MFC. Ho scritto un programma per imparare la gestione degli eventi legati
al mouse (stampa delle frasi sull'area client sia attraverso una
combinazione tra tasti e pulsanti del mouse sia attraverso un menu popup),
però non capisco perché se riduco ad icona o sposto la finestra fuori dallo
schermo, il contenuto della finestra viene "resettato" e torna bianco. Ho
provato ad utilizzare
SaveDC e RestoreDC ma senza successo.
Ringrazio chiunque mi possa dare una mano.
--
  Jerle Shannara
Togli NO SPAM dall'email

: 

La finestra viene ridisegnata inviando una serie di messaggi alla sua window 
proc:
WM_ERASEBKGND (credo di averlo scritto giusto)
WM_PAINT
Il redraw della finestra viene normalmente gestito all'interno del secondo 
messaggio:
BeginPaint(....)
... codice di redraw ...
EndPaint(...)
E' anche possibile disegnare all'interno di una qualsiasi finestra utilizzando 
GetDC (e ReleaseDC). La prima volta che la finestra verrà ridisegnata (dopo 
averla minimizzata/restorata ma anche dopo averla portata dietro un'altra 
finestra), la client area sarà ripulita (WM_ERASE...) e quindi tutto quello che 
era stato disegnato sparirà.
Se vuoi inserire un contenuto "permanente" (qualcosa che possa sopravvivere al 
redraw) devi disegnarlo durante il processing del WM_PAINT.
Qualcosa del tipo:
HRESULT miaWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
static char* testo="";
switch (msg)
{
    	case WM_PAINT:
    	    	BeginPaint(...)
    	    	DrawText(...,testo,...)
    	    	EndPaint(...)
    	    	...
    	case WM_<messaggio che vuoi intercettare per cambiare il testo>
    	    	testo="<nuovo testo>";
    	    	InvalidateRect(hwnd,NULL,TRUE); //si può fare di meglio calcolando 
l'area da ridisegnare...
    	    	UpdateWindow(hwnd);
    	    	...
}
}
come vedi il messaggio si limita a cambiare il contenuto della variabile e a 
forzare un repaint immediato:
- InvalidateRect segnala che la client area (o parte di essa) deve essere 
ridisegnata
- UpdateWindow forza un repaint immediato (genera un messaggio WM_PAINT).
N.B. il messaggio viene generato solo se ci sono porzioni della client area 
invalide, da cui la necessità di richiamare prima InvalidateRect.
-- 
Valter Minute
min...@inwind.it
 (the reply address of this message is invalid)

 torna bianco.
Evidentemente non gestisci il disegno del testo dentro alla WM_PAINT (e`
sempre preferibile farlo, a meno che non si tratti di aggiornamenti
frequenti e temporanei).
WM_PAINT e` un messaggio che viene spedito a una finestra ogni volta che
Windows ha "bisogno" che determinate zone di essa vengano ridisegnate,
perche` sono state "sporcate" per diversi motivi (uno dei quali l'hai
indicato tu stesso).
---
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/

Mi sono accorto (troppo tardi del resto) di essere stato poco chiaro: il
testo non cambia ma viene stampato in corrispondenza di dove viene fatto
click con il mouse e, secondo se non vi è alcun tasto premuto oppure si è
premuto CRTL oppure ancora SHIFT, viene stampata una frase diversa. Insomma
laddove nell'area client viene fatto click viene stampato qualcosa (ho
aggiunto anche un menu context che permette di scegliere la frase senza
premere altri tasti, ma questo non importa). Data l'impossibilità di sapere
quante sono e dove sono stampate tali frasi, la soluzione da te postata non
servirebbe a molto. Avevo pensato di salvare l'area client ogni volta che
viene fatto click con il mouse e ripristinarlo quando arriva il messaggio
WM_PAINT ma con quali funzioni? SaveDC e RestoreDC sembrano non funzionare.


La stampa del testo dipende, come ho già spiegato nell'altra risposta, dalla
posizione del mouse per questo non ho usato OnPaint(). Allora ho provato a:
1) salvare l'area client in OnLButtonDown così:
    save = pDC->SaveDC();
dove save è membro della classe vista
2) in OnPaint ho scritto
    CPaintDC dc;
    dc.RestoreDC(save);
Tuttavia non funziona ^_^


: 

Save e RestoreDC non salvano il contenuto di un DC (inteso come aspetto 
grafico dello stesso), ma solo il suo stato (brush attivo, pen 
selezionata...) e quindi non servono al tuo scopo.
Hai due alternative:
1. salvi le informazioni che ti servono per visualizzare le varie label in 
una struttura (una lista dovrebbe fare al caso tuo) che utilizzi 
all'interno di WM_PAINT per ridisegnare tutte le tue label.
2. Crei un DC in memoria, gli associ una bitmap ed esegui tutte le 
operazioni di draw su quel DC (che è "permanente" finchè non lo rilasci e 
distruggi la bitmap) e ti limiti a copiare la bitmap con BitBlt quando devi 
ridisegnare la finestra. La cosa si complica se la tua finestra è 
scrollabile o ridimensionabile (la bitmap deve avere la dimensione massima 
e ti devi ricalcolare le coordinate).


Grazie mille. Oltre ad aver finalmente capito a che servono SaveDC e
RestoreDC mi hai anche dato un'ottima idea! Grazie ancora!!
