|
-
Sep 26th, 2005, 09:28 PM
#1
Thread Starter
Fanatic Member
[RESOLVED] Press toolbar button
Why doesn't this work? idCommand always comes back as zero. It is finding the correct hWnd for the toolbar.
VB Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
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 Const WM_USER = &H400
Private Const TB_BUTTONCOUNT = (WM_USER + 24)
Private Const TB_GETBUTTON = (WM_USER + 23)
Private Const TB_PRESSBUTTON = (WM_USER + 3)
Private Type TBBUTTON
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved1 As Byte
bReserved2 As Byte
dwData As Long
iString As Long
End Type
Private Sub ClickToolbarButton()
Dim lToolbarHwnd As Long
Dim lButtonCount As Long
Dim MyButton As TBBUTTON
lToolbarHwnd = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "WorkerW", vbNullString)
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ReBarWindow32", vbNullString)
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ToolbarWindow32", "")
Debug.Print lToolbarHwnd
lButtonCount = SendMessage(lToolbarHwnd, TB_BUTTONCOUNT, 0, 0)
For lButton = 1 To lButtonCount
SendMessage lToolbarHwnd, TB_GETBUTTON, lButton, MyButton
Debug.Print lButton & " : " & MyButton.idCommand
SendMessage lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, True
Next lButton
End Sub
-
Sep 26th, 2005, 11:27 PM
#2
Thread Starter
Fanatic Member
Re: Press toolbar button
Arrrrrgh!
OK. SO I need to buffer the memory of the TBBUTTON struct because I'm going across processes. So I used the Dr. Memory module. Now it works--sort of.
I get the button IDs, and TB_PRESSBUTTON is sure making the buttons go up and down, but they aren't invoking the click event on the buttons!!!! I tried TB_CHECKBUTTON too, but all I get is button movement and no event is firing in Interent Explorer.
I tried sending BM_CLICK with the button idCommand as the wParam but it always returns false. Any ideas on how to fire off the click event of the button???
VB Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
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 Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Type TBBUTTON
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved1 As Byte
bReserved2 As Byte
dwData As Long
iString As Long
End Type
Private Const WM_USER = &H400
Private Const TB_GETBUTTON = (WM_USER + 23)
Private Const TB_BUTTONCOUNT = (WM_USER + 24)
Private Const TB_PRESSBUTTON = (WM_USER + 3)
Private Const TB_CHECKBUTTON = (WM_USER + 2)
Private Sub ClickToolbarButton()
Dim lToolbarHwnd As Long
Dim lButtonCount As Long
Dim MyButton As TBBUTTON
Dim xpBuffer As Long ' Address of cross-process buffer.
lToolbarHwnd = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "WorkerW", vbNullString)
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ReBarWindow32", vbNullString)
lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ToolbarWindow32", "")
Debug.Print lToolbarHwnd
lButtonCount = SendMessage(lToolbarHwnd, TB_BUTTONCOUNT, 0&, 0&)
xpBuffer = drMemoryAlloc(lToolbarHwnd, 1024)
For lButton = 0 To lButtonCount - 1
SendMessageLong lToolbarHwnd, TB_GETBUTTON, lButton, xpBuffer
drMemoryRead xpBuffer, VarPtr(MyButton), Len(MyButton)
SendMessageLong lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, True
SendMessageLong lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, False
Next lButton
End Sub
-
Sep 26th, 2005, 11:44 PM
#3
Thread Starter
Fanatic Member
Re: Press toolbar button
Here's an excerpt of Dr. Memory that has the functions need for this code.
VB Code:
Option Explicit
'=======================================================================
' drMemory - Cross-Process Memory Buffer support
'
' (c) 2003 "Dr Memory" ==> Jim White
' MathImagics
' Uki, NSW, Australia
' Puttenham, Surrey, UK
'=======================================================================
'=======================================================================
' Excerpted and abbreviated by WorkHorse.
'=======================================================================
Private fpHandle As Long ' the foreign-process instance handle. When we want
' memory on NT platforms, this is returned to us by
' OpenProcess, and we pass it in to VirtualAllocEx.
' We must preserve it, as we need it for read/write
' operations, and to release the memory when we've
' finished with it.
''================== WinNT/2000 Process Memory functions
Private Declare Function OpenProcess Lib "KERNEL32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) 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, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function WriteProcessMemory Lib "KERNEL32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As Long, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "KERNEL32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As Long, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "KERNEL32" (ByVal hObject As Long) As Long
'================== Common Platform
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Const PAGE_READWRITE = &H4
Const MEM_RESERVE = &H2000&
Const MEM_RELEASE = &H8000&
Const MEM_COMMIT = &H1000&
Const PROCESS_VM_OPERATION = &H8
Const PROCESS_VM_READ = &H10
Const PROCESS_VM_WRITE = &H20
Public Function drMemoryAlloc(ByVal xpWindow As Long, ByVal nBytes As Long) As Long
' Returns pointer to a share-able buffer (size nBytes) in target process that owns xpWindow
Dim xpThread As Long ' target control's thread id
Dim xpID As Long ' process id
' Assumes using WIN NT type OS. -WorkHorse
xpThread = GetWindowThreadProcessId(xpWindow, xpID)
drMemoryAlloc = VirtualAllocNT(xpID, nBytes)
End Function
Public Sub drMemoryRead(ByVal xpBuffer As Long, ByVal myBuffer As Long, ByVal nBytes As Long)
' Assumes using WIN NT type OS. -WorkHorse
ReadProcessMemory fpHandle, xpBuffer, myBuffer, nBytes, 0
End Sub
Public Sub drMemoryFree(ByVal mPointer As Long)
' Assumes using WIN NT type OS. -WorkHorse
VirtualFreeNT mPointer
End Sub
Private Function VirtualAllocNT(ByVal fpID As Long, ByVal memSize As Long) As Long
fpHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, fpID)
VirtualAllocNT = VirtualAllocEx(fpHandle, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
End Function
Private Sub VirtualFreeNT(ByVal MemAddress As Long)
Call VirtualFreeEx(fpHandle, ByVal MemAddress, 0&, MEM_RELEASE)
CloseHandle fpHandle
End Sub
-
Sep 27th, 2005, 12:45 AM
#4
Thread Starter
Fanatic Member
Re: Press toolbar button
I got it. WD_COMMAND invokes the click event. I tried combing the memory functions into one module, but I must have did something wrong because it crashed and deleted my saved project and eveything. Ahhhh..the joys of screwing around with memory pointers!
Anyway, here's the code to click a button on a remote toolbar (using the Dr. Memory code to handle the memory.) You can get the full module at Dr. Memory .
VB Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
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 Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Type TBBUTTON
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved1 As Byte
bReserved2 As Byte
dwData As Long
iString As Long
End Type
Private Const WM_USER = &H400
Private Const TB_GETBUTTON = (WM_USER + 23)
Private Const WM_COMMAND = &H111
Private Sub TestClickingToolbarButton()
Dim hToolbar As Long
hToolbar = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
hToolbar = FindWindowEx(hToolbar, 0, "WorkerW", vbNullString)
hToolbar = FindWindowEx(hToolbar, 0, "ReBarWindow32", vbNullString)
hToolbar = FindWindowEx(hToolbar, 0, "ToolbarWindow32", "")
ClickToolbarButtonByIndex hToolbar, 7 ' Button 7 is the Favorites button.
End Sub
Private Sub ClickToolbarButtonByIndex(ByVal hToolbar As Long, ByVal lButtonIndex As Long)
Dim MyButton As TBBUTTON
Dim xpBuffer As Long ' Address of cross-process buffer.
xpBuffer = drMemoryAlloc(hToolbar, 1024)
SendMessageLong hToolbar, TB_GETBUTTON, lButtonIndex, xpBuffer
drMemoryRead xpBuffer, VarPtr(MyButton), Len(MyButton)
PostMessage GetParent(hToolbar), WM_COMMAND, MyButton.idCommand, hToolbar
drMemoryFree xpBuffer
End Sub
-
Jul 31st, 2008, 03:48 PM
#5
New Member
Re: [RESOLVED] Press toolbar button
This works super, thanks for sharing.
Is there a way to send clicks to buttons on add-in toolbars such as the Goggle toolbar?
-
Sep 2nd, 2011, 12:09 PM
#6
New Member
Re: [RESOLVED] Press toolbar button
hi,
sorry if i am wrong. i have tried WM_COMMAND lot of times.i am not able to send the click event.Eventhough sendmessage returns zero.but no expected output.
-
Sep 2nd, 2011, 12:13 PM
#7
Re: [RESOLVED] Press toolbar button
Where are you trying to send the click event?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|