Sviluppo

Come faccio? - parte XV

Gianni Ceccarelli
 

stesura originale in inglese di Eric Slaats - liberamente tradotto da Gianni Ceccarelli
comparso per la prima volta su Os/2 e-Zine! volume 3 numero 2

Salve, salve, e benvenuti a un altro episodio di "Come faccio?" Continueremo a migliorare la nostra calcolatrice per farla diventare un'applicazione PM più completa.

Cosa ci aspetta questo mese? Visto che questi articoli sono incentrati sul PM, ci occuperemo soprattutto di questo. Mostreremo come si possono usare i presentation parameters in una applicazione. Questo ci darà la possibilità di colorare i nostri controlli e usare diversi fonts. Oltre a questo, daremo un'occhiata al controllo 'lista', e ovviamente ci sarà un po' di programmazione C per ottenere una calcolatrice migliore. Ci occuperemo di cose come la divisione per zero e i formati di uscita. Per coloro che vogliono addentrarsi nel codice, i cambiamenti nell'esempio (ZIP, 25k) sono evidenziati da "/NEW-NEW."

I presentation parameters sono usati continuamente da chiunque usi OS/2. Adoro questi aspetti di OS/2, e secondo me mostrano la superiorità di OS/2 su altri sistemi operativi. Credo che chiunque sappia come usare la tavolozze dei colori, font o schemi. Potete prendere un colore o un font e trascinarlo sul controllo che volete. Se è una buona applicazione OS/2, reagirà assumendo quel colore o font. Sappiamo che tutti i componenti standard del PM come cartelle, menu, barre di scorrimento ecc. reagiranno correttamente. Alcuni addirittura salveranno le modifiche (ogni buona applicazione PM dovrebbe).

In un programma possiamo usare i presentation parameters per cambiare colori e font della nostra applicazione in modo molto semplice. Per i dialog, i PP si possono impostare con l'editor. In un programma, si possono impostare usando le apposite chiamate API. I font e i colori dell'help di Smalled, per esempio, sono impostati proprio in questo modo. Saremo pigri ancora una volta e coloreremo la nostra calcolatrice usando i PP tramite il dialog editor (comodo che la nostra applicazione sia un dialog!). In questo modo ho colorato i tasti della calcolatrice in nero con le scritte bianche. Lo sfondo della calcolatrice è colorato di rosso. L'entry field e la lista sono bianche, e il font è impostato a WarpSans (Se usate Warp 3.0, potreste non vederlo, ma riparleremo di font e PP tra un attimo).

Molti dialog editor hanno un modo per applicare PP ai controlli. Così facendo aggiungerete dei comandi alla descrizione del controllo nel file RC. Per esempio, il colore rosso del dialog è ottenuto aggiungendo questa linea alla descrizione del dialog.

        PRESPARAMS PP_BACKGROUNDCOLORINDEX , 2L

Per impostare il font dell'entry field a WarpSans 9 punti si aggiunge alla descrizione del controllo una linea come questa:

        PRESPARAMS PP_FONTNAMESIZE "9.WarpSans"

Come potete vedere, PP per font e colori sono applicati allo stesso modo. I parametri, però, sono di tipo molto diverso. Per PP_BACKGROUNDCOLORINDEX è uno short, per PP_FONTNAMESIZE è una stringa. Le cose diventano più complicate quando vi accorgete che ci sono PP che prendono come parametro una terna RGB. Ce ne occuperemo un'altra volta, quando tratteremo i PP impostati via API.

