2009-12-27
自作あぷりからAPIで他のあぷりをいじるときのめも。(3/4)
前回の記事→自作あぷりからAPIで他のあぷりをいじるときのめも。(2/4)
電卓だけだと、いじりたい物がついてなかったりするんで
他にいじってみたいものだけ集めて1つのフォームを作ってみました。
↑上から順にTextBox/RichEdit/ListBox/ComboBox
ListBoxには、 ListBox01,ListBox02,・・・,ListBox10が入っていて
ComboBoxには、ComboBox01,ComboBox02,・・・,ComboBox10が入ってます
各ボタンは、それぞれの値を表示するボタンです。
各クラス名とツリー関係はこうなってます。
TextBoxに文字を送る(WB_SETTEXT)
じゃ、文字でも送ってみます。
・(&HC)WM_SETTEXT…文字列を送る
SendMessageの
第3引数:未使用
返り値 :成功すると1、失敗した場合、ウィンドウによってエラーが違いますね。
Imports System.Text Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer Public Const WM_SETTEXT = &HC Public Const BM_CLICK = &HF5 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示1") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.EDIT.app.0.378734a", "") 'TextBoxに何か文字列を送ってみる。 Dim Ret As Integer, sb = New StringBuilder sb = New StringBuilder("ほげほげ") Ret = SendMessageStr(hwnd3, WM_SETTEXT, 0, sb) '表示1をクリックしてみる SendMessage(hwnd2, BM_CLICK, 0, 0) End Sub End Module
これで「ほげほげ」って表示されますね。
しれっと、StringBulider型の変数に文字列をつっこんで
送信したんですが…String型でも送れますね。。
試しに、RichEdit欄にString型で送りつけてみる。
Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As String) As Integer Public Const WM_SETTEXT = &HC Public Const BM_CLICK = &HF5 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示2") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.RichEdit20W.app.0.378734a", "") 'RichEDITに何か文字列を送ってみる。 Dim Ret As Integer, str As String str = "ほげ" & vbCr & "ほげ" Ret = SendMessageStr(hwnd3, WM_SETTEXT, 0, str) '表示2をクリックしてみる SendMessage(hwnd2, BM_CLICK, 0, 0) End Sub End Module
こんな感じでちゃんと表示されますね。
ListBoxをいじってみる
ここでやってみることは、
ListBoxのリスト内容を調べる。
目的の項目を選択状態にしてみる。
この2点に絞ります。
コードがかけたもんじゃないんで、リストの数を調べるメッセージでも
投げてみたいと思います。
リストボックス関係は、LB_系ですね。
・(&H18B)LB_GETCOUNT…リストボックスの項目するを調べる
SendMessageの
第3引数:未使用
第4引数:未使用
返り値 :エラー時、LB_ERR(-1)
次に、個数がわかればFor文でくるくるまわして各アイテムを取得するだけなので
電卓の例で表示の文字列を取得した時のように各項目の長さを調べて
変数を作って受取るの繰り返しをすればよさそうですね。
使うメッセージは・・・
・(&H18A)LB_GETTEXTLEN…指定した項目の長さを取得
SendMessageの
第3引数:どの項目の長さを知りたいか指定します
第4引数:未使用
返り値 :該当する項目の文字数
・(&H189)LB_GETTEXT…指定した項目の文字列を取得
SendMessageの
Imports System.Text Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer Public Const LB_GETCOUNT = &H18B Public Const LB_GETTEXT = &H189 Public Const LB_GETTEXTLEN = &H18A Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示3") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.LISTBOX.app.0.378734a", "") Dim Index As Integer Index = SendMessage(hwnd3, LB_GETCOUNT, 0, 0) Dim LB As String = "" For i As Integer = 0 To Index - 1 Dim length As Integer length = SendMessage(hwnd3, LB_GETTEXTLEN, i, 0) Dim Ret As Integer, sb = New StringBuilder sb = New StringBuilder("", length) Ret = SendMessageStr(hwnd3, LB_GETTEXT, i, sb) If LB = "" Then LB = sb.ToString & vbCrLf Else LB = LB & sb.ToString & vbCrLf End If Next MsgBox(LB) End Sub End Module
これはこれで各項目の値が取得できるんですが…
WM_GETTEXTの時には、SendMessageの第3引数に受取る文字列のバイト数を指定して
第4引数に受取る変数を指定したのに対し、LB_GETTEXTの場合には、第3引数が
どの項目を受取るのか指定するだけなんですね。。
試してみる。
Imports System.Text Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As StringBuilder) As Integer Public Const LB_GETCOUNT = &H18B Public Const LB_GETTEXT = &H189 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示3") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.LISTBOX.app.0.378734a", "") Dim Index As Integer Index = SendMessage(hwnd3, LB_GETCOUNT, 0, 0) Dim LB As String = "" For i As Integer = 0 To Index - 1 Dim Ret As Integer, sb = New StringBuilder sb = New StringBuilder("") Ret = SendMessageStr(hwnd3, LB_GETTEXT, i, sb) If LB = "" Then LB = sb.ToString & vbCrLf Else LB = LB & sb.ToString & vbCrLf End If Next MsgBox(LB) End Sub End Module
これでもいけますね。
次に目的の項目を選択してみる…
(&H186)LB_SETCURSEL…リストボックスの項目を選択する
SendMessageの
第3引数:選択したい項目を指定。
-1を指定すると選択解除となる。
第4引数:未使用。
返り値 :エラー時、LB_ERR(-1)
ついでに、
(&H197)LB_SETTOPINDEX…指定した項目をリストの上部に表示する
SendMessageの
第3引数:項目を指定
第4引数:未使用。
返り値 :エラー時、LB_ERR(-1)
Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Public Const LB_GETCOUNT = &H18B Public Const BM_CLICK = &HF5 Public Const LB_SETCURSEL = &H186 Public Const LB_SETTOPINDEX = &H197 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示3") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.LISTBOX.app.0.378734a", "") Dim Index As Integer Index = SendMessage(hwnd3, LB_GETCOUNT, 0, 0) For i As Integer = 0 To Index - 1 SendMessage(hwnd3, LB_SETTOPINDEX, i, 0) SendMessage(hwnd3, LB_SETCURSEL, i, 0) SendMessage(hwnd2, BM_CLICK, 0, 0) Next End Sub End Module
これで、リストの最初の物から順にスクロールしつつ、選択が変わっていくんだけど…
ボタンをおすことで現在選択されているリストを表示する
部分で正しく選択されなーーーーい。なぜ????
ComboBoxをいじる。
ここまでやれば、もう説明不要かと。。
リストボックスで送ったメッセージがLBだったのがCBに変わっただけですね。
CBになった際の値は、
・CB_GETCOUNT = &H146
・CB_SETCURSEL = &H14E
・CB_SETTOPINDEX = &H15C
Module Module1 Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _ (ByVal hwndParent As Integer, ByVal hwndChildAfter As Integer, _ ByVal lpszClass As String, ByVal lpszWindow As String) As Integer Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer) As Integer Declare Function SendMessageStr Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As String) As Integer Public Const CB_GETCOUNT = &H146 Public Const BM_CLICK = &HF5 Public Const WM_SETTEXT = &HC Public Const CB_SETCURSEL = &H14E Public Const CB_SETTOPINDEX = &H15C Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer, hwnd3 As Integer, hwnd4 As Integer hwnd1 = FindWindow("WindowsForms10.Window.8.app.0.378734a", "test") hwnd2 = FindWindowEx(hwnd1, 0, "WindowsForms10.BUTTON.app.0.378734a", "表示4") hwnd3 = FindWindowEx(hwnd1, 0, "WindowsForms10.COMBOBOX.app.0.378734a", "") hwnd4 = FindWindowEx(hwnd3, 0, "EDIT", "") Dim Index As Integer Index = SendMessage(hwnd3, CB_GETCOUNT, 0, 0) For i As Integer = 0 To Index - 1 SendMessage(hwnd3, CB_SETTOPINDEX, i, 0) SendMessage(hwnd3, CB_SETCURSEL, i, 0) SendMessage(hwnd2, BM_CLICK, 0, 0) Next Dim Ret As Integer Ret = SendMessageStr(hwnd4, WM_SETTEXT, 0, "ほげほげ") SendMessage(hwnd2, BM_CLICK, 0, 0) End Sub End Module
こちらは、クリックのメッセージを送ってボタンをおした際にちゃんと表示されますね。
- 26170 https://www.google.co.jp/
- 4501 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=18&cts=1331212547535&ved=0CF8QFjAHOAo&url=http://d.hatena.ne.jp/maeyan/20091227&ei=97BYT5rYMtCviQeP86mqDQ&usg=AFQjCNGz8ho6q0eijH3wYRfbso5Zjx_nyQ&sig2=EiCyjbazWmLAX6fgSC6DlQ
- 3456 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&ved=0CCQQFjAA&url=http://d.hatena.ne.jp/maeyan/20091227/1261848549&ei=5i8xT9jLFfHKmQWKrvjWBQ&usg=AFQjCNFE-9i3PB_g1i7xVpC2XBNgjwSB-A&sig2=Z5XvME2kc7-8NNe_f3vEbw
- 3154 https://www.google.com/
- 2826 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=20&ved=0CHAQFjAJOAo&url=http://d.hatena.ne.jp/maeyan/20091227/1261848549&ei=ZIdyT7e0FI_4mAXPrIHXDw&usg=AFQjCNFE-9i3PB_g1i7xVpC2XBNgjwSB-A&sig2=tGFfL3LzTdDRy7nLPvZ1Cw
- 2740 https://www.google.co.jp
- 2647 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&ved=0CEIQFjAC&url=http://d.hatena.ne.jp/maeyan/20091227/1261917136&ctbs=lr:lang_1ja&ei=c9pDT_ks8c-YBa2VlesM&usg=AFQjCNEQDLk0YBBMQi_4V57tBeVMXpqr1Q&sig2=XlKyAr3z0Mg_RuC042QU2g
- 2345 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&sqi=2&ved=0CDsQFjAD&url=http://d.hatena.ne.jp/maeyan/20091227/1261936878&ei=v9JmT8jRAouemQXzo5C0CA&usg=AFQjCNHZQ5wm3KnQIVWSvwipJKV8PaO6xw
- 2196 http://search.yahoo.co.jp/
- 2018 http://www.google.co.jp/url?url=http://d.hatena.ne.jp/maeyan/20091227/1261917136&rct=j&sa=U&ei=M82DTryiEc7hrAet493jDA&ved=0CDEQFjAH&q=VB2005+FINDWINDOW+FINDWINDOWEX+SENDMESSAGE&usg=AFQjCNFkHjV60rpf2JwQH1D3Db-WKsnZOQ