Results 1 to 7 of 7

Thread: [RESOLVED] Press toolbar button

  1. #1

    Thread Starter
    Fanatic Member WorkHorse's Avatar
    Join Date
    Jul 2002
    Location
    Where you live.
    Posts
    591

    Resolved [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:
    1. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    2. 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
    3. 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
    4.  
    5. Private Const WM_USER = &H400
    6. Private Const TB_BUTTONCOUNT = (WM_USER + 24)
    7. Private Const TB_GETBUTTON = (WM_USER + 23)
    8. Private Const TB_PRESSBUTTON = (WM_USER + 3)
    9.  
    10. Private Type TBBUTTON
    11.    iBitmap      As Long
    12.    idCommand    As Long
    13.    fsState      As Byte
    14.    fsStyle      As Byte
    15.    bReserved1   As Byte
    16.    bReserved2   As Byte
    17.    dwData       As Long
    18.    iString      As Long
    19. End Type
    20.  
    21. Private Sub ClickToolbarButton()
    22.    
    23.     Dim lToolbarHwnd    As Long
    24.     Dim lButtonCount    As Long
    25.     Dim MyButton        As TBBUTTON
    26.    
    27.     lToolbarHwnd = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
    28.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "WorkerW", vbNullString)
    29.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ReBarWindow32", vbNullString)
    30.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ToolbarWindow32", "")
    31.  
    32.     Debug.Print lToolbarHwnd
    33.  
    34.     lButtonCount = SendMessage(lToolbarHwnd, TB_BUTTONCOUNT, 0, 0)
    35.    
    36.     For lButton = 1 To lButtonCount
    37.    
    38.         SendMessage lToolbarHwnd, TB_GETBUTTON, lButton, MyButton
    39.         Debug.Print lButton & " : " & MyButton.idCommand
    40.         SendMessage lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, True
    41.  
    42.     Next lButton
    43.  
    44. End Sub

  2. #2

    Thread Starter
    Fanatic Member WorkHorse's Avatar
    Join Date
    Jul 2002
    Location
    Where you live.
    Posts
    591

    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:
    1. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    2. 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
    3. 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
    4. 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
    5.  
    6. Private Type TBBUTTON
    7.    iBitmap As Long
    8.    idCommand As Long
    9.    fsState As Byte
    10.    fsStyle As Byte
    11.    bReserved1 As Byte
    12.    bReserved2 As Byte
    13.    dwData As Long
    14.    iString As Long
    15. End Type
    16.  
    17. Private Const WM_USER = &H400
    18. Private Const TB_GETBUTTON = (WM_USER + 23)
    19. Private Const TB_BUTTONCOUNT = (WM_USER + 24)
    20. Private Const TB_PRESSBUTTON = (WM_USER + 3)
    21. Private Const TB_CHECKBUTTON = (WM_USER + 2)
    22.  
    23. Private Sub ClickToolbarButton()
    24.    
    25.     Dim lToolbarHwnd    As Long
    26.     Dim lButtonCount    As Long
    27.     Dim MyButton        As TBBUTTON
    28.     Dim xpBuffer        As Long     ' Address of cross-process buffer.
    29.    
    30.     lToolbarHwnd = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
    31.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "WorkerW", vbNullString)
    32.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ReBarWindow32", vbNullString)
    33.     lToolbarHwnd = FindWindowEx(lToolbarHwnd, 0, "ToolbarWindow32", "")
    34.  
    35.     Debug.Print lToolbarHwnd
    36.  
    37.    lButtonCount = SendMessage(lToolbarHwnd, TB_BUTTONCOUNT, 0&, 0&)
    38.    
    39.    xpBuffer = drMemoryAlloc(lToolbarHwnd, 1024)
    40.  
    41.    For lButton = 0 To lButtonCount - 1
    42.      
    43.       SendMessageLong lToolbarHwnd, TB_GETBUTTON, lButton, xpBuffer
    44.       drMemoryRead xpBuffer, VarPtr(MyButton), Len(MyButton)
    45.       SendMessageLong lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, True
    46.       SendMessageLong lToolbarHwnd, TB_PRESSBUTTON, MyButton.idCommand, False
    47.      
    48.     Next lButton
    49.  
    50. End Sub

  3. #3

    Thread Starter
    Fanatic Member WorkHorse's Avatar
    Join Date
    Jul 2002
    Location
    Where you live.
    Posts
    591

    Re: Press toolbar button

    Here's an excerpt of Dr. Memory that has the functions need for this code.

    VB Code:
    1. Option Explicit
    2. '=======================================================================
    3. ' drMemory   - Cross-Process Memory Buffer support
    4. '
    5. '  (c) 2003  "Dr Memory" ==> Jim White
    6. '            MathImagics
    7. '            Uki, NSW, Australia
    8. '            Puttenham, Surrey, UK
    9. '=======================================================================
    10. '=======================================================================
    11. ' Excerpted and abbreviated by WorkHorse.
    12. '=======================================================================
    13.  
    14.    Private fpHandle      As Long     ' the foreign-process instance handle. When we want
    15.                                      ' memory on NT platforms, this is returned to us by
    16.                                      ' OpenProcess, and we pass it in to VirtualAllocEx.
    17.  
    18.                                      ' We must preserve it, as we need it for read/write
    19.                                      ' operations, and to release the memory when we've
    20.                                      ' finished with it.
    21.  
    22. ''================== WinNT/2000 Process Memory functions
    23.    Private Declare Function OpenProcess Lib "KERNEL32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    24.    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
    25.    Private Declare Function VirtualFreeEx Lib "KERNEL32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
    26.    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
    27.    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
    28.    Private Declare Function CloseHandle Lib "KERNEL32" (ByVal hObject As Long) As Long
    29.  
    30. '================== Common Platform
    31.    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    32.  
    33.    Const PAGE_READWRITE = &H4
    34.    Const MEM_RESERVE = &H2000&
    35.    Const MEM_RELEASE = &H8000&
    36.    Const MEM_COMMIT = &H1000&
    37.    Const PROCESS_VM_OPERATION = &H8
    38.    Const PROCESS_VM_READ = &H10
    39.    Const PROCESS_VM_WRITE = &H20
    40.  
    41. Public Function drMemoryAlloc(ByVal xpWindow As Long, ByVal nBytes As Long) As Long
    42.    
    43.    ' Returns pointer to a share-able buffer (size nBytes) in target process that owns xpWindow
    44.    
    45.    Dim xpThread As Long    ' target control's thread id
    46.    Dim xpID As Long        '                  process id
    47.    
    48.    ' Assumes using WIN NT type OS. -WorkHorse
    49.     xpThread = GetWindowThreadProcessId(xpWindow, xpID)
    50.     drMemoryAlloc = VirtualAllocNT(xpID, nBytes)
    51.  
    52. End Function
    53.  
    54. Public Sub drMemoryRead(ByVal xpBuffer As Long, ByVal myBuffer As Long, ByVal nBytes As Long)
    55.    ' Assumes using WIN NT type OS. -WorkHorse
    56.     ReadProcessMemory fpHandle, xpBuffer, myBuffer, nBytes, 0
    57. End Sub
    58.  
    59. Public Sub drMemoryFree(ByVal mPointer As Long)
    60.    ' Assumes using WIN NT type OS. -WorkHorse
    61.     VirtualFreeNT mPointer
    62. End Sub
    63.  
    64. Private Function VirtualAllocNT(ByVal fpID As Long, ByVal memSize As Long) As Long
    65.    fpHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, fpID)
    66.    VirtualAllocNT = VirtualAllocEx(fpHandle, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
    67. End Function
    68.  
    69. Private Sub VirtualFreeNT(ByVal MemAddress As Long)
    70.    Call VirtualFreeEx(fpHandle, ByVal MemAddress, 0&, MEM_RELEASE)
    71.    CloseHandle fpHandle
    72. End Sub

  4. #4

    Thread Starter
    Fanatic Member WorkHorse's Avatar
    Join Date
    Jul 2002
    Location
    Where you live.
    Posts
    591

    Smile 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:
    1. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    2. 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
    3. 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
    4. 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
    5. 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
    6. Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
    7.  
    8. Private Type TBBUTTON
    9.    iBitmap      As Long
    10.    idCommand    As Long
    11.    fsState      As Byte
    12.    fsStyle      As Byte
    13.    bReserved1   As Byte
    14.    bReserved2   As Byte
    15.    dwData       As Long
    16.    iString      As Long
    17. End Type
    18.  
    19. Private Const WM_USER = &H400
    20. Private Const TB_GETBUTTON = (WM_USER + 23)
    21. Private Const WM_COMMAND = &H111
    22.  
    23. Private Sub TestClickingToolbarButton()
    24.  
    25.     Dim hToolbar    As Long
    26.    
    27.     hToolbar = FindWindow("IEFrame", "Google - Microsoft Internet Explorer")
    28.     hToolbar = FindWindowEx(hToolbar, 0, "WorkerW", vbNullString)
    29.     hToolbar = FindWindowEx(hToolbar, 0, "ReBarWindow32", vbNullString)
    30.     hToolbar = FindWindowEx(hToolbar, 0, "ToolbarWindow32", "")
    31.  
    32.     ClickToolbarButtonByIndex hToolbar, 7   ' Button 7 is the Favorites button.
    33.  
    34. End Sub
    35.  
    36. Private Sub ClickToolbarButtonByIndex(ByVal hToolbar As Long, ByVal lButtonIndex As Long)
    37.    
    38.     Dim MyButton        As TBBUTTON
    39.     Dim xpBuffer        As Long     ' Address of cross-process buffer.
    40.    
    41.     xpBuffer = drMemoryAlloc(hToolbar, 1024)
    42.     SendMessageLong hToolbar, TB_GETBUTTON, lButtonIndex, xpBuffer
    43.     drMemoryRead xpBuffer, VarPtr(MyButton), Len(MyButton)
    44.     PostMessage GetParent(hToolbar), WM_COMMAND, MyButton.idCommand, hToolbar
    45.     drMemoryFree xpBuffer
    46.    
    47. End Sub

  5. #5
    New Member
    Join Date
    Jul 2008
    Posts
    1

    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?

  6. #6
    New Member
    Join Date
    Sep 2011
    Posts
    1

    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.

  7. #7
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333

    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
  •  



Click Here to Expand Forum to Full Width