Utilisation SB_GETTEXT (lecture texte barre de statut)

Résolu
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010 - 29 juil. 2010 à 23:26
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Derniè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...

Simon

------------------------------------------------------------------------------------------------------------------------

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

End Sub

3 réponses

Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Derniè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&)

Private Const MEM_RELEASE = &H8000
Private Const MEM_COMMIT = &H1000
Private Const PAGE_READWRITE = &H4

Private Const WM_GETTEXT = &HD
Private Const SB_GETTEXT = &H402
Private Const SB_GETTEXTLENGTH = &H403

Sub test2_SB_GETTEXT()

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

MsgBox "Item length: " & Len(sBuffer)
MsgBox "Item: " & sBuffer

End Sub
3
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010
29 juil. 2010 à 23:48
Oupssssss, j'ai eu un problème de CTRL+C/CTRL-V...... Il manque une ligne dans le code. Voici le code complet !

------------------------------------------------------------------------------------------------------------------------

'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

End Sub
0
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010
31 juil. 2010 à 12:01
Bon, a force de chercher, je suis tombé sur un code C:

http://www.eggheadcafe.com/software/aspnet/29502197/get-text-from-nonowned-s.aspx

...développé à partir de:

http://www.codeproject.com/KB/threads/int64_memsteal.aspx?df=100&forumid=29535&exp=0&select=1604427&tid=1604427

Ca a pas l'air simple pour le novice que je suis. Reste à savoir si c'est adaptable en VBA...
0
Rejoignez-nous