Link to home
Start Free TrialLog in
Avatar of ducados
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!!!

Avatar of ErnestMH
ErnestMH

May be you can try the 'SetWindowPos' API and set the window positions to TopMost or the 'BringWindowToTop' API.
Avatar of ducados

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
Have you tried:

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(hWndChild, 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:\myprogram")

then use this:

Call BringWindowToTop(hHandle)

or

Call SetForegroundWindow(hHandle)
Call SetActiveWindow(hHandle)

to bring it to active/focus
Avatar of ducados

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(hHandle)
  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
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.
Avatar of DanRollins
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
ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial