需要点击另外一个程序中toolbar的按钮,我知道toolbar按钮其实不是按钮,已经取得了按钮的ID,并且用TB_ENABLEBUTTON成功,想用WM_CLICK单击按钮不成功,用WM_LBUTTONDOWN、WM_LBUTTONUP也没效果~~昏~
那位大大知道如何才能实现点击,谢谢!============下面附上TB_ENABLEBUTTON源码,这个是成功的~
Option Explicit
  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 GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
  Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
  Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
  Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten 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, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
  Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    
  Private Const PROCESS_ALL_ACCESS = &H1F0FFF
    
  Private Const MEM_COMMIT = &H1000
  Private Const MEM_DECOMMIT = &H4000
    
  Private Const PAGE_READWRITE = &H4&
    
  Private Const WM_USER       As Long = &H400
  Private Const TB_GETBUTTON         As Long = (WM_USER + 23)
  Private Const TB_ENABLEBUTTON       As Long = (WM_USER + 1)
    
  Private Type TBBUTTON
          iBitmap   As Long
          idCommand   As Long
          fsState   As Byte
          fsStyle   As Byte
          bReserved(1)   As Byte
          dwData   As Long
          iString   As Long
  End Type
    
  Private Function MAKELONG(ByVal a As Long, ByVal b As Long) As Long
          MAKELONG = (b And &HFFFF&) * &H10000 + (a And &HFFFF&)
  End Function
    
  Function EnableTBButtion(ByVal hTBWnd As Long, ByVal lIndex As Long, Optional fEnabled As Boolean = True, Optional fIsIndex As Boolean = True) As Long
          Dim utBtn     As TBBUTTON
          Dim lButtonID     As Long
          Dim lpRemote_utBtn     As Long
          Dim lProcessId     As Long, hProcess       As Long
          hTBWnd = Text1.Text
          Call GetWindowThreadProcessId(hTBWnd, lProcessId)
            
          If fIsIndex Then
                  hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, lProcessId)
                  If hProcess <> 0 Then
                          lpRemote_utBtn = VirtualAllocEx(ByVal hProcess, ByVal 0&, Len(utBtn), MEM_COMMIT, PAGE_READWRITE)
                          Call SendMessage(hTBWnd, TB_GETBUTTON, lIndex, ByVal lpRemote_utBtn)
                          Call ReadProcessMemory(ByVal hProcess, ByVal lpRemote_utBtn, utBtn, Len(utBtn), ByVal 0)
                          Call VirtualFreeEx(hProcess, ByVal lpRemote_utBtn, 0, MEM_DECOMMIT)
                  End If
                  CloseHandle hProcess
                  lButtonID = utBtn.idCommand
          Else
                  lButtonID = lIndex
          End If
            
          EnableTBButtion = SendMessage(hTBWnd, TB_ENABLEBUTTON, lButtonID, ByVal MAKELONG(Abs(fEnabled), 0))
  End Function
    
  Private Sub Command2_Click()
          '禁用第3个按钮
          Debug.Print EnableTBButtion(&H17104A4, 3 - 1, False)
  End Sub
    
  Private Sub Command1_Click()
          '启用第3个按钮
          Debug.Print EnableTBButtion(&H17104A4, 3 - 1, True)
  End Sub
 

解决方案 »

  1.   

    你的思路是不错,问题是方向有问题!通用控件一般都会把相关消息“藏”在WM_NOTIFY消息里,你上网查查TBN_开头的消息就明白了!
      

  2.   

    貌似发送工具栏按钮点击,用不着申请虚拟内存的
    你给它新增一个按钮的时候才需要申请虚拟内存,再说了,万一客户端禁用了虚拟内存,你这代码还是白搭
    还是用Heapxxxx的API函数申请物理内存吧只需要发送一条WM_NOTIFY消息,而且不是发给Toolbar,而是发给Toolbar的父窗体
    wParam参数中高位为控件ID(不是句柄)
    wParam参数中低位为通知消息(TBN_开头的消息)
    lParam参数根据wParam参数中低位的通知消息有所不同而结构也不同还是那句,自己上网查询查询!
      

  3.   


    ok!谢谢Sandrer,我试试 
      

  4.   

    嘿,刚刚试验了一下,工具栏点击的消息,应该是发送WM_COMMAND消息给主窗口
    WM_NOTIFY消息也可以,通知消息为NM_CLICK,lParam结构体为TBITEM,不过这样的话比较复杂用WM_COMMAND最方便。
    wParam:
    高位为工具栏的ID号(如果没有就设为0)
    低位为按钮的序列号(从左到右0~N)lParam:
    为工具栏的句柄其实就跟发送点击菜单的命令一样!
      

  5.   

    还是没有成功~代码如下
    '发送消息
    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
    '返回控件ID
    Private Declare Function GetDlgCtrlID Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Private Const WM_COMMAND = &H111
     Private Sub Command1_Click()
    Dim frmhwnd As Long, tbhwnd As Long, tbID As Long
    frmhwnd = Text1.Text '窗体句柄,应该是toolbar的上层句柄
    tbhwnd = Text2.Text  'toolbar句柄
    tbID = GetDlgCtrlID(tbhwnd) 'GetDlgCtrlID得到ToolbarID返回0~奇怪
    'tbID= GetWindowLong(tbhwnd, GWL_ID) '得到ToolbarID~~~用这个ID的话MAKELONG就溢出~SendMessage frmhwnd, WM_COMMAND, MAKELONG(2, tbID), tbhwnd
    End SubFunction MAKELONG(ByVal a As Long, ByVal b As Long) As Long
              MAKELONG = (b And &HFFFF&) * &H10000 + (a And &HFFFF&)
      End Function
      

  6.   

    SendMessage 主窗口句柄,WM_COMMAND,MakeLong(按钮ID,BN_CLICKED),toolbar句柄SendMessage frmhwnd, WM_COMMAND, MAKELONG(2, BN_CLICKED), tbhwnd这个也没用,奇怪
      

  7.   

    用CreateWindowEx函数创建的窗体一般都没有ID号
    你或者可以用GetWindowLong来获取看看(第二个参数设GWL_ID)再不行的话,直接用SPY++检测它,看点击工具栏到底是什么消息!
      

  8.   

    昨天下了本windows核心编程看看~确实应该是WM_COMMAND,并且发送给窗体框架~~暂时是搞不定了~还是先给分吧~