回答編集履歴

1

追記

2016/06/08 03:18

投稿

jawa
jawa

スコア3013

test CHANGED
@@ -11,3 +11,239 @@
11
11
  ```
12
12
 
13
13
  を行い、新たなメモ帳を起動し、そのウィンドウハンドルに対してクロ-ズしているからではないでしょうか?
14
+
15
+
16
+
17
+ 追記
18
+
19
+ ---
20
+
21
+ TerminateProcessで完結したものと思い込んでいましたが、まだ未解決のようでしたので遅くなってしまいましたが追記いたします。
22
+
23
+
24
+
25
+ ---
26
+
27
+
28
+
29
+ まず、CloseHandleについてですが、ハンドルを解放する関数とされているので私もこれで終了できるつもりでいましたが、実際できないようです。
30
+
31
+ ここらへん知識乏しくて申し訳ないです。※詳しい方いましたら補足お願いしますm(__)m
32
+
33
+
34
+
35
+ ---
36
+
37
+
38
+
39
+ 次にOpenProcessについてですが、この戻り値はプロセスのハンドルでありウィンドウハンドルではありません。
40
+
41
+ このため、取得結果に対してSendMessageしても目的のウィンドウには届きません。
42
+
43
+ ※運が悪ければ意図しない他のアプリを終了してしまうかもしれません。
44
+
45
+
46
+
47
+ ---
48
+
49
+
50
+
51
+ 最後にTerminateProcessについてですが、これはプロセスIDを使ってプロセスを終了することができます。
52
+
53
+ しかしタスクマネージャから強制終了(KILL)させているような終了方法なので、あまり好ましい方法ではありません。
54
+
55
+
56
+
57
+
58
+
59
+ ---
60
+
61
+
62
+
63
+ TerminateProcess以外の方法で終了させる方法を紹介します。
64
+
65
+
66
+
67
+ 方法1:プロセスIDでアプリをアクティブ化して、SendKeyで終了操作を送信する。
68
+
69
+ ```
70
+
71
+ Sub Sample1()
72
+
73
+ 'メモ帳をShell起動してプロセスIDを取得
74
+
75
+ lngPid = Shell("notepad.exe", vbNormalFocus)
76
+
77
+ Call Shell("calc.exe", vbNormalFocus) '←ダミーで別アプリも起動
78
+
79
+
80
+
81
+ 'プロセスIDでアプリをアクティブ化
82
+
83
+ Call AppActivate(lngPid)
84
+
85
+
86
+
87
+ 'メモ帳の終了操作(Alt→F→X)をSend
88
+
89
+ Application.SendKeys "%FX"
90
+
91
+ End Sub
92
+
93
+ ```
94
+
95
+ 対象アプリを一度アクティブ化するので、画面最前面に表示されることになります。
96
+
97
+
98
+
99
+
100
+
101
+ 方法2:プロセスIDからウィンドウハンドルを取得する
102
+
103
+ ```
104
+
105
+ Option Explicit
106
+
107
+
108
+
109
+ 'WindowsAPI定義
110
+
111
+ Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
112
+
113
+ Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As Long) As Long
114
+
115
+ Public Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, ByRef ProcessId As Long) As Long
116
+
117
+ Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
118
+
119
+
120
+
121
+ '定数定義
122
+
123
+ Public Const WM_CLOSE = &H10
124
+
125
+
126
+
127
+ '共通変数
128
+
129
+ Public lngPid As Long
130
+
131
+ Public lngWid As Long
132
+
133
+
134
+
135
+ Sub Sample2()
136
+
137
+ Dim lWid As Long
138
+
139
+
140
+
141
+ 'メモ帳をShell起動してプロセスIDを取得する
142
+
143
+ lngPid = Shell("notepad.exe", vbNormalFocus)
144
+
145
+ Call Shell("calc.exe", vbNormalFocus) '←ダミーで別アプリも起動
146
+
147
+
148
+
149
+ 'プロセスIDからウインドウハンドルを取得
150
+
151
+ lWid = GetHwndFromPid(lngPid)
152
+
153
+
154
+
155
+ If lWid = 0 Then
156
+
157
+ MsgBox "NotFound"
158
+
159
+ Exit Sub
160
+
161
+ End If
162
+
163
+
164
+
165
+ Call SendMessage(lngWid, WM_CLOSE, 0&, 0&)
166
+
167
+
168
+
169
+ End Sub
170
+
171
+
172
+
173
+ 'プロセスIDからウィンドウハンドルを検索
174
+
175
+ Public Function GetHwndFromPid(ByVal pid As Long) As Long
176
+
177
+ Dim hwnd As Long
178
+
179
+ '初期化
180
+
181
+ lngWid = 0
182
+
183
+ Call EnumWindows(AddressOf GetProc, 0)
184
+
185
+
186
+
187
+ GetHwndFromPid = lngWid
188
+
189
+
190
+
191
+ End Function
192
+
193
+
194
+
195
+ 'EnumWindowsのコールバック関数
196
+
197
+ Public Function GetProc(ByVal hwnd As Long, lParam As Long) As Boolean
198
+
199
+ GetProc = True
200
+
201
+ If IsWindowVisible(hwnd) <> 0 Then
202
+
203
+ '非表示ウィンドウでない場合、PIDのチェック
204
+
205
+ If GetPidFromHwnd(hwnd) = lngPid Then
206
+
207
+ '同じPIDを見つけたら、ウィンドウハンドルを格納
208
+
209
+ lngWid = hwnd
210
+
211
+ '戻り値FalseでEnumWindowsのループが終了
212
+
213
+ GetProc = False
214
+
215
+ End If
216
+
217
+ End If
218
+
219
+ End Function
220
+
221
+
222
+
223
+ 'ウィンドウハンドルからをプロセスIDを取得
224
+
225
+ Public Function GetPidFromHwnd(ByVal hwnd As Long) As Long
226
+
227
+ Dim pid As Long
228
+
229
+
230
+
231
+ Call GetWindowThreadProcessId(hwnd, pid)
232
+
233
+
234
+
235
+ GetPidFromHwnd = pid
236
+
237
+ End Function
238
+
239
+ ```
240
+
241
+ APIも多く、コールバック関数を使ったりと難易度高めになってしまいますが、ウィンドウハンドルを取得する場合はこの方法が確実です。
242
+
243
+
244
+
245
+ ---
246
+
247
+
248
+
249
+ 遅レスとなってしまいましたが、参考になれば幸いです。