2015-01-01 26 views
5

enter image description here Ho cercato di trovare una soluzione semplice per modificare il colore di un controllo di modifica con il flag ES_READONLY. Il codice che ho (sorta) funziona quando il controllo di modifica è modificabile, tuttavia non ha alcun effetto sul mio controllo di modifica che ha il flag di sola lettura.È possibile modificare il colore di sfondo di un controllo di modifica di sola lettura

case WM_CTLCOLOREDIT: 
{ 
    HDC hdc = (HDC)wParam; 
    //if (GetDlgItem(hwnd, IDC_EDIT_IN) == (HWND)lParam) 
    //{ 
     SetTextColor(hdc, RGB(255, 255, 255)); // Set text color to white 
     SetBkColor(hdc, RGB(255, 255, 255)); // Set background color to black 
    //} 
    return 0; 
} 
break; 

ho il commento lì solo per controllare se il mio codice ha funzionato, e lo fa sul controllo di modifica che non è di sola lettura. Se tolgo ES_READONLY sul mio altro controllo di modifica, funziona su di esso. Sto creando un programma di chat e non voglio che l'utente sia in grado di digitare nell'area della chat. E quando è di sola lettura, lo rende un colore grigio, ma io voglio un colore bianco. c'è un altro modo per fare ciò? Inoltre, il colore solo colora l'area in cui si trova il testo, non l'intera altezza del controllo di modifica. Che cosa sto facendo di sbagliato?

+2

Ti consiglio di consultare 'WM_CTLCOLORSTATIC' –

+2

Leggi l'articolo MSDN, ti dice di restituire un pennello. –

risposta

5

È necessario creare un pennello e tenerne traccia. Quindi si restituisce questo pennello invece di return 0 nello snippet di codice. Una volta che il pennello non è più necessario, devi cancellarlo. Questo di solito viene fatto in risposta al messaggio WM_DESTROY.

Nel tuo caso puoi schivare il proiettile usando il pennello di scorta, che è quello che raccomanderei.

In modalità di sola lettura, controlli di modifica rispondono a WM_CTLCOLORSTATIC invece di WM_CTLCOLOREDIT, quindi è necessario gestire correttamente questo messaggio:

case WM_CTLCOLORSTATIC: 
{ 
    if((HWND)lParam == GetDlgItem(hwnd, IDC_EDIT_IN)) 
    { 
     SetBkMode((HDC)wParam, TRANSPARENT); 
     SetTextColor(hdc, RGB(255, 255, 255)); 
     return (LRESULT)((HBRUSH)GetStockObject(BLACK_BRUSH)); 
     // if edit control is in dialog procedure change LRESULT to INT_PTR 
    } 
    else // this is some other static control, do not touch it!! 
     return DefWindowProc(hwnd, message, wParam, lParam); 
} 

Quando la pittura controllo di modifica/static, si dispone di 3 parti disponibili per la pittura:

  • colore del testo
  • sfondo del testo
  • ba del controllo SFONDO

per dipingere intero controllo in colore desiderato è necessario tornare pennello con colore desiderato (return (LRESULT)someBrush per la procedura finestra o return (INT_PTR)someBrush per la finestra di dialogo).

La chiamata al SetBkColor imposta il colore del testo sfondo, che è diverso dal colore di sfondo del controllo. Questo è il motivo per cui chiamiamo SetBkMode con il parametro TRANSPARENT, per "dire" che vogliamo che lo sfondo del testo corrisponda allo sfondo del controllo.

Nel tuo caso ho usato il pennello di scorta, perché non devi tenerne traccia, né devi cancellarlo dopo che non è più necessario.

Tuttavia, potrebbero esserci casi in cui si desidera un altro colore. In tal caso, qui è quello che si dovrà fare:

  • Creare HBRUSH variabile globale o static HBRUSH variabile nella vostra window procedure/finestra di dialogo.
  • Inizializza questa variabile in risposta a WM_CREATE se in una finestra. Se nella procedura di dialogo inizializzare il pennello in WM_INITDIALOG. Qualcosa come someBrush = CreateSolidBrush(RGB(255, 0, 255)); Vedere documentation per maggiori informazioni ed esempi.
  • ritorno questo pennello, come vi ho mostrato nell'esempio di cui sopra (per la procedura return (LRESULT)someBrush finestra o return (INT_PTR)someBrush per la finestra di dialogo).
  • Elimina il pennello quando non è più necessario. Questo di solito viene effettuato nel WM_DESTROY con la chiamata DeleteObject(someBrush);.

vi consiglio vivamente di fare la cancellazione in risposta a WM_DESTROY invece di WM_CLOSE perché questo è il messaggio finestra riceverà sempre, mentre WM_CLOSE a volte può essere saltati (una ricerca su Internet per trovare esempi di questo scenario).

Spero che questo aiuti, se avete ulteriori domande lasciare un commento e cercherò di aiutare. I migliori saluti.

+0

Quote da MSDN: "Non è necessario (ma non è dannoso) eliminare gli oggetti stock chiamando' DeleteObject' ". – 0xC0000022L