
No.5ベストアンサー
- 回答日時:
(今会社なのですが、、、)サンプルありました。
奥深く眠ってました。Microsoftの終了方法と、定数が違いますが、こちらでも終了ができます。
コメントを見たら、処理の流れがわかると思いますが、処理の流れを記します。
Shellで電卓を起動します。Shell関数は起動したアプリのプロセスIDを返します。
次に Call EnumWindows(AddressOf EnumWinProc, 0&)を実行します。
これはたった一文で、FOR文/DO~LOOP文を使用してませんが、EnumWinProc関数内を何度も実行します。実行回数はWindowsに存在するハンドルの数だけ実行されます。
そしてその関数内で電卓のプロセスと同じハンドルを探し、電卓に終了の命令を送ってます。
EnumWinProc内を詳しく説明します。
GetParentが'0'ゼロの時、未処理としています。
これは何を意味するかというと、フォームだけでなく、フォームの中に存在するボタン、リストボックス、ラベル、それぞれのコントロールにハンドルが存在します。
しかしフォームとその中のコントロールには親子の関係があります。
GetParent(子のハンドル)の時 → '0以外'の数値を返します。基本的にフォーム(親)のハンドルのを返します。
GetParent(フォームのハンドル)の時 → '0'を返します。親が存在しないためです。
電卓にも多くのボタンが存在してます。そのボタンのハンドルはチェックする必要がないのでGoto文で未処理にさせています。必要なのは電卓本体が必要で、GetParentで0を返すものが、チェックの候補となるわけです。
あとは電卓のプロセスと比較し、一致するハンドルを取得するだけです。
Option Explicit
' ウィンドウのプロセスIDとスレッドIDを取得する関数の宣言
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
'親ハンドルを取得する関数の宣言
Private Declare Function GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
'ウィンドウを列挙する関数の宣言
Public Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
'ウィンドウにメッセージ定数を送る関数の宣言
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Public Const WM_CLOSE = &H10
'見つかったウィンドウハンドル
Private FindWinWnd As Long
'探すべきプロセス
Private FindPrs As Long
Sub Main()
Dim lngSts As Long
'初期化を行う
FindWinWnd = 0
FindPrs = 0
'とりあえず電卓を起動と同時に、電卓のプロセスを得る
FindPrs = Shell("Calc.exe")
'プロセス=0のとき起動失敗
If FindPrs = 0 Then
MsgBox "電卓の起動失敗"
GoTo PGMEND
End If
'Windowsに存在する全部のハンドルから、電卓のプロセスの一緒のハンドルを探す
Call EnumWindows(AddressOf EnumWinProc, 0&)
'電卓を終了します。
If (FindWinWnd <> 0&) Then
MsgBox "電卓が見つかりませた。終了します。"
Call SendMessage(FindWinWnd, WM_CLOSE, 0&, 0&)
Else
MsgBox "電卓が見つかりませんでした。"
End If
PGMEND:
End Sub
'Windowsの全ハンドルを得ることができる関数
'内部処理は、
'(1)指定のプロセスを探す
'(2)見つかったプロセスのハンドルを記憶
Public Function EnumWinProc(ByVal hwnd As Long, lParam As Long) As Boolean
Dim lngTrd As Long 'スレッド
Dim lngPrs As Long 'プロセス
'Trueの間は、Windowsに存在するハンドルを最後まで取得しようとする
EnumWinProc = True
'子ウィンドウは未処理
If Not (GetParent(ByVal hwnd) = 0) Then GoTo PGMEND
'スレッドとプロセスを取得する
lngTrd = GetWindowThreadProcessId(hwnd, lngPrs)
'同じプロセスだとしたら
If lngPrs = FindPrs Then
'取得してきたハンドルを記憶
FindWinWnd = hwnd
'これ以上のハンドルは取得しないでもいいので、Falseをセット
EnumWinProc = False
End If
PGMEND:
End Function
No.4
- 回答日時:
あっSendMessageの回答がでましたね。
で注意して欲しいのは、FindWindowを使う点です。
これはWindowのCaption、もしくはクラス名でWindowを探す点です。
クラス名は[CTRL]+[ALT]+[DEL]で起動中のアプリのクラス名の一覧が出てきます。
あれから参考にしてみてください。
電卓は複数起動が可能です。
Microsoftのサンプルでは、すでに電卓を起動してあったとき、先に起動してあったほうを終了させるおそれがあります。
よってFindWindowだけでWindowを探すには注意が必要です。
(それでもSendkeysよりは、かなりいいと思います。)
もし自分で作成したソフトをShellで起動するなら、このままでも大丈夫かもしれませんが、そうでなければShellで起動した時のプロセスIDを取得して、起動中のアプリ達のプロセスIDと比較し、自分の起動したEXEかをチェックする必要があるのです。
今までのサンプルで大丈夫ならいいのですが、帰ってから締め切ってなかったら、またあとで書き込みます。
ちなみに書き込もうとしてるサンプルはVB6限定です。
No.2
- 回答日時:
Sendkeys は一番手っ取り早いです。
確かにHELPにも出ています。
しかし、どのVBのメーリングリストもSendkeysは使用しない方向でやっております。
それはWindowsにかかっている負荷の状況により、Sendkeysの処理が必ずしも一致するわけではないからです。
以前にサンプルを作ったのですが、どうやら自宅においたままになっているようなので、またあとで書き込みます。
キーワードはSendMessageです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
VBAでこんなことできますか?
PowerPoint(パワーポイント)
-
vbaから他のアプリを終了
Visual Basic(VBA)
-
外部プロセスを終了したい!!
Visual Basic(VBA)
-
-
4
プロセスIDの取得方法について
Visual Basic(VBA)
-
5
他のアプリケーションの終了処理
Visual Basic(VBA)
-
6
ExcelVBAにてアプリをタスクマネージャーから強制終了させたいのですが
Visual Basic(VBA)
-
7
VBアプリケーションで終了コードを指定する方法
Visual Basic(VBA)
-
8
VBAでOutlookを終了させたい ExcelVBAで既に起動されているOutlookを終了させる
Visual Basic(VBA)
-
9
他アプリケーションの終了
Visual Basic(VBA)
-
10
ExcelのマクロでAccessのmdbを起動したい
Excel(エクセル)
-
11
Access サブフォームでの選択行の取得
その他(データベース)
-
12
VB6から他のプログラムを強制終了したい
Visual Basic(VBA)
-
13
VBで実行中のEXEファイルの情報を取得したい
Visual Basic(VBA)
-
14
VBプログラムから「管理者として実行」したい
Visual Basic(VBA)
-
15
サブフォームに対してGoToRecordするには?
その他(Microsoft Office)
-
16
Access VBAから使用したExcelプロセスを閉じる方法について
Visual Basic(VBA)
-
17
CreateObjectで作成したExcelのプロセスを終了させたい。
Visual Basic(VBA)
-
18
ウィンドウを終了させたい・・・
Visual Basic(VBA)
-
19
VBAで既に開いている別アプリケーションのオブジェクトを得る
Visual Basic(VBA)
-
20
VBプログラムの終了
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プロセスIDの取得方法について
-
アプリケーションが終了するま...
-
vb.netでEXCEL起動がうまくでき...
-
AppActivate関数について
-
C++のプログラムをバックグラウ...
-
バックグラウンドのプロセスの...
-
IISがフリーズ
-
他のアプリケーションの起動と...
-
C言語 特定のプロセスの終了を...
-
OSPFでプロセスを分ける意義に...
-
Process.Startの戻り値を後で取得
-
別のプロセスの関数を呼び出す...
-
タスクマネージャーのプロセス...
-
Linuxのchdir(カレントディレク...
-
プロセスIDの再利用
-
windowsのプロセスIDやスレッド...
-
非表示になったエクセルは?
-
Linuxでのスレッド間メッセージ...
-
forkについて
-
Windowsのユーザログイン/ログ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
タスクマネージャーのプロセス...
-
バックグラウンドのプロセスの...
-
プロセスのアタッチ・デタッチ...
-
OSPFでプロセスを分ける意義に...
-
ADOでアクセスのレコードに...
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
vb.netでEXCEL起動がうまくでき...
-
C#でのbatファイル実行結果取得
-
プロセスIDの取得方法について
-
Linuxでのスレッド間メッセージ...
-
Visual C++からpingを実行して...
-
SendMessageが失敗するときがある
-
IISがフリーズ
-
スティーブ・ジョブズはプログ...
-
c言語でプロセスIDを調べたい
-
特定ユーザーのプロセス情報を...
-
怪しいプロセス教えてください。
-
セマフォとmutexの違いは?
-
Windowsでのfork方法
おすすめ情報