Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

TRAITEMENT DES MESSAGES WINDOWS SOUS VB6


Information sur la source

Catégorie :Système Classé sous : message, windows, traitement, form, évènement Niveau : Initié Date de création : 15/01/2007 Date de mise à jour : 19/01/2007 11:17:42 Vu / téléchargé: 6 656 / 424

Note :
Aucune note

Commentaire sur cette source (6)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
L'évenementiel prend une place importante en VB6.

On traite en effet généralement de nombreux évènements tels que Click, Load, KeyDown.

En interne, c'est Windows qui récupère toutes les actions souris et clavier, qui est au courant de l'activation des fenêtres...

Il envoie donc tout un tas de messages aux différentes applications pour leur signifier ce qui se passe.

Le compilo de VB6 intègre automatiquement une boucle de traitement dans les executables.

Dans cette boucle, l'application inspecte la pile des messages que lui envoie Windows.

(On peut forcer un exe à traiter les messages de cette pile à tout moment dans le code via l'instruction DoEvents.)

Les messages de cette pile sont envoyés aux différentes fenêtres.

Les différentes fenêtres traitent les messages et déclenchent les évènements implémentés par le programmeur.


Nous nous proposons ici de placer une routine qui sera appelé à chaque message reçut par une fenêtre.

Les messages pourront être inspecté, et on aurat la possibilité de les bloquer pour que leur traitement normal ne soit pas effectuer.

Cette opération n'est pas anodine, et on pourra avoir des soucis avec le débogueur de VB6.

L'implémentation étant en partie effectuée dans un ocx, VB6 est stable, néanmoins, il arrive que notre fonction ne se fasse plus appeler ou encore qu'un point d'arrêt ne fonctionne pas.

Cette possède deux évènement :

  1 Le premier permet d'inspecter des messages. Les messages sont traités normalement.
  2 Le deuxième permet d'inspecter des messages, mais ceux-ci ne seront pas traités normalement.

(Attention : La valeur retourné pour les messages bloqué est de zéro, valeur commune mais pas universselle.).

Quelques mises en garde :

  1 Le traitement des messages n'est pas particulièrement simple.
    Il faut bien lire la doc avant de faire quoi que ce soit.
    Un exemple: afficher du texte à chaque message WM_PAINT risque de créer beaucoup d'ennuis...

  2 Windows envoie une grande quantité de messages : Mettre en place une procédure à chaque arrivée de message est couteux en CPU.

Dans le zip joint, il y a les sources d'un exe et d'un ocx.
L'exe montre quelques exemples de traitement de messages.

 

Source

  • Option Explicit
  • 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 Type RECT
  • Left As Long
  • Top As Long
  • Right As Long
  • Bottom As Long
  • End Type
  • Private Const WA_INACTIVE = 0
  • Private Const WA_ACTIVE = 1
  • Private Const WA_CLICKACTIVE = 2
  • Private Const WM_GETMINMAXINFO = &H24
  • Private Const WM_ACTIVATE = &H6
  • Private Const WM_MOVE = &H3
  • Private Const GWL_STYLE = (-16)
  • Private Const WM_MOUSEWHEEL = 522
  • Private AnMsgs(0 To 3) As Long ' Les messages traités
  • Private AnBlockedMsgs(0 To 1) As Long ' Les messages blockés
  • Private uRect As RECT ' Pour la taille de la fenêtre
  • Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  • Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  • Private Declare Function AdjustWindowRect Lib "user32" (lpRect As RECT, ByVal dwStyle As Long, ByVal bMenu As Long) As Long
  • '******************************************************************************
  • ' Calcul de la taille de la fenêtre en fonction de la taille de la zone
  • ' cliente, spécification des messages à récupérer
  • '******************************************************************************
  • Private Sub Form_Activate()
  • ' Calcul de la taille de la fenêtre
  • With uRect
  • .Left = 0
  • .Top = 0
  • .Right = 500
  • .Bottom = 300
  • End With
  • fraMain.Width = uRect.Right
  • fraMain.Height = uRect.Bottom
  • AdjustWindowRect uRect, GetWindowLong(hwnd, GWL_STYLE), 0
  • With uRect
  • .Right = .Right - .Left
  • .Bottom = .Bottom - .Top
  • End With
  • ' On veux savoir quand l'application reçoit ces messages, mais les traiter quand même
  • AnMsgs(1) = WM_ACTIVATE
  • AnMsgs(2) = WM_MOVE
  • AnMsgs(3) = WM_MOUSEWHEEL
  • ' On veut savoir quand l'application reçoit ce message, et qu'ils ne soient pas traités
  • AnBlockedMsgs(1) = WM_GETMINMAXINFO
  • ' On initialise le contrôle
  • MessageListener.Init Me.hwnd, AnMsgs, AnBlockedMsgs
  • End Sub
  • '******************************************************************************
  • ' Efface le contenu de la text box
  • '******************************************************************************
  • Private Sub cmdErase_Click()
  • txtMsgs.Text = ""
  • End Sub
  • '******************************************************************************
  • ' Cet évenement récupère tous les messages traités spécifiés
  • '******************************************************************************
  • Private Sub MessageListener_OnMsg(ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
  • Select Case uMsg
  • Case WM_ACTIVATE
  • ' Pour savoir de quelle type d'activation il s'agit, il faut regarder les 2 octets de poid faible de wParam
  • Select Case (wParam And &HFFFF)
  • Case WA_INACTIVE
  • txtMsgs = txtMsgs + "La fenêtre est déactivée" & vbCrLf
  • Case WA_ACTIVE
  • txtMsgs = txtMsgs + "La fenêtre est activée" & vbCrLf
  • Case WA_CLICKACTIVE
  • txtMsgs = txtMsgs + "La fenêtre est activée par un clique" & vbCrLf
  • End Select
  • Case WM_MOVE
  • txtMsgs = txtMsgs + "La fenêtre est déplacée" & vbCrLf
  • Case WM_MOUSEWHEEL
  • ' Le delta de la roulette est dans les 2 octets de poid fort de wParam
  • txtMsgs = txtMsgs + "Roulette de la souris déplacée de " & CStr(wParam / 65536) & vbCrLf
  • End Select
  • End Sub
  • '******************************************************************************
  • ' Cet évenement récupère tous les messages non traités spécifiés
  • '******************************************************************************
  • Private Sub MessageListener_OnBlockedMsg(ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
  • Dim uMinMaxInfo As MINMAXINFO
  • ' L'adresse de la structure à modifiée est lParam, on recopie celle-ci
  • CopyMemory uMinMaxInfo, ByVal lParam, Len(uMinMaxInfo)
  • ' On la modifie avec la taille minimum
  • uMinMaxInfo.ptMinTrackSize.X = uRect.Right
  • uMinMaxInfo.ptMinTrackSize.Y = uRect.Bottom
  • ' On remplace l'original par la modifiée
  • CopyMemory ByVal lParam, uMinMaxInfo, Len(uMinMaxInfo)
  • End Sub
Option Explicit

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 Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Private Const WA_INACTIVE = 0
Private Const WA_ACTIVE = 1
Private Const WA_CLICKACTIVE = 2
Private Const WM_GETMINMAXINFO = &H24
Private Const WM_ACTIVATE = &H6
Private Const WM_MOVE = &H3
Private Const GWL_STYLE = (-16)
Private Const WM_MOUSEWHEEL = 522

Private AnMsgs(0 To 3) As Long              ' Les messages traités
Private AnBlockedMsgs(0 To 1) As Long       ' Les messages blockés
Private uRect As RECT                       ' Pour la taille de la fenêtre

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function AdjustWindowRect Lib "user32" (lpRect As RECT, ByVal dwStyle As Long, ByVal bMenu As Long) As Long

'******************************************************************************
' Calcul de la taille de la fenêtre en fonction de la taille de la zone
' cliente, spécification des messages à récupérer
'******************************************************************************
Private Sub Form_Activate()
  
  ' Calcul de la taille de la fenêtre
  With uRect
    .Left = 0
    .Top = 0
    .Right = 500
    .Bottom = 300
  End With
  fraMain.Width = uRect.Right
  fraMain.Height = uRect.Bottom
  AdjustWindowRect uRect, GetWindowLong(hwnd, GWL_STYLE), 0
  With uRect
    .Right = .Right - .Left
    .Bottom = .Bottom - .Top
  End With
  
  ' On veux savoir quand l'application reçoit ces messages, mais les traiter quand même
  AnMsgs(1) = WM_ACTIVATE
  AnMsgs(2) = WM_MOVE
  AnMsgs(3) = WM_MOUSEWHEEL
  
  ' On veut savoir quand l'application reçoit ce message, et qu'ils ne soient pas traités
  AnBlockedMsgs(1) = WM_GETMINMAXINFO
  
  ' On initialise le contrôle
  MessageListener.Init Me.hwnd, AnMsgs, AnBlockedMsgs
  
End Sub

'******************************************************************************
' Efface le contenu de la text box
'******************************************************************************
Private Sub cmdErase_Click()
  txtMsgs.Text = ""
End Sub

'******************************************************************************
' Cet évenement récupère tous les messages traités spécifiés
'******************************************************************************
Private Sub MessageListener_OnMsg(ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
  Select Case uMsg
    Case WM_ACTIVATE
    
      ' Pour savoir de quelle type d'activation il s'agit, il faut regarder les 2 octets de poid faible de wParam
      Select Case (wParam And &HFFFF)
        Case WA_INACTIVE
          txtMsgs = txtMsgs + "La fenêtre est déactivée" & vbCrLf
        Case WA_ACTIVE
          txtMsgs = txtMsgs + "La fenêtre est activée" & vbCrLf
        Case WA_CLICKACTIVE
          txtMsgs = txtMsgs + "La fenêtre est activée par un clique" & vbCrLf
      End Select
      
    Case WM_MOVE
      txtMsgs = txtMsgs + "La fenêtre est déplacée" & vbCrLf
    Case WM_MOUSEWHEEL
      
      ' Le delta de la roulette est dans les 2 octets de poid fort de wParam
      txtMsgs = txtMsgs + "Roulette de la souris déplacée de " & CStr(wParam / 65536) & vbCrLf
      
  End Select
End Sub

'******************************************************************************
' Cet évenement récupère tous les messages non traités spécifiés
'******************************************************************************
Private Sub MessageListener_OnBlockedMsg(ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long)
  Dim uMinMaxInfo As MINMAXINFO
  
  ' L'adresse de la structure à modifiée est lParam, on recopie celle-ci
  CopyMemory uMinMaxInfo, ByVal lParam, Len(uMinMaxInfo)
  
  ' On la modifie avec la taille minimum
  uMinMaxInfo.ptMinTrackSize.X = uRect.Right
  uMinMaxInfo.ptMinTrackSize.Y = uRect.Bottom
  
  ' On remplace l'original par la modifiée
  CopyMemory ByVal lParam, uMinMaxInfo, Len(uMinMaxInfo)
  
End Sub

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

15 janvier 2007 13:10:29 :
Problème de copier coller sous gedit : 2 caractères de retour à la ligne...
19 janvier 2007 11:10:02 :
Remplacement d'un source exploitant le traitement des messages pour spécifier une taille minimale pour une fenêtre par un source expliquant et facilitant le traitement des messages.
19 janvier 2007 11:17:42 :
Orthographe et correction des commentaires

Commentaires et avis

signaler à un administrateur
Commentaire de Renfield le 15/01/2007 16:06:01 administrateur CS

voir ici :
     http://www.vbfrance.com/codes/BLOQUER-REDIMENSIONNEMENT-VOS-FORMES_31210.aspx

une source similaire...

signaler à un administrateur
Commentaire de rt15 le 15/01/2007 18:46:34 administrateur CS

Salut Renfield

Tout à fait la même lol.

Si tu veux supprimer celle-ci, no prob, au contraire.

Je pensais pas qu'un truc aussi moche ai déjà été écrit...

signaler à un administrateur
Commentaire de capoueidiablo le 15/01/2007 21:57:27

On a donc deux codes "moches" ...
Y'a pas quelqu'un pour proposer quelque chose de "beau" ?

signaler à un administrateur
Commentaire de Renfield le 15/01/2007 22:59:41 administrateur CS

coté résultat, c'est correct....

pas 36 facons de faire : intercepter WM_GETMINMAX

signaler à un administrateur
Commentaire de rt15 le 16/01/2007 10:10:21 administrateur CS

Comme le dit Renfield sur sa source, dans une dll, pas de problèmes lors du débogage.

Donc on doit pouvoir aussi faire un contrôle stocké dans un .ocx pour faciliter l'emploi au maximum. Même si certains préfèrent pas multiplier les dépendances.

Si j'ai le temps, je vais essayer de faire un ocx qui propose un event appelé à chaque message. Si ça foire pas, ça devrait faciliter la mise en place de manips sympa du même genre que la spécfication de la taille min de la form. La gestion de petits icônes en bas à droites par exemple.

signaler à un administrateur
Commentaire de rt15 le 19/01/2007 11:14:56 administrateur CS

Hop.
Echange standard.
J'ai pas fait les icônes en bas à droite, y a déjà des sources qui traitent du sujet (Mais différement d'ailleurs).

C'est pas encore parfait lors du débogage, mais au moins c'est stable.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

message d'accueil en apparition qu'une seule fois [ par Jeg ] Bonjour,J'ai une frmaccueil avec trois autres frm, sur l'acceuil form_activate une fenetre bonjour bienvenue sauf que quand je reviens sur un bouton r Message de windows [ par Johjo ] Je cherche un site ou je pourrais trouver tous les messages de windows recapitulés et expliqués, en francais ou en Anglais de preference.Ou alors, si Wait après appel d'une Fonction [ par Cpapy ] Bonjour Dans une FORM j'appelle une fonction qui se trouve dans un MODULE.Comment faire pour interrompre le traitement de la FORM tant que le Traiteme Form bloqué [ par AtomixSnake ] Salut,J'ai un big problème ! Je ne trouve pas comment ouvrir un form et bloquer tout le reste de Windows. En fait l'utilisateur ne doit plus pouvoir a Décharger une dll, win98, patch et message d'erreur [ par phleup ] bonjour à tous,mon problème est le suivant : j'ai un programme écrit en VB qui doit cohabiter avec un autre programme sur un machine sous 98. ce derni variable et texte dans un fichier !! [ par codefalse ] Bonjour a tous, j'aimerai mettre dans un fichier du texte et deux variables , MAIS celle ci doivent etre entourée de " " dans le fichier ce qui, pour variable et texte dans un fichier !! [ par codefalse ] Bonjour a tous, j'aimerai mettre dans un fichier du texte et deux variables , MAIS celle ci doivent etre entourée de " " dans le fichier ce qui, pour variable et texte dans un fichier !! [ par codefalse ] Bonjour a tous, j'aimerai mettre dans un fichier du texte et deux variables , MAIS celle ci doivent etre entourée de " " dans le fichier ce qui, pour .Net > copier un fichier sur le réseau [URGENT] [ par Mikax ] je cherche donc à copier un fichier sur une machine dans le réseau.le code suivant (dans le bouton d'une windows form):--------------------------- Try Message Box configurable [ par RockmanX ] salut!j'ai une form1 sur laquelle je fais une série d'opération dont l'ouverture de la form2 contenant une liste de sélection dont la suit des opérati


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,842 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.