Sviluppo

Come faccio? - parte VIII

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 2 numero 6

Salve a tutti. È tempo di qualcosa di nuovo! Come promesso la volta scorsa, esamineremo qualcosa di diverso dai controlli di frame. Questo mese, cominceremo una breve serie su come creare e usare le finestre di dialogo (dialog boxes). Un dialog è un modo molto importante e flessibile per ottenere input in un programma PM. Inoltre, i dialog possono essere creati con strumenti visuali.

Il PM ha un gran numero di dialog predefiniti, tipo il dialog di apertura file, di scelta del font, e i vari message box. Questa serie di articoli sarà anche usata come punto di partenza per futuri articoli in cui useremo controlli avanzati come notebooks, contenitori, ecc. Di cosa tratteremo questo mese:

  • I concetti di parent (genitore) e owner (possessore) per le finestre
  • Dialog non modali
  • Dialog modali
  • La chiamata WinMessageBox.

Una finestra di dialogo / WinMessageBox

Cosa è esattamente una finestra di dialogo? Una finestra di dialogo è una figlia della finestra principale dell'applicazione in cui si realizza un'interazione con l'utente che non può essere ottenuta con i menu. So che questa definizione non è molto precisa: le sotto-finestre in una MDI (Multi Document Interface) potrebbero ben essere chiamate finestre di dialogo secondo questa definizione. Quindi per rendere le cose più chiare, ecco alcuni esempi di tipici dialog:
  • La finestra ricercare/sostituire dell'editor di sistema (E.EXE)
  • Il message box che appare per dire che c'è un errore o qualche altro evento
  • I dialog Aprire/Salvare file
  • Il dialog di scelta del font
  • In genere, le finestre Informazioni (About) delle applicazione
Molto spesso un dialog viene usato per comunicare qualcosa all'utente, per mostrare un errore, chiedere all'utente se proseguire o annullare l'azione corrente, ecc. Porterebbe via troppo tempo, memoria e velocità aver da costruire un dialog per ognuno di questi semplici usi. È per questo che ci sono due dialog predefiniti tra le API di OS/2: WinMessageBox e WinMessageBox2. Il secondo è una versione più sofisticata della finestra messaggio, e può essere modificata in molti modi (dateci un'occhiata, è divertente).

In questo articolo useremo WinMessageBox per mostrare il comportamento dei dialog. La chiamata di WinMessageBox è di questo tipo:

HWND     hwndParent;  //  Handle della finestra parent
HWND     hwndOwner;   //  Handle della finestra owner
PSZ      pszText;     //  Messaggio
PSZ      pszCaption;  //  Testo del titolo
ULONG    idWindow;    //  Window ID
ULONG    flStyle;     //  Stile della finestra
ULONG    usResponse;  //  Risposta dell'utente

usResponse = WinMessageBox(hwndParent, hwndOwner,pszText, pszCaption, idWindow, flStyle);
Per creare un message box, dobbiamo innanzitutto conoscere quali finestre saranno parent e owner del dialog. Ce ne occuperemo tra un momento. Il messaggio da passare all'utente deve essere specificato in pszText, il cui contenuto sarà mostrato all'interno della finestra. WinMessageBox gestisce molto bene questo testo. Se questo richiede molte linee per essere visualizzato, OS/2 semplicemente divide il testo nel punto più conveniente e modifica l'altezza della finestra per fargli posto. Questo è molto comodo poiché tra sistemi con risoluzioni diverse la lunghezza del testo può variare. OS/2 farà in modo che il message box sia mostrato corretamente.

La stringa pszCaption definisce il testo per il titolo della finestra. Io uso di solito una o due parole per descrivere il significato del dialog. Qualcosa tipo "ERRORE!" o "Attenzione" andranno bene. Notare che se il testo è troppo lungo sarà semplicemente troncato.

Il parametro idWindow non è molto importante per quello che facciamo questo mese. È un ID che viene passato al sistema di help quando il relativo pulsante (se lo abbiamo definito) viene premuto nel message box. Siccome non lo usiamo, poniamo questo parametro a 0.

Segue flStyle. Questo è un parametro che mi piace; con questo possiamo controllare completamente il funzionamento del message box. Questo parametro si usa in maniera molto simile ai flag FCF per una frame window. Dobbiamo solo mettere in 'or' (|) varie costanti e il risultato sarà un intero che il sistema esaminerà per mostrare il box nel modo che vogliamo.

WinMessageBox usa queste costanti per definire i pulsanti:

MB_OK                Pulsante OK
MB_OKCANCEL          Pulsanti OK e Annulla
MB_CANCEL            Pulsante Annulla
MB_ENTER             Pulsante Enter
MB_ENTERCANCEL       Pulsanti Enter e Annulla
MB_RETRYCANCEL       Pulsati Riprove e Annulla
MB_ABORTRETRYIGNORE  Pulsanti Annulla, Riprova, Ignora
MB_YESNO             Pulsanti Sì e No
MB_YESNOCANCEL       Pulsanti Sì, No, Annulla
MB_HELP              Pulsante Guida
Come utenti di OS/2, avrete notato che alcuni message box contengono immagini per indicare che tipo di messaggio viene visualizzato. Gli identificatori seguenti sono usati per mostrare un'icona nel message box. Notare che solo uno di questi identificatori può essere usato. Se ne vengono usati di più, il risultato può essere impredicibile. Noterete anche che ci sono diversi modi di mostrare la stessa icona. La ragione profonda di ciò mi è ignota.
MB_ERROR             Cerchio rosso con una linea rossa attraverso
MB_ICONASTERISK      Icona di informazione (i)
MB_ICONEXCLAMATION   Punto esclamativo (!)
MB_ICONHAND          Cerchio rosso con una linea rossa attraverso
MB_ICONQUESTION      Punto interrogativo (?)
MB_INFORMATION       Punto esclamativo (!)
MB_NOICON            Nessuna icona
MB_QUERY             Punto interrogativo (?)
MB_WARNING           Punto esclamtivo (!)
Il gruppo successivo include i cosiddetti indicatori di modalità. Cosa significhi modale e non modale sarà chiarito successivamente.
MB_APPLMODAL         Il message box è application modal
MB_SYSTEMMODAL       Il message box è system modal
Infine abbiamo l'indicatore di mobilità. Possiamo definire un message box in modo che non possa essere spostato. Tale box non avrà una barra del titolo. Se vogliamo che l'utente possa spostare il box, dobbiamo usare l'identificatore MB_MOVEABLE.

