• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 195
  • Last Modified:

Close button disabled

How can you close a window that has it's close button disabled?

When I execute the following it doesn't work:
PostMessage app_hwnd, WM_CLOSE, 0, 0&

I am assuming that the problem is the grayed out close button because this line of code works with all other windows.

I don't want to use send keys. If I could use PostMessage to tell the window "YES or "NO" (those are the buttons within the window/dialog box) then that would be fine.
0
bscmis
Asked:
bscmis
  • 3
  • 3
1 Solution
 
Richie_SimonettiIT OperationsCommented:
Example:

In a form:
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

Private Sub Form_Click()
Dim l As Long
l = FindWindow(vbNullString, "Microsoft Excel - Libro1") ' replace with caption's target
If l <> 0 Then
    EnumChildWindows l, AddressOf EnumChildProc, 0&
End If
End Sub

'In a module:
Option Explicit

Private 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

Public Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
    Dim sSave As String, ret As Long
    'Get the windowtext length
    sSave = Space$(255)
    ret = GetClassName(hwnd, sSave, 255)
    Debug.Print "Class name: " & sSave
    If UCase$(Left$(sSave, ret) = "BUTTON") Then
        'get the window text
        GetWindowText hwnd, sSave, Len(sSave)
        Debug.Print "Text: " & sSave
        'remove the last Chr$(0)
        If Left$(sSave, Len(sSave) - 1) = "Yes" Then
           
        ElseIf Left$(sSave, Len(sSave) - 1) = "No" Then

        End If
    End If
   
    'continue enumeration
    EnumChildProc = 1
End Function
0
 
Richie_SimonettiIT OperationsCommented:
With the previous code, you would get the hwnd for every child window in the dialog.
After that, we check if hwnd belongs to a button and if caption is "Yes" or "No".
We need to send messages to that button, telling that it is pressed (you have to choose which one to click)
To send a message like that, check here:
http://www.mvps.org/vbnet/code/intrinsic/buttonpress.htm
and
http://www.vbweb.co.uk/scripts/print.php?id=34
0
 
Richie_SimonettiIT OperationsCommented:
One more thing: NOT USESTOP BUTTON from VB IDE!!!!!
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
bscmisAuthor Commented:
Thank you very much for your help. I have to leave for the day but it looks like what you gave me will work great.

Thank you!

lauren
0
 
bscmisAuthor Commented:
Don't know what just happened. I accepted your answer but it didn't post.

I have to leave for the day but it looks like what you gave me will work great.

Thank you so much for your quick and helpful response,
lauren
0
 
tWiZtErCommented:
what code are you using.
Use the Remove Menu API:

Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
Const MF_BYPOSITION = &H400&
Const MF_REMOVE = &H1000&

Private Sub Form_Load()
    Dim hSysMenu As Long, nCnt As Long
    ' Get handle to our form's system menu
    ' (Restore, Maximize, Move, close etc.)
    hSysMenu = GetSystemMenu(Me.hwnd, False)

    If hSysMenu Then
        ' Get System menu's menu count
        nCnt = GetMenuItemCount(hSysMenu)
        If nCnt Then
            ' Menu count is based on 0 (0, 1, 2, 3...)
            RemoveMenu hSysMenu, nCnt - 1, MF_BYPOSITION Or MF_REMOVE
            RemoveMenu hSysMenu, nCnt - 2, MF_BYPOSITION Or MF_REMOVE ' Remove the seperator
            DrawMenuBar Me.hwnd
            ' Force caption bar's refresh. Disabling X button
        End If
    End If
End Sub




And to close the window: use PostMessage API



Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) 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 ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Const SW_SHOWNORMAL = 1
Const WM_CLOSE = &H10
Const gcClassnameMSWord = "OpusApp"
Const gcClassnameMSExcel = "XLMAIN"
Const gcClassnameMSIExplorer = "IEFrame"
Const gcClassnameMSVBasic = "wndclass_desked_gsk"
Const gcClassnameNotePad = "Notepad"
Const gcClassnameMyVBApp = "ThunderForm"
Private Sub Form_Load()
    'KPD-Team 1998
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net
    Dim WinWnd As Long, Ret As String, RetVal As Long, lpClassName As String
    'Ask for a Window title
    Ret = InputBox("Enter the exact window title:" + Chr$(13) + Chr$(10) + "Note: must be an exact match")
    'Search the window
    WinWnd = FindWindow(vbNullString, Ret)
    If WinWnd = 0 Then MsgBox "Couldn't find the window ...": Exit Sub
    'Show the window
    ShowWindow WinWnd, SW_SHOWNORMAL
    'Create a buffer
    lpClassName = Space(256)
    'retrieve the class name
    RetVal = GetClassName(WinWnd, lpClassName, 256)
    'Show the classname
    MsgBox "Classname: " + Left$(lpClassName, RetVal)
    'Post a message to the window to close itself
    PostMessage WinWnd, WM_CLOSE, 0&, 0&
End Sub


This worked for me, i used all border styles:
0 - None
1 - Fixed Single
2 - Sizable
3 - Fixed Dialog
4 - Fixed Toolwindow
5 - Sizable Toolwindow
And set ShowInTaskbar = True and False for all of them


Im using Windows XP Pro.
No SP1, hope this works for you.
0
 
bscmisAuthor Commented:
thank you tWiZtEr I will give that a try as well
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now