OS/2 supporta un grande insieme di PP. Ci sono PP distinti per il colore del bordo attivo e non attivo. PP per cambiare l'aspetto dei menu, delle evidenziazioni, delle parti non attive ecc. In breve, i PP vi danno moltissime possibilità. La cosa strana è che queste sono raramente sfruttate. Esaminate il file RC dell'esempio di qesto mese e guardate come è fatto. Fatelo leggere al vostro dialog editor per vedere (l'esempio è stato fatto con il Borland C++ 2.00 for OS/2). Ho usato i più semplici PP di FOREGROUND e BACKGROUND con indici di colore. Se non vi piacciono, cambiateli.

Cos'altro abbiamo cambiato questo mese? Usando la calcolatrice, potreste notare che i risultati dei calcoli vengono mostrati nella lista che forma la parte superiore della calcolatrice. Penso che questo sia un buon momento per introdurre il controllo lista.

La lista (list box) è uno dei miei controlli preferiti, perché può essere usata per moltissime cose. Inoltre, può essere controllata in modo molto sofisticato (guardate, ad esempio, cosa fanno molte delle applicazioni Lotus fanno con le lista). Mostrerò alcuni semplici usi della lista esaminando cosa ci serve per la calcolatrice.

Cosa vogliamo dal foglietto 'stampato'? Deve mostrare operandi e risultati, e quale operazione è stata fatta. Per farlo dobbiamo innanzitutto sapere come inserire una linea di testo nella lista. Il contenuto di una linea un un list box è una stringa di caratteri, quindi dobbiamo convertire in questa forma ogni dato che vogliamo inserire. Inoltre, dobbiamo dire al list box in quale poszione inserire la linea. Tutte le linee della lista sono numerato come gli elementi di un array. La prima linea ha il numero 0. L'inserimento può essere effettuato inviando il seguente messaggio al list box:

LM_INSERTITEM.

        MP1: l'indice della riga

        MP2: puntatore alla stringa.

        return: l'indice della riga inserita.

Vogliamo inserire la nuova linea in fondo a quelle già presenti, come possiamo fare? Dovremmo tenere il conto di quante linee ci sono già, aggiungere uno e inserire la nuova linea in quella posizione. Molto diretto, ma pigri come siamo, vorremmo qualcosa di più semplice. Dovrebbe essere possibile aggiungere qualcosa direttamente alla fine della lista, essendo una cosa così comune. E in effetti si può! I creatori dei messaggi di OS/2 hanno incluso il valore LIT_END per l'indice della riga. Questo valore indica sempre il numero di righe presenti più uno.

Inserire le linee in questo modo non basta. Diciamo di aver già inserito una cinquantina di linee. La lista mostra ancora le prime. Dobbiamo fare in modo che la linea inserita sia anche visibile. Possiamo farlo selezionando la linea appena inserita. Si può fare con questo messaggio:

LM_SELECTITEM

        MP1: l'indice della riga

        MP2: flag per selezionare o deselezioanre

Vogliamo che la linea sia visibile, non che sia evidenziata. Il bello è che se MP2 è falso, la linea non sarà selezionata, ma verrà comunque spostata nell'intervallo visibile. A questo punto il valore di ritorno di LM_INSERTITEM dovrebbe avere un senso. Possiamo usarlo per selezionare la linea appena inserita. Sapendo questo possiamo scrivere una funzione che inserisca la linea nella lista al posto nostro. Nell'esempio è fatta così:

void PrintListboxLine (PSZ achLine, HWND hwndDlg)

        {

        short I;

        I = (short) WinSendDlgItemMsg(hwndDlg, LISTBOX1,

                                                        LM_INSERTITEM,

                                                        (MPARAM)LIT_END,

                                                        (MPARAM)achLine);

        WinSendDlgItemMsg(hwndDlg, LISTBOX1,

                                   LM_SELECTITEM,

                                   (MPARAM)I, 0L);

        }

Nell'esempio questa funzione viene chiamata ogni volta che viene inserito un valore, ma anche dopo un '='. Inoltre, vorremmo sapare quale operazione è in corso, quindi dopo la pressione di '+', '-', '*' o '/' viene inserito anche l'operatore (controllate l'eccezione del '-' per i numeri negativi).

Ho usato i messaggi, ma OS/2 ha un sacco di macro che possono tornare utili. Cercate ad esempio la macro WinInsertLboxItem.

Come avrete notato, anche una semplice calcolatrice può diventare piuttosto complessa. E non abbiamo ancora finito! Questo mese vedremo due aggiunte per rendere la calcolatrice più utilizzabile. La prima è impedire le divisioni per zero. Se lasciamo che accadano, l'applicazione terminerebbe, mostrando il dialog di sistema che mostra l'errore. Ho scelto una soluzione semplice ma non del tutto corretta. In effetti impedisce anche di sommare e sottrarre zero, nonché di moltiplicare per zero. Sono azioni valide, ma non hanno alcun senso. A che punto dovremmo mettere in controllo? Quando alla pressione di '=' flRightMember è zero, o dopo la pressione di un operatore ('-', '+', '/', '*') se stiamo facendo operazoni in cascata. Perciò in due punti è stato inserito il controllo

        if (flRightMember != 0)

(nell'esempio è contrassegnato da "//NEW-NEW".)

Un'altra cosa che mi dava fastidio della versione del mese scorso è che ci sono sempre un mucchio di cifre dopo il punto decimale, anche se sono tutti zeri. Ho scritto una funzione che elimina gli zeri finali e il punto se non sono necessari. L'ho chiamata PrintOutput poiché si occupa anche di alcune cose precdentemente gestite nel corpo del case WM_COMMAND. Dopo aver convertito il valore in una stringa, le linee seguenti si occuperanno di togliere il superfluo:

        while (achOutput[strlen(achOutput)-1] == '0')   // toglie gli zeri

                achOutput[strlen(achOutput)-1] = 0;

        if (achOutput[strlen(achOutput)-1] == '.')      // toglie il punto

                achOutput[strlen(achOutput)-1] = 0;

Il trucco sta nel fatto che il C termina le stringhe con uno 0, quindi se inseriamo uno 0 da qualche parte nella stringa, a tutti gli effetti essa terminerà a quel punto. Notate anche che il carattere zero ('0') è diverso dal valore numerico zero che marca la fine della stringa. Beh, cercate di capire. Trovo questi trucchi di parsing molto utili. Gli strumenti di Smalled si appoggiano pesantemente su funzioni come questa.

Basta per questo mese. Il mese prossimo finiremo la calcolatrice aggiungendo qualche altra funzionalità. Fatto questo, la prime applicazione di "Come faccio?" sarà una reltà. Arrivederci al mese prossimo.


[Pagina precedente] [Sommario] [Pagina successiva]