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.

























Commenti
Ho aggiornato anche il Progetto di Esempio.
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
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.
avevo già fatto come mi hai detto, ma non avevo eliminato la riga:
FontName = frm.FontName
Adesso funzione perfettamente!
Grazie
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
Codice:
DimensioneIniziale : 100 = NuovaDimensione : Zoomper calcolare il nuovo valore di Zoom, quindi si ricava che:
Codice:
Zoom = (NuovaDimensione * 100) / DimensioneInizialeTi basta calcolare questo valore ogni volta che il form viene ridimensionato.
Run Time 13
tipo non corrispondente e si blocca
Private Sub Form_Initialize ()
Set FormResizer = New clsResizer
With FormResizer
Set .OnForm = Me
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.
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.
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?
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.
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
Mandami pure un indirizzo via mail.
Ciao e Grazie
RSS feed dei commenti di questo post.