プロが教えるわが家の防犯対策術!

環境: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を使用して終了させるにはどのようにしたら良いのでしょうか?

A 回答 (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型にしていると、
#ほぼ確実に誤動作を起こすでしょうね。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
無事プログラムを完成することができました。
原因はコードを書く際の雑さで、APIをあまり使用したことがない為
同じAPIに対しての宣言を複数していたためでした;
適切な回答本当にありがとうございました。

お礼日時:2006/12/23 17:42

私も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
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
今回のプログラム作成でコードを記述する際の記述構成の大切さと
VB.NETとVB6の大きな違いを改めて感じることができました。
本当にありがとうございました。

お礼日時:2006/12/23 17:46

> この時点で電卓が開いているかどうかの判定はうまくいっています。


との事ですが、その確認に使用している

> 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の問題かですね・・。

補足日時:2006/12/16 12:28
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!