Attribute VB_Name = "modSubClass"
Option Explicit

Private Declare Function SetActiveWindow Lib "user32" (ByVal Hwnd As Long) As Long

Declare Function SetWindowLong Lib "user32" _
   Alias "SetWindowLongA" ( _
   ByVal Hwnd As Long, _
   ByVal nIndex As Long, _
   ByVal dwNewLong As Long _
) As Long

Declare Function CallWindowProc Lib "user32" _
   Alias "CallWindowProcA" ( _
   ByVal lpPrevWndFunc As Long, _
   ByVal Hwnd As Long, _
   ByVal msg As Long, _
   ByVal wParam As Long, _
   ByVal lParam As Long _
) As Long

Public Const GWL_WNDPROC As Long = (-4)
Public Const WM_CAPTION_CHANGED As Long = &H7C
Private Const WM_SETTEXT = &HC
Public Const WM_DESTROY = &H2
Public Const WM_NCDESTROY = &H82
Public Const WM_SHOWWINDOW = &H18

Public m_SubClassList As List
Public m_Perspective As ucPerspective
Public m_ListenCaptionChanged As Boolean

Private Function isIDE() As Boolean

   On Error GoTo ERROR_HANDLE
   
   Debug.Print 1 / 0
   
   Exit Function
   
ERROR_HANDLE:

   isIDE = True

End Function

' Hook a window by its handle.
'
' @lngHwnd The window handle
Public Sub Hook(ByVal lngHwnd As Long)
   
   Dim isHooked As Boolean
   Dim PrevProc As Long

   ' If isIDE Then Exit Sub

   isHooked = Not m_SubClassList.IsEmpty

   If isHooked Then
      isHooked = m_SubClassList.Contains("View_" & lngHwnd)
   End If

   If Not isHooked Then

      PrevProc = SetWindowLong(lngHwnd, GWL_WNDPROC, AddressOf WindowProc)

      m_SubClassList.Add "View_" & lngHwnd, PrevProc

   End If
   
End Sub

' Unhook a window by its handle.
'
' @lngHwnd The window handle
Public Sub UnHook(ByVal lngHwnd As Long)
    
    Dim PrevProc As Long
    
    If m_SubClassList Is Nothing Then Exit Sub
    
    If Not m_SubClassList.IsEmpty Then
       
       PrevProc = m_SubClassList.Item("View_" & lngHwnd)
    
       If PrevProc = 0 Then
          PrevProc = m_SubClassList.Item(1)
       End If
    
       If PrevProc > 0 Then
          SetWindowLong lngHwnd, GWL_WNDPROC, PrevProc
    
          m_SubClassList.Remove "View_" & lngHwnd
       End If
    
    End If
    
End Sub

Public Function WindowProc(ByVal Hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    On Error Resume Next
    
    Dim i As Long
    Dim l_View As View
    Dim l_Folder As Folder
    Dim PrevProc As Long
      
    If m_SubClassList Is Nothing Then
       Exit Function
    End If
          
    Select Case uMsg
  
        Case WM_NCDESTROY 'WM_SHOWWINDOW

            If Not CBool(wParam) Then
            If Not m_Perspective Is Nothing Then

               ' Show the activated view with the window handle
               With m_Views
                  For i = 0 To .Count
                     Set l_View = .Item(i)

                     If l_View.View.Hwnd = Hwnd Then
                        m_Perspective.CloseView l_View.ViewId
                        GoTo Finally
                     End If
                  Next i
               End With
            End If

            Exit Function
            End If
                                    
       ' View or Editor caption has changed
       Case WM_CAPTION_CHANGED
'
'            Debug.Print "lParam = " & lParam
'            Debug.Print "wParam = " & wParam
'
            If Not m_Perspective Is Nothing And _
               m_ListenCaptionChanged And _
               wParam = -20 Then

               ' Get view id of the editor by the window handle
               With m_Editors
                  For i = 0 To .Count
                     Set l_View = .Item(i)

                     If l_View.View.Hwnd = Hwnd Then
                        Exit For
                     Else
                        Set l_View = Nothing
                     End If
                  Next i
               End With

               ' Get view id of the view by the window handle
               With m_Views
                  For i = 0 To .Count
                     Set l_View = .Item(i)

                     If l_View.View.Hwnd = Hwnd Then
                        Exit For
                     Else
                        Set l_View = Nothing
                     End If
                  Next i
               End With

               ' Change capiton and reset style
               If Not l_View Is Nothing Then

                  setWindowStyle Hwnd, vbNone
                  SetWindowPos Hwnd, 0&, 0&, 0&, 0&, 0&, SWP_FRAMECHANGED

                  If Not m_Perspective Is Nothing Then
                  
                     Dim l_Perspective As Perspective
                    ' Dim l_Folder As Folder
                     Set l_Perspective = m_Perspective.Perspectives.Item(m_Perspective.ActivePerspectiveId)
                     
                     With l_Perspective.Folders
                        For i = 0 To .Count
                           Set l_Folder = .Item(i)

                           If l_Folder.Views.Contains(l_View.ViewId) Then
                              m_Perspective.EventRaise "ActivateView", l_Folder.FolderId, l_View.ViewId
                              Exit For
                           End If
                        Next i
                     End With
                     
                  
                  '   m_Perspective.RefreshView l_View.ViewId
                  End If

                  GoTo Finally
               End If

            End If

      ' View / Editor was actived
       Case WM_MOUSEACTIVATE

            If Not m_Perspective Is Nothing Then

               ' Show the activated view with the window handle
               With m_Views
                  For i = 0 To .Count
                     Set l_View = .Item(i)

                     If l_View.View.Hwnd = Hwnd Then
                        m_Perspective.ShowView l_View.ViewId
                        GoTo Finally
                     End If
                  Next i
               End With

            End If
            
   End Select
       
   PrevProc = m_SubClassList.Item("View_" & Hwnd)
       
   WindowProc = CallWindowProc(PrevProc, Hwnd, uMsg, wParam, lParam)
     
Finally:
   
   m_ListenCaptionChanged = True
   Set l_View = Nothing
   Set l_Folder = Nothing
    
End Function

