Link to home
Start Free TrialLog in
Avatar of ChrisH
ChrisH

asked on

Finding Window Handle

After making the following call:

Call Shell(GetSetting(App.EXEName, "Configuration", "VideoButton" & Str(Index)), vbNormalFocus)

does anyone know a way in which I can grab the handle of the window without using the title of the window that is on the top bar of the window?
ASKER CERTIFIED SOLUTION
Avatar of Erick37
Erick37
Flag of United States of America image

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
Avatar of mcrider
mcrider

ChrisH,

I already gave that to you in your "Window Precedence" question.... you posted this new question too soon. ;-)

Cheers!®©
By the way, I posted it a minute before Erick posted this answer, and almost an hour before you posted the question...


Cheers!®©

Avatar of ChrisH

ASKER

I have a question.  I used this link.. and everything seems to be working fine, except the GetWindowText portion.  The handle to the window is returned just fine.. yet for some reason, nothing (zero) gets returned from the GetWindowText function.  Any idea why?  I used the exact same code the Microsoft site had.  Also.. do I need to get the name of the window if I have the handle?
I tried it as well and it works.

MS forgot to add
Option Explicit
to the top of both the form's code and the module code.
Add it and see if there are any compile errors in your code.
You only need the hWnd of a window if you are using API which require it.  The Title is for the user only.
What are you doing with the shelled application that you need the hwnd for?

This worked for me:

Sub Command1_Click()
   Dim hInst As Long             ' Instance handle from Shell function.
   Dim hWndApp As Long           ' Window handle from GetWinHandle.
   Dim buffer As String          ' Holds caption of Window.
   Dim numChars As Integer       ' Count of bytes returned.
   
   ' Shell to an application
   hInst = Shell("notepad.exe")
   
   ' Begin search for handle
   hWndApp = GetWinHandle(hInst)
   
    If hWndApp <> 0 Then
        ' Init buffer
        buffer = Space$(128)
        ' Get caption of window
        numChars = GetWindowText(hWndApp, buffer, Len(buffer))
        buffer = Left(buffer, numChars)
        Debug.Print buffer
        ' Display window's caption
        MsgBox "You shelled to the Application: " & buffer
    End If
End Sub
Also, GetWindowText function assumes you are passing the handle of a normal window with a title bar.
Avatar of ChrisH

ASKER

Basically, I'm opening up internet explorer from my main app when the user clicks a button.  I want the IE to always be on top of the main application.  Actually.. this is just one of many cases that could possibly happen.  I have a registry setting which could hold any file, and I want to be able to query the registry for the setting and open it.. then give the opened window focus over the main application.
Avatar of ChrisH

ASKER

Yea.. with further testing I've found that if I launch the calculater or notepad, the window gets focus over the calling app.  However, when opening the internet explorer, the IE window will not take precedence.  Any thoughts to why one window would take focus where another won't?
Well, you have specified vbNormalFocus in the Shell call, so the shelled app will open with focus.  It will not "be always on top" of your app if the user selects your app.  Is this what you want?
Avatar of ChrisH

ASKER

Yep.. I want it always on top.
I do not see that behavior. IE opens with focus.
You can set your shelled app explicitly as the foreground window by calling:

Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" _
    (ByVal hwnd As Long) As Long

'~~~
Call SetForeGroundWindow(hWndApp)
'~~~
Avatar of ChrisH

ASKER

Adjusted points to 200
Avatar of ChrisH

ASKER

IE does open with focus.. but it doesn't remain always ontop for some reason..
A window can be set to be always on top, but it will be always on top of all applications.  If this is what you want:

"HOWTO: Create a Form That Always Stays on Top"
http://support.microsoft.com/support/kb/articles/Q184/2/97.ASP

Just modify the code with the window handle you want to target:
lR = SetTopMostWindow(hWndApp, True)
Avatar of ChrisH

ASKER

Yea.. I was already doing that.. I've tracked the problem down to the fact that the handle I get from the process ID of the internet explorer is just plain wrong.  I don't understand why this would happen.
Try this:
After the call to shell, insert a short pause to allow the application to load.  IE may be starting with a splash screen, etc.

'Module declare:
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


'After Shell
Call Sleep(2000) 'Sleep 2 secs
Avatar of ChrisH

ASKER

That didn't work either.. I norrowed the problem down even furter.  It seems like there is a parent window that has the browser as a subwindow or something to this effect.. When I launched IE.. I got the process ID.. and then the handle.  When I look up the handle in Spy++, I get some "Auto Suggestion Drop Down Box" window that has that handle. If I open up the subdirectory of that window.. it shows several other windows including the Internet Explorer.  Now, the caption of the IE is "Internet Explorer".  Is there a way for me to find the handle of this Suggestion Drop box.. and then search for the Internet Explorer handle withing the subwindows of the Suggestion Drop box?
Actually, since you are shelling the app to show with focus, you could simply call GetForegroundWindow to get its handle.  This is more reliable for IE.

Code:

Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
    (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Sub Command1_Click()
   Dim hInst As Long
   Dim hWndApp As Long
   Dim buffer As String
   Dim numChars As Integer
   
   ' Shell to an application
   hInst = Shell("c:\program files\microsoft internet\ie20.exe", vbNormalFocus)
   ' Wait a bit
   Call Sleep(3000)
   ' Get the app with focus
   hWndApp = GetForegroundWindow
   If hWndApp <> 0 Then
      ' Init buffer
      buffer = Space$(128)
      ' Get caption of window
      numChars = GetWindowText(hWndApp, buffer, Len(buffer))
      ' Display window's caption
      MsgBox "You shelled to the Application: " & Left$(buffer, numChars)
   End If
End Sub
Avatar of ChrisH

ASKER

Thanks.. that did the trick!
Glad to help
Thanks!