Comment spécifier la taille minimum d'une fenêtre ? Est-ce possible autrement que par le code parce que j'ai fait avec l'évènement resize mais c'est assez pourri :?
Version imprimable
Comment spécifier la taille minimum d'une fenêtre ? Est-ce possible autrement que par le code parce que j'ai fait avec l'évènement resize mais c'est assez pourri :?
Citation:
Envoyé par Gaetch
Et si tu changais les proprietes Width et Height directement en mode creation ?? je crois qu'avec ca tu n'aurais pas a le faire par code.
Non ça ça modifie la taille de la fenêtre au lancement, moi je veux que la fenêtre soit redimensionable mais avec une taille minimum.
Définit deux constantes dans la zone Déclarations. Une pour la largeur min et l'autre pour la hauteur min. Dans l'événement Resize, tu teste si les dimensions sont plus petite que les min et tu les redéfinis.
Code:
1
2
3
4
5
6
7
8 Option Explicit Private Const hMin As Single = 1530 Private Const lMin As Single = 2895 Private Sub Form_Resize() If Me.Height <= hMin Then Me.Height = hMin If Me.Width <= lMin Then Me.Width = lMin End Sub
pour eviter:
Erreur d'exécution 384
Une feuille ne peut être déplacée ou dimensionnée lorsqu'elle est réduite ou agrandie.Code:
1
2
3
4
5 If Me.WindowState = vbNormal Then 'le code de zazaraignée restant valable If Me.Height <= hMin Then Me.Height = hMin If Me.Width <= lMin Then Me.Width = lMin End If
Justement c'est ce aue j'avais fait à la base, passer par l'évènement resize mais quand je redimensionne ma fenêtre en dessous de la valeur min fixée ça "clignote" un moment avant de reprendre la bonne taille je sais pas si vous voyez ce que je veux dire ?
Bonjour à tous,
Quelqu'un aurait-il une solution autre que celle évoquée ici afin d'éviter le clignotement ?
Les Api peut-être ?
Merci d'avance
Bonjour,
Impossible à faire sans restituer la taille minimum, que l'on utilise ou non l'Api de Windows.
Raison : la taille n'est connue qu'au lacher de la souris, dans un redimensionnement par souris, et pas "pendant" (et ce : y compris si l'on utilise un timer additionnel )
Edit : existe toujours la solution complexe et chère en ressources qui consiste en :
1) mettre à None la propriété Borderstyle
2) redessiner alors ta barre de titre (un Frame, par exemple)
3) jouer avec l'évènement MouseMove sur ta Form (lorsque sur les bords).
Je ne te le conseille absolument pas ;)
Bonjour ucfoutu,
Je sais qu'avec les API cela est possible mais je ne me souviens pas exactement comment. C'est pour cela que j'ai reposé la question.
Je me souviens que le principe était le suivant :
- On trappe (hook) les messages windows concernant la fenêtre
- Si un message de type "Move" arrive, on fixe la taille mini et on renvoi le message
Voila le tour est joué !
Le problème c'est que je ne me souviens que du principe...
Salut ucfoutu, désolé de te contredire, c'est possible avec les apis de sous classement.
Il faut intercepter le message WM_GETMINMAXINFO
Dans le code ci dessous n'apparaitra pas la partie de code faisant le souclassement
il ne s'agit plus de ramener la taille de la fenetre à une taille predefinie, mais de limiter l'agrandissement/reduction directement au niveau windowsCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 Private Const WM_GETMINMAXINFO = &H24 'Windows data types Private Type POINTAPI x As Long y As Long End Type Private Type MINMAXINFO ptReserved As POINTAPI ptMaxSize As POINTAPI ptMaxPosition As POINTAPI ptMinTrackSize As POINTAPI ptMaxTrackSize As POINTAPI End Type Private Sub Subclass1_WndProc(Msg As Long, wParam As Long, lParam As Long, Result As Long) Dim MinMax As MINMAXINFO If Msg = WM_GETMINMAXINFO Then 'Copier vers notre propere structure CopyMemory MinMax, ByVal lParam, Len(MinMax) 'mise en place des valeurs mini/maxi de la fenetre MinMax.ptMinTrackSize.x = 150 MinMax.ptMinTrackSize.y = 150 MinMax.ptMaxTrackSize.x = 400 MinMax.ptMaxTrackSize.y = 400 'on recopie notre structure pour le retour CopyMemory ByVal lParam, MinMax, Len(MinMax) Result = 0 End If End Sub
Bonjour et merci Delbeke,
Merci pour ta solution.
A ton avis, cette gestion de la taille minimum d'une fenêtre peut-elle être mise directement dans un controle ?
Le sous-classement dans un controle pose-t-il un problème ?
Ainsi, il suffirai de poser le controle sur la feuille et de lui indiquer les tailles mini et maxi.
Encore un grand MERCI :D
Le sous-classement d'un controle pose des problèmes sous vb car le code de sous-classement est obligatoirement dans un module, qui sera partagé entre toutes les occurences du dit controle.
Donc possible, mais avec beaucoup de précautions.
Merci,
Il va falloir que j'essaie cela.
Je vous tiens au courant !
Rebonjour (et un salut à Delbeke)
Bon...
J'ai longuement réfléchi en regardant le mouvement des vagues et ce mouvement m'a donné une idée ...:lol: (dont je crois qu'elle va tenir la route, sans sous-classement, que je veux éviter, et sans être gourmand en ressources.)
Question pour Nadjar :
Accepterais-tu (les cas à traiter serait ainsi moins nombreux) de ne pouvoir rapetisser la forme qu'en agissant sur ses bords droit et bas (et en refusant depuis les bords haut et/ou gauche) ?
Je me mets à ma tentative ou abandonne en fonction de ta réponse
Re,
Ben voilà ! Mis en application (en ce qui me concerne).
Sans sous-classement ...
Quand tu seras prêt, donc, car il va me falloir t'exposer comment mettre la chose en route ...
Bonjour ucfoutu,
Personnellement la solution du sous-classement ne me pose pas de problème de principe.
Je sais qu'il est très facile d'avoir des défaillances de pages si le code n'est pas bien bordé, mais en faisant attention.
L'intérêt de la solution de Delbeke est d'utiliser le quelque chose qui est prévu pour ça dans Windows. Je trouve cela toujours mieux et pérenne que d'utiliser "une astuce".
Néanmoins, je ne suis pas réfractaire à une autre solution. Elles sont tous les biens venus. Alors, qu'elle est ton idée ?
Bonjour,
Première idée, mise en application et fonctionnant : utilisation de la fonction GetCursor de l'Api de Windows et d'un timer (pour au total moins de 2 KO)...
Cette solution fonctionne bien mais :
- le timer est embêtant
- si l'on "accroche" le haut, le curseur passe spontanément en bas, si l'on est lent (ce qui peut irriter)
- même défaut qu'avec Windows sans liimites : ce n'est pas visuellement agréable et "parlant" (on voit l'ancienne fenêtre et la taille de la nouvelle jusqu'au relacher...)
J'ai donc commencé à développer autre chose et sans timer ( pour 1 KO seulement) et le résultat est très agréable visuellement (fenêtre mise aux nouvelles dimensions sans continuer à voir l'ancienne)...
Il ne me reste plus qu'à mettre la chose dans un module pour que ce soit plus facile à insérer dans une appli, ce que je fais au retour des courses...
Tu verras ... A Plus...
Bon (fait)...
Voilà le deuxième jus (sans Timer) ...
Pour essayer :
Un nouveau projet :
- une form avec ses propriétés
borderstyle = 1 (fixed single)
minbutton = true (à ton gré)
maxbutton = true (à ton gré)
controlbox = true (à ton gré)
- 1 lalbel nommé upg sur ta form (où tu veux) avec sa propriété index = 0
code pour la form :
Et dans un module .bas :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 Option Explicit Private Sub Form_Activate() Me.ScaleMode = vbTwips minw = 4300 ' ta largeur minimum en twips minh = 3300 ' ta hauteur minimum en twips placons Me End Sub Private Sub Form_Resize() If Me.WindowState <> vbMinimized Then placons Me End Sub Private Sub upg_MouseDown(Index As Integer, Button As Integer, Shift As Integer, x As Single, y As Single) appuie Me, Button, x, y End Sub Private Sub upg_MouseMove(Index As Integer, Button As Integer, Shift As Integer, x As Single, y As Single) bougeons Me, Index, Button, x, y End Sub Private Sub upg_MouseUp(Index As Integer, Button As Integer, Shift As Integer, x As Single, y As Single) If Button = 1 Then placons Me End Sub
Tu remarqueras que :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 Option Explicit Public Type POINTAPI x As Long y As Long End Type Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long Public minw As Integer, minh As Integer Private oux As Long, ouy As Long, gauche As Integer, large As Integer, NLG As Integer, NLH As Integer, haut As Integer, bas As Integer Public Sub placons(f As Form) Dim MC As Variant, i As Integer Static lg As Integer If f.Width < minw Then f.Width = minw If f.Height < minh Then f.Height = minh If lg = 0 Then lg = 200 With f.upg(0) .BackStyle = 0 .Caption = "" .MousePointer = 8 .Move 0, 0, lg, lg .Visible = False End With MC = Array(9, 6, 7, 8, 9, 6, 7) For i = 1 To 7 Load f.upg(i) If i < 6 Then f.upg(i).Visible = True f.upg(i).MousePointer = MC(i - 1) If i Mod 2 = 0 Then f.upg(i).ZOrder Next End If f.upg(1).Move 0, 0, lg, f.Height f.upg(2).Move 0, f.Height - lg - lg, lg, lg f.upg(3).Move 0, f.Height - lg - lg, f.Width, lg f.upg(4).Move f.Width - lg, f.Height - lg - lg, lg, lg f.upg(5).Move f.Width - lg, 0, lg, f.Height f.upg(6).Move f.Width - lg, 0, lg, lg f.upg(7).Move 0, 0, f.Width, lg End Sub Public Sub vasy(f As Form, AG As Integer, NL As Integer, NH As Integer) If NL < minw Then NL = minw: AG = f.Left If NH < minh Then NH = minh f.Move AG, f.Top, NL, NH DoEvents End Sub Public Sub appuie(f As Form, bouton As Integer, x As Single, y As Single) If bouton <> 1 Then Exit Sub Dim Point As POINTAPI GetCursorPos Point oux = Point.x: ouy = Point.y gauche = f.Left: large = f.Width: haut = f.Height: bas = f.Top + haut End Sub Public Sub bougeons(f As Form, Index As Integer, bouton As Integer, x As Single, y As Single) If bouton <> 1 Then Exit Sub Dim Point As POINTAPI, NLH As Integer, NLG As Integer, cx As Integer, cy As Integer cx = Screen.TwipsPerPixelX: cy = Screen.TwipsPerPixelY GetCursorPos Point Select Case Index Case 1, 2 NLG = large - (Point.x - oux) * cx: NLH = haut If Index = 2 Then NLH = haut - (-Point.y + ouy) * cy vasy f, gauche + (Point.x - oux) * cx, NLG, NLH Case 3, 4 NLH = haut - (-Point.y + ouy) * cy: NLG = large If Index = 4 Then NLG = large + (Point.x - oux) * cx vasy f, gauche, NLG, NLH Case 5 NLG = large + (Point.x - oux) * cx: NLH = haut vasy f, gauche, NLG, NLH End Select End Sub
1) je n'ai pas traité les 3 points hauts (je traite si tu veux).
2) j'ai traité en twips mais peux te faire du polyvalent
Si tu veux, je peux également traiter avec une Form sans bordure (ce que ne fait pas un dimensionnement normal)
Pour étirer et redimensionner, tu peux de faire depuis :
le coté gauche (horizontalement
le côté droit (horizontalement)
le côté bas (verticalement)
le coin gauche inférieur (en diagonale)
le coin droit inférieur (en diagonale)
Essaye et dis-moi ce que tu en penses.
Merci ucfoutu,
Je vais y regarder ces prochains jours quand j'aurai terminé mon travail actuel.
Je te remercie du temps passé sur ce problème.
Je te tiens au courant.