-2

EDIT: "I realized after posting this question that the code does not actually switch to another window but it does get the Window ID Number. thus I modified the question to reflect what the Code actually does. I did get the code to work as 64 bit and will post the answer once I deal with the suggestion from Eugene Astafiev's answer at the bottom."

I have found this code in multiple threads but it was 32 bit and I have attempted to convert it to 64 bit.

Here is what I have:

Option Explicit

Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As LongPtr) As Boolean

Private Const GW_HWNDNEXT = 2
Private Sub Test()

    Dim lhWndP As Long
    If GetHandleFromPartialCaption(lhWndP, "Excel") = True Then
        If IsWindowVisible(lhWndP) = True Then
          MsgBox "Found VISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
        Else
          MsgBox "Found INVISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
        End If
    Else
        MsgBox "Window 'Excel' not found!", vbOKOnly + vbExclamation
    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

    GetHandleFromPartialCaption = False
    lhWndP = FindWindow(vbNullString, vbNullString) 'PARENT WINDOW

    Do While lhWndP <> 0
        sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
        GetWindowText lhWndP, sStr, Len(sStr)
        sStr = Left$(sStr, Len(sStr) - 1)
        If InStr(1, sStr, sCaption) > 0 Then
            GetHandleFromPartialCaption = True
            lWnd = lhWndP
            Exit Do
        End If
        lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
    Loop

End Function

When I run the SUB it gets to the last line of the Function and I get this error message: enter image description here

It took a lot of searching to find the 64 bit adjustment to the declarations is there something I missed?

Update: After posting the question I discovered that I had not declared the FindWindow Function as LongPtr.

I corrected it according to what I had found at jkp-ads.com but now I get the Type mismatch error at the beginning.

enter image description here

DryBSMT
  • 51
  • 2
  • 12

1 Answers1

0

To write for all versions of Office use a combination of the newer VBA7 and Win64 conditional Compiler Constants.

VBA7 determines if code is running in version 7 of the VB editor (VBA version shipped in Office 2010+).

#If VBA7 Then 
 Declare PtrSafe Sub... 
#Else 
 Declare Sub... 
#EndIf

Declare statements with the PtrSafe keyword is the recommended syntax. Declare statements that include PtrSafe work correctly in the VBA7 development environment on both 32-bit and 64-bit platforms.

Win64 determines which version (32-bit or 64-bit) of Office is running.

#if Vba7 then 
'  Code is running in the new VBA7 editor 
     #if Win64 then 
     '  Code is running in 64-bit version of Microsoft Office 
     #else 
     '  Code is running in 32-bit version of Microsoft Office 
     #end if 
#else 
' Code is running in VBA version 6 or earlier 
#end if 

Read more about that in the 64-bit Visual Basic for Applications overview article.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Thank you Eugene. our environment is all 64 bit running Office365 but I was going to include this modification for others searching for this same answer. However, when I include the 32 bit Functions, the editor flags them in Red and says they must be updated for use on 64 bit systems. I assume I can ignore that since my system is 64 bit which is why I am getting the warning? – DryBSMT Jan 26 '23 at 15:26
  • Try using conditional compiler constants described in my post. – Eugene Astafiev Jan 26 '23 at 15:35
  • I did use #If VBA7 Then, #Else, #End If. See (https://www.dropbox.com/s/mqlvl4boi15w7gr/Screenshot%202023-01-26%20110229.png?dl=0) – DryBSMT Jan 26 '23 at 16:05
  • While this suggestion is correct for those who seek to support Office 2007 and older (apart from the use of `#Win64` which is [not needed](https://stackoverflow.com/a/56940710/11683)), it does not seem to be related to the problems described in the question. – GSerg Jan 27 '23 at 08:56