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で質問しましょう!
似たような質問が見つかりました
- Windows 10 バッチファイルでのエクスプローラー終了 1 2022/05/30 14:32
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- その他(プログラミング・Web制作) Windows上のプログラム。「予め決められた時刻に自分で起動して処理して自分で終了する」って可能? 3 2023/01/04 14:29
- Excel(エクセル) excelvbaでスライドショーを作りたい 2 2023/04/20 14:32
- Outlook(アウトルック) outlook メモリ不足 1 2022/05/31 10:16
- オンラインゲーム 15年位前?のロボットをプログラムしてアリーナで戦うゲーム 1 2022/06/08 22:32
- Windows 10 パソコン スリープで使っていると電源が点滅していますが 機械 マザーボードに悪いですか? 4 2023/03/13 18:09
- Java Java 年数計算 3 2023/01/28 10:52
- C言語・C++・C# C#の問題です。 文字列型の配列 s[100] にキーボードから入力された100文字以内の文字列(単 2 2022/06/22 15:18
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
VBAでこんなことできますか?
PowerPoint(パワーポイント)
-
vbaから他のアプリを終了
Visual Basic(VBA)
-
外部プロセスを終了したい!!
Visual Basic(VBA)
-
-
4
他のアプリケーションの終了処理
Visual Basic(VBA)
-
5
プロセスIDの取得方法について
Visual Basic(VBA)
-
6
ウィンドウのタイトルからプロセス取得
Visual Basic(VBA)
-
7
ExcelVBAにてアプリをタスクマネージャーから強制終了させたいのですが
Visual Basic(VBA)
-
8
VBプログラムの終了
Visual Basic(VBA)
-
9
VBで実行中のEXEファイルの情報を取得したい
Visual Basic(VBA)
-
10
VBAで既に開いている別アプリケーションのオブジェクトを得る
Visual Basic(VBA)
-
11
ExcelVBAでPDFを閉じるソース
その他(Microsoft Office)
-
12
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
13
バックグラウンドのプロセスのエクセルを閉じる方法
Visual Basic(VBA)
-
14
VBAでOutlookを終了させたい ExcelVBAで既に起動されているOutlookを終了させる
Visual Basic(VBA)
-
15
起動中のアプリ、ソフトの取得
Visual Basic(VBA)
-
16
ExcelVBAでスペースキー操作したい
Excel(エクセル)
-
17
メッセージボックスを前面に表示させるには?
Visual Basic(VBA)
-
18
起動しているプロセスの確認
Visual Basic(VBA)
-
19
どこにもフォーカスを当てたくない
Access(アクセス)
-
20
VBAにてメッセージボックスを最前面に表示させる
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
Process.Startの戻り値を後で取得
-
sleep関数の精度について
-
VB6.0 SHELLで起動...
-
タスクマネージャーのプロセス...
-
共有メモリの同時アクセスにつ...
-
プロセスのアタッチ・デタッチ...
-
C#でのbatファイル実行結果取得
-
C++のプログラムをバックグラウ...
-
ShellExecuteが起動したプロセ...
-
プロセスIDからウィンドウハ...
-
バッチファイルでPINGログ取得
-
プロセスIDの取得方法について
-
別のプロセスの関数を呼び出す...
-
Windowsのユーザログイン/ログ...
-
怪しいプロセス教えてください。
-
ウィンドウのタイトルからプロ...
-
win10でpythonのプロセス名を変...
-
プロセスが実行中かどうか調べ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
なぜ女性は男性が忘れたことを...
-
タスクマネージャーのプロセス...
-
プロセスのアタッチ・デタッチ...
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
C#でのbatファイル実行結果取得
-
プロセスIDからウィンドウハ...
-
c言語でプロセスIDを調べたい
-
Linuxでのスレッド間メッセージ...
-
プロセスIDの取得方法について
-
ADOでアクセスのレコードに...
-
怪しいプロセス教えてください。
-
vb.netでEXCEL起動がうまくでき...
-
別のプロセスの関数を呼び出す...
-
C++のプログラムをバックグラウ...
-
Visual C++からpingを実行して...
-
VBS(WSH)で開いたIEのウィンド...
-
IISがフリーズ
おすすめ情報