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.

 

HEADER  

 
+3 #1 TheTruster Y-m-d H:i
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.
 
 
0 #2 Y-m-d H:i
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
 
 
+3 #3 TheTruster Y-m-d H:i
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.
 
 
0 #4 Y-m-d H:i
Grazie The Truster
avevo già fatto come mi hai detto, ma non avevo eliminato la riga:
FontName = frm.FontName

Adesso funzione perfettamente!
 
 
0 #5 Y-m-d H:i
Come potrei adattare il codice al VBA di Excel?
Grazie
 
 
0 #6 TheTruster Y-m-d H:i
QUOTE_PREFIX RosarioQUOTE_SU FFIX
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.
 
 
0 #7 Y-m-d H:i
QUOTE_PREFIX TheTrusterQUOTE _SUFFIX
QUOTE_PREFIX RosarioQUOTE_SU FFIX
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
 
 
0 #8 TheTruster Y-m-d H:i
Come dicevo basta implementare una semplice proporzione. Sono nozioni di matematica piuttosto elementari:

CODEDimensioneIniziale : 100 = NuovaDimensione : Zoom

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

CODEZoom = (NuovaDimensione * 100) / DimensioneIniziale

Ti basta calcolare questo valore ogni volta che il form viene ridimensionato.
 
 
0 #9 Y-m-d H:i
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
 
 
0 #10 TheTruster Y-m-d H:i
QUOTE_PREFIX FdsergioQUOTE_S UFFIX
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.
 
 
0 #11 Y-m-d H:i
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.
 
 
0 #12 TheTruster Y-m-d H:i
QUOTE_PREFIX FdsergioQUOTE_S UFFIX
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.
 
 
0 #13 Matteo Y-m-d H:i
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?
 
 
0 #14 Y-m-d H:i
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.
 
 
0 #15 TheTruster Y-m-d H:i
QUOTE_PREFIX LukeQUOTE_SUFFI X
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
 
 
0 #16 Y-m-d H:i
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
 
 
0 #17 Y-m-d H:i
Ciao
A causa della mia ignoranza access, non riesco a capire dove inserire il secondo codice di seguito. Nella maschera non ho l'evento Initialize() grazie

Dim FormResizer As clsResizer

Private Sub Form_Initialize ()

Set FormResizer = New clsResizer

With FormResizer
Set .OnForm = Me
.SameFont = True
.FontName = "Tahoma"
.JustShiftContro ls = False
End With

End Sub
 
 
0 #18 Y-m-d H:i
Ciao The Truster
Non riesco a capire dove inserire la seconda parte del codice grazie 1000
Queste sono le uniche righe di codice da utilizzare per ottenere l'effetto di ridimensionare i controlli al variare della dimensione del form:
 
 
0 #19 TheTruster Y-m-d H:i
Salve Christian, mi scuso per il ritardo nella risposta.
Purtroppo non puoi utilizzare quel codice in Access. Anche se il linguaggio è VBA, che è simile al VB6, e ci sono dei Form, questi hanno una gestione interna e una concezione radicalmente diversa da Visual Basic 6 e persino dalle altre applicazioni che usano VBA come Word ed Excel.

Mi spiace di non poterti essere più utile e ti ringrazio per avermi scritto.
 

Sondaggio

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

Utenti on-line

 202 visitatori online

MasterDrive.it



Aggiungi TheTruster's Box ai preferiti!


Scarico di Responsabilità


Tutto il materiale pubblicato è di libero utilizzo.
E' gradito il riferimento al Sito ed all'autore nel codice o nel progetto in cui questo viene utilizzato. NON si garantisce in alcun modo per errori di programmazione o eventuali danni causati da bugs, nè si è responsabili di alcuna problematica inerente all'utilizzo del codice o dei prodotti esposti. Chi usa il materiale esposto nel sito lo fà a proprio rischio assumendosene la completa responsabilità.

Questo sito utilizza cookie, anche di terze parti, per personalizzare i contenuti. Per informazioni o negare il consenso a tutti o ad alcuni cookie leggi la nostra Cookie Policy. Chiudendo questo banner, scorrendo questa pagina o cliccando su qualunque suo elemento acconsenti all'uso dei cookie. Per informazioni sui Cookies che usiamo e su come cancellarli, guarda la nostra Cookie Policy.

Accetto esplicitamente i Cookies di questo sito.

EU Cookie Directive Module Information