TheTruster's Box

  • Increase font size
  • Default font size
  • Decrease font size
Home Programmazione Articoli Adattare un Form alla risoluzione dello schermo

Adattare un Form alla risoluzione dello schermo

E-mail Stampa PDF

Quando si realizza un'applicazione, spesso si progetta l'interfaccia grafica tenendo conto solo dello spazio relativo alla risoluzione impostata sul proprio monitor. Questo di per se, non sarebbe un male... senonchè è sicuramente probabile che gli utenti della nostra applicazione abbiano impostato risoluzioni diverse dalla nostra. In pratica ci sarà chi non subirà nessun fastidio perchè avrà impostato una risoluzione maggiore di quella con la quale abbiamo sviluppato il programma e chi, invece, non farà altro che maledirci perchè vedrà solo parte del Form principale a causa di una risoluzione inferiore!

Certamente chi usa il nostro programma potrà fare lo sforzo di cambiare la risoluzione del suo monitor per vedere tutti i nostri TextBox, ma sono sicuro che defraudare l'utente della libertà di scegliersi la sua risoluzione non sia tanto costruttivo per la popolarità del nostro programmino... tantomeno riterrei opportuno far compiere questa operazione all'applicazione stessa, perchè questo andrebbe certamente a cozzare con le impostazioni previste da altre applicazioni.

In sostanza, ritengo che la soluzione migliore sia quella di fare in modo che la nostra applicazione sia in grado di adattarsi all'ambiente in cui si trova a "girare", spostando e/o ridimensionando i controlli presenti sul form per adattarlo ad una risoluzione diversa da quella con cui lo si è progettato.

In linea di principio è un'operazione relativamente semplice, ma la difficoltà risiede nell'adottare una soluzione flessibile, in grado di funzionare form di qualsiasi dimensione e contenente un numero qualsiasi di controlli.

Per facilitare le cose ho deciso di scrivere una Classev in Visual Basic 6 che, una volta istanziata, si occupa di ricevere, attraverso le sue proprietà, il riferimento al Form da ridimensionare, più altri parametri facoltativi che descriverò in seguito.

Ecco il codice della Classe che dovrà essere inserito in un Modulo di Classe nel progetto in cui si intende utilizzarlo, denominato clsResizer:

'***************************************************************************************
'***************************************************************************************
'**                                                                                   **
'**  Created By  : Mirko Marchese AKA TheTruster                                      **
'**                http://thetruster.altervista.org         (TheTruster's Box)        **
'**                                                                                   **
'**  Created On  : 22 Feb 2010                                                        **
'**  Last Update :                                                                    **
'**                                                                                   **
'**  VB Versions : 5.0 / 6.0                                                          **
'**                                                                                   **
'**  Requires    : a VB Project                                                       **
'**                                                                                   **
'**  Description : Classe per l'adattamento dei controlli presenti su un form alla    **
'**                sua dimensione, tramite  il ridimensionamento  e lo spostamento    **
'**                degli stessi.                                                      **
'**                                                                                   **
'***************************************************************************************
'***************************************************************************************

Dim WithEvents m_ParentFrm As Form
Dim clControls As Collection
Dim Start_frmWidth As Single
Dim Start_frmHeight As Single
Dim m_SameFont As Boolean
Dim m_FontName As String
Dim m_JustShiftControls As Boolean
 
Property Let JustShiftControls(ByVal newValue As Boolean)
m_JustShiftControls = newValue
End Property
 
Property Get JustShiftControls() As Boolean
JustShiftControls = m_JustShiftControls
End Property
 
Property Let SameFont(ByVal newValue As Boolean)
m_SameFont = newValue
End Property
 
Property Get SameFont() As Boolean
SameFont = m_SameFont
End Property
 
Property Let FontName(ByVal newValue As String)
m_FontName = newValue
End Property
 
Property Get FontName() As String
FontName = m_FontName
End Property
 
Property Set OnForm(ByVal frm As Form)
Set m_ParentFrm = frm
FontName = frm.FontName
End Property
 
Property Get OnForm() As Form
Set OnForm = m_ParentFrm
End Property
 
Public Sub ResetControls()
 
End Sub
 
Private Sub m_ParentFrm_Load()
 
