2009-12-27
自作あぷりからAPIで他のあぷりをいじるときのめも。(2/4)
前回の記事→自作あぷりからAPIで他のあぷりをいじるときのめも。(1/4)
引き続き、あぷりをいじるメモです。
ラジオボタンの状態を知る(BM_GETCHECK)
一応、分けて書きますね。
・(&HF0)BM_GETCHECK…ラジオorチェックボックスのチェック状態を知る
SendMessageの
第3引数:未使用
第4引数:未使用
返り値 :0…(&H00)BST_UNCHECKED 'チェックされてない
1…(&H01)BST_CHECKED 'チェックされてる
2…(&H02)BST_INDETERMINATE 'グレー状態(選択できない状態ですね)
※BST_INDETERMINATEは、3状態可能な場合のみ
ラジオボタンの状態確認
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 BM_GETCHECK = &HF0 Sub Main() Dim hwnd As Integer hwnd = FindWindow("SciCalc", "電卓") '親ハンドルを取得 Dim title() As String = {"16 進", "10 進", "8 進", "2 進"} Dim hwnd2(3) As Integer hwnd2(0) = FindWindowEx(hwnd, 0, "Button", title(0)) hwnd2(1) = FindWindowEx(hwnd, 0, "Button", title(1)) hwnd2(2) = FindWindowEx(hwnd, 0, "Button", title(2)) hwnd2(3) = FindWindowEx(hwnd, 0, "Button", title(3)) Dim Ret As Integer For i As Integer = 0 To hwnd2.Length - 1 Ret = SendMessage(hwnd2(i), BM_GETCHECK, 0, 0) Console.WriteLine(Ret & ":" & title(i)) Next End Sub End Module
実行すると、ラジオボタンがついているとこだけ1になりますね。
ここで問題が…
BM_GETCHECKで状態が見れるのだからBM_SETCHECKでチェックをつけれるのかな?
と、思ってしまいがちですがそういうわけでもないもたいですよ??
というわけで、やってみる。
ラジオボタンを切り替える(BM_SETCHECK)
・(&HF1)BM_SETCHECK…ラジオorチェックボックスのチェック状態を変更する
SendMessageの
0…(&H00)BST_UNCHECKED 'チェックされてない
1…(&H01)BST_CHECKED 'チェックされてる
2…(&H02)BST_INDETERMINATE 'グレー状態(選択できない状態ですね)
※BST_INDETERMINATEは、3状態可能な場合のみ
第4引数:未使用
返り値 :0
ってのをやってみますか。
これが16進をクリックすると
こうなるはず。
じゃ、さっそく上の画像の状態で16 進をクリックするコードを実行してみます。
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 BM_SETCHECK = &HF1 Public Const BST_CHECKED = &H1 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer hwnd1 = FindWindow("SciCalc", "電卓") hwnd2 = FindWindowEx(hwnd1, 0, "Button", "16 進") SendMessage(hwnd2, BM_SETCHECK, BST_CHECKED, 0) End Sub End Module
結果は、こうなりました。
16進のとこにチェックがついたのはいいけど...
10進のとこにもついてるままじゃんか 汗
ラジオボタンにあるまじき状態になってますね 汗
表示している値をみても10進数の時のままですね。。
もしかして…
GETCHECKで値を調べてループさせていき、チェックがあればチェックを
はずしチェックを付けたいとこに来たらチェックをつけて、さらに
クリックでもすればいいの??
って、思ったけど…実際のところラジオボタンをクリックしてるんだから
クリックすればいいんじゃ??
ってことで、やってみると…
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 BM_CLICK = &HF5 Sub Main() Dim hwnd1 As Integer, hwnd2 As Integer hwnd1 = FindWindow("SciCalc", "電卓") hwnd2 = FindWindowEx(hwnd1, 0, "Button", "16 進") SendMessage(hwnd2, BM_CLICK, 0, 0) End Sub End Module
これなら、うまくいきました。
チェックボックスの状態を知る(BM_GETCHECK)
基本的にラジオボタンと同じなんで項目を分ける必要はないんだけどさ・・・
ひとつよくわからないことがあって、チェックボックスの状態がとれるものと
取れないものがあるのね。。
ただそれがいいたかっただけなんだけど。。
思ったら状態取得できなかったんですよねぇ。。
これってなんでなんだろ。。
というわけで、もはや代わり映えのないコードだけども
一応、のっけてみる。電卓の Inv or Hypチェックボックスに
チェックがあれば、はずすコード。
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 BM_GETCHECK = &HF0 Public Const BM_CLICK = &HF5 Public Const BST_CHECKED = &H1 Sub Main() Dim hwnd As Integer, hwnd2(1) As Integer hwnd = FindWindow("SciCalc", "電卓") hwnd2(0) = FindWindowEx(hwnd, 0, "Button", "Inv") hwnd2(1) = FindWindowEx(hwnd, 0, "Button", "Hyp") For i As Integer = 0 To hwnd2.Length - 1 If SendMessage(hwnd2(i), BM_GETCHECK, 0, 0) = BST_CHECKED Then _ SendMessage(hwnd2(i), BM_CLICK, 0, 0) Next End Sub End Module
SendMessageStr関数について・・・というよりAPI宣言について
Declare構文を使う場合とDllImport属性を使う方法の2通りがあります。
ここではDeclare構文を使っているのでDeclare構文の方だけ触れます。
Declare構文の定義は下記のようになってます。
[スコープ] Declare [文字コード] Function名 API関数名 _
Lib "DLLファイル名" [Alias "エイリアス名"] (引数) _
・スコープ:スコープの修飾子が先頭に着きます。ただし省略可能で省略した場合「Private」になります
・文字コード:APIに文字列を渡す時のコードを指定できます。
省略した場合Autoが指定されます。
・API関数名 と Alias "エイリアス名":定義を知るまでこの2つが何者なのかよくわからなかったです。。
API関数は、コードを書く人間が好きに名前をつけてよいところです。
hogehogeでもよいわけです。ただし、それだとAPIのどの関数を参照していいかわからないので
Alias "エイリアス名"でAPIに記載されている名称の関数名をここに指定します。
Alias "エイリアス名"が省略可能になっているのは、APIに記載されている名称を
API関数名に書くと重複となるのでAlias "エイリアス名"は、省略することができます。
なので、SendMessageStr関数とか書いているけど、これはAPIの中でこういう名称の
関数が用意されているのでなくて、SendMessageAという関数の別名として規定した
だけにすぎません。なので、ネットでSendMessageStrって何よ??って検索しても
あまりヒットしないはずです 笑
じゃ、APIに記載されている関数についてですが、最後にAとかWとかついて
いるのに気づくと思いますが(ほとんどが互換性を考慮してAかな?)
これは、ANSI用の場合関数の最後にAがつき、Unicode用の場合関数の最後に
Wがつきます。9X系では、ANSI用のみですが、NT系では、ANSI用とUnicode用の
関数が使えることになっているそうです。
関数名にAもWもついていない場合はカーネルに合わせてANSIかUnicode
か判断して関数を呼ぶようです。その場合9X系は、ANSI/NT系は、Unicodeになるようです。
・引数 と 戻り値の型は、API関数で必要な引数と必要に応じて戻り値の型を用意するってことですね。
結局、
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 System.Text.StringBuilder) As Integer
って、SendMessageAという関数に対し渡したい引数(lParam)が違うんで
SendMessageという名前の関数とSendMessageStrという名前の関数を
便宜上作ったというだけです。はい。
Declare Function tarou 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 jirou Lib "user32.dll" Alias "SendMessageA" _ (ByVal hWnd As Integer, ByVal MSG As Integer, _ ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer
でも、お好きな名前をどうぞ 笑
- 26286 https://www.google.co.jp/
- 4542 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
- 3518 https://www.google.com/
- 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
- 2852 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
- 2679 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
- 2369 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
- 2226 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