Des actualités personnelles sous un style impersonnel, et inversement.
Follow @Thomas_Jannaud
Pour coder en Visual Basic, il faut disposer de Visual Studio par exemple, ou de Visual Basic. (les "Express Edition" sont mises gracieusement à disposition par Microsoft). J'utilise la version 6 (qui correspond à l'année 1998) car celles d'après (les ".net") n'ont pas survécu, et c'est cette version qu'on retrouve dans VBA (les macros Excel, ...)
Rappelons brièvement les avantages de Visual Basic :
Vous trouverez dans cet ouvrage de quoi apprendre VB6. C'est bien simple, ce livre m'a tout appris.
Vous aurez dans ce livre à construire des petites applications simples, pas à pas, et vous allez découvrir 1001 techniques essentielles,
entre le multimédia, les bases de données, Excel, faire de vraies applications professionnelles, ... Mon premier livre de programmation
et sans doute le meilleur investissement que j'ai jamais fait.
D'autre part, par expérience, vous verrez qu'un site internet ne remplacera jamais un livre papier.
Cette version est en français.
Je ne vous conseillerai que trop le site VBFrance et sa mailing list : il y a beaucoup d'astuces, ... que l'on ne peut pas inventer tout seul. D'ailleurs je ne sais même pas comment les gens les trouvent. Il y a plein de petits bouts de code dont on aura toujours besoin à un moment ou à un autre dans notre vie, comme mettre des icones à nos menus, rendre une partie de la fenêtre transparente, ...
Je vous conseille aussi d'aller voir ma page de codes sources, où je mets pas mal de programmes en ligne, ce qui peut être très utile pour avoir une vision d'ensemble de la physionomie d'un programme en VB
Pour comprendre la logique de Visual Basic, il faut se dire qu'un logiciel, c'est 2 choses : une interface (utilisateur), et le code qui est
derrière pour gérer les événements (clics, ...) et intéragir avec l'utilisateur par le biais justement de l'interface. Et bien VB est fait
exactement de cette manière : il y a une partie "interface", c'est elle qui s'ouvre en premier quand on fait nouveau projet, et une autre partie,
le code qui se cache derrière.
Vous pouvez prendre des controles dans la barre sur la gauche, et les glisser - déposer sur la fenêtre. Si vous trouvez que vous n'avez pas
assez de contrôles ou si vous en cherchez un en particulier, faites Ctrl+T ou Projet->Components et faites ce qu'il vous plaît.
Construisez votre interface de cette manière. Dans l'espèce de petit tableur sur la droite figurent les propriétés des contrôles (ou plutôt
du contrôle sélectionné). Vous pouvez changer le nom, la propriété Caption, ... si ça vous chante. Double cliquez sur un contrôle pour arriver à
la partie "Code". Visual Basic crée automatiquement pour vous une nouvelle procédure / fonction / méthode associée à l'événement 'Click' sur ce
contrôle. Sur la liste déroulante tout en haut à gauche figurent tous les contrôles de la fenêtre, et sur la liste de droite l'événement associé
(si vous décidez d'associer un événement).
Et voila, vous êtes prêts à coder !
Certaines fonctions internes de Visual Basic ne sont pas complètement détaillées ici, et ce pour 2 raisons :
Rappel : [n] désigne que n est un paramètre optionnel
Il n'y a pas d'accolades en Visual Basic pour déterminer des blocs de code, comme en C++ pour dire que faire dans une boucle for. Ici, cela ressemblerait plus à du html par exemple : on ouvre une "balise", et on la referme plus loin.
Dim x as integer, y as double, z as string
x = 2
Option Explicit
if ... then
...
elseif ... then 'ceci est un commentaire : elseif est ATTACHE !
...
elseif
...
else
...
end if
On peut aussi écrire une condition if sur une seule ligne, sans utiliser de end if if (x < 0) then x = (-x)
Select case nom
case "papa"
...
case "maman"
...
case else
...
End Select
Remarque : avec les nombres, on peut aussi avoir : case >= 3 par exemple.
Goto
La fameuse instruction goto, très décriée des "pros". Moi je la trouve bien pratique.
goto label
...
label:
Le label peut se situer avant l'instruction goto, dans le code ! Mais il doit toujours être dans la même procédure/fonction !! Goto peut servir à tout, même à sauter plusieurs boucles à la fois ! Plus qu'utile.
for k = 1 to 10 [step 2]
...
next k
do [while condition]
...
loop
On peut mettre 'loop while' si l'on veut (mais rien mettre après do alors). On peut aussi remplacer while par until (pour les conditions négatives)
L'instruction 'break' pour les boucles for ou do...loop est Exit For
et Exit Do
et amène
directement à la sortie de la boucle.
for each a in b 'b doit être une 'collection' (défini plus loin)
...
next
private function mafonction(a as integer, b as string, optional c = 2) as double
'ou un autre type !
...
mafonction = 3.1415
end function
A noter que l'on peut placer ses fonctions n'importe où dans le code, en particulier que l'on n'est pas obligé de placer plus haut sur le fichier une fonction qui est utilisée par une autre plus bas. Il n'y a pas non plus de prototype à écrire.
public, private, ...
private sub mafonction(a as integer, b as string, optional c = 2)
...
...
end sub
C'est la déclaration d'une fonction qui ne renvoie pas d'argument ; autrement dit, une procédure.
mafonction(ByRef a as integer, byval b as integer, byref c as integer) ...
pour avoir a et c passés par référence au lieu de par
valeur, qui est par défaut. Je conseille FORTEMENT de toujours mettre byval, surtout quand vous passez des paramètres comme des
chaînes ou des classes, même si c'est par défaut. On ne sait jamais ! Et le jour où vous vous en rendrez compte, comme moi vous comprendrez
que vous venez de perdre 4 heures de suite de débogage. A bon entendeur... ;)a = f(x, y, z)
f x,y,z
Call f(x, y, z)
Prélude : c'est un type un peu particulier : à la fois tableau et variable, on ne sait jamais. En VB, contrairement à beaucoup d'autres langages
objets, la chaîne est comme une variable integer par exemple : on peut la passer en paramètre sans craindre que ce soit une référence seulement
qui soit passée, ... Bref, il ne faut pas s'inquiéter ici.
D'autre part, attention !!! Les indices commencent donc à 1, et non pas à 0 comme c'est souvent le cas dans d'autres langages !!!
Dim a as string
dim b as string * 10 'limite la taille de b à 10 caractères
a = "bonjour"
b = "thomasthomas" 'b vaudra "thomasthom" en réalité
len(a)
LTrim(a), RTrim()
chaine1 & chaine2
Mid("bonjour", 3, 4)
mid(a, 3, 4) = "abcd"
, et ainsi a -> "boabcdr"split
dim tableau() as string 'déclare un tableau sans en préciser la taille
tableau = split("bonjour les amis", " ")
ultra-puissant : si on le met à " " ça va détacher les mots d'une phrase. Si on le met à "o" ça va détacher "bonjour" en {"b","nj","r"}. On peut ensuite accéder à ces parties avec tableau(1), tableau(2,), ... : tableau.lbound et tableau.ubound donnent les indices de début et de fin du tableau créé de cette manière. (l pour 'lower' et u pour 'upper')
s1 = Replace(s1, "toto", "tagada")
Instr(s1, s2)
La création de tableaux est quelque chose de vraiment très sympa, en VB : les indices commencent où l'on veut !
D'autre part, les tableaux sont soit de taille fixée au départ, soit modelables
Dim t(1 to 10) as integer
Dim u(2 to 4, 5 to 8) as string
dim t(1 to n, 1 to 3) as Double
et on a alors 3 colonnes pour gérer les 3 coordonnées de nos n points)Dim t() as integer
... (et plus loin dans le code)
Redim [preserve] t(1 to n)
Preserve sert à faire en sorte que si on aggrandit ou diminue notre tableau de 1 case seulement (par exemple), VB va faire en sorte de conserver le maximum d'éléments à leur valeur d'origine ; en clair il va recopier une partie de notre ancien tableau dans le nouveau
A noter que l'on peut déclarer des tableaux à plusieurs dimensions sans connaitre qu'une seule des dimensions (la dernière), sinon c'est impossible.
Ce sont des objets assez simples et bien faits, mais pas forcément très rapides (ne les utilisez pas pour des listes de plus de 10000 éléments par exemple, surtout si vous voulez avir un accès séquentiel). Il n'y a pas beaucoup de fonctions toutes faites sur les Collection (comme inverser la collection, la trier, ...).
Dim maliste as New Collection
maliste.AddItem "bonjour"
maliste.item(n)
maliste.count
Faites attention lorsque vous parcourez une liste, si vous supprimez des éléments, l'indice des éléments suivants peut changer !
Et plutot que de faire for i = 1 to maliste.count ...maliste.item(i)... next i
, faites plutot for each element in maliste, ... element... next
sinon l'ordinateur va à chaque fois repartir de l'indice 1 pour calculer item(i) ce qui est très lent, surtout vers la fin de la liste, au lieu de tout parcourir d'un seul bloc.
Personnellement je ne les trouve pas forcément utiles, mais bon, faites comme bon vous semble. La seule utilité que j'y vois, c'est que si l'on a la liste des positions x d'objets (de dessins par exemple) et une autre la liste des y, et dans une autre la liste des z, on peut tout combiner en un seul ce qui peut faire plus propre au niveau du code.
Mais VB ne gère pas très bien ce genre de type, donc vaut mieux ne pas trop faire de choses comme ca. Pour ne pas prendre de risque, personnellement, j'utilise un tableau à plusieurs dimensions, même si c'est plus moche au niveau du code.
Attention : je parle ici des versions jusqu'à la 6, car il parait que ça a changé depuis et que VB est devenu nettement plus orienté objet. En tout cas, jusque dans là 6, on ne peut pas se faire de tableaux de type prédéfini.
Contrairement à ce qu'on pourrait croire, quand on passe un type prédéfini dans une fonction, il est passé par valeur aussi (à moins de préciser ByRef). En gros il y a une copie de faite.
Type montype (à déclarer dans un module, c'est préférable)
x as integer
y as integer
nom as string
aaa as unautretypeamoi
end type
et pour initialiser :
dim a as montype
a.x = 2
a.y = 4
a.nom = "bonjour"
...
Ne pas abuser de leur codage simplissime ! Ça devient très vite énervant pour l'utilisateur.
a = Msgbox("bonjour ça va ?", vbyesno + vbquestion + vbdefaultbutton1, "un titre)
vbyes
si l'utilisateur a cliqué sur "Oui", vbno sinon. Si on se fiche de la valeur renvoyée, on peut mettre comme d'habitude
(cf fin du paragraphe sur les fonctions) msgbox "ça va ?", vb..... On n'est pas obligé de choisir l'image (vbcritical, vbinformation, vbquestion
ou vbexclamation), et on peut mettre vbokonly, vbyesnocancel, ...
en boutons (VB nous propose tout seul des possibilités)a = inputbox("Entrez votre age ici", "textepardefaut", "titre ici")
Voici divers codes :
Penser au préalable à fixer la propriété CancelError de la boîte à True : cela nous renseigne sur le fait que l'utilisateur a cliqué sur
"Annuler"
private sub changer_couleur()
on error goto erreur:
boite.showColor
Me.backColor = boite.color
exit sub
erreur:
Msgbox "Vous n'avez pas souhaité changer la couleur de fond"
'boite de dialogue qui énerve l'utilisateur
end sub
private sub ouvrir()
on error goto erreur:
boite.showOpen
if boite.filename <> "" then
ouvrir_fichier(boite.folder & boite.filename)
' c'est à vous d'écrire le code d'ouverture d'un fichier !!! Vous croyez quoi :)
' (cf système de fichiers pour plus d'infos)
exit sub
end if
erreur:
Msgbox "Vous n'avez pas souhaité ouvrir de fichier" 'boite de dialogue tout aussi intempestive
end sub
Et il y a encore beaucoup d'autres boites : showPrint, showSave, ...
Pour en créer : Fichier, ajouter -> Class Module (la même boite que pour les Form, Module, ...). Pensez à renseigner le champ "name" de votre classe. Ce sera un peu comme un nouveau type pour vos variables. A une différence : c'est que cette fois, c'est un pointeur sur votre classe, c'est toujours passé par référence, donc il faut faire attention, mais c'est souvent plus pratique.
Option Explicit
public nom as string
public age as integer
private poids as integer
private function mafonctionpriveequifaitjenesaisquoi(ByVal a as integer)
...
End Function
// Renseigner les champs d'initialisation, c'est mieux (équivalent à un constructeur)
Puis dans le code (associé à une fenetre ou à un module ou à...) :
dim thomas as new nomdemaclasse
thomas.age = 22
thomas.nom = "thomas"
dim pierre as nomdemaclasse
set pierre = thomas
' il faut souvent associer set à l'assignation à une valeur en ce qui concerne les objets (ex : les images, ...)
msgbox pierre.age
' affiche 22 : pierre est un POINTEUR ou une REFERENCE à THOMAS. Autrement dit 2 noms pour le même objet. Changer l'un
change l'autre.
Une partie que les gens trouvent souvent dure. C'est dommage, je la trouve vraiment très simple en Visual Basic. Il y a deux types d'accès à un fichier, que ce soit en lecture, ou en écriture. Soit on lit un fichier ligne par ligne jusqu'à (si l'on veut) la dernière, soit on demande de lire le n ième octet d'un fichier. (idem pour l'écriture). Quelque chose qui fait peur et qui peut être contre-intuitif est qu'il faut toujours pour la sauvegarde écraser l'ancien fichier et le remplacer entièrement par un nouveau. (C'est comme ca. Pensez à l'implémentation sur le disque dur d'un fichier, et à ce qu'impliquerait l'insertion d'un seul caractère en plein milieu d'un fichier par exemple).
Exemples
Notre programme a beaucoup d'options à enregistrer, de type "oui" ou "non" ('afficher ...' ou 'ne pas afficher ...') ou des couleurs ou autre. On peut alors stocker pour gagner de la place dans le premier octet du fichier d'options, 'true', puis 'false' dans le 2eme, puis la couleur du fond d'écran préféré de l'utilisateur sur les 4 octets qui suivent, puis ...
C'est moins parlant, mais en même temps sur un fichier texte, le fait d'écrire sur la première ligne 'true', puis 'false' sur la 2eme, ... ne serait guère plus parlant.
Un autre avantage est de garantir une certaine sécurité : l'utilisateur ne pourra pas s'amuser à modifier les options directement en ouvrant le fichier texte.
Un inconvénient est que c'est pas facile facile de se rappeler à quel octet correspond quelle option et ça induit souvent des erreurs, surtout quand on veut ajouter de nouvelles options au fur et à mesure du déroulement du programme, ... (même si les options on les charge au début et après c'est fini).
C'est d'ailleurs pour ça que le xml est de plus en plus utilisé (vous pouvez très bien sauvegarder sous ce format en écrivant vous même vos balises dans le fichier texte ! Rien ne l'interdit)
Pour ouvrir un fichier (qu'importe le type) : Windows accède à un fichier par un flux de données, et il ouvre donc un canal. En gros, au lieu de dire "lis la ligne du fichier "Bureau\\toto.txt"" on va dire "lis la ligne du fichier associé au flux du canal 34".
La question qui vient naturellement (ou pas) sur les lèvres est : comment savoir quel est le numéro de canal ?
Réponse : C'est nous qui le choisissons. Mais comme on n'a pas le droit à un numéro déjà pris, il y a une fonction toute faite qui gère ça :
FreeFile() -> renvoie un entier.
Passons à la pratique !
dim f as integer
dim ligne as string
f = freefile()
open "C:\\.....\\fichier.doc" for append as #f
do until EOF(f)
line input #f, ligne
'exécuter le code en rapport avec la ligne lue ici
loop
close #f 'on ferme le flux / canal
'EOF' signifie "End of File". Donc on lit les lignes jusqu'à ce que la fin du fichier soit atteinte. Si l'on sait à l'avance le nombre de lignes, par exemple 10, ou bien s'il est écrit dans la toute première ligne de notre fichier :
dim f as integer, n as integer, i as integer
dim ligne as string
f = freefile()
open "C:\\.....\\fichier.doc" for input as #f
line input #f, ligne
n = cint(ligne)
for i = 1 to n
line input #f, ligne
'exécuter le code en rapport avec la ligne lue ici
Next i
Close #f 'A NE PAS OUBLIER !!!!
Pour écrire dans le fichier, c'est pareil :
'si le fichier existe déjà on le supprime
if (dir("C:\\....\\toto.txt") <> "" ) then
Kill "C:\\....\\toto.txt"
end if
dim f as integer, i as integer
f = freefile()
open "C:\\....\\toto.txt" for append as #f
print #f, n
for i = 1 to n
print #f, nom_contact(i) 'si on a un tableau de contacts
next i
close #f 'A NE PAS OUBLIER !!!!
Bref, c'est facile, vous voyez ! printf #numerofichier, cequonveut et line input #numerofichier, cequonveut.
Remarque :Vous pouvez utiliser "input" au lieu de "line input", mais cela lira les mots un par un, au lieu de lire ligne par ligne.
C'est pas forcément plus pratique, car si on écrit le nom de l'utilisateur, et qu'on veut le lire au prochain lancement du programme, et que le
nom de famille c'est De Gaulle, et bien on va lire un mot au lieu de deux, et tout le reste va être décalé.
C'est encore plus simple :
dim f as integer
dim b() as byte
f = freefile()
redim b(1 to filelen("C:\\...\\toto.txt")
open "C:\\...\\toto.txt" for binary as #f
get #f, 1, b
close #f
Et en écriture : idem avec put au lieu de get. (pensez à effacer le fichier au préalable pour éviter certains bugs)
Ici, b() est un tableau d'octets ('byte' en anglais). A la lecture, on lui donne la taille du fichier puis on l'initialise avec get.
A l'écriture, on possède un tableau d'octets (déjà affectés : ce sont les données à enregistrer) et on envoie ça dans le fichier.
A noter que le 1 de "get #f, 1, b" signifie ici : lire les octets du fichier du canal numéro f à partir du 1er et placer ça dans b(). Dans notre
cas celà revient à lire tout le fichier puisque b() a la même taille que le fichier (à cause de filelen()). Cependant on peut très bien décider
de lire les octets un par un, et on pourrait faire dim c as byte ...for i = 1 to n... get #f, i , c
A noter que si l'on veut stocker une variable plus grosse, int par exemple (4 octets peut-être, ou plus ??) on n'a pas besoin de faire de multiples divisions euclidiennes pour connaitre l'écriture en base hexadécimale de notre entier, et stocker ça byte par byte (octet par octet). L'ordinateur gère ça tout seul. Il faut quand même faire gaffe au décalage induit par le fait que ça prend 4 octets.
Exemple :
dim a as integer, b as integer
'code d'ouverture avec freefile, ...
get #f, 1, a
get #f, 5, b
close #f
open "C:\\..." for Random as #f
. C'est un peu comme le mode Binary, sauf que là il faut dire à l'avance quels
types de données seront où. En fait c'est surtout pour stocker des enregistrements (= types prédéfinis, du genre "nom" puis "n° téléphone") où
il faut définir par avance la taille que l'on réserve à chacun. Par exemple 20 caractères max. pour le nom. Je trouve ce mode un peu bête
parce que l'on ne sait jamais par avance ce que va rentrer l'utilisateur, et d'autre part, si quelqu'un a un nom à 5 lettres seulement cela fait
15 caractères non utilisés (même si vu la taille des disques durs de nos jours, on peut se le permettre).Le code qui suit est un peu complexe, et la documentation à son sujet est peu fournie sur internet. La raison est qu'il utilise un truc un peu "louche" : la fonction CreateObject ; en gros ça permet d'utiliser des fonctions propres à Windows mais qui ne sont pas des fonctions connues de VB.
Dim oFs As Object
Set oFs = CreateObject("Scripting.FileSystemObject")
Dim oDossier As Object
Dim oSousDossier As Object
Dim oSousDossiers As Object
Dim sDossier As String
Dim f, f2
Set oDossier = oFs.GetFolder("C:\\...\\Bureau\\")
'oDossier est l'objet "Dossier" associé à la chaîne de caractères (ici : le bureau)
Set oSousDossiers = oDossier.SubFolders
'tous les sous-dossiers du Bureau. C'est une collection d'objets 'Dossiers'
Set f = oDossier.Files
'la collection de tous les fichiers de l'objet 'Dossier', donc tous les fichiers du bureau
for Each f2 in f
me.print f2.Name
Next
For Each oSousDossier In oSousDossiers
sDossier = sNomDossier & oSousDossier.Name & "\\"
Me.Print sDossier
Next
La gestion d'événements est intimement liée à l'existence d'une interface graphique. La création de celle-ci est développée en tête de cette page.
Pour gérer les événements associés à des objets, double-cliquez sur l'un deux, puis dans la fenêtre du code, dans la liste déroulante en haut à
droite, sélectionnez l'événement qui vous intéresse. Vous avez un choix assez grand. Utilisez ensuite les propriétés fournies (ou pas) en argument
pour faire ce que vous voulez (ex : mousedown
renvoie le x et le y du curseur de la souris en coordonnées relatives, où l'origine est en haut
à gauche de l'objet). Les procédures ainsi définies peuvent être appelées tout comme n'importe quelle autre procédure de votre confection.
Pour accéder aux propriétés d'un objet, donnez le nom de l'objet puis faites "." (sans les guillemets ^^). Le plus simple est d'écrire Me. Me ça veut dire "moi" en anglais. En clair, c'est votre fenêtre. '.' va ensuite vous donner la liste de tous les objets sur votre fenêtre. Vous pouvez bien entendu vous adresser au contrôle d'une autre fenêtre (par exemple Form2) en faisant Form2. ... Form2 doit par contre être loadée, ce qui ce fait comme suit :
Load Form2
Form2.show 'si vous voulez
Form2.Label1.Caption = "bonjour ! je suis contrôlé depuis le code de la form1"
'il faut déjà avoir un label1 sur Form2
On ne peut pas vraiment créer des objets comme ça, à la volée, c'est pas fait pour, et VB va très vite ramer : le mieux est de placer vos objets dès le début. Mais on peut quand même le faire si l'envie nous en dit : Créer un contrôle, n'importe lequel, et mettez sa propriété index à 0. (sans le point, c'était un signe de ponctuation cette fois). Disons que c'est Text1(0). Dans le code :
For i = 1 to 10
Load Text1(i)
Text1(i).Visible = true
Text1(i).top = text1(i - 1) + 300
Next i
...
Unload Text1(i) pour en supprimer un.
Vous apprendrez très vite les propriétés des objets si vous vous amusez à lire les listes déroulantes qui s'offrent à vous, dans le code.
Les propriétés principales restent .Visible
(pour cacher un contrôle ou pas), .height, .left, .width, .top (hauteur, largeur, position), .caption,
.text, .ToolTipText
(la petite bulle d'aide qui apparait quand on laisse la souris 5 secondes de suite sur le même contrôle), .AddItem (pour
les list, combobox, ...), .Tag
(c'est une variable propre à chaque contrôle qui ne sert à rienen tant que tel, mais pourtant très utile et on
peut y mettre ce qu'on veut : chaîne de caractères, entier, ...
Exemple d'utilisation : vous avez plein de boites de saisie de texte, et vous voulez que certaines aient une saisie alpha-numérique bloquée. Et bien vous allez mettre toutes vos textBox avec le même nom mais un index différent, mettre par exemple "chiffre" dans tous les Tag de vos TextBox bloquées, et après dans l'événement keypress, vous allez gérer suivant que le .Tag de votre textbox soit à "chiffre" ou pas.
Drag & Drop : très pratique : gère le glisser-déposer de n'importe quel contrôle à votre place. Mettre la propriété dragmode d'un contrôle à 'Automatic' pour cela, puis :
Private Sub Form_DragDrop(Source as Control, X as Single, Y as Single)
Source.Move X, Y
End Sub
Remarque : par Source.name on a accès au nom d'un contrôle, et donc on peut dans Form_DragDrop gérer les contrôles au cas par cas si l'envie nous prend.
PopupMenu : tout simplement génialissime. Permet d'ouvrir un menu, souvent au clic droit sur un objet. Pour cela créez vous un nouveau menu avec Menu Editor (clic droit sur une form, dans le créateur d'interface initial), mettez le en visible = false (si vous voulez), ne mettez pas de Caption à l'élément racine, mais donnez quand meme un nom, par exemple 'mnuderoulant'. Ensuite, par exemple dans Form_MouseDown :
If Button = 2 then 'clic droit
Me.PopMenu Me.mnuderoulant
end if
Frame1.visible = false
, au lieu de
le faire pour chaque objet du Frame. Très pratique. L'essayer, c'est l'adopter.Me.Dir1.Path = Me.Drive1.Drive, Me.File1.Path = Me.Dire1.Path
et dans Dir1_Change : Me.File1.Path = Me.Dir1.Path
. En fait, dès qu'on change de dossier il faut réactualiser la liste des fichiers (pour pointer
vers le nouveau dossier) et idem pour le driver.C'est là dedans que je fais tous les dessins que j'ai à faire, c'est fait pour, comme son nom l'indique. Je vous conseille de mettre sa propriété scaleMode à Pixel au lieu de Twip sinon les effets peuvent être inattendus. En gros, 1 pixel = 15-20 twips. On se demande bien à quoi peuvent servir les twips étan donné qu'un pixel est une unité indivisible, mais bon... Mettez aussi AutoRedraw à True, sinon si vous placez une autre fenêtre devant votre PictureBox, ça va effacer le dessin dessus.
Me.Picture1.line(x1, y1)-(x2, y2), vbblue [,B ou BF]
: trace une ligne bleue sur la pictureBox Picture1 de la fenêtre ; B veut dire que ça fait
pas une ligne, mais le rectangle associé, et BF dit que ce rectangle sera rempli ('box' et 'box full')
Dim a as stdPicture
set a = loadPicture("C:\\...\\image.jpg ou bmp")
Me.Picture1.Paint(a, x, y[, width, height])
'si l'on veut faire un aggrandissement ou pas de notre image
Les coordonnées commencent toujours en haut à gauche d'un contrôle, et l'axe des y est orienté vers le bas, ce qui est assez déroutant, pour le moins au début
SavePicture Me.Picture1.Image, "C:\\Bureau\\image.bmp"
pour sauvegarder une image. Cela veut dire que ce qui est dessiné sur la PictureBox est
stocké/accessible via la propriété image de celle-ci.
Vous voyez qu'il est assez simple d'utiliser une PictureBox, alors qu'il n'en est pas de même pour DirectX. Comment choisir ? Je vous conseille de faire d'abord votre jeu (ou autre) en dessinant sur une PictureBox, et si c'est lent, de passer à DirectX. L'avantage de DirectX, c'est qu'on se fait une Sub spéciale où l'on dessine tout. Alors que sur une PictureBox, il faut effacer ce qu'on déplace, pour le re-dessiner plus loin, ce qui est plus contraignant. En gros pour un serpent une PictureBox ira très bien. Après... à vous de voir ce qui vous convient le mieux. Il y a au moins 5 codes utilisant DirectDraw dans la partie codes sources. Faites des copier-coller pour utiliser DDraw à votre tour !
Randomize Timer
puis rand
Timer
CInt(), CDbl(), CString, ...
Format()
isnumeric()
Asc
et Chr
Set
DoEvents
Mettre tout d'abord Excel en référence au projet (comme on le ferait pour une dll par exemple) : Projet -> References -> Cocher Excel
dim xlapp as Object, xlbook as object, xlsheet as object
Set xlapp = New Excel.Application
Set xlbook = xlapp.Workbooks.Open("C:\\Bureau\\toto.xls")
Set xlsheet = xlbook.Sheets("Aube")
xlsheet.Cells(ligne, colonne).Value = "bonjour"
xlapp.ActiveWorkbook.Close False
xlapp.Quit
Set xlapp = Nothing
Pour interdire la saisie autre que numérique par exemple, dans un TextBox : dans l'événement keyPress, on reçoit KeyAscii. On peut alors
faire if (KeyAscii < Asc('0') Or KeyAscii > Asc('9')) then KeyAscii = 0
. De même, si on décide (pour rire), qu'à chaque fois qu'un 'a' est
tapé, de le remplacer par un 'b', on fait if KeyAscii = Asc('a') then KeyAscii = Asc('b').
On se sert souvent du KeyAscii = 13 (touche Entrée) pour que l'utilisateur n'ait qu'à appuyer sur Entrée, au lieu de relâcher le clavier pour se servir de sa souris et clicquer sur "Ok" ou "Valider" par exemple : If KeyAscii = 13 then Call Command_Valider_Click()
Si vous avez juste besoin de gérer un peu les touches dans un jeu qui ne va pas forcément vite (si si ça existe ! cf le jeu worms dans ma page
de codes sources, et il marche très bien) vous pouvez utiliser l'événement keydown ou keypress de la form
(je recommande plutôt keydown, car keypress c'est plus pour les lettres que pour les touches du genre flèches, control, ...).
Sinon ...
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
'à déclarer dans Option Explicit, ou en public dans un module
dim a as integer
a = GetAsyncKeyState(37) 'flèche gauche (38, 39, 40, correspondent
' aux flèches droite, bas, haut, dans un ordre à déterminer)
if a <> 0 then ...
end if
Attention : a = 0 si et seulement si l'état de la touche n'a pas changé depuis le dernier appel à la fonction (avec la même touche en paramètre) c'est à dire que si la dernière fois c'était appuyé, le joueur a laissé enfoncé la touche depuis. C'est pour ça qu'il faut initialiser à Form_load() en espérant que le joueur n'appuie sur aucune touche au moment où le jeu se lance, et faire du getasynckeystate sur tous les numéros qu'on utilisera.
Téléchargez ici une source utilisant les fichiers .res pour copier discrètement un fichier .exe sur votre ordinateur. Rassurez-vous ça ne le fera pas chez vous car mon fichier .res n'est pas livré avec le programme. Téléchargez ici un fichier .res contenant toutes les images d'un jeu de cartes de 52 cartes (+ joker + explication). Ultra-pratique.
Ces fichiers se créent grâce à Visual C++. Il servent principalement à stocker d'autres fichiers à "l'intérieur" de notre programme VB. En effet on peut avoir un exécutable qui se trouve dans un dossier, et dans ce même dossier mettre des images ou tout autre type de ressources. Mais si l'on fait ça, cela veut dire que l'utilisateur peut récupérer nos belles images pour les utiliser à ses fins propres. Et on ne veut pas forcément si l'on est égoïste (ou si l'on aime le droit à la propriété). D'autre part, si l'exécutable doit être placé dans le même dossier que d'autres images pour fonctionner, ce n'est pas forcément très pratique non plus, parce qu'il faut l'expliquer aux utilisateurs, et on n'a pas non plus envie de créer un Setup pour tout.
Soit on n'a pas que des images à mettre. Alors créez un nouveau document texte avec le bloc-notes, et écrivez autant de lignes que vous avez
de fichiers à ajouter. Les lignes sont du genre :
logiexe EXE C:\\Bureau\\logiciel.exe
Vous n'êtes pas obligés de mettre EXE parce que vous avez un fichier *.exe, mais c'est plus pratique. En fait, le premier item (ici : "logiexe")
est le nom de votre ressource dans le fichier .res que vous allez créer, le second (ici : "EXE") est le nom du "dossier" dans lequel votre fichier
sera mis (toujours dans le fichier .res), et le troisième item (ici : "C:\\....exe") indique au "compilateur de ressources" où trouver le fichier
sur votre ordinateur.
Enfin enregistrez votre fichier texte du bloc notes en .rc et non pas .txt. Ouvrez votre .rc avec Visual C++, et faites Enregistrer sous... et là choisissez .res comme extension. Voila c'est fini.
Récapitulatif : dans le bloc-notes,
fichier1 DOSSIER1 C:\\....toto.bmp
fichier2 DOSSIER1 C:\\....maman.jpg
fichiertuesmoche DOSSIERMOCHE C:\\....moche.avi
...
à enregistrer en .rc
Faites clic droit sur votre projet dans l'arborescence d'en haut à droite, et Add file, puis sélectionnez votre fichier .res tout beau tout neuf. Faites :
Dim Data() as Byte
Data = LoadResData("logiexe", "EXE")
ou Data = LoadResData("fichier2", "DOSSIER1")
pour les images : Set Me.Picture1.Picture = LoadResPicture("image1", "BMP")
où vous l'avez compris, image1 peut très bien être une jpg même si elle est dans le dossier "BMP"
Il y a encore une fois 2 manières : avec Direct Sound (cf la source de Phoenix), ou avec un objet spécial (que l'on insère donc en faisant Ctrl+T, ou Projet->Composants) : le Microsoft Multimédia Control. J'en met un sur ma form par musique ou son que je voudrais jouer. Il faut renseigner 'Filename' (le .wav ou .mp3 (jamais essayé)) et on peut mettre en Visible=False pour cacher un peu. Attention, si ce n'est pas fait, ce n'est pas parce qu'on clique sur le bouton Play que ça va marcher. Idem avec Pause, ... !!! C'est à nous de gérer l'événement "clic sur le bouton ||", "clic sur |>", ... Mais ça se fait bien.
A Form_Load : Form1.MMControl1.Command = "Open"
, Form1.MMControl1.Command = "Play"
pour jouer,
et Form1.MMControl1.Command = "Prev"
pour remettre à 0 la "bande son".
Vous trouverez dans ma page codes sources :
Tous ces exemples n'ont pas étaient faits dans le but de les mettre un jour accolés à un tutoriel, mais dans des situations bien réelles où ils étaient nécéssité. En clair, programmez pour vous faire plaisir, et naturellement vous verrez que vous aurez besoin de maitriser telle ou telle technique, et là vous regarderez sur internet comment ça marche, comment on s'en sert, et après vous aprenez à la maîtriser, ... Et 2 ou 3 ans plus tard vous commencez à devenir un super guerrier de l'utilisation de VB parce que vous avez acquis sans vous en rendre compte un nombre incroyable de bagages techniques, qui vous permettent de faire à peut près tout.
Laissez un commentaire !
Pas besoin de vous connecter, commencez à taper votre nom et une case "invité" apparaîtra.