I don't have permission to do this on the network here at school, but this code should create a "Task Manager" type program from which you can end other running programs.

I'm a little new to this, so it may not be perfect, but it's yours to try...

Create a new project with a form (Form1) and a standard module (Module1). Drop a listbox (List1) and three command buttons (Command1, Command2, Command3) on the form (layout doesn't matter, 'cause my prog will set them up for you).

I am using DestroyWindow to close the program, but there are many other APIs which may work just as well or better. Look at documentation on TerminateProcess, ExitProcess, CloseHandle, etc.

Anyway, here's a good start at least.

Paste this code into the standard module:
Code:
Option Explicit

Public Declare Function GetWindowText Lib "user32" Alias _
    "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, _
    ByVal cch As Long) As Long
    
Public Declare Function GetWindowLong Lib "user32" Alias _
    "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    
Public Declare Function EnumWindows Lib "user32" _
    (ByVal lpfn As Long, ByVal lParam As Long) As Boolean
    
Private Declare Function ExitWindowsEx Lib "user32" _
    (ByVal uFlags As Long, ByVal dwReserved As Long) As Boolean
       
Public Declare Function DestroyWindow Lib "user32" _
    (ByVal hwnd As Long) As Long

Public Declare Function GetLastError Lib "kernel32.dll" () As Long
    
Public lHandleArray() As Long
Public Const GWL_HWNDPARENT = -8
Public Const GWL_STYLE = -16
Public Const WS_CAPTION = &HC00000
Public Const GWT_MAXCOUNT As Integer = 128
Public Const QW_SHUTDOWN = 1

Private Function EnumWindowsProc(ByVal wHandle As Long, lParam As Long) As Long
    ReDim Preserve lHandleArray(UBound(lHandleArray) + 1)
    
    lHandleArray(UBound(lHandleArray)) = wHandle
    EnumWindowsProc = True
End Function

Public Sub GetWindowHandles()
    Dim lRetVal As Long, _
        lParam As Long
        
    lRetVal = EnumWindows(AddressOf EnumWindowsProc, lParam)
End Sub

Public Function QuitWindows(lQuitType As Long) As Long
    QuitWindows = ExitWindowsEx(lQuitType, 0)
End Function
And paste this into the form's code window:
Code:
Option Explicit

Private sWinInfo() As String

Private Sub Command1_Click()
    Dim lWinHandle As Long, _
        lRetVal As Long, _
        lErrorCode As Long
    
    If List1.ListIndex >= 0 Then
        lWinHandle = CLng(sWinInfo(0, List1.ListIndex + 1))
        
        lRetVal = DestroyWindow(lWinHandle)
        
        If lRetVal = 0 Then
            lErrorCode = GetLastError()
            MsgBox "Error code: " & lErrorCode
        End If
        
        Form_Load
    Else
        MsgBox "Select a task to end from the list", _
            vbOKOnly + vbInformation, "No Item Selected"
    End If
End Sub

Private Sub Command2_Click()
    Dim lRetVal As Long
    
    lRetVal = CLng(MsgBox("Are you sure you want to close" & vbNewLine & _
        "all programs and shut down windows?", vbOKCancel + vbExclamation, _
        "Shut Down Windows"))
        
    If lRetVal = CLng(vbOK) Then
        lRetVal = QuitWindows(QW_SHUTDOWN)
    End If
End Sub

Private Sub Command3_Click()
    End
End Sub

Private Sub Form_Load()
    Dim lWindowParent As Long, _
        lWindowStyle As Long, _
        lTitleLen As Long, _
        lCounter As Long, _
        sBuffer As String, _
        nCounter As Integer, _
        sLongestItem As String
            
    ReDim lHandleArray(0) As Long
    ReDim sWinInfo(2, 0)    ' Will hold handle and text for each window
    sBuffer = Space$(GWT_MAXCOUNT)  ' Holds window text

    GetWindowHandles    ' Fills lHandleArray with window handles
    List1.Clear
    For lCounter = 1 To UBound(lHandleArray)
        lWindowParent = GetWindowLong(lHandleArray(lCounter), GWL_HWNDPARENT)
        If lWindowParent = 0 Then   ' Window has no parents
            lWindowStyle = GetWindowLong(lHandleArray(lCounter), GWL_STYLE)
            'This next if statement checks to see if window has a title bar.
            'If you want to display all windows regardless of whether they
            'have a title bar or not, remove this if statement
            If (lWindowStyle And WS_CAPTION) Then
                lTitleLen = GetWindowText(lHandleArray(lCounter), _
                    sBuffer, GWT_MAXCOUNT)
                'This next if statment weeds out windows without captions.
                'Remove it if you want to include all windows.
                If lTitleLen > 0 Then
                    nCounter = nCounter + 1
                    ReDim Preserve sWinInfo(2, nCounter)
                    sWinInfo(0, nCounter) = CStr(lHandleArray(lCounter))
                    sWinInfo(1, nCounter) = Left$(sBuffer, lTitleLen)
                    List1.AddItem sWinInfo(1, nCounter)
                    'This if statement determines the width of the form and
                    'the listbox based on the longest-named item.
                    If Len(sWinInfo(1, nCounter)) > Len(sLongestItem) Then
                        sLongestItem = sWinInfo(1, nCounter)
                    End If
               End If
            End If
        End If
    Next lCounter
        
    LayoutForm sLongestItem
End Sub

Private Function LayoutForm(sStringIn As String)
    Dim ctlControl As Control
    
    With Me
        .Caption = "Task Manager"
        .Width = .TextWidth(sStringIn) + 800
        If .Width < 4400 Then
            .Width = 4400
        End If
        .Height = 5000
        .Left = (Screen.Width - .Width) / 2
        .Top = (Screen.Height - .Height) / 2
    End With
    
    With List1
        .Left = 100
        .Top = 100
        .Width = Me.ScaleWidth - 200
        .Height = 3800
    End With
    
    For Each ctlControl In Controls
        If TypeOf ctlControl Is CommandButton Then
            With ctlControl
                .Width = 1400
                .Height = 400
                .Top = List1.Top + List1.Height + 200
            End With
        End If
    Next ctlControl
            
    With Command1
        .Caption = "&End Task"
        .Left = (Me.ScaleWidth - 3 * .Width) / 4
    End With
    
    With Command2
        .Caption = "&Shut Down"
        .Left = Command1.Left * 2 + Command1.Width
    End With
    
    With Command3
        .Caption = "&Cancel"
        .Left = Command1.Left * 3 + Command1.Width * 2
    End With
End Function
Run the program, select an item from the list, and then click "End Task", and the task should (hopefully) end. Or click on "Shut Down" to exit windows or "Cancel" to quit the program.

Hope that helps a little!

~seaweed

Edited by seaweed on 02-24-2000 at 05:00 PM