Newsgroup: it.comp.lang.visual-basic
Titolo: Ridimensionamento form

Come e' possibile permettere all'utente di ingrandire/rimpicciolire la form
come vuole in modo che anche gli oggetti contenuti nel form si ridimensioni
in proporzione?
Nella  proprietą BorderStyle della form metto Sizable in modo che si
ingrandisce come si vuole. Il mio problema perņ č che gli oggetti rimangono
con le stesse dimensioni, come faccio ad ingrandire anche loro?.
Ciao e Grazie.

 in proporzione?
è un casino, lascia perdere, secondo me non ne vale la pena, piuttosto
blocca la ridimensionabilità del form con fixed single, così all'utente non
viene in mente di modificare le dimensioni.
In ogni caso devi lavorare sulle proprietà width ed height, penso(non sono
un guru) e poi il casino viene dopo perchè secondo me per fare un lavoro
"decente", dopo averli ridimensionati li devi anche spostare
Qualcuno ora mi lancerà delle pietre per le castronerie dette (uno ci prova
ad analizzare i problemi, poi non sono mica tutti dei fenomeni come voi a
'sto mondo!)
:-P
;-)
Davide

 Qualcuno ora mi lancerà delle pietre per le castronerie dette
No, anzi, hai detto bene. Ma perchè pensi che sia tanto un casino ?
E' solo questione di un po' di matematica elementare... solo
semplici moltiplicazioni e divisioni, in effetti :-)
Comunque, visto che è uno dei primi problemi che si presentano
ad un VBista, non ti stupirà sapere che in rete esistono OCX, .DLL,
classi e anche semplici sub che fanno proprio questo.
Se ti interessa, vedi sul Sito Comune, se non ricordo male c'è una DLL.
Bye, G.
--
Le risposte alle tue domande sono sul Sito Comune
di questo NewsGroup: 
http://it-lang-vb.net/
... e nell'help in linea !

 semplici moltiplicazioni e divisioni, in effetti :-)
Più che altro penso che non ne valga la pena, insomma capisco che sia
matematica ma secondo me non la fai in mezz'ora una procedura del genere se
non sei un guru.
si fà prima a mettere il form fixed single, poi forse dipende da uno cosa
deve fare.....
smentiscimi se credi, non aspetto altro,  :-)
Davide

 deve fare.....
Anch'io pensavo che non ne valesse la pena a meno che non fosse un
programma particolarmente "grafico". Poi ho cominciato a programmare
anche per altri, non solo per me... Vedi, questo ragionamento è valido
solo finché gli utenti usano tutti la stessa tua risoluzione di schermo.
Se un utente ha 600*800 (per non parlare di un 640*480, e ce ne
sono ancora tanti) e tu usi 1024*768, un tuo form un po' grande
potrebbe uscirgli dallo schermo. Se capitasse il contrario, magari non
riuscirebbe neanche a leggere le label.
Hai mai visto la differenza fra un 15 pollici settato a 800*600 e un bel
monitorone 21'' da CAD, con magari 1280*1024 o addirittura un fuori
standard, tipo 2048*1536 ? Ti garantisco che se un prog non è
disegnato apposta, non è neanche utilizzabile.
***********************************
DISCLAIMER - DISCLAIMER - DISCLAIMER
Il codice sviluppato nel seguito è a solo scopo
dimostrativo, non pretende di essere un trattamento
esaustivo, nè formalmente corretto del problema.
Può certamente essere ottimizzato, migliorato
e completato, lo so benissimo...
DISCLAIMER - DISCLAIMER - DISCLAIMER
***********************************
Così chi dico io non mi si mangia ;-)))
Vabbe', torniamo al problema originale... analizziamo il problema
e vediamo come si potrebbe risolvere, magari non in una
mezz'oretta, o magari anche in meno :-). Tanto per cominciare,
semplifichiamo: immagina un form con un solo controllo, prendiamo
per fare un esempio un Frame. Volendo che all'ingrandirsi o ridursi
del form si ingrandisca anche il Frame, dovremo ricalcolarne
le dimensioni (.Width e .Height) e la posizione (.Top e .Left), in
proporzione alle dimensioni del Form, come tu giustamente dicevi.
Proviamo a raddoppiare le dimensioni del form; dovremmo
raddoppiare anche le dimensioni del Frame, giusto ? E se triplicassimo
il form, dovremmo triplicare anche il frame... se invece lo riducessimo
a metà, dovremmo dimezzare il Frame, giusto ? Se invece riducessimo
l'altezza e contemporaneamente aumentassimo la larghezza ?...
Beh, dovremmo fare la stessa cosa al Frame, no ?
Generalizzando, dobbiamo quindi vedere di quanto abbiamo modificato
ognuna delle dimensioni del form e modificare nella stessa proporzione
il controllo contenuto. Per fare questo dobbiamo memorizzare le
dimensioni e le posizioni prima delle modifiche; potremmo farlo nel
Form_Load. Cominciando a buttare giù un po di codice, dichiariamo
quindi qualche variabile:
Option Explicit
    Dim LargOriginaleForm As Long
    Dim AltOriginaleForm As Long
    Dim LargOriginaleFrame As Long
    Dim AltOriginaleFrame As Long
    Dim LeftOriginaleFrame As Long
    Dim TopOriginaleFrame As Long
e nel Form_load facciamo:
    LargOriginaleForm = Me.Width
    AltOriginaleForm = Me.Height
    LargOriginaleFrame = Frame1.Width
    AltOriginaleFrame = Frame1.Height
    TopOriginaleFrame = Frame1.Top
    LeftOriginaleFrame = Frame1.Left
A questo punto, dobbiamo vedere quando il Form viene ridimensionato;
per questo c'è la sub Form_Resize, che è fatta apposta. Andiamo lì e
inseriamo quello che vogliamo fare:
With Frame1
' la dimensione che vogliamo ottenere è in proporzione alla dimensione
' originaria del Form e quella attuale, quindi, ricordando dalle medie
' come si fanno le proporzioni:
.Width = LargOriginaleFrame * (Me.Width / LargOriginaleForm)
.Height = AltOriginaleFrame * (Me.Height / AltOriginaleForm)
.Left = LeftOriginaleFrame * (Me.Width / LargOriginaleForm)
.Top = TopOriginaleFrame * (Me.Height / AltOriginaleForm)
End With
Proviamo a vedere i risultati... FUNZIONA !!! :-)))
Già... però funziona solo per _questo_ controllo frame. Se ne
mettiamo un altro non si muove di un pixel, neanche se preghiamo
in sanscrito.
Evidentemente non siamo stati abbastanza generici: noi vogliamo
che qualunque cosa mettiamo sul Form si ridimensioni, giusto ?
Quindi, per ogni controllo dovremmo dichiarare le variabili, e poi aggiungere
il codice nella resize, bell'affare :-((((
Eppure una soluzione ci sarà... se solo si potesse fare qualcosa tipo:
"per ogni controllo sul Form, ridimensionalo", sarebbe facile, no ?
Ok, veniamo alle buone notizie: SI PUO' :-))) ! Una bella cosa del VB
che ti aiuta proprio in questo caso è che c'è la Controls collection,
cioè proprio un elenco dei controlli caricati. Un'occhiata all'help per
capire come funziona, poi modifichiamo il programmillo di conseguenza:
ci serve una bella serie di variabili, poi vediamo anche i ridimensionamenti.
-------------------------------------------------
Nelle "generali":
Option Explicit
Dim LargOriginaleForm As Long
Dim AltOriginaleForm As Long
' su un form IMHO non ci dovrebbero essere più di una ventina
' di controlli al massimo, per ragioni di leggibilità, ma non si sa mai.
' e poi ci sono anche i controlli non visibili...
Dim LargOriginaleControllo(256) As Long
Dim AltOriginaleControllo(256) As Long
Dim LeftOriginaleControllo(256) As Long
Dim TopOriginaleControllo(256) As Long
Nella Form_Load:
     LargOriginaleForm = Me.Width
     AltOriginaleForm = Me.Height
     Dim N As Long
     For N = 0 To Me.Controls.Count - 1
          With Controls.Item(N)
               LargOriginaleControllo(N) = .Width
               AltOriginaleControllo(N) = .Height
               TopOriginaleControllo(N) = .Top
               LeftOriginaleControllo(N) = .Left
          End With
     Next N
Nella Form_Resize:
     Dim N As Long
     For N = 0 To Me.Controls.Count - 1
          With Controls.Item(N)
               ' la dimensione che vogliamo ottenere è in proporzione alla
dimensione
               'originaria del Form e quella attuale, quindi:
               .Width = LargOriginaleControllo(N) * (Me.Width /
LargOriginaleForm)
               .Height = AltOriginaleControllo(N) * (Me.Height /
AltOriginaleForm)
               .Left = LeftOriginaleControllo(N) * (Me.Width /
LargOriginaleForm)
               .Top = TopOriginaleControllo(N) * (Me.Height / AltOriginaleForm)
          End With
     Next N
-------------------------------------------------
Già così, con una trentina di linee di codice, abbiamo fatto buona parte
del lavoro: qualunque controllo normale viene ridimensionato.
D'altra parte abbiamo ancora qualche "problemino":
--- i caratteri, che rimangono sempre uguali.
--- eventuali controlli che non essendo visibili a runtime, non hanno le
proprietà relative alle dimensioni, o altri (ComboBox, per esempio)
che le hanno in sola lettura.
--- ci sarebbe da vedere eventuali controlli Line, che vanno gestiti a
parte, poiché non hanno Top, Left eccetera, ma X1, X2...
--- controlli creati o caricati/scaricati a runtime.
--- si dovrebbe ottimizzare un po', per esempio tirando fuori dal ciclo
del resize i calcoli delle percentuali di ridimensionamento, non
dimensionare le matrici delle dimensioni dei controlli e usare Redim
Preserve con Me.Controls.Count; il che ci faciliterebbe anche le cose
in caso di aggiunta di controlli a runtime.
--- Se ne dovrebbe poi fare una routine generica, che possa essere messa
in un modulo/dll/ocx e utilizzata in caso di necessità, magari passando
come parametro il form.
Per il problema dei caratteri, lo lasciamo come compito a casa per i
più volenterosi, OK ?
Dai, non è difficile: un'altra matrice di variabili e un'altra proporzione...
Per il secondo prob, una maniera sporca ma veloce di risolvere il problema
sarebbe quella di piazzare un bel (Roal adesso mi ammazza...) "On error
resume next" nella _Resize, mentre un sistema più corretto prevede
una verifica del TypeOf Control.
Già a questo punto, un'altra dozzina di righe, e il 90 per cento dei
programmi che non usano Line, non caricano controlli a runtime, e
magari non abbiano decine di form, sono a posto.
Comunque quella classe clresize.zip sul Sito Comune fa già tutto questo :-)
Bye, G.

