GetWindowRect function is returning zeros for Solidworks Applications

72 Views Asked by At

I am trying to get the location of a solidworks window on my screen. I'm using the GetWindowRect function to do this. This works for all applications I've tried, except for Solidworks Applications. This is a Solidworks macro so its written in VBA:

Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String _
) As LongPtr
    
Private Declare PtrSafe Function GetWindowRect Lib "user32" ( _
    ByVal hwnd As LongPtr, _
    lpRect As RECT _
) As Long

Private Type RECT
    Left As Long
    Top As Long
    right As Long
    bottom As Long
End Type

Private this As RECT

Public Sub swWindow(lpClassName As String, lpWindowName As String)

    Dim hwnd As LongPtr
    hwnd = FindWindow(lpClassName, lpWindowName)
    
    Dim check As long
    check = GetWindowRect(hwnd, this)
    
    Debug.Print Err.LastDllError
    
End Sub

I get locations for all tested applications (excel, txt, etc), but Solidworks Applications only returns zero values.

  • The "FindWindow" method does return a handle (724300)
  • The "GetWindowRect" method returns a value of 1 (check variable), which means the function was successful.
  • The Err.LastDllError is zero, which indicates nothing went wrong.

But my actual locations being return are all zeros. Anybody out there ran into a similar problem, or know what I'm doing wrong?

Thanks.

1

There are 1 best solutions below

0
On

My problem was my lpWindowName was referencing a child window instead of the parent window. The caption at the top of the screen is the file name. If you use this for lpWindowname, then you'll get the child handle. The correct format to get the parent is "SOLIDWORKS Premium 2022 SP4.0 - [filename]"

To generate this programmatically for the currently active document, and get its parent handler, I did the following:

#If Win64 Then

    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String _
    ) As LongPtr
    
    Private Declare PtrSafe Function GetWindowRect Lib "user32" ( _
        ByVal hWnd As LongPtr, _
        lpRect As rect _
    ) As Long
#Else

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String _
    ) As Long
    
    Private Declare Function GetWindowRect Lib "user32" ( _
        ByVal hWnd As Long, _
        lpRect As rect _
    ) As Long
    
#End If


Private Type rect
    left As Long
    top As Long
    right As Long
    bottom As Long
End Type


Private Type swType
    app As SldWorks.SldWorks
    model As SldWorks.ModelDoc2
    draw As SldWorks.DrawingDoc
End Type

Private Type thisType
    sw As swType
End Type

Private this As thisType

Public Sub centerForm(ByRef myForm As IUserForm)
    Dim windLoc As rect
    Dim boolCheck As Long
    boolCheck = GetWindowRect(windowHandle, windLoc)
end sub



'Returns the window handle for the solidworks model.
#If Win64 Then
    Private Function windowHandle() As LongPtr
#Else
    Private Function windowHandle() As Long
#End If

    Dim fileName As String
    fileName = this.sw.model.getTitle
    
    'this dirtyFlag (astrisk) is added to the caption name when anything
    '   in the solidworks document is not saved or up to date.
    Dim dirtyFlag As String
    If this.sw.model.GetSaveFlag Then _
        dirtyFlag = " *"
    
    Dim caption As String
    caption = swTitle & " - [" & fileName & dirtyFlag & "]"
    
    windowHandle = FindWindow(vbNullString, caption)
    
End Function



'The swApp.RevisionNumber method returns a major.minor version number
'   The major number correlates with the release year, starting with
'   major version 8 for the year 2000, with the year and major version
'   incrementing each year. So the year 2022 will have major version 30
'   The following equation will convert the major version into a year:
'       year = 2000 + major revision - 8
'   The minor version is the service pack (SP) number
Private Function swTitle() As String
    
    'The swTitle should look something like this:
    '   SOLIDWORKS Premium 2022 SP4.0
    
    Dim revision() As String
    revision = split(this.sw.app.RevisionNumber, ".")
    
    Const INITIAL_YEAR As Long = 2000
    Const INITIAL_REV As Long = 8
    Dim year As String
    year = INITIAL_YEAR + revision(0) - INITIAL_REV
    
    Dim SP As String
    SP = revision(1) & "." & revision(2)

    swTitle = "SOLIDWORKS Premium " & year & " SP" & SP
    
End Function