Hello,
I’m trying to force an app into the foreground through the winapi. It needs to be in the postopen event of a form but I’m just trying to get it working from a button (experimenting w/firefox) right now.
Here is the code that I’ve tried to gather and patch together from a few place - I’m quite lost when it comes to the winapi:
Declarations:
Declare Function GetWindowThreadProcessId Lib “user32” (Byval hWnd As Long, lpdwProcessId As Long) As Long
Declare Function AttachThreadInput Lib “user32” (Byval idAttach As Long, Byval idAttachTo As Long, Byval fAttach As Long) As Long
Declare Function GetForegroundWindow Lib “user32”() As Long
Declare Function SetForegroundWindow Lib “user32”(Byval hWnd As Long) As Long
Declare Function IsIconic Lib “user32” (Byval hWnd As Long) As Long
Declare Function ShowWindow Lib “user32” (Byval hWnd As Long, Byval nCmdShow As Long) As Long
Declare Function GetExitCodeProcess Lib “kernel32” (Byval hProcess As Long, lpExitCode As Long) As Long
Declare Function OpenProcess Lib “kernel32” (Byval dwDesiredAccess As Long, Byval bInheritHandle As Long, Byval dwProcessId As Long) As Long
Declare Function CloseHandle Lib “kernel32” ( Byval hObject As Long) As Long
Declare Function EnumProcesses Lib “PSAPI” ( lpidProcess As Any, cb As Long, cbNeeded As Long) As Boolean
Declare Function EnumProcessModules Lib “PSAPI” ( Byval hProcess As Long, lphModule As Any, cb As Long, lpcbNeeded As Long) As Boolean
Declare Function GetModuleBaseName Lib “PSAPI” Alias “GetModuleBaseNameA” (Byval hProcess As Long, Byval hModule As Long, Byval lpBasename As String, nSize As Long) As Boolean
Declare Function CreateToolhelpSnapshot Lib “kernel32” Alias “CreateToolhelp32Snapshot” (Byval lFlags As Long, lProcessID As Long) As Long
Declare Function BringWindowToTop Lib “user32” (Byval hwnd As Long) As Long
Declare Function GetDesktopWindow Lib “user32” () As Long
Declare Function GetWindow Lib “user32” (Byval hwnd As Long, Byval wCmd As Long) As Long
Private Type MODULEINFO
lpBaseOfDll As Long
SizeOfImage As Long
EntryPoint As Long
End Type
Const SW_RESTORE = 9
Const SW_SHOW = 5
Private Const MAX_PATH = 260&
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Const PROCESS_CREATE_PROCESS = &H80&
Private Const PROCESS_CREATE_THREAD = &H2&
Private Const PROCESS_DUP_HANDLE = &H40&
Private Const PROCESS_HEAP_ENTRY_BUSY = &H4&
Private Const PROCESS_HEAP_ENTRY_DDESHARE = &H20&
Private Const PROCESS_HEAP_ENTRY_MOVEABLE = &H10&
Private Const PROCESS_HEAP_REGION = &H1&
Private Const PROCESS_HEAP_UNCOMMITTED_RANGE = &H2&
Private Const PROCESS_QUERY_INFORMATION = &H400&
Private Const PROCESS_SET_INFORMATION = &H200&
Private Const PROCESS_SET_QUOTA = &H100&
Private Const PROCESS_TERMINATE = &H1&
Private Const PROCESS_VM_OPERATION = &H8&
Private Const PROCESS_VM_READ = &H10&
Private Const PROCESS_VM_WRITE = &H20&
Dim lngHandFirefox As Long
Sub Click(Source As Button)
Dim hWnd As Long
Call GetProcessList()
If lngHandFirefox<>0 Then
Call ForceForegroundWindow(hWnd)
End If
End Sub
Function ForceForegroundWindow(Byval hWnd As Long) As Boolean
Dim ThreadID1 As Long
Dim ThreadID2 As Long
Dim nRet As Long
If hWnd = GetForegroundWindow() Then
ForceForegroundWindow = True
Else
ThreadID1 = GetWindowThreadProcessId(GetForegroundWindow, Byval 0&)
ThreadID2 = GetWindowThreadProcessId(hWnd, Byval 0&)
If ThreadID1<> ThreadID2 Then
Call AttachThreadInput(ThreadID1, ThreadID2, True)
nRet = SetForegroundWindow(hWnd)
Call AttachThreadInput(ThreadID1, ThreadID2, False)
Else
nRet = SetForegroundWindow(hWnd)
End If
If IsIconic(hWnd) Then
Call ShowWindow(hWnd, SW_RESTORE)
Else
Call ShowWindow(hWnd, SW_SHOW)
End If
ForceForegroundWindow = Cbool(nRet)
End If
End Function
Function GetProcessList() As String
Dim pbolRtn As Boolean
Dim plngRtn As Long
Dim plngNeeded As Long
Dim plngNumItems As Long
Dim plngNumItemsMods As Long
Dim plngLoop As Long
Dim plngNumCols As Long
Dim plngNumRows As Long
Dim plngProcessHwnd As Long
Dim plngPos As Long
Dim plngLenFileName As Long
Dim palngModHwnds() As Long
Dim palngProcesses() As Long
Dim pstrProcessName As String
Dim ptypModuleInfo As MODULEINFO
Dim sProcessList As String
sProcessList = ""
plngNumItems = 1024
Redim palngProcesses(0 To plngNumItems)
pbolRtn = EnumProcesses(palngProcesses(0), (1024 * 4), plngNeeded)
If pbolRtn = 0 Then
Exit Function
End If
plngNumItems = plngNeeded / 4
Dim xx As Integer
xx = 0
For plngLoop = 0 To plngNumItems - 1
If palngProcesses(plngLoop) <> 0 Then
pstrProcessName = ""
plngProcessHwnd = OpenProcess( _
PROCESS_QUERY_INFORMATION& Or PROCESS_VM_READ&, 0&, _
palngProcesses(plngLoop))
plngNumItemsMods = 1024
Redim palngModHwnds(0 To plngNumItemsMods)
pbolRtn = EnumProcessModules(plngProcessHwnd, _
palngModHwnds(0), (1024 * 4), plngNeeded)
If pbolRtn <> 0 Then
plngLenFileName = MAX_PATH
pstrProcessName = Space$(plngLenFileName)
pbolRtn = GetModuleBaseName(plngProcessHwnd, _
palngModHwnds(0), pstrProcessName, plngLenFileName)
plngPos = Instr(pstrProcessName, Chr$(0))
If plngPos > 0 Then
pstrProcessName = Mid$(pstrProcessName, 1, _
plngPos - 1)
End If
If sProcessList <> "" Then sProcessList = _
sProcessList & Chr(0)
sProcessList = sProcessList & pstrProcessName
If Instr(Lcase(pstrProcessName), "firefox") Then
'tried
' lngHandFirefox = plngProcessHwnd
' lngHandFirefox = palngModHwnds(plngPos) 'plngProcessHwnd
lngHandFirefox = plngLenFileName
End If
End If
End If
plngRtn = CloseHandle(plngProcessHwnd)
Next plngLoop
Erase palngProcesses
GetProcessList = sProcessList
End Function