- ベストアンサー
VB.netでSendMessageを使用して電卓を閉じたい
環境:Win XP,VB.net 2003 sendmessageを使用して電卓を閉じるプログラムを作成しているのですが、どうもあと少しでうまくいかないので質問させていただきます。 Dim hfwnd As Long hfwnd = FindWindowEx(0, 0, "SciCalc", "電卓") If FindWindowEx(0, 0, vbNullString, "電卓") Then MsgBox("電卓動いてます。") Call SendMessage(hfwnd, WM_CLOSE, 0&, 0&) end if この時点で電卓が開いているかどうかの判定はうまくいっています。 ですが、sendmessageのところでうまくいっておらず、hfwndに取得したウインドハンドルが代入されていない?と思いGetWindowTextでタイトル取得してみたところ空白でした。電卓をSendMessageを使用して終了させるにはどのようにしたら良いのでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。 貴方のおっしゃりたい事は分かりますが・・・ でしたら、ちゃんと、同じにしたコードを提示してください。 それから、「hfwnd」の値は確認されましたか?ちゃんと「有効な値」になってますか? > おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているので このIf文で分かるのは、『「FindWindowEx」の結果が「True」と判断されるものである。』と言うだけであって、 『ハンドルは正常』かどうかは分からないのでは? #全然関係ないWindowのハンドルを持ってきている可能性だってあります。 #いや、実際「GetWindowTextでタイトル取得してみたところ空白でした。」って事は、全然関係ないハンドルって事でしょうね。 「FindWindowEx」や「SendMessage」の宣言はどうしてますか? また、 > Dim hfwnd As Long となってますが、WindowのハンドルってIntegerの範囲なのでは・・・ #VB6までなら、Long型で良かったですが、 #VB.NETでは、型の有効範囲が変わってますのでLongだと誤動作する可能性が・・・ #特に「FindWindowEx」や「SendMessage」の宣言でLong型にしていると、 #ほぼ確実に誤動作を起こすでしょうね。
その他の回答 (2)
- 1050 円(@1050YEN)
- ベストアンサー率69% (477/687)
私もdsuekichiさんと同じことを感じました。 longや使用しているAPIを見ると、VB6でやっているようなイメージですねー 強制終了でよいのであれば、APIを使用しないでも、フレームだけでできちゃいます。 でもやはり、通常終了がよいと思うので、APIを利用したサンプルをあげておきます。 Imports System.Runtime.InteropServices Module Module1 Public Const WM_CLOSE As Integer = &H10 <DllImport("user32")> _ Private Function SendMessage( _ ByVal hwnd As IntPtr, _ ByVal wMsg As Integer, _ ByVal wParam As Integer, _ ByVal lParam As Integer _ ) As Integer End Function Sub Main() For Each l_proc As Process In Process.GetProcessesByName("calc") If l_proc.MainWindowTitle.Equals("電卓") Then '通常終了 Call SendMessage(l_proc.MainWindowHandle, WM_CLOSE, 0, 0) '↓強制終了でもよないらこれ 'l_proc.Kill() End If Next End Sub End Module
お礼
ご回答ありがとうございます。 今回のプログラム作成でコードを記述する際の記述構成の大切さと VB.NETとVB6の大きな違いを改めて感じることができました。 本当にありがとうございました。
- dsuekichi
- ベストアンサー率64% (171/265)
> この時点で電卓が開いているかどうかの判定はうまくいっています。 との事ですが、その確認に使用している > If FindWindowEx(0, 0, vbNullString, "電卓") Then の第三引数には「vbNullString」を使用してるのに、 実際にクローズを行う、 > Call SendMessage(hfwnd, WM_CLOSE, 0&, 0&) で対称にしている「hfwnd」を参照する、 > hfwnd = FindWindowEx(0, 0, "SciCalc", "電卓") の第三引数が「"SciCalc"」なのは、何故ですか? 同じ条件にしないと意味が無いのではありませんか?
補足
参考意見ありがとうございます。 クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。 おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているのでhfwndの変数に代入する時点で問題が起きているのではないかと思われます。それかSendMessageの問題かですね・・。
お礼
ご回答ありがとうございました。 無事プログラムを完成することができました。 原因はコードを書く際の雑さで、APIをあまり使用したことがない為 同じAPIに対しての宣言を複数していたためでした; 適切な回答本当にありがとうございました。