>>>> "P" == Paperino  <non...@lo.dico> writes:
P> Anch'io pensavo che non ne valesse la pena a meno che non fosse un
P> programma particolarmente "grafico". Poi ho cominciato a programmare
P> anche per altri, non solo per me... Vedi, questo ragionamento è valido
P> solo finché gli utenti usano tutti la stessa tua risoluzione di schermo.
C'e` sempre la soluzione rozza  di verificare il form alle risoluzioni
minori.  Ha il  grosso vantaggio  di non  richiedere cicli  macchina a
runtime.
P> Hai mai visto la differenza fra un 15 pollici settato a 800*600 e un bel
P> monitorone 21'' da CAD, con magari 1280*1024 o addirittura un fuori
P> standard, tipo 2048*1536 ? Ti garantisco che se un prog non è
P> disegnato apposta, non è neanche utilizzabile.
In passato ho  speso una decina d'anni in un'ambiente  in cui c'era un
cluster  di 100  workstation con  quello che  windows  chiama "profilo
roaming". In realta` era solo yello pages (prima) o NIS+ (poi) con NFS.
C'erano macchine  con monitor da 15, 17,  19 ed un bestione  da 21 sul
quale  ci si  andava malvolentieri  perche', per  un uso  orientato ai
testi e sorgenti  (e non alla grafica), era scomodo  a causa del campo
visivo troppo ampio richiesto.
E' corretto come principio pensare  anche a questo ma al momento della
ingegnerizzazione di un prodotto si passa dal mondo della lavagna alla
vita reale. Un programma gestionale  di solito viene usato da un tizio
che non gradisce che tutta la sua scrivania sia occupata da un colosso
da  21' :).   E d'altro  canto i  CAD usati  nell'industria richiedono
grosse  risorse  come CPU  e  spazio  disco  (salvano molti  risultati
intermedi per non ricalcolarli) e  quindi di solito la contabilita` va
su altre macchine :).
P> .Left = LeftOriginaleFrame * (Me.Width / LargOriginaleForm)
P> .Top = TopOriginaleFrame * (Me.Height / AltOriginaleForm)
Occhio. I controlli  piu` a sinistra e piu` in alto  e` meglio che non
cambino il  loro left  o il  loro top che  altrimenti li  distanzi dal
bordo ed aumenti  lo spazio "sprecato" ai bordi e  l'effetto non e` (a
parer mio) gradevole.
P> Ok, veniamo alle buone notizie: SI PUO' :-))) ! Una bella cosa del VB
P> che ti aiuta proprio in questo caso è che c'è la Controls collection,
Genericissima si,  ma il  tempo che tu  risparmi a programmare  lo fai
perdere  a runtime  all'utente.  Le collezioni,  rispetto a  strutture
statiche, sono lente.
In alcuni  casi abbiamo sviluppato dei programmi  dove alcune maschere
erano ridimensionabili (non ha molto senso ridimensionare una maschera
di sole textbox, sopratutto considerando che il numero di utenti di un
programma del  genere con  uno schermo  da 21' si  avvicina a  zero da
sotto :)  :) ).  In  quei casi abbiamo  optato per la modifica  di una
routine  scheletro  standard.  Questo   tra  l'altro  ha  permesso  di
eliminare tutti i test sui tipi e la gestione degli errori... 
P> Comunque quella classe clresize.zip sul Sito Comune fa già tutto questo :-)
Interessante ... Sarebbe da vedere come si comporta a runtime, magari
scopro che abbiamo fatto del lavoro per nulla... :)
-- 
Gian  | main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Uberto|                        David Korn, 1987 ioccc best one liner 
Lauri |-------------------------------------------------------------------
(aka saint) >>Vedere X-Nospam nell'header - See X-Nospam field in Header<<

 statiche, sono lente.
Dai, su, ora stai facendo il pignolo :-)))
Ci sarà una differenza sì e no di qualche decimo di millisecondo, per una
funzione che viene richiamata una volta ogni tanto... :-)
A proposito, io l'ho chiamata Collection per abitudine, ma nell'help
del mio VB5 trovo questa frase:
"Nota: L'insieme Controls non è un membro della classe Collection
di Visual Basic. Dispone infatti di un insieme di  proprietà e metodi
più ridotto rispetto a un oggetto Collection e non è possibile crearne
istanze."
Su VB6, invece, come stanno le cose ? Ricordo chiaramente un
"For Each...Next" sulla Controls Collection che qualcuno suggerì
tempo fa, o me lo sono sognato ?
Un Paperino mumble mumble...