Solved

Close window by window Header name even if not in focus

Posted on 2010-09-15
10
435 Views
Last Modified: 2012-05-10
I need a vb6 example of closing a window that is or is not in focus and all i know is the window name.
0
Comment
Question by:rjef
10 Comments
 
LVL 17

Expert Comment

by:xDJR1875
ID: 33685637
Here are a couple of links to help you out with the win32 API required to do this.

http://www.dreamincode.net/code/snippet2732.htm
http://www.vb6.us/tutorials/activate-window-api
http://www.codeproject.com/KB/dialog/closewindow.aspx

hope that helps
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 33685739
Bare bones example:
*requires an exact match on window title!
Private Const WM_CLOSE = &H10



Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long



Private Sub Command1_Click()

    Dim targetHwnd As Long

    targetHwnd = FindWindow(vbNullString, "exact window title in here")

    SendMessage targetHwnd, WM_CLOSE, 0, 0 

End Sub

Open in new window

0
 

Author Comment

by:rjef
ID: 33685772
Private Const WM_CLOSE = &H10

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Sub Command1_Click()
    Dim targetHwnd As Long
    targetHwnd = FindWindow(vbNullString, "Printers and Faxes")
    SendMessage targetHwnd, WM_CLOSE, 0, 0
End Sub

this did not close the 'Printers and Faxes" window
0
 
LVL 11

Expert Comment

by:kbirecki
ID: 33690313
Cutting from a working program I have, paste the first portion of the code onto a form with a button "Command1", and the second portion into it's own module.  Open the Printers anf Faxes windows, run the app, and click the btn.

I prefer this FindWindowLike function because it allows for wildcards.  I can't take credit for the whole solution; I put it together many years ago from stuff I found on the Internet.  I left the debugging code I had in there.
'Form Code:

Private Sub Command1_Click()

    Dim lngResult As Long

    Dim lngReturnValue As Long

    Dim lNumAppsFound As Long

    Static varHWnds() As Variant

    

    lNumAppsFound = FindWindowLike(varHWnds(), 0, "Printers and *", "*", Null)

    For lLoop = 1 To lNumAppsFound

        lngReturnValue = PostMessage(varHWnds(lLoop), WM_CLOSE, vbNull, vbNull)

        lngResult = WaitForSingleObject(varHWnds(lLoop), INFINITE)

    Next lLoop



End Sub



'*********************************

'Separate Module Code

Option Explicit



Declare Function SetFocusAPI Lib "user32" Alias "SetForegroundWindow" _

   (ByVal hwnd As Long) As Long

Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, _

 ByVal wCmd As Long) As Long

Declare Function GetDesktopWindow Lib "user32" () As Long

Declare Function GetWindowLW Lib "user32" Alias "GetWindowLongA" _

(ByVal hwnd As Long, ByVal nIndex As Long) As Long

Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long

Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _

 (ByVal hwnd As Long, ByVal lpClassName As String, _

  ByVal nMaxCount As Long) As Long

Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _

 (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) _

  As Long

Declare Function GetWindowPlacement Lib "user32" _

    (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long

Private Declare Function SetForegroundWindow Lib "user32" _

    (ByVal hwnd As Long) As Long

Private Declare Function ShowWindow Lib "user32" _

    (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long



Public Declare Function WaitForSingleObject Lib "kernel32" _

   (ByVal hHandle As Long, _

   ByVal dwMilliseconds As Long) As Long

Public Declare Function PostMessage Lib "user32" _

   Alias "PostMessageA" _

   (ByVal hwnd As Long, _

   ByVal wMsg As Long, _

   ByVal wParam As Long, _

   ByVal lParam As Long) As Long



Public Declare Function IsWindow Lib "user32" _

   (ByVal hwnd As Long) As Long



Public Declare Function 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) As Long



Private lpwndpl   As WINDOWPLACEMENT



Private Type POINTAPI

    x As Long

    y As Long

End Type



Private Type RECT

    Left   As Long

    Top    As Long

    Right  As Long

    Bottom As Long

End Type



Private Type WINDOWPLACEMENT

    Length           As Long

    FLAGS            As Long

    showCmd          As Long

    ptMinPosition    As POINTAPI

    ptMaxPosition    As POINTAPI

    rcNormalPosition As RECT

End Type



Private Const GWL_ID = (-12)

Private Const GW_HWNDNEXT = 2

Private Const GW_CHILD = 5

Private Const SWP_NOMOVE = 2

Private Const SWP_NOSIZE = 1

Private Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE

Private Const HWND_TOPMOST = -1

Private Const HWND_NOTOPMOST = -2

Private Const GWL_STYLE = (-16)

Private Const GWL_EXSTYLE = (-20)

Private Const WM_GETTEXT = &HD

Private Const WM_GETTEXTLENGTH = &HE

Private Const GWL_HWNDPARENT = (-8)

Private Const WM_COMMAND = &H111

Private Const MIN_ALL = 419

Private Const MIN_ALL_UNDO = 416

Private Const MAX_PATH = 260

Private Const SW_SHOW = 5

Private Const SW_RESTORE = 9

Private Const SW_SHOWMINIMIZED = 2

Private Const SW_SHOWMAXIMIZED = 3

Private Const SW_SHOWNORMAL = 1



'Constants used by the API functions

Public Const WM_CLOSE = &H10

Public Const INFINITE = &HFFFFFFFF



'FindWindowLike

' - Finds the window handles of the windows matching the specified

'   parameters

'

'hwndArray()

' - An integer array used to return the window handles

'

'hWndStart

' - The handle of the window to search under.

' - The routine searches through all of this window's children and their

'   children recursively.

' - If hWndStart = 0 then the routine searches through all windows.

'

'WindowText

' - The pattern used with the Like operator to compare window's text.

'

'ClassName

' - The pattern used with the Like operator to compare window's class

'   name.

'

'ID

' - A child ID number used to identify a window.

' - Can be a decimal number or a hex string.

' - Prefix hex strings with "&H" or an error will occur.

' - To ignore the ID pass the Visual Basic Null function.

'

'Returns

' - The number of windows that matched the parameters.

' - Also returns the window handles in hWndArray()

'

'----------------------------------------------------------------------

'Remove this next line to use the strong-typed declarations

#Const WinVar = True

#If WinVar Then

    Function FindWindowLike(hWndArray() As Variant, _

     ByVal hWndStart As Variant, WindowText As String, _

      Classname As String, _

      ID) As Integer

        ' Comments  :

        ' Parameters: hWndArray()

        '             hWndStart

        '             WindowText

        '             Classname

        '             ID -

        ' Returns   : Integer -

        ' Modified  :

        '

        ' --------------------------------------------------

        

        On Error GoTo PROC_ERR

        

        Dim hwnd

        Dim r

        Static level

        Static iFound

#ElseIf Win32 Then

    Function FindWindowLike(hWndArray() As Long, ByVal hWndStart As Long, _

     WindowText As String, Classname As String, ID) As Long

        Dim hwnd As Long

        Dim r As Long

        ' Hold the level of recursion:

        Static level As Long

        ' Hold the number of matching windows:

        Static iFound As Long

#ElseIf Win16 Then

    Function FindWindowLike(hWndArray() As Integer, _

     ByVal hWndStart As Integer, WindowText As String, _

     Classname As String, ID) As Integer

        Dim hwnd As Integer

        Dim r As Integer

        ' Hold the level of recursion:

        Static level As Integer

        'Hold the number of matching windows:

        Static iFound As Integer

#End If

Dim sWindowText As String

Dim sClassname As String

Dim sID

' Initialize if necessary:

If level = 0 Then

    iFound = 0

    ReDim hWndArray(0 To 0)

    If hWndStart = 0 Then

        hWndStart = GetDesktopWindow()

    End If

End If

' Increase recursion counter:

level = level + 1

' Get first child window:

hwnd = GetWindow(hWndStart, GW_CHILD)

Do Until hwnd = 0

    DoEvents ' Not necessary

    ' Search children by recursion:

    r = FindWindowLike(hWndArray(), hwnd, WindowText, Classname, ID)

    ' Get the window text and class name:

    sWindowText = Space(255)

    r = GetWindowText(hwnd, sWindowText, 255)

    sWindowText = Left(sWindowText, r)

    'Debug.Print sWindowText

    sClassname = Space(255)

    r = GetClassName(hwnd, sClassname, 255)

    sClassname = Left(sClassname, r)

    

    'DEBUG CODE:

    'MsgBox sWindowText & " / " & sClassname

    

    ' If window is a child get the ID:

    If GetParent(hwnd) <> 0 Then

        r = GetWindowLW(hwnd, GWL_ID)

        sID = CLng("&H" & Hex(r))

    Else

        sID = Null

    End If

    ' Check that window matches the search parameters:

    If sWindowText Like WindowText And sClassname Like Classname Then

        If IsNull(ID) Then

            ' If find a match, increment counter and

            '  add handle to array:

            iFound = iFound + 1

            ReDim Preserve hWndArray(0 To iFound)

            hWndArray(iFound) = hwnd

        ElseIf Not IsNull(sID) Then

            If CLng(sID) = CLng(ID) Then

                ' If find a match increment counter and

                '  add handle to array:

                iFound = iFound + 1

                ReDim Preserve hWndArray(0 To iFound)

                hWndArray(iFound) = hwnd

            End If

        End If

        'Debug.Print "Window Found: "

        'Debug.Print "  Window Text  : " & sWindowText

        'Debug.Print "  Window Class : " & sClassname

        'Debug.Print "  Window Handle: " & CStr(hwnd)

        'MOD: 3/14/03/KB - Added stmt to jump out of loop when window is found

        Exit Do

        'ENDMOD: 3/14/03/KB

    End If

    ' Get next child window:

    hwnd = GetWindow(hwnd, GW_HWNDNEXT)

Loop

' Decrement recursion counter:

level = level - 1

' Return the number of windows found:

FindWindowLike = iFound

PROC_EXIT:

Exit Function



PROC_ERR:

'ErrorLog ThisProject, ThisModule, ThisProcedure, Format(Err.Number), Err.Description, bolErrCritical

'********

'Put some error handling routine here

'********

Resume PROC_EXIT



End Function

Open in new window

0
 

Author Comment

by:rjef
ID: 33715762
what is interesting is when i right click on one of my printers then properties then click on print test page then set the program to close the test page window the trouble shoot window is opened.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 11

Expert Comment

by:kbirecki
ID: 33715940
What troubleshoot window do you mean?
0
 
LVL 11

Expert Comment

by:kbirecki
ID: 33715948
Can you post a screenshot?
0
 

Author Comment

by:rjef
ID: 33717015
when i try to close this window
trob.jpg
0
 
LVL 11

Accepted Solution

by:
kbirecki earned 500 total points
ID: 33720445
That should work as well.  I just tested it on one of my printers and it worked, however, there's a caveat (I'll come back to that.)