Dim clControlProps As Collection
Set clControls = New Collection
 
Start_frmWidth = m_ParentFrm.ScaleWidth
Start_frmHeight = m_ParentFrm.ScaleHeight
 
On Error Resume Next
 
Dim ctl As Control
For Each ctl In m_ParentFrm.Controls
    Set clControlProps = New Collection
    With clControlProps
        .Add ctl, "CtlRef"
        If Not TypeOf ctl Is Line Then
            .Add ctl.Left, "Left"
            .Add ctl.Top, "Top"
            .Add ctl.Width, "Width"
            .Add ctl.Height, "Height"
        Else
            .Add ctl.X1, "Left"
            .Add ctl.Y1, "Top"
            .Add ctl.X2, "Width"
            .Add ctl.Y2, "Height"
        End If
        .Add ctl.Font.Size, "FontSize"
    End With
    clControls.Add clControlProps
    Set clControlProps = Nothing
Next ctl
 
End Sub
 
Private Sub m_ParentFrm_Resize()
 
Dim XRatio As Double
Dim YRatio As Double
Dim AvgRatio As Double
 
XRatio = m_ParentFrm.ScaleWidth / Start_frmWidth
YRatio = m_ParentFrm.ScaleHeight / Start_frmHeight
AvgRatio = (XRatio + YRatio) / 2
 
Dim ctlToResize As Control
Dim ctlProps As Collection
 
On Error Resume Next
 
Dim tmpControl As Object
 
For c = 1 To clControls.Count
    Set ctlProps = clControls(c)
    Set ctlToResize = ctlProps("CtlRef")
    With ctlToResize
        If Not TypeOf ctlToResize Is Line Then
            .Left = ctlProps("Left") * AvgRatio
            .Top = ctlProps("Top") * AvgRatio
            If Not JustShiftControls Then
                .Width = ctlProps("Width") * AvgRatio
                .Height = ctlProps("Height") * AvgRatio
                If SameFont And FontName <> "" Then
                    .Font.Name = FontName
                End If
                .Font.Size = ctlProps("FontSize") * AvgRatio
            End If
        Else
            .X1 = ctlProps("Left") * AvgRatio
            .Y1 = ctlProps("Top") * AvgRatio
            .X2 = ctlProps("Width") * AvgRatio
            .Y2 = ctlProps("Height") * AvgRatio
        End If
    End With
Next
 
End Sub

La classe è in grado di intercettare l'evento Resize del Form, nella cui routine di evento esegue il codice necessario al ridimensionamento/spostamento dei controlli e si può definirne le proprietà nell'evento Initialize del Form ove va utilizzata.
Queste sono le uniche righe di codice da utilizzare per ottenere l'effetto di ridimensionare i controlli al variare della dimensione del form:

Dim FormResizer As clsResizer
 
Private Sub Form_Initialize()
 
Set FormResizer = New clsResizer
 
With FormResizer
    Set .OnForm = Me
    .SameFont = True
    .FontName = "Tahoma"
    .JustShiftControls = False
End With
 
End Sub

La prima riga istanzia la classe. Nell'evento Initialize viene impostato il riferimento al Form, attraverso la proprietà onForm.
Questa la descrizione delle altre Proprietà:

  • SameFont se è True specifica che i controlli dovranno avere tutti lo stesso Font;
  • FontName Imposta il nome del Font da utilizzare. Se non è specificato viene usato quello del Form;
  • JustShiftControls Se impostata a True sposta i Controlli per distribuirli sul Form, ma senza ridimensionarli.

Spero di essere stato sufficientemente chiaro nell'esposizione del funzionamento della Classe. In caso contrario contattatemi pure per chiarimenti o consigli.


Scarica la Classe e il progetto di esempio.

 

Commenti  

 
0 #1 TheTruster 2010-02-28 16:26
Su segnalazione fornitami da un utente di MasterDrive.it, ho aggiunto la possibilità da parte della classe di ridimensionare anche i controlli Linea, che in precedenza avevo trascurato.
Ho aggiornato anche il Progetto di Esempio.
Citazione
 
 
0 #2 2010-06-07 10:28
Ciao TheTruster
Volevo chiederti come fare con i form MDI perchè ho provato a inserire la tua routine in un mio progetto e mi dà questo errore:

"L'oggetto o la classe non supporta il gruppo di eventi"

alla riga:
Set m_ParentFrm = frm

Grazie mille
Citazione
 
 
+1 #3 TheTruster 2010-06-07 10:49
Ciao Giacomo,
Il tutto potrebbe essere adattato ad un MDIForm.

Per farlo funzionare, nella Classe, devi variare tutte le dichiarazioni "As Form" ponendole "As MDIForm".

Inoltre, nella routine "Property Set OnForm" devi eliminare la la seguente riga:

FontName = frm.FontName

Considera che potrebbero esserci alcune imprecisioni nel ridimensionamen to, soprattutto dovute alla leggera differenza di gestione tra un MDI e un Form normale.

Altro particolare: i Child Forms non subiscono alcuna alterazione delle dimensioni, a meno che essi non siano massimizzati.
Citazione
 
 
0 #4 2010-06-07 11:20
Grazie The Truster
avevo già fatto come mi hai detto, ma non avevo eliminato la riga:
FontName = frm.FontName

Adesso funzione perfettamente!
Citazione
 
 
0 #5 2010-07-08 06:54
Come potrei adattare il codice al VBA di Excel?
Grazie
Citazione
 
 
0 #6 TheTruster 2010-07-08 07:17
Citazione Rosario:
Come potrei adattare il codice al VBA di Excel?


Ciao Rosario,
In Excel ci sono diverse difficoltà di adattamento della classe in argomento, che risiedono principalmente nella mancanza di alcune proprietà del Form (ScaleWidth e ScaleHeight).

A prescindere dal codice postato, comunque, il ridimensionamen to proporzionale del controlli, in Excel è possibile attraverso il semplice utilizzo della proprietà Zoom del Form. Quando è impostata a 100 i controlli sono nelle dimensioni normali e rimpiccioliscon o o ingrandiscono a seconda che questo valore diminuisca o aumenti. Basta legare questo valore alle dimensioni del Form con una semplice proporzione per ottenere l'adattamento immediato dei controlli.
Citazione
 
 
0 #7 2010-07-08 08:34
Citazione TheTruster:
Citazione Rosario:
Come potrei adattare il codice al VBA di Excel?


Ciao Rosario,
In Excel ci sono diverse difficoltà di adattamento della classe in argomento, che risiedono principalmente nella mancanza di alcune proprietà del Form (ScaleWidth e ScaleHeight).

A prescindere dal codice postato, comunque, il ridimensionamen to proporzionale del controlli, in Excel è possibile attraverso il semplice utilizzo della proprietà Zoom del Form. Quando è impostata a 100 i controlli sono nelle dimensioni normali e rimpiccioliscon o o ingrandiscono a seconda che questo valore diminuisca o aumenti. Basta legare questo valore alle dimensioni del Form con una semplice proporzione per ottenere l'adattamento immediato dei controlli.

Potresti farmi un esempio ... sai non sono un esperto di VBA
Citazione
 
 
0 #8 TheTruster 2010-07-08 10:23
Come dicevo basta implementare una semplice proporzione. Sono nozioni di matematica piuttosto elementari:

Codice:DimensioneIniziale : 100 = NuovaDimensione : Zoom

per calcolare il nuovo valore di Zoom, quindi si ricava che:

Codice:Zoom = (NuovaDimensione * 100) / DimensioneIniziale

Ti basta calcolare questo valore ogni volta che il form viene ridimensionato.
Citazione
 
 
0 #9 2010-07-17 14:03
ho inserito la classe in un Form MDI e come hai suggerito a Giacomo ho fatto la stessa cosa e si è verificato il seguente errore su una child massimizzata a prescindere dalla risoluzione:
Run Time 13
tipo non corrispondente e si blocca
Private Sub Form_Initialize ()
Set FormResizer = New clsResizer

With FormResizer
Set .OnForm = Me
Citazione
 
 
0 #10 TheTruster 2010-07-19 05:22
Citazione Fdsergio:
ho inserito la classe in un Form MDI e come hai suggerito a Giacomo ho fatto la stessa cosa e si è verificato il seguente errore su una child massimizzata a prescindere dalla risoluzione


