Newsgroup: it.comp.lang.c++
Titolo: Colore Dialog in VC++

Chi mi sa dire come faccio in Visual C++ a cambiare il colore di una dialog
che altrimenti mi rimane sempre grigia.
Grazie,
Mirko Tedaldi.
--
Posted from 
ro...@mbox.queen.it
 [195.31.228.37]
via Mailgate.ORG Server - 
http://www.mailgate.org

che altrimenti mi rimane sempre grigia.
Il modo piu` flessibile e` gestire il messaggio WM_ERASEBKGND,
che Windows spedisce alla finestre ogni volta che sta per cancellarne
lo sfondo; in essa, puoi recuperare il device context castando il
wParam, fare quel che vuoi a quel device context (in particolare
"cancellarne" lo sfondo come preferisci), poi tornare TRUE per
dire a Windows che lo sfondo l'hai gia` cancellato tu.
Se usi MFC, questo puoi farlo cosi`:
1. Aggiungi ON_WM_ERASEBKGND() fra le macro della
    message map della tua classe dialogo,
2. Aggiungi la funzione:
        afx_msg BOOL OnEraseBkgnd( CDC* pDC );
    ai membri pubblici o protetti della tua classe dialogo,
3. Implementala ad esempio come:
BOOL CMidiaDlg::OnEraseBkgnd( CDC* pDC )
{
    CRect cr(0,0,1000,1000);
    pDC->FillSolidRect(cr,RGB(200,150,20));
    return TRUE;
}
per avere come colore di sfondo del dialogo una
specie di arancione, ecc ecc.
Alex

Mirko Tedaldi.
Un'alternativa molto semplice a quella proposta da Alex Martelli, potrebbe
essere:
CWinApp::SetDialogBkColor(COLORREF clrCtlBk = RGB(192 , 192 , 192),
                                          COLORREF clrCtlText = RGB(0 , 0 ,
0 ) );
Se chiami questa funzione quando il Dialog-Box é già aperto, devi eseguire
un redraw dello stesso per vederne l'effetto.
Inoltre questa funzione é protetta, quindi , se la usi in Run-Time (e non in
CMyApp::InitInstance( ) ), devi implementare una funzione (per esempio
CambiaColoreDialogo( ) ) nella tua classe derivata da CWinApp ed
accedervi tramite questa, eccoti un piccolo esempio:
CMyApp theApp;
void CMyDialog::Funzione()
{
    ....
    ....
    theApp.CambiaColoreDialogo( );
    // redraw del Dialog-Box
    InvalidateRect( NULL );
    ....
    ....
}
void CMyApp::CambiaColoreDialogo( )
{
    // cambia il fondo con il Ciano
    SetDialogBkColor( RGB( 0 , 255 , 255 ) , RGB( 0 , 0 , 0 ) );
}
Saluti, Neil
P.S.:  Questa funzione agisce su tutti i Dialog-Box e MessageBox aperti
          dalla tua applicazione indistintamente.

                                          COLORREF clrCtlText = RGB(0 , 0 , 0 ) );
Molto semplice, ma talmente poco flessibile da non costituire neppure
una risposta alla domanda letteralmente posta -- come tu stesso fai
notare, questo non cambia il colore di _una_ dialog, ma di _tutte_ quelle
dell'applicazione (message-box incluse).  Se e` proprio questo che si
vuol fare, benissimo, ma una soluzione piu` flessibile presenta una
maggiore generalita` (a prezzo, certo, di un po' di complicazione:-).
Alex


Ciao Alex, prima di tutto voglio rinnovarti i ringraziamenti per l'aiuto
che mi avevi dato qualche settimana fa a proposito di Events e
Callback in VB.
Sono d'accordo sulla scarsa flessibilità di SetDialogBkColor, ma
ho specificato appunto "potrebbe essere un'alternativa" proprio
perché la mia voleva essere solo questo.
Spesso si ricorre per (buona) abitudine ad una soluzione flessibile
(e quindi solitamente più elaborata) anche quando il caso non lo
richiede affatto.
Tieni conto che in fondo questa soluzione é limitativa solo se si
verificano due condizioni contemporaneamente:
    1. Si vuole applicare il colore di fondo a Dialog modeless.
                                        AND
    2. Si vuole un colore di fondo diverso per ogni Dialog modeless.
Se il colore desiderato é unico (tipo come un marchio di fabbrica)
basta inserire SetDialogBkColor in InitInstance.
Se i colori sono diversi, ma applicati solo a dei Dialog modal
(spesso é così, quindi mai più di un Dialog per volta a meno di un
annidamento), allora basta inserire SetDialogBkColor prima dei
rispettivi DoModal.
Infine, diversamente da quanto specificato nell'Help-in-line, questa
funzione non influenza i MessageBox.
Per dirla tutta, ho provato ad usare la tool Spy++ con l'opzione
"All Windows in System", lasciando "passare" solo i messaggi
WM_CTLCOLORMSGBOX, ma questo "evento" non si é verificato
in nessun caso.
Saluti, Neil

funzione non influenza i MessageBox.
Buono a sapersi. Vuoi scommettere che questa osservazione
puo` dipendere dall'esatto release di Win32 in gioco, causando
poi magari delle anomalie del comportamento dell'applicazione
su, che so, un certo OEM release di Win95 ma non altri...? Eh,
purtroppo, nessuno puo` testare le applicazioni su tutti i release
di Win32, ce ne sono stati troppi e tanti altri ce ne saranno.
Quando una funzione non fa quello che dice la documentazione,
giudicando dai test fatti su di un sistema o due, forse e` meglio,
se c'e` una buona alternativa (come, qui, gestire la funzione di
erase background), evitare la funzione che non sappiamo se
sia mal documentata, ovvero bacata in qualche implementazione.
Alex