OK, I wrote (stole) this over a year ago, and I no longer remember how it works, but it does. I modified from code that closed the calculator. The original code is still here, but commented out.
Good luck, and YMMV.
Option Compare Database
'************** Code Start ***************
Private Const WM_CLOSE = &H10
Private Const INFINITE = &HFFFFFFFF
Private Declare Function apiPostMessage _
Lib "user32" Alias "PostMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) _
As Long
Private Declare Function apiFindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) _
As Long
Private Declare Function apiWaitForSingleObject _
Lib "kernel32" Alias "WaitForSingleObject" _
(ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) _
As Long
Private Declare Function apiIsWindow _
Lib "user32" Alias "IsWindow" _
(ByVal hWnd As Long) _
As Long
Private Declare Function apiGetWindowThreadProcessId _
Lib "user32" Alias "GetWindowThreadProcessId" _
(ByVal hWnd As Long, _
lpdwProcessID As Long) _
As Long
'Function fCloseApp(lpClassName As String) As Boolean
Function fCloseApp(lpCaption As String) As Boolean
'Usage Examples:
' To close Calculator:
' ?fCloseApp("SciCalc")
'
Dim lngRet As Long, hWnd As Long, pID As Long
'hWnd = apiFindWindow(lpClassName, vbNullString)
hWnd = apiFindWindow(vbNullString, lpCaption)
If (hWnd) Then
lngRet = apiPostMessage(hWnd, WM_CLOSE, 0, ByVal 0&)
Call apiGetWindowThreadProcessId(hWnd, pID)
Call apiWaitForSingleObject(pID, 1000) 'INFINITE)
fCloseApp = Not (apiIsWindow(hWnd) = 0)
End If
End Function
'************* Code End ***************