Esempio: dlg_three

Non interpretate male, questo è un Tutorial, non una Referenza, ma alcune domande vengono fatte così frequentemente che ho deciso di includere queste FAQ.

Cambiare i colori

In generale, l’unico motivo per cui si fa una cosa del genere è per simulare un link o cose simili in una dialog box., perchè altrimenti state solamente trasformando il vostro programma in qualcosa di brutto e disgustoso da vedere. Aggiungere una marea di colori ad una dialog box è quindi qualcosa di altamente sconsigliato, ma ci stanno un sacco di persone che lo fanno e siccome ci sono un paio di ragioni valide, vediamo come fare. :)

Windows invia svariati messaggi relativi ai colori alle nostre Dialog Procedure, e processando questi messaggi è possibile cambiare i colori di alcune cose visualizzate all’interno. Per esempio per cambiare il colore della dialog box stessa, bisogna processare WM_CTLCOLORDLG, per cambiare i colori di un controllo statico bisogna processare WM_CTLCOLORSTATIC e così via.

Prima di tutto bisogna creare un brush da usare per disegnare lo sfondo e conservarlo per essere usato in seguito; il messaggio WM_CTLCOLORDLG e relativi vengono chiamati spesso durante il corso del programma, e se create un brush ogni volta, vi troverete probabilmente ad usare inutilmente un grande quantitativo di RAM dedicato a brush morti. In questo modo ne abbiamo solo uno e possiamo cancellarlo nel momento in cui la dialog box viene distrutta e siamo sicuri che non ci servirà più

    HBRUSH g_hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
    case WM_CTLCOLORDLG:
        return (LONG)g_hbrBackground;
    case WM_CTLCOLORSTATIC:
    {
        HDC hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(255, 255, 255));
        SetBkMode(hdcStatic, TRANSPARENT);
        return (LONG)g_hbrBackground;
    }
    break;

Notate la linea che setta lo sfondo a trasparente… se togliete questa riga, lo sfondo del controllo verrà sarà riempito con il brush specificato, ma quando il controllo disegna il testo, esso sarà scritto con lo sfondo di default! Usando invece lo sfondo trasparente, viene eliminato il problema. L’altra opzione sarebbe stata SetBkColor() dello stesso colore del nostro brush di background ma personalmente preferisco questa soluzione.

Cambiare i colori praticamente su quasi tutti i controlli standard funziona allo stesso modo, date semplicemente un’occhiata ai messaggi WM_CTLCOLOR* nella vostra referenza a Win32 per trovare quello che vi serve. Notate che un edit control invierà WM_CTLCOLORSTATIC se è in modo sola lettura e WM_CTLCOLOREDIT se non lo è Se avete bisogno di avere più di un controllo statico (o altri) di colori differenti dovrete effettuare un controllo sull’ID del controllo che riceve il messaggio per cambiare i colori appropriatamente. L’HWND del controllo viene passato all’interno di lParam, e potete ricavarne l’ID chiamando GetDlgCtrlID(). Ricordate che i controlli statici hanno assegnati di default ID IDC_STATIC (-1) dal vostro editor di risorse e non sarete in grado di effettuare operazioni su di essi se non assegnate loro un nuovo ID.

Assegnare un'icona alla Dialog Box

Questa è un’operazione molto semplice, basta inviare WM_SETICON alla finestra di dialogo. Ricordate però che le finestre usano due tipi di icone, una piccola 16x16 visualizzata in alto a sinistra della finestra e una grande 32x32 quando si preme Alt-Tab. Potete inviare lo stesso handle come visto in precedenza, a patto che l’icona contenga le immagini a grandezza richiesta.

Per settare l’icona di default per l’applicazione, potete usare i codice seguente:

    SendMessage(hwnd, WM_SETICON, ICON_SMALL,
             (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)));
    SendMessage(hwnd, WM_SETICON, ICON_BIG,
             (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)));

Quando sostituite la vostra icona di default, ricordate di cambiare il parametro HINSTANCE di LoadIcon() con l’istanza della vostra applicazione (potete ricavarvelo chiamando GetModuleHandle(NULL) se non lo avete salvato in precedenza quando vi è stato passato da WinMain()).

Perchè la mia Combo Box non funziona?

Un problema molto diffuso è quello di persone che aggiungono una Combo Box all’interno delle loro Dialog e poi si rendono conto che la lista non viene fuori al momento dell’esecuzione quando fanno click sulla piccola freccia verso il basso. La soluzione effettivamente non è molto intuitiva.

Quando create le combo box e ne specificate l’altezza, state specificando l’intera altezza, inclusa la lista di scorrimento, NON solo l’altezza del controllo quando sta chiuso, che oltretutto viene determinata dal sistema in base alla grandezza del font usato.

Per esempio, assegnando ad un controllo l’altezza di 100 pixels, il sistema dimensionerà il controllo all’altezza di default (diciamo 30 pixels in questo caso), e quando farete click sulla freccetta, la lista di scorrimento sarà alta 70 pixels, per un totale di 100 pixels.

Se usate l’editor di risorse di VC++ potete notare che quando inserite una combo box all’interno della dialog, non sarà possibile ridimensionarla in altezza finchè non fate click sulla freccetta, a questo punto cambierà il rettangolo selezionato per indicare che ora potete modificare l’altezza della lista di scorrimento.

Dove sono gli esempi e il codice per gli altri controlli!

Beh, potrei fornirvi esempi per tutti i controlli esistenti ma questo è quello che fanno MSDN e Petzold :) Se non riuscite ad immaginare come usarli, probabilmente avete bisogno di rileggere alcune parti di questo tutorial, oppure comprare un libro che spiega le cose molto più in dettaglio.

Vi darei volentieri un link ad una sezione molto utile della MSDN, ma pare che Microsoft sia determinata a prevenire che io faccia una cosa del genere dato che i link sul sito cambiano rapidamente o non funzionano per un certo periodo. Probabilmente dovete capire voi come andare avanti da soli, effettuate ricerche per sezioni tipo User Interface Services, e Windows Controls, alcune volte all’interno della sezione Platform SDK.

MSDN - Windows Controls