Quindi, se vogliamo creare una finestra di errore, possiamo fare così:

WinMessageBox(hwndParent,
              hwndOwner,
              "C'è stato un errore!",
              "ERRORE!"
              MB_OK | MB_ERROR);

Dialog modali e non modali

Le finestre di dialogo possono essere usate in molti modi. In effetti questo è il nocciolo di questo articolo. Se usate regolarmente applicazioni OS/2, saprete che ci sono dei dialog che appaiono e che devono essere chiusi prima che possiate accedere a qualsiasi altra finestra dell'applicazione. Un esempio di ciò sono le finestre di informazioni (About) e i dialog di apertura file in e.exe e in Smalled. Ci sono anche dei dialog che restano in primo piano rispetto all'applicazione, ma lasciano la possibilità di usare tutto quello che l'applicazione offre. Un esempio sono i dialog trova/sostituisci di molti editor. Finestre con queste caratteristiche sono chiamate modali e non modali, rispettivamente.

Un dialog modale restringerà l'interazione dell'utente al dialog stesso. L'utente non può interagire con altre finestre dell'applicazione. Con i message box possiamo andare un passo oltre e rendere il box system modal. Questo significa che l'utente non può interagire con alcun componente del sistema tranne il box stesso. Un esempio è un messaggio d'errore del sistema.

I dialog non modali, d'altra parte, permettono all'utente di interagire con tutte le altre finestre del sistema e dell'applicazione. A seconda del parent (vedi sezione seguente), la finestra resterà sopra all'applicazione, anche se non è attiva (si può vedere questo comportamento nel programma d'esempio di questo mese). Nel programma di questo mese (ZIP, 16k) non controlliamo se il dialog è già attivo. Poiché possiamo interagire con la finestra principale, possiamo aprire molte istanze dello stesso dialog. Secondo me questo è un errore comune. Vedremo come evitarlo più avanti in questi articoli dedicati ai dialog.

Owner e Parent

Non è mai stato detto esplicitamente in questi articoli, ma ogni finestra che creiamo deve avere un parent (genitore) e un owner (possessore). Ad esempio la client window delle piccole applicazioni che abbiamo scritto finora aveva la frame window sia come parent sia come owner. Questi concetti sono importanti perché, in buona parte, definiscono il comportamento di una finestra.

Cos'è un parent?

Il compito più ovvio che una finestra genitrice ha è quello di controllare dove le sue finestre figlie (child windows) saranno visibili. Le child windows sono ritagliate (clipped) entro la parent window. Questo significa che se spostate una finestra figlia oltre i bordi della genitrice, le parti "in eccedenza" non saranno visibili (questo si piò vedere nel programm d'esempio). Significa anche che se vogliamo poter spostare un dialog per tutto lo schermo, il parent non può essere la finestra dell'applicazione: dobbiamo usare il desktop. Per questo, OS/2 ha la costante HWND_DESKTOP che può essere usata come hwndParent.

Una finestra figlia erediterà anche tutti gli stili della genitrice. Questo significa che se la genitrice è visibile, lo sarà anche la figlia. Potete controllare facilmente nascondendo la finestra di Sample8. Se viene aperto un dialog, questo verrà nascosto assieme al parent (in questo caso, la frame window). Una finestra figlia verrà anche spostata assieme alla genitrice se quest'ultima viene mossa. Di nuovo, potete controllare spostando Sample8 con un dialog aperto. Infine, una child window sarà sempre in primo piano rispetto alla parent window.

L'esistenza di una child window dipende dall'esistenza della parent. Se quest'ultima viene distrutta, anche tutte le figlie verranno distrutte. Tutto ciò è logico, perché, se non c'è la genitrice, la figlia non ha un posto in cui mostrarsi.

Cos'è un owner?

I compiti di una owner window sono in gran parte gli stessi della parent window. Le finestre possedute sono distrutte, nascoste, o minimizzate assieme al possesore. La differenza principale è che le finestre possedute non sono ritagliate entro il possessore. Le finestre possedute possono quindi essere spostate oltre i bordi del possessore.

Un'altra differenza degna di nota è che c'è comunicazione tra owner (possessore) e owned (posseduto). L'owner riceverà un messaggio WM_CONTROL con i parametri che indicano quale dialog ha inviato il messaggio e cosa è accaduto. Ci occuperemo di questo in un articolo futuro.

L'esempio di questo mese contiene un programma molto semplice che mostra il comportamento dei dialog con varie impostazioni. Per questo vengono usati dei message box. Il mese prossimo ci addentreremo più a fondo nei dialog. Creeremo dei nuovi dialog e daremo un'occhiata alle procedure di gestione dei dialog. E ovviamente riappariranno dialog modali e non modali.


[Pagina precedente] [Sommario] [Pagina successiva]