If App.PrevInstance = True '自己の2重起動判定はできるのですが
指定ファイルを関連付けられたアプリケーションで起動した
アプリケーションの判定はどのようにすればいいのでしょうか?
ShellExecute(0&, "open", strPath, vbNullString, "", SW_SHOW)
strPathは、パス指定で起動するプログラムです。(ExcelやVBなど)
関連付けられたアプリケーションは
FindExecutable
で取得できるみたいです。
あとはプロセスを列挙して、そのアプリケーションが実行されているか
どうかを判定してやるということで良いでしょうか?
具体的に例を挙げてもらえますか?すみません。
'標準モジュール
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, lPalam As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
'標準モジュール
Public Function Rekkyo(ByVal Handle As Long) As Boolean
Dim Ret As Long
Dim Leng As Long
'バッファ確保
Name = String(255, Chr(0))
Leng = Len(Name)
'名前を取得する
Ret = GetWindowText(Handle, Name, Leng)
'起動プログラム判定
If Ret <> 0 Then
If Name = MYPG Then
ExPGname = Name
End If
End If
'次にいく
Rekkyo = True
End Function
'ここからはフォームの処理
Private Sub Command1_Click()
Dim Ret As Long
Ret = EnumWindows(AddressOf Rekkyo, 0)
End Sub
で
Ret = EnumWindows(AddressOf Rekkyo, 0)でDLLが正しく呼び出せません
のエラーになってしまうのですが?
なんか回答内容とあなたの作ろうとしているものが微妙にちがうきがします。
もう一度、やりたいことを詳しく書いてもらえますか?
ちなみに最初に回答したのは
あるファイルに関連付けられているアプリケーションが起動しているかどうかを判定する
というものに対して答えたつもりです。
あなたのプログラムを見ていると全てのウィンドウに指定したウィンドウテキスト
をもつウィンドウがあるかを判定したいように見えますが。
ShellExecute(0&, "open", strPath, vbNullString, "", SW_SHOW)
で起動したプログラムの2重起動回避をしたいのです。
strPathは、パス指定で起動するプログラムです。(ExcelやVBなど)
あなたのいう2重起動の定義の確認のため再度質問です。
例えばメモ帳(Notepad.exe)の場合
A.txtを開いてメモ帳が起動しているときに、もう一つのメモ帳のプロセス
を起動してB.txtを開こうとするのを2重起動と呼んでいるのでしょうか?
(開くファイルが異なっても同じ実行ファイルのプロセスを起動することが2重起動か?)
それともB.txtを開くために、もう一つメモ帳のプロセスを実行するのは
2重起動ではなく、A.txtをメモ帳で開くときのみ2重起動である
と定義するのでしょうか?
(開いているファイルを同じ実行ファイルで2回開かないことを2重起動
と呼んでいるのか?)
開いているファイル、または実行ファイルで2回開かないように
(2重起動)にしたいのです。
Ret = EnumWindows(AddressOf Rekkyo, 0)でDLLが正しく呼び出せません
のエラーになってしまうのですが?
ここだけうまくいけば出来そうなのですが?
>開いているファイル、または実行ファイルで2回開かないように
>(2重起動)にしたいのです。
つまり、例えばA.csvというファイルをメモ帳で開いているとき
A.csvをエクセルで開こうとしても2重起動と見るわけですか?
EnumWindowsのAPI宣言の2番目の引数が、ByRefなので、0を指定すると不味いということです。
> Ret = EnumWindows(AddressOf Rekkyo, 0)
を
Ret = EnumWindows(AddressOf Rekkyo, ByVal 0&)
としてみてはどうでしょうか?
(概念的なことは全然考えていません。)
それと、GetWindowTextで取得した文字列 Name はChr$(0)(vbNullChar)がくっついていますので、
Name = Left$(Name, InStr(Name, vbNullChar) - 1)
のようにとる作業が必要です。(APIを使う上での基本中の基本)
あとEnumWindowProcも(この場合はRekkyoプロシジャー)
Public Function Rekkyo(ByVal Handle As Long,ByVal lParam As Long) As Long
とした方がいいかもしれません。
(同じく概念的なことは考えてません)
EnumWindowProcの引数は決まっているので、勝手に削ってはダメでは...。
Win98あたりでは「たまたま」動くかもしれませんが、
Win2000/XPではアウトみたいです。
あと、VB6のBoolean型(16bit)とWin32APIのBOOL型(32bit)は等価でないので、
As Booleanじゃなくて、As Long で宣言しておくべきでしょう。
まあ、コピペ元と思われる、
http://madia.world.coocan.jp/vb/API/EnumWindows.htm
がそうなっていますので、マスターにご一報を入れておくべき ということで。
Ret = EnumWindows(AddressOf Rekkyo, 0)
でDLLが正しく呼び出せません
のエラーで駄目です。
Ret = EnumWindows(AddressOf Rekkyo, ByVal 0&)
にしても駄目です。参照設定等あるのですか?
人のレスをよく読みましょうよ
Public Function Rekkyo(ByVal Handle As Long,ByVal lParam As Long) As Long
にしようって書いているのが見えなかったんでしょうか。
再度書いておきますね。
QAさん、ありがとうございました。解決しました。ワーイ!!
ツイート | ![]() |