Se hai apportato alla Classe i cambiamenti suggeriti allora hai variato anche la dichiarazione da As Form a As MDIForm.

Questo, ovviamente, rende incompatibile la classe con un form Child.
Per usare la classe in entrambe i Form devi crearne 2 versioni: una così com'è esposta nell'articolo e una modificata ed adattata per l'MDI. Ovviamente le classi dovranno avere nomi differenti, e ognuna dovrà essere usata nello specifico contesto.
Citazione
 
 
0 #11 2010-07-24 12:16
Ti ringrazio prima di tutto per la risposta, adesso funziona quasi correttamente; ti segnalo un piccolo problema con lo StatusBar - utilizzo risoluzione 1024x768 e con questa risoluzione lo statusBar risulta già ingrandito, aumentando la risoluzione aumenta lo StatusBar in maniera spropositata.
Citazione
 
 
0 #12 TheTruster 2010-07-25 16:44
Citazione Fdsergio:
aumentando la risoluzione aumenta lo StatusBar in maniera spropositata.


Analogamente a quanto già suggerito per la Line, ti basta inserire una condizione che ti permetta di escludere il codice di ridimensionamen to casomai il TypeOf del controllo sia StatusBar.
Citazione
 
 
0 #13 Matteo 2010-09-13 08:13
Ciao "TheTruster",
ho provato ad usare la tua classe ma forse sbaglio in qualcosa perchè non mi funzione.
Ti spiego il mio problem. Ho un progetto composto da 1 mdiForm e 7 form normali. Ho proggettato il tutto con il mio pc che ha una risoluzione di 1280 x 800. Quando vado a installare il programma su un altro pc che ha una risoluzione di 1024 x 768 vedo tutto molto piu grande. Non so cortesemente mi puoi dare qualche suggerimento?
Citazione
 
 
0 #14 Luke 2011-11-13 16:18
Ciao TheTruster,
innanzitutto ti faccio i complimenti per il tuo progetto.
Riscontro però un problema con i commandbutton.
Se avvio il progetto vedo il form iniziale giustamente ridimensionato poi attraverso il button passo ad un altro form e anche qui vedo tutto ridimensionato nel modo giusto, ma se torno al form iniziale e poi ripasso ad un'altro form mi spariscono alcune impostazioni dei commandbutton come ad esempio il colore e il caption.
I comandi però continuano a funzionare correttamente.
Hai idea di cosa possa causare questo problema?
Grazie mille per l'attenzione e per il tuo lavoro.
Citazione
 
 
0 #15 TheTruster 2011-11-15 18:47
Citazione Luke:
Se avvio il progetto vedo il form iniziale giustamente ridimensionato poi attraverso il button passo ad un altro form e anche qui vedo tutto ridimensionato nel modo giusto, ma se torno al form iniziale e poi ripasso ad un'altro form mi spariscono alcune impostazioni dei commandbutton come ad esempio il colore e il caption.


Ciao Luke,
Ho fatto qualche prova, cercando di compiere le azioni che hai descritto... ma a me funziona tutto regolarmente.
Anche se uso diversi form nell'applicazione tutte continuano a mantenere la possibilità di essere ridimensionate e non si verificano problemi di sorta nella visualizzazione dei controlli.

Magari potresti creare una versione semplificata del tuo progetto, includendo i Form malfunzionanti, e caricarla su un servizio di hosting. Se me ne fornisci il link potrei dare un'occhiata direttamente al tuo prgetto.

TheTruster
Citazione
 
 
0 #16 Luke 2011-11-15 20:04
Dove posso inviarti lo zippato del progetto? Non pesa molto, ho lasciato solo il necessario per darti un'idea.
Mandami pure un indirizzo via mail.
Ciao e Grazie
Citazione
 

Aggiungi commento

Si prega di aggiungere commenti in tema.
Sono assolutamente vietati messaggi volgari, pubblicitari e/o promozionali.
I commenti ritenuti non conformi saranno rimossi.


Codice di sicurezza
Aggiorna

Sondaggio

Cosa vorresti vedere di più su TheTruster's Box?
 

Utenti on-line

 2 visitatori online

MasterDrive.it



Aggiungi TheTruster's Box ai preferiti!