![]() |
Come faccio? - parte VIII![]() |
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:
Una finestra di dialogo / WinMessageBoxCosa è 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:
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 GuidaCome 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 modalInfine 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 modaliLe 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 ParentNon è 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. |