Introduzione alle API Win32

Capitolo 29: GUI per grafico di funzione

Rassicurati dalla sia pur minimale funzionalità dello stub di IndiEs, messa sia pur minimamente alla prova dal relativo skeleton, possiamo passare a pensare seriamente alla GUI (sigla di "graphical user interface", cioè "interfaccia-utente grafica") con la quale vorremo presentare il nostro famoso grafico di funzione.

La struttura principale sarà naturalmente un dialogo, sia perchè, sinora, non ne abbiamo studiate altre:-), sia perchè un dialogo è, in effetti, ragionevolmente adeguato ai nostri scopi. Sul dialogo dovranno trovare posto vari controlli cui accennavamo un paio di capitoli fa (oltre alle scritte con le quali i controlli stessi vengono identificati):

Un attimo di ulteriore riflessione ci rivela che manca almeno una indicazione: quando calcoleremo la funzione, N volte, per disegnarla e determinare, se richiesto, i min e max di Y? Oops, due indicazioni: quanto deve valere N, il numero di punti separati (e presumibilmente equidistanti) in cui calcolare la funzione...?

Nessun 'evento' identificabile, sui controlli sinora pensati, ci dice univocamente 'disegna adesso': se anche l'utente, ad esempio, ha finito di immettere il testo della funzione, o uno dei vari dati di min e max (e questo possiamo saperlo, basandoci sull'evento 'perdita di focus' del relativo controllo di edit), ciò non significa che sia già pronto a vedere il grafico -- bisognerà che tutti i vari controlli siano considerati "pronti" dall'utente, e questo 'evento semantico' può segnalarcelo solo lui. E quindi, ci vorrà un pushbutton 'Disegna'; ne faremo, naturalmente, il pushbutton di default, cosicchè un 'Enter' in qualsiasi momento causi il disegno.

Il numero di punti in cui è necessario il calcolo della funzione potremmo imporlo noi, basandoci sull'ampiezza in pixel della "area di disegno" e una qualche scelta forzata di 'precisione'; ma sembra assai più flessibile non forzare questa scelta, lasciando invece che sia l'utente a determinare la precisione ottenuta; avremo, dunque, un ulteriore campo di edit, per darci il numero dei 'passi' in cui dividere il disegno.

Infine, poichè è probabile che l'utente faccia un qualche errore prima o poi (nel formato di uno dei vari numeri che può editare, nella sintassi dell'espressione, ...), dobbiamo già pensare, in fase di progetto del dialogo, a come lo segnaleremo. Una possibilità è certamente una "message box" -- ma, riflettendoci, NON è la cosa più comoda per l'utente; ad ogni errore, egli dovrebbe cliccare sull'OK della message box prima di poterlo correggere. Riserviamo, piuttosto, un'area di testo (uno static, quindi), normalmente vuoto, nel quale porre eventuali messaggi d'errore necessari; diagnosticando un errore, rimetteremo inoltre il focus sul campo non soddisfacente, per rendere il più facile possibile all'utente apportare la necessaria correzione.

Ecco, dunque, un possibile schema di dialogo, come emerge da tutte queste considerazioni...:

IDD_INDIES_DIALOG DIALOG 0, 0, 350, 330 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Grafico di una funzione" FONT 8, "MS Sans Serif" BEGIN LTEXT "Espressione in X:",IDC_STATIC,10,5,55,15,SS_CENTERIMAGE EDITTEXT IDC_FUNZIONE,65,5,215,15,ES_AUTOHSCROLL LTEXT "",IDC_STATUS,10,25,260,15,SS_CENTERIMAGE LTEXT "MinX:",IDC_STATIC,55,45,25,15,SS_CENTERIMAGE EDITTEXT IDC_MINX,80,45,40,15,ES_AUTOHSCROLL LTEXT "#X passi:",IDC_STATIC,165,45,30,15,SS_CENTERIMAGE EDITTEXT IDC_PASSI,200,45,40,15,ES_AUTOHSCROLL | ES_NUMBER LTEXT "MaxX:",IDC_STATIC,275,45,25,15,SS_CENTERIMAGE EDITTEXT IDC_MAXX,300,45,40,15,ES_AUTOHSCROLL CONTROL "",IDC_GRAFICO,"Static",SS_OWNERDRAW | SS_SUNKEN | WS_DISABLED | WS_BORDER,55,65,285,250 LTEXT "MaxY:",IDC_STATIC,5,65,40,15,SS_CENTERIMAGE EDITTEXT IDC_MAXY,5,80,40,15,ES_AUTOHSCROLL CONTROL "Auto-Y",IDC_AUTOY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 5,180,40,15 LTEXT "MinY:",IDC_STATIC,5,285,40,15,SS_CENTERIMAGE EDITTEXT IDC_MINY,5,300,40,15,ES_AUTOHSCROLL DEFPUSHBUTTON "Disegna",IDOK,290,5,50,15 END

Abbiamo usato IDC_STATIC come id di tutte le scritte; questa costante vale 0, e indica un controllo a cui non ci interesserà mai accedere nel corso dell'esecuzione. L'ordine dei controlli (scritte a parte, che non sono tab-stop) è un minimo pensato per comodità dell'utente -- il pushbutton di default è messo per ultimo, perchè è l'ultima delle preoccupazioni dell'utente quella di arrivarci a forza di tab, visto che, per "premerlo", gli basta in realtà battere un Enter.

Il controllo più grande di tutto il dialogo, naturalmente, è IDC_GRAFICO; esso non è altro che uno static, con il bit di stile SS_OWNERDRAW (oltre ad altri, puramente estetici, come SS_SUNKEN per dargli un aspetto "scavato" rispetto al resto del dialogo). Come faremo a disegnare su di questo, è dunque l'aspetto chiave che ci resta da chiarire, al di là di tante piccole finezze sul "controllo" complessivo del dialogo nel suo insieme e nel dettaglio. E questo chiarimento, naturalmente, lo proseguiremo al prossimo capitolo.


Capitolo 28: l'interprete: stub+scheletro
Capitolo 30: il disegno in Windows
Elenco dei capitoli