Regarding your failing test of the app, here's one possiblity: I failed to mention that the routine FindWindowLike is case senstive (took me a while to figure that one out when I first started using it).  I never felt the need to change it, but you could make it case insensitive by changing this line in FindWindowLike() from:

If sWindowText Like WindowText And sClassname Like Classname Then

...to...

If UCASE(sWindowText) Like UCASE(WindowText) And sClassname Like Classname Then

(You may also want to change the comparison of the ClassName vars as well in case you use that.)

Another way you can troubleshoot this is to enable some of the debug.print statements and step through the code to see where exactly it fails, and where it misses what you expect.  That comparison line abov is where it finds the window you're looking for.  Watch the debug output until you see the window you're looking for.  I'd suggest doing this with as few applications and windows open as possible, including apps int he system tray, because it cycles through all of them.

That will definitely narrow down where you're having a problem with this routine.  It does work, so try those ideas.

The caveat:  I found that when I close the dialog you reference using the close command in this example app, Windows treats this just like I clicked [Troubleshoot] and pops up the Help window with printer troubleshooting tips (not helpful.)  So instead of sending a close command, you may want to simulate clicking the [OK] button instead.  One way would be to wait until you see that window (or a specified timeout), then issue a SendKeys command for <ENTER>, the default button.

Are you scripting a process to manage printers?
0
 

Author Closing Comment

by:rjef
ID: 33733952
this works
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

The purpose of this article is to demonstrate how we can use conditional statements using Python.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The viewer will learn how to implement Singleton Design Pattern in Java.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now