2013-07-18 25 views
1

假設我有一個編譯好的二進制程序,它運行並在屏幕上顯示一些GUI。 我需要從Win32中的其他程序訪問其工具欄,找到一個按鈕,然後單擊它。Win32,如何訪問工具欄上的按鈕

我知道如何找到Hwnd的工具欄,但我真的不知道如何枚舉它上面的按鈕。 任何想法如何在Win32調用中做到這一點?

有沒有像Spy ++這樣的工具能夠顯示工具欄下的按鈕手柄? Spy ++不會這樣做。

感謝

+2

爲什麼不使用自動化API? –

+0

自動化API是訪問對象的較慢方式。 –

+1

我看不到指定性能約束的問題部分。 –

回答

4

如果它是一個標準的Win32工具欄控件,那麼你發送工具欄一個TB_BUTTONCOUNT消息來確定工具欄上有多少個按鈕,然後發送一個TB_GETBUTTON消息來檢索給定索引處按鈕的信息。

棘手的部分是需要擁有該工具欄相同的過程被分配接收按鈕信息的TBBUTTON結構,所以你必須:

  1. 呼叫GetWindowThreadProcessId()檢索工具欄的進程ID
  2. 呼叫OpenProcess()獲得HANDLE這一進程
  3. 呼叫VirtualAllocEx()來分配過程的內部結構
  4. TB_GETBUTTON消息(S)到工具欄,指定由VirtualAllocEx()
  5. 調用ReadProcessMemory()返回結構數據備份複製到自己的過程,以便您可以根據需要
  6. 呼叫VirtualFreeEx()釋放所分配的內存處理它的指針。
+1

這種方法(儘管「正確」)受到*整個*問題的困擾。不要這樣做。爲作業使用正確的界面:自動化。而且,@AlekGaisman,儘管我知道這並不總是可能的,但請重新考慮您的設計。如果我同意明天我會爲午餐付款,並不意味着我*同意讓你進入我的口袋,拿出我的錢包並帶走我的美國運通。 –

0

關閉我的頭頂:

使用EnumChildWindows找到工具欄的子控件。

然後使用GetWindowText來查看它是否是一個按鈕。

如果是PostMessage它來調用它的操作。

+8

大多數工具欄上的單個按鈕不是子控件與他們自己的HWNDs。它們通常只是直接在工具欄上繪製的區域。 –

+0

現在它變得更有意義,謝謝 –

0

AFAIR通過調用GetDlgItem可以獲得工具欄按鈕的HWND。第一個參數是工具欄的HWND,第二個參數是按鈕的ID(在TBBUTTON結構中設置的那個)。你需要有按鈕ID來使用這種方法。

===編輯===

除了EnumChildWindows,由@ graham.reeds建議,可以嘗試SendInput。將目標窗口移動到前景,計算工具欄左上角的屏幕座標(使用其HWND),添加目標按鈕中間的X-Y偏移量,然後將鼠標單擊到該位置。 (我成功地使用了這種方法來點擊在IE窗口內渲染的Flash和Silverlight對象。)

+1

不幸的是,我沒有按鈕ID,我正在使用MS Spy ++。它只顯示一個ToolbarWindow32對象,但沒有顯示按鈕。是否有任何工具可以深入到工具欄結構中 –

0

當單擊該按鈕時,它會向主窗口發送WM_COMMAND消息。模擬工具欄按鈕上的點擊不太實際。更好的方法是使用Spy ++來查找WM_COMMAND消息及其參數。然後在你的程序中發送相同的WM_COMMAND消息。

+0

我明白WM_COMMANDS的概念,但我仍然需要訪問該按鈕,因爲該按鈕僅包含唯一的狀態指示器運行過程。 –