ducados
asked on
SetForegroundWindow in Windows 2000
I have a program that starts other applications using a shell statement. I need to make sure that the applications always are the Fore Ground window and have focus. I think that the "SetForegroundWindow API" is my souloutin but I cant get it to work within Windows 2000.
HELP!!!
HELP!!!
May be you can try the 'SetWindowPos' API and set the window positions to TopMost or the 'BringWindowToTop' API.
ASKER
Sorry Ernest. Did not work.
If someone could explain how to implement the infofor VB at: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q97925
This maybe the fix
If someone could explain how to implement the infofor VB at: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q97925
This maybe the fix
Have you tried:
Shell "C:\path\app.exe", vbNormalFocus
Shell "C:\path\app.exe", vbNormalFocus
Here, this may help you... All code included. :)
'paste this into a new module
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" _
(ByVal hwnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
Private Declare Function SetActiveWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function BringWindowToTop Lib "user32" _
(ByVal hwnd As Long) As Long
Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDLAST = 1
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3
Private Const GW_OWNER = 4
Private Const GW_CHILD = 5
Public Function ShellAndGetHandle(ByVal sPath As String, _
Optional ByVal WindowStyle As VBA.VbAppWinStyle = vbNormalFocus) As Long
Dim hProcessID As Long
hProcessID = Shell(sPath, WindowStyle)
Dim hWndDesktop As Long
Dim hWndChild As Long
Dim hWndChildProcessID As Long
'Sleep 1000 'uncomment to insert a delay
'get the handle to the desktop
hWndDesktop = GetDesktopWindow()
'get the first child under the desktop
hWndChild = GetWindow(hWndDesktop, GW_CHILD)
'hwndchild will = 0 when no more child windows are found
Do While hWndChild <> 0
'get the ThreadProcessID of the window
Call GetWindowThreadProcessId(h WndChild, hWndChildProcessID)
'if it matches the target, exit returning that value
If hWndChildProcessID = hProcessID Then
ShellAndGetHandle = hWndChild
Exit Do
End If
'not found, so get the next hwnd
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)
Loop
End Function
now call your shell command like this:
Dim hHandle
hHandle = shellandgethandle("c:\mypr ogram")
then use this:
Call BringWindowToTop(hHandle)
or
Call SetForegroundWindow(hHandl e)
Call SetActiveWindow(hHandle)
to bring it to active/focus
'paste this into a new module
Option Explicit
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Private Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" _
(ByVal hwnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
Private Declare Function SetActiveWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Public Declare Function BringWindowToTop Lib "user32" _
(ByVal hwnd As Long) As Long
Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDLAST = 1
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3
Private Const GW_OWNER = 4
Private Const GW_CHILD = 5
Public Function ShellAndGetHandle(ByVal sPath As String, _
Optional ByVal WindowStyle As VBA.VbAppWinStyle = vbNormalFocus) As Long
Dim hProcessID As Long
hProcessID = Shell(sPath, WindowStyle)
Dim hWndDesktop As Long
Dim hWndChild As Long
Dim hWndChildProcessID As Long
'Sleep 1000 'uncomment to insert a delay
'get the handle to the desktop
hWndDesktop = GetDesktopWindow()
'get the first child under the desktop
hWndChild = GetWindow(hWndDesktop, GW_CHILD)
'hwndchild will = 0 when no more child windows are found
Do While hWndChild <> 0
'get the ThreadProcessID of the window
Call GetWindowThreadProcessId(h
'if it matches the target, exit returning that value
If hWndChildProcessID = hProcessID Then
ShellAndGetHandle = hWndChild
Exit Do
End If
'not found, so get the next hwnd
hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)
Loop
End Function
now call your shell command like this:
Dim hHandle
hHandle = shellandgethandle("c:\mypr
then use this:
Call BringWindowToTop(hHandle)
or
Call SetForegroundWindow(hHandl
Call SetActiveWindow(hHandle)
to bring it to active/focus
ASKER
Hi aekland
Eeeemmmm looks interesting. I will need to try it tomorrow when I get back to the office.
I have already tried it with the:
BringWindowToTop(hHandle)
SetForegroundWindow(hHandl e)
SetActiveWindow(hHandle)
without much success in Windows 2000.
I think the problem is with the application start-up process (quite complicated). During this process, I think that the original calling application is losing focus. Once lost it seems imposable to get it back with Windows 2000 (works fine in NT4). If the main calling application loses focus (foreground status), the above functions will have no affect on any child applications called later.
What do you think? How can I retain or regain focus (foreground status) with the original app?
(Sorry, hope it makes sense)
Eeeemmmm looks interesting. I will need to try it tomorrow when I get back to the office.
I have already tried it with the:
BringWindowToTop(hHandle)
SetForegroundWindow(hHandl
SetActiveWindow(hHandle)
without much success in Windows 2000.
I think the problem is with the application start-up process (quite complicated). During this process, I think that the original calling application is losing focus. Once lost it seems imposable to get it back with Windows 2000 (works fine in NT4). If the main calling application loses focus (foreground status), the above functions will have no affect on any child applications called later.
What do you think? How can I retain or regain focus (foreground status) with the original app?
(Sorry, hope it makes sense)
Hi!
Might be a problem when the window handle of child applications won't get the shell callback.
Shuld try list all windows hwnd of that app and it's call's maybe a message hook? A bad problem to get the value and deside what's the foreground window, latest created, text on it's caption or what?
PS Have you tried this API
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Matti
Might be a problem when the window handle of child applications won't get the shell callback.
Shuld try list all windows hwnd of that app and it's call's maybe a message hook? A bad problem to get the value and deside what's the foreground window, latest created, text on it's caption or what?
PS Have you tried this API
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Matti
Or if that doesn't work, this should:
Option Explicit
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "User32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Public Function WindowActivate(ByVal hwnd as Long)
SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
SetWindowPos hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End Sub
Just pass the function the handle to the window you want to make active and set focus to.
Option Explicit
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "User32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Public Function WindowActivate(ByVal hwnd as Long)
SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
SetWindowPos hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End Sub
Just pass the function the handle to the window you want to make active and set focus to.
ducados, an EE Moderator will handle this for you.
Moderator, my recommended disposition is:
Refund points and save as a 0-pt PAQ.
DanRollins -- EE database cleanup volunteer
Moderator, my recommended disposition is:
Refund points and save as a 0-pt PAQ.
DanRollins -- EE database cleanup volunteer
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.