简体   繁体   中英

Bring a window programme to foreground in full screen even if it is minimized using VBA?

let's say there are four different window programs are running at a time. I want a macro which can bring a program "NESTTRADER.EXE" in the front with full screen and minimize other three (including excel). I tried Appactivate() but it works only if program ("NESTTRADER.EXE") is not minimized in the taskbar.Also tried some SetForegroundWindow method but it is giving error that I should update it for win 64.

Dim Processes, Process As Variant
Dim Shell As Object
Set Processes = GetObject("winmgmts:").InstancesOf("Win32_Process")
Set Shell = CreateObject("WScript.Shell")

For Each Process In Processes
    If StrComp(Process.Name, "Nesttrader.exe", vbTextCompare) = 0 Then
        Shell.AppActivate Process.ProcessId
        Exit For
    End If
Next

Above code does not do the job if "nesttrader.exe" is minimized to the taskbar.

Finally I found soultion for this. Below code will maximize your window even if it is minimized by giving partial text of title of window.

    Option Explicit

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

Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long

Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long

Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Boolean

Private Const GW_HWNDNEXT = 2

Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Const SW_SHOWMAXIMIZED = 3

Private Declare PtrSafe Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long

Private Sub SHOW()

    Dim lhWndP As Long

    If GetHandleFromPartialCaption(lhWndP, "NEST TRADER") = True Then
        If lhWndP <> 0 Then
         BringWindowToTop (lhWndP)
         ShowWindow lhWndP, SW_SHOWMAXIMIZED
      End If
   End If
End Sub

Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean

    Dim lhWndP As Long
    Dim sStr As String
    Dim ise As String
    GetHandleFromPartialCaption = False
    lhWndP = FindWindow(vbNullString, vbNullString)
    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        sStr = Left$(sStr, Len(sStr) - 1)
        ise = IsWindowVisible(lhWndP)
        If InStr(1, sStr, sCaption, vbTextCompare) > 0 And ise = True Then
            GetHandleFromPartialCaption = True
            lWnd = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop
End Function


 

I needed to get the handle from a partial caption, but that answer didn't work without some modification. It looked like the PtrSafe update maybe was added but not tested. This is what worked for me:

Declare PtrSafe Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
Const WM_CLOSE = &H10
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As LongPtr) As Long
Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As LongLong) As LongLong
Declare PtrSafe Function GetWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal wCmd As Long) As LongPtr
Const GW_HWNDNEXT = 2
Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hwnd As LongPtr) As LongPtr

'_2022_09_20
'get the window pointer from a partial caption
Function fGetHandleFromPartialCaption(strCaption As String) As LongPtr
Dim lnpWindowPointer As LongPtr 'we loop through window pointers
Dim strWindow As String 'and look at the window captions
    fGetHandleFromPartialCaption = 0 'default if nothing found
    
    lnpWindowPointer = FindWindow(vbNullString, vbNullString)   'get the first window pointer
    Do While lnpWindowPointer <> 0  'loop through all the pointers
        If CBool(IsWindowVisible(lnpWindowPointer)) = True Then  'only if window visible
            strWindow = String(GetWindowTextLength(lnpWindowPointer) + 1, Chr$(0))  'for caption
            GetWindowText lnpWindowPointer, strWindow, Len(strWindow)   'get window caption
            If InStr(1, strWindow, strCaption, vbTextCompare) > 0 Then 'look for our caption
                fGetHandleFromPartialCaption = lnpWindowPointer 'return window handle if found
                Exit Do 'done
            End If
        End If
        lnpWindowPointer = GetWindow(lnpWindowPointer, GW_HWNDNEXT) 'else get next window pointer
    Loop
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM