Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDernière intervention 2 septembre 2010
-
29 juil. 2010 à 23:26
Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDernière intervention 2 septembre 2010
-
1 août 2010 à 22:19
Bonsoir,
Je cherche à lire le texte d'un élément d'une barre de statut, mais je n'y arrive pas.
Par exemple, supposons que je cherche à récupérer le texte du 1er élément de la barre de statut de Wordpad. Si j'utilise WM_GETTEXT, cela marche parfaitement. Mais dès que je veux utiliser SB_GETTEXT, j'obtiens un plantage systématique.
Le code VBA que j'utilise est donné ci-dessous (il est directement utilisable dans Excel par copier/coller - avec Wordpad ouvert en parallèle bien sûr !). Quelqu'un saurait il me dire d'où vient le problème ? Merci d'avance pour votre aide, parce que là, je sèche...
Private Declare Function GetDlgItem Lib "user32.dll" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_GETTEXT As Long = &HD
Private Const SB_GETTEXT As Long = &H402
Private Const SB_GETTEXTLENGTH = &H403
Sub test1_WM_GETTEXT()
'Handles de la fenêtre et de la barre de statut
Dim hWordpadWnd As Long
Dim hWordpadStatusBar As Long
hWordpadWnd = FindWindow("WordPadClass", vbNullString)
hWordpadStatusBar = GetDlgItem(hWordpadWnd, 59393)
MsgBox "Handle de la fenêtre: " & hWordpadWnd & " | Handle de la barre de statut: " & hWordpadStatusBar
'Lecture du texte de la barre de statut
Dim sbuffer As String
sbuffer = Space$(50)
SendMessage hWordpadStatusBar, WM_GETTEXT, 50, ByVal sbuffer
MsgBox "Texte de la barre de statut: " & sbuffer
End Sub
Sub test2_SB_GETTEXT()
'Handles de la fenêtre et de la barre de statut
Dim hWordpadWnd As Long
Dim hWordpadStatusBar As Long
hWordpadWnd = FindWindow("WordPadClass", vbNullString)
hWordpadStatusBar = GetDlgItem(hWordpadWnd, 59393)
MsgBox "Handle de la fenêtre: " & hWordpadWnd & " | Handle de la barre de statut: " & hWordpadStatusBar
'Lecture du texte de la barre de statut
Dim String_size As Long
Dim sbuffer As String
'Taille de la chaine
String_size = SendMessage(hWordpadStatusBar, SB_GETTEXTLENGTH, ByVal 0, ByVal 0)
String_size = (String_size And &HFFFF&)
MsgBox "Nombre de caractères lus: " & String_size
'Récupération du texte
sbuffer = Space$(String_size)
SendMessage hWordpadStatusBar, SB_GETTEXT, ByVal 0, ByVal sbuffer
MsgBox "Texte de la barre de statut: " & sbuffer
Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDernière intervention 2 septembre 2010 1 août 2010 à 22:19
J'ai finalement eu la raison du non fonctionnement de ce code sur un forum de MSDN (problème d'allocation de mémoire)
Je met le code corrigé ci-dessous (adapté d'un code publié par Renfield sur ce site) , ça peut toujours servir !
PS
J'espère n'avoir pas trop écrit d'anneries dans les commentaires, je ne suis pas informaticien et ne maitrise totalement ces API... J'ai juste adaptaté un code existant et les commentaires reflètent uniquement ma compréhension.
'API et constantes
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetDlgItem Lib "user32.dll" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const SYNCHRONIZE As Long = &H100000
Private Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF&)
Dim StatusBar_Item_Nb
StatusBar_Item_Nb = 0 'Numéro de l'élément à traiter dans la barre de statut
Dim pid As Long
Dim process As Long
Dim ptr_sBuffer As Long
Dim sBuffer As String
Dim sBufferSize As Long
'~~ Récupération des handlers de la fenêtre et de la barre de statut ~~
Dim hWordpadWnd As Long
Dim hWordpadStatusBar As Long
hWordpadWnd = FindWindow("WordPadClass", vbNullString)
hWordpadStatusBar = GetDlgItem(hWordpadWnd, 59393)
'~~ Récupération de la taille de la chaine de caractère avec SB_GETTEXTLENTGH~~
sBufferSize = SendMessage(hWordpadStatusBar, SB_GETTEXTLENGTH, StatusBar_Item_Nb, 0)
sBufferSize = (sBufferSize And &HFFFF&)
sBuffer = Space$(sBufferSize)
'~~ Récupération du contenu de la chaine de caratère ~~
'On récupère le process ID de la barre de statut
GetWindowThreadProcessId hWordpadStatusBar, pid
'A partir de ce process ID, on récupère le handler du process...
process = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
'... et on alloue un emplacement mémoire au sein de ce process
ptr_sBuffer = VirtualAllocEx(process, 0, sBufferSize, MEM_COMMIT, PAGE_READWRITE)
'On copie ensuite le texte dans l'emplacement mémoire alloué avec SB_GETTEXT...
SendMessage hWordpadStatusBar, SB_GETTEXT, StatusBar_Item_Nb, ByVal ptr_sBuffer
'...et on vient lire cet emplacement mémoire pour récupèrer le texte
ReadProcessMemory process, ByVal ptr_sBuffer, ByVal sBuffer, sBufferSize, 0
'Pour finir, on libère l'emplacement mémoire alloué
VirtualFreeEx process, ptr_sBuffer, 0, MEM_RELEASE
'API et constantes
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetDlgItem Lib "user32.dll" (ByVal hDlg As Long, ByVal nIDDlgItem As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_GETTEXT As Long = &HD
Private Const SB_GETTEXT As Long = &H402
Private Const SB_GETTEXTLENGTH = &H403
Sub test1_WM_GETTEXT()
'Handles de la fenêtre et de la barre de statut
Dim hWordpadWnd As Long
Dim hWordpadStatusBar As Long
hWordpadWnd = FindWindow("WordPadClass", vbNullString)
hWordpadStatusBar = GetDlgItem(hWordpadWnd, 59393)
MsgBox "Handle de la fenêtre: " & hWordpadWnd & " | Handle de la barre de statut: " & hWordpadStatusBar
'Lecture du texte de la barre de statut
Dim sbuffer As String
sbuffer = Space$(50)
SendMessage hWordpadStatusBar, WM_GETTEXT, 50, ByVal sbuffer
MsgBox "Texte de la barre de statut: " & sbuffer
End Sub
Sub test2_SB_GETTEXT()
'Handles de la fenêtre et de la barre de statut
Dim hWordpadWnd As Long
Dim hWordpadStatusBar As Long
hWordpadWnd = FindWindow("WordPadClass", vbNullString)
hWordpadStatusBar = GetDlgItem(hWordpadWnd, 59393)
MsgBox "Handle de la fenêtre: " & hWordpadWnd & " | Handle de la barre de statut: " & hWordpadStatusBar
'Lecture du texte de la barre de statut
Dim String_size As Long
Dim sbuffer As String
'Taille de la chaine
String_size = SendMessage(hWordpadStatusBar, SB_GETTEXTLENGTH, ByVal 0, ByVal 0)
String_size = (String_size And &HFFFF&)
MsgBox "Nombre de caractères lus: " & String_size
'Récupération du texte
sbuffer = Space$(String_size)
SendMessage hWordpadStatusBar, SB_GETTEXT, ByVal 0, ByVal sbuffer
MsgBox "Texte de la barre de statut: " & sbuffer