cavo789
Messages postés168Date d'inscriptionvendredi 9 janvier 2004StatutMembreDernière intervention28 juillet 2009
-
19 mars 2007 à 12:29
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 2008
-
22 mars 2007 à 13:33
Bonjour
Je développe en VB 6 et en VBA. En VB6, j'ai écris une toute grosse DLL qui reprend une multitude de classes que j'utilise ensuite; par exemple, en VBA MS Access ou Excel.
Dans ma DLL, j'ai prévu une variable publique bDebug qui, une fois initialisée à True, m'affiche une série de messages type debugging.
Ma demande : j'aimerais que ma DLL puisse retrouver le handle de la fenêtre de debugging Debug Window de MS Excel (fenêtre qu'on obtient lorsqu'on appuie sur CTRL-G). Une fois le handle de la fenêtre trouvée (ça je sais le faire), permettre d'écrire dans cette fenêtre.
Pour dire les choses autrement : en VBA, je peux faire un Debug.Print "Blabla". Je voudrais que ma DLL puisse faire la même chose et que l'output arrive dans la Debug Window de Excel.
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 200810 19 mars 2007 à 13:34
Salut, si j'ai bien compris tu cherches un handle! Si tu connais le titre de cette fenêtre cette API devrai suffir:
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
· lpClassName
Points to a null-terminated string that specifies the class name or is an atom that identifies the class-name string. If this parameter is an atom, it must be a global atom created by a previous call to the GlobalAddAtom function. The atom, a 16-bit value, must be placed in the low-order word of lpClassName; the high-order word must be zero.
· lpWindowName
Points to a null-terminated string that specifies the window name (the window’s title). If this parameter is NULL, all window names match.
cavo789
Messages postés168Date d'inscriptionvendredi 9 janvier 2004StatutMembreDernière intervention28 juillet 20091 20 mars 2007 à 13:05
Merci Drikce06. Tu as bien compris. Le stud', c'est que j'ai réussi à trouver le handle de la fenêtre (ainsi j'arrive à changer le Caption "Debug Window" vers autre chose).
Ce que je n'arrive pas à faire, c'est de capturer le handle de la zone texte : cette fenêtre semble n'avoir qu'un seul contrôle et c'est une zone texte. C'est la zone dans laquelle il faut que je puisse écrire. J'ai déjà essayé avec un SendMessage et un WM_SETTEXT mais sans succès.
Si quelqu'un avait un truc qui me permettrait de commencer...
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 200810 20 mars 2007 à 13:16
Salut, mon exemple servait à trouver le handle de la fenêtre mère à partie du titre, maintenant il faut récupérer le handle du contrôle soit une fenêtre enfant! J'ai déjà fait ce genre de truc, je recherhce ce que j'avais fait et je vois ça, après de là à ce que ça marche!
Drikce 06
Si la réponse vous convient: Réponse acceptée. Si la réponse vous convient pas:
Vous n’avez pas trouvé la réponse que vous recherchez ?
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 200810 20 mars 2007 à 13:35
Voici un exemple c'est en .Net donc peut-être des modifs à faire pour VB6 notament pour les API remplacer les Integer par des Long.
Ici je cherchai la fenêtre PDF Creator et appuyer sur le bouton "enregistrer"! Pour plus de précision sur les api va sur www.allapi.net et télécharge APIGuide.
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, _
ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Object) As Integer
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Integer) As Integer
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, _
ByVal lpString As String, ByVal cch As Integer) As Integer
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Integer) As Integer
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Integer
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Integer, _
ByVal lpString As String) As Integer
Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Integer, _
ByVal wFlag As Integer) As Integer
Sub recherche()
Dim hwnd, hwnd1 As Integer
Dim NbChr As Integer
'cherche la fenêtre parent par son titre
hwnd = FindWindow(vbNullString, "PDFCreator 0.9.0")
'la met au premier plan
SetForegroundWindow (hwnd)
'pause
Sleep (100)
'cherhce les fenêtres enfants (contrôle)
hwnd1 = GetWindow(hwnd, GW_CHILD)
'pause
Sleep (100)
'Boucle sur tous les contrôles
Do While hwnd <> 0
'pause
Sleep (100)
Dim MyStr As String
MyStr = ""
'cherche le nombre de caractère du titre du contrôle
NbChr = GetWindowTextLength(hwnd1)
'création buffer
MyStr = MyStr.PadLeft(NbChr)
'cherche son titre
Call GetWindowText(hwnd1, MyStr, NbChr + 1)
'si le titre correspond
If MyStr = "Enregistrer" Then
'mettre la fenêtre enfant au premier plan (ici focus sur un boutton)
SetForegroundWindow (hwnd1)
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 200810 20 mars 2007 à 14:03
Désolé, j'avais oublié pas mal de truc et là je l'ai arangé pour qu'il soit compatible avec VB6 (je l'ai fais en VBA), j'ai essayé en lançant la commande: démarrer > executé. ça ouvre la fenêtre et à partir de là je cherche à appuyer sur le boutton OK.
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, _
ByVal wFlag As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Sub recherche()
Dim hwnd, hwnd1 As Long
Dim NbChr As Long
'cherche la fenêtre parent par son titre
hwnd = Int(FindWindow(vbNullString, "Exécuter"))
'la met au premier plan
SetForegroundWindow (hwnd)
'pause
Sleep (100)
'cherhce les fenêtres enfants (contrôle)
hwnd1 = GetWindow(hwnd, GW_CHILD)
'pause
Sleep (100)
'Boucle sur tous les contrôles
Do While hwnd <> 0
'pause
Sleep (100)
Dim MyStr As String
'cherche le nombre de caractère du titre du contrôle
NbChr = GetWindowTextLength(hwnd1)
MyStr = String(NbChr + 1, Chr$(0))
'cherche son titre
Call GetWindowText(hwnd1, MyStr, NbChr + 1)
'si le titre correspond
If Left(MyStr, 2) = "OK" Then
'mettre la fenêtre enfant au premier plan (ici focus sur un boutton)
SetForegroundWindow (hwnd1)
cavo789
Messages postés168Date d'inscriptionvendredi 9 janvier 2004StatutMembreDernière intervention28 juillet 20091 22 mars 2007 à 11:57
Drikce
J'ai utilisé ton code et l'ai un tout petit peu adapté. Il retrouve bien le handle de la fenêtre et, malheureusement, aucun autre handle ==> il semble ne pas y avoir de fils or cette fenêtre contient une zone texte.
Voici comme j'ai testé :
<li>Je lance Excel</li><li>J'appuie sur ALT-F11 pour passer en VBA</li><li>Je crée un nouveau module</li><li>Je copy/paste le code ci-dessous</li><li>J'appuie sur CTRL-G pour afficher la "Immediate" window (c'est ce que j'appelais à tort la Debug window)</li><li>Je lance la subroutine Recherche</li>Le handle de la Immediate window est bien trouvé et pas celui de la zone texte dans cette fenêtre.
Pour rappel, j'aimerais justement pouvoir récupérer cette zone texte de telle manière qu'avec l'API SetWindowText ou SendMessage je puisse écrire dans données dans cette fenêtre; exactement comme le fait Debug.Print en VBA.
Je ne peux pas utiliser Debug.Print car c'est une DLL VB que j'ai développé qui doit pouvoir écrire dans cette fenêtre.
Une fois encore, un très grand merci pour l'aide déjà apportée.
Christophe
Option Explicit
Const GW_HWNDNEXT = 2
Const GW_CHILD = 5
Public Declare Function lstrlen Lib "kernel32" Alias "lstrlenW" (ByVal lpString As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, _
ByVal wFlag As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Function TrimNull(sTemp As String) As String
TrimNull = Left$(sTemp, lstrlen(StrPtr(sTemp)))
End Function
Sub recherche()
Dim hwnd, hwnd1 As Long
Dim NbChr As Long
Dim MyStr As String
' Cherche la fenêtre parent par son titre
hwnd = Int(FindWindow(vbNullString, "Immediate"))
' Cherche les fenêtres enfants (contrôle)
hwnd1 = GetWindow(hwnd, GW_CHILD)
' Pause
Sleep (100)
' Boucle sur tous les contrôles
Do While hwnd1 <> 0
' Pause
Sleep (100)
' Cherche le nombre de caractère du titre du contrôle
drikce06
Messages postés2236Date d'inscriptionlundi 29 mai 2006StatutMembreDernière intervention29 mai 200810 22 mars 2007 à 13:33
'Toujours mon exemple avec la fenêtre exécuter dans démarrer > exécuter
'je cherche la combobox par le nom de sa classe
'je suppose que pour toi la classe que tu cherche est de type TextBox
Const GW_HWNDNEXT = 2
Const GW_CHILD = 5
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, _
ByVal wFlag As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Sub CommandButton1_Click()
Dim hwnd, hwnd1 As Long
Dim NbChr As Long
Dim MyStr As String
Dim lpClassName As String
' Cherche la fenêtre parent par son titre
hwnd = Int(FindWindow(vbNullString, "Exécuter"))