過去ログにも、アプリの起動(Shell関数)についてはあったのですが、
起動させたいのでは無く、起動しているかを確認したいだけなのですが。
どうしたら、良いのでしょうか?
VB.NETを使用しています。
If 'calc.exe'が動いている Then
MsgBox "電卓動いてます。"
Else
MsgBox "電卓動いてない。"
End If
下記を試して見て下さい。
Option Explicit
Private Declare Function FindWindowEx Lib "user32" Alias _
"FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Sub Command1_Click()
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox "電卓動いてます。"
Else
MsgBox "電卓動いてない。"
End If
End Sub
.NET だったのでしたよね!
.NET 用に変換して下さい。
お返事ありがとうございます。
やってみたのですが、VB.NETでは上手く行きませんでした・・・。
Option Explicit On
Public Class Form1
Inherits System.Windows.Forms.Form
Private Declare Function FindWindowEx Lib "user32" Alias _
"FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'---------メッセージボックスで見ると----------------
MsgBox(FindWindowEx(0, 0, vbNullString, "電卓"))
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Else
MsgBox("電卓動いてない。")
End If
End Sub
End Class
FindWindowEx(〜)をメッセージボックスで表示すると、
電卓が起動してる・してないに関わらず、9222812402616238386の
数字がダイアログが表示されます。
あ、書き忘れましたが、電卓が起動していても・していなくても
どちらも"電卓動いてます。"でした。
.NETをもっていないので未確認ですが
APIの宣言が
Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" (ByVal hWnd1 As Integer, _
ByVal hWnd2 As Integer, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Integer
で ボタンのクリックイベントの文が
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Else
MsgBox("電卓動いてない。")
End If
End Sub
で試して見て下さい。
おなじく.netのことは知りませんけど——。
If FindWindowEx(0, 0, vbNullString, "電卓") Then という文の中には、
暗黙の変換(整数値から真偽値への変換)が行われてますね。
このような記述は、記述が簡単だし、VBの長所ともいえなくもないですが、
予想外のエラーの原因にもなります。
hwnd = FindWindowEx(0, 0, vbNullString, "電卓")
if hwnd = 0 then ...
という記述のほうがいいでしょう。
(hwndは整数型、.netにHWND型があるならそれがいいでしょう)
ところで、親ウィンドウを探すだけなんだから、
FindWindowExよりFindWindowのほうがいいのでは?
(引数が少ないし、親ウィンドウを探すだけなら、そのほうがらくですよ)
ありがとうございます。正常に動作しました!
APIの宣言は使ったことが無く、LongとIntegerが違うだけでここまで
動作が違うとは!
しかし、
MsgBox(FindWindowEx(0, 0, vbNullString, "電卓"))で表示させると
電卓が起動していても・いなくても、やっぱり今度は'0'でした。
つまり、
hwnd = FindWindowEx(0, 0, vbNullString, "電卓")
if hwnd = 0 then ...
と、するとどっちも'0'の為、起動判断できませんでした。
FindWindowの方が良いのかも知れませんが、API宣言も知らないので・・・。
追加ですが、今は、
If FindWindowEx(0, 0, vbNullString, "電卓") Then という形で
正常に動作してます。
どうしてなんだろ?
すいません。動いたと思ったのですが、
動作してませんでした・・・。
見間違えたのかな?
> FindWindowの方が良いのかも知れませんが、API宣言も知らないので・・・。
この情報の宝庫であるインターネット、"検索"ということが出来るじゃありませんか^^;
InternetExplorerでは、検索ボタンを押せば、検索用タブがでてきます。Operaなら検索バーバーに何か書いてEnterです。
"FindWindow VB" とでもやれば、すぐに見つかります。
(ダブルクオーテーションを入れると、検索結果が変わってしまうことがあるので注意)
そういえば、vbNullStringって、ヌル(Null)文字を示しましたっけ?
VBは触らなくなって久しいので、よく覚えていませんが、
たしかVBにはNULLと名のつく定数は3種類あって、
vbNull(何かの関数の定数だったと思います。ここでは使えません)
vbNullString(長さ0の文字列)
vbNullChar(ヌル文字)
だったと思います。あってますか?(ヘルプで確認してください)
上のAPI関数の"vbNullString"と指定しているところには、"ウィンドウクラス"の名前を指定するんですけど、
指定なしの場合は、そこにヌル文字を指定することになってます。
つまりわたしの記憶が正しければ、そこにはvbNullCharを指定しないとダメということになります。
これでどうでしょうか?
ところで、"API宣言がわからない"とのことですが、
せめてAPIビューアの一つは持っておいたほうがいいですよ。
(たまにVBの宣言例が、どこにもないAPIもありますし)
わたしの"おんぷむらのうら"、"旧学校"で紹介してますから、
よければちょっと見てみてください。
あ!そっか!
ヘルプを見まくっていたのですが、ネットで調べるのか!
すみませんでした。早速、探します。
追記:vbNullCharでも両方'0'でした。
「たかみちえ」さんのHPも拝見させて頂きました。今の私にとても参考に
なるHPですが少しレベルが高いので、今後ゆっくりと拝見させて頂きます。
その他、いろいろ探してみたところ、同じ質問をしている人が見つかったのですが・・・。
「APIの宣言で、VB6のLong は VB.NETのInteger」だけで動作したらしく、
私も直してはいるのですが、動作しませんでした。
FindWindowのAPI宣言が、
Declare Function FindWindow Lib "user32.dll" Alias _
"FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Integer
そして、使用方法が、
hWnd = FindWindow("電卓", vbNullString)
MsgBox(hWnd)
まだ、できません。電卓の起動に関係なくどっちも'0'・・・。
手強いです・・・。今までぶっ続けだったので少し休憩しよっと。
VB.NETの場合
Private Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Declare Function FindWindowEx Lib "user32" Alias _
"FindWindowExA" (ByVal hWnd1 As Integer, ByVal _
hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
Private Sub Command1_Click(ByVal eventSender As System.Object, _
ByVal eventArgs As System.EventArgs) Handles Command1.Click
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Else
MsgBox("電卓動いてない。")
End If
End Sub
Private Sub Command2_Click(ByVal eventSender As System.Object, _
ByVal eventArgs As System.EventArgs) Handles Command2.Click
If FindWindow(vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Else
MsgBox("電卓動いてない。")
End If
End Sub
とやればどちらでもいけます。
追伸
>手強いです
のではなく
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (
ByVal lpClassName As String
ByVal lpWindowName As String
) As Long
のlpClassNameとlpWindowNameがどこかで入れ替わりましたよ(^_^;
前回のコードでも .NET で動作するそうです。(確認してもらいました)
(windowsXP VB.NET2003)
尚、vbNullCharにはしないで下さいね。vbNullCharでは動作しません。
電卓はアクセサリーの電卓ですよね。
取得のコードをLoadイベントに書いておられるなら電卓を完全に起動
してから実行して下さい。
起動しているのに 0 が返ってくるならAPIの宣言等見直して下さい。
下記は、クラス名でハンドルを取得しています。
どちらも電卓の場合は問題ないはずですので記入されたコードを
今一度確認して見てください。(念の為下記コードも試して下さい)
因みにFindWindowを使ってもFindWindowExを使っても同じです。
If FindWindowEx(0, 0, "SciCalc", vbNullString) Then
MsgBox("電卓動いてます。")
Else
MsgBox("電卓動いてない。")
End If
電卓は
ClassName------"SciCalc"
WindowName-----"電卓"
従って
◎ MsgBox(FindWindowEx(0, 0, vbNullString, "電卓"))
× MsgBox(FindWindowEx(0, 0, "電卓", vbNullString))
◎ MsgBox(FindWindowEx(0, 0, "SciCalc", vbNullString))
× MsgBox(FindWindowEx(0, 0, vbNullString, "SciCalc"))
◎ MsgBox(FindWindowEx(0, 0, "SciCalc", "電卓"))
ということですか。
なるほど〜!!言われて思い当たる節がありました!
おそらく、見間違えたと言ったのは、フォームのLoad時に
チェックしていた為でした。
お手間とらせてどうもすみませんでした。
無事に動作しました!!
しかし、プログラムとは面白いものですね〜。
つくづく皆さんのレベルの高さには感心致します。
ツイート | ![]() |