vbAccelerator - Contents of code file: cNCCalcSize.cls

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "cNCCalcSize"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit

' =========================================================================
' cNCCalcSize
'
' Copyright  2000 Steve McMahon (steve@vbaccelerator.com)
'
' Allows you to significantly modify the title and
' borders for a window.
'
' 18 Jan 2003
' Don't allow window to move when maximised
'
' -------------------------------------------------------------------------
' Visit vbAccelerator at http://vbaccelerator.com
' =========================================================================

Private Type POINTS
   x  As Integer
   y  As Integer
End Type
Private Type WINDOWPOS
   hwnd As Long
   hWndInsertAfter As Long
   x As Long
   y As Long
   cx As Long
   cy As Long
   flags As Long
End Type
Private Type NCCALCSIZE_PARAMS
   rgrc(0 To 2) As RECT
   lppos As Long 'WINDOWPOS
End Type

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal
 hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

Private Declare Function InflateRect Lib "user32" (lpRect As RECT, ByVal x As
 Long, ByVal y As Long) As Long
Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As
 Long, ByVal y As Long) As Long
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal x As
 Long, ByVal y As Long) As Long

Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long)
 As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long,
 lpPoint As POINTAPI) As Long
Private Declare Function MapWindowPoints Lib "user32" (ByVal hwndFrom As Long,
 ByVal hwndTo As Long, lppt As Any, ByVal cPoints As Long) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal
 hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, lpsz2 As Any) As
 Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect
 As RECT) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As
 Long
Private Declare Function IsZoomed Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA"
 (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Any) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA"
 (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long)
 As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal
 hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long,
 ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long)
 As Long
Private Declare Function RedrawWindow Lib "user32" (ByVal hwnd As Long,
 lprcUpdate As Any, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function CreateDCAsNull Lib "gdi32" Alias "CreateDCA" (ByVal
 lpDriverName As String, lpDeviceName As Any, lpOutput As Any, lpInitData As
 Any) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As
 Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long,
 ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc
 As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal
 hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As
 Long

Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function GetSysColorBrush Lib "user32" (ByVal nIndex As Long)
 As Long
Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As
 RECT, ByVal hBrush As Long) As Long

Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As
 Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal
 hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long)
 As Long

Private Declare Function DrawFrameControl Lib "user32" (ByVal lHDC As Long, tR
 As RECT, ByVal eFlag As Long, ByVal eStyle As Long) As Long
Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT,
 ByVal edge As Long, ByVal grfFlags As Long) As Long
Private Declare Function DrawCaptionAPI Lib "user32" Alias "DrawCaption" (ByVal
 hwnd As Long, ByVal hdc As Long, pcRect As RECT, ByVal un As Long) As Long

Private Declare Function SetMenu Lib "user32" (ByVal hwnd As Long, ByVal hMenu
 As Long) As Long
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dX
 As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

' mouseevent
Private Const MOUSEEVENTF_ABSOLUTE = &H8000 '  absolute move
Private Const MOUSEEVENTF_LEFTDOWN = &H2 '  left button down
Private Const MOUSEEVENTF_LEFTUP = &H4 '  left button up
Private Const MOUSEEVENTF_MIDDLEDOWN = &H20 '  middle button down
Private Const MOUSEEVENTF_MIDDLEUP = &H40 '  middle button up
Private Const MOUSEEVENTF_MOVE = &H1 '  mouse move
Private Const MOUSEEVENTF_RIGHTDOWN = &H8 '  right button down
Private Const MOUSEEVENTF_RIGHTUP = &H10 '  right button up

' SysMetrics
Private Const SM_CXBORDER = 5
Private Const SM_CXDLGFRAME = 7
Private Const SM_CXFIXEDFRAME = SM_CXDLGFRAME
Private Const SM_CXFRAME = 32
Private Const SM_CXHSCROLL = 21
Private Const SM_CXVSCROLL = 2
Private Const SM_CYCAPTION = 4
Private Const SM_CYDLGFRAME = 8
Private Const SM_CYFIXEDFRAME = SM_CYDLGFRAME
Private Const SM_CYFRAME = 33
Private Const SM_CYHSCROLL = 3
Private Const SM_CYMENU = 15
Private Const SM_CYSMSIZE = 31
Private Const SM_CXSMSIZE = 30

' DrawFrameControl:
Private Const DFC_CAPTION = 1
Private Const DFC_MENU = 2
Private Const DFC_SCROLL = 3
Private Const DFC_BUTTON = 4
'#if(WINVER >= =&H0500)
Private Const DFC_POPUPMENU = 5
'#endif /* WINVER >= =&H0500 */

Private Const DFCS_CAPTIONCLOSE = &H0
Private Const DFCS_CAPTIONMIN = &H1
Private Const DFCS_CAPTIONMAX = &H2
Private Const DFCS_CAPTIONRESTORE = &H3
Private Const DFCS_CAPTIONHELP = &H4

Private Const DFCS_INACTIVE = &H100
Private Const DFCS_PUSHED = &H200
Private Const DFCS_CHECKED = &H400

' DrawEdge:
Private Const BDR_RAISEDOUTER = &H1
Private Const BDR_SUNKENOUTER = &H2
Private Const BDR_RAISEDINNER = &H4
Private Const BDR_SUNKENINNER = &H8

Private Const BDR_OUTER = &H3
Private Const BDR_INNER = &HC
Private Const BDR_RAISED = &H5
Private Const BDR_SUNKEN = &HA

Private Const EDGE_RAISED = (BDR_RAISEDOUTER Or BDR_RAISEDINNER)
Private Const EDGE_SUNKEN = (BDR_SUNKENOUTER Or BDR_SUNKENINNER)
Private Const EDGE_ETCHED = (BDR_SUNKENOUTER Or BDR_RAISEDINNER)
Private Const EDGE_BUMP = (BDR_RAISEDOUTER Or BDR_SUNKENINNER)

Private Const BF_LEFT = &H1
Private Const BF_TOP = &H2
Private Const BF_RIGHT = &H4
Private Const BF_BOTTOM = &H8

Private Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
Private Const BF_TOPRIGHT = (BF_TOP Or BF_RIGHT)
Private Const BF_BOTTOMLEFT = (BF_BOTTOM Or BF_LEFT)
Private Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
Private Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)

' Map WIndow Points
Private Const HWND_DESKTOP = 0

' Redraw window:
Private Const RDW_ALLCHILDREN = &H80
Private Const RDW_ERASE = &H4
Private Const RDW_ERASENOW = &H200
Private Const RDW_FRAME = &H400
Private Const RDW_INTERNALPAINT = &H2
Private Const RDW_INVALIDATE = &H1
Private Const RDW_NOCHILDREN = &H40
Private Const RDW_NOERASE = &H20
Private Const RDW_NOFRAME = &H800
Private Const RDW_NOINTERNALPAINT = &H10
Private Const RDW_UPDATENOW = &H100
Private Const RDW_VALIDATE = &H8

' Sys colours:
Private Const COLOR_WINDOWFRAME = 6
Private Const COLOR_BTNFACE = 15
Private Const COLOR_BTNTEXT = 18
Private Const COLOR_INACTIVECAPTION = 3
Private Const COLOR_ACTIVEBORDER = 10
Private Const COLOR_ACTIVECAPTION = 2
Private Const COLOR_INACTIVEBORDER = 11

' Window MEssages
Private Const WM_DESTROY = &H2
Private Const WM_ACTIVATE = &H6
Private Const WM_PAINT = &HF
Private Const WM_SETTEXT = &HC
Private Const WM_ACTIVATEAPP = &H1C
Private Const WM_SETCURSOR = &H20
'Private Const WM_CHILDACTIVATE = &H22
Private Const WM_STYLECHANGING = &H7C
Private Const WM_STYLECHANGED = &H7D
Private Const WM_NCCALCSIZE = &H83
Private Const WM_NCPAINT = &H85
Private Const WM_NCHITTEST = &H84
Private Const WM_NCACTIVATE = &H86
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const WM_NCLBUTTONUP = &HA2
Private Const WM_NCLBUTTONDBLCLK = &HA3
Private Const WM_SYSCOMMAND = &H112
Private Const WM_INITMENU = &H116
Private Const WM_INITMENUPOPUP = &H117
Private Const WM_MDIGETACTIVE = &H229

' flags for DrawCaption
Private Const DC_ACTIVE = &H1
Private Const DC_SMALLCAP = &H2
Private Const DC_ICON = &H4
Private Const DC_TEXT = &H8
Private Const DC_INBUTTON = &H10
Private Const DC_GRADIENT = &H20

' WM_NCCALCSIZE return values;
Private Const WVR_ALIGNBOTTOM = &H40
Private Const WVR_ALIGNLEFT = &H20
Private Const WVR_ALIGNRIGHT = &H80
Private Const WVR_ALIGNTOP = &H10
Private Const WVR_HREDRAW = &H100
Private Const WVR_VALIDRECTS = &H400
Private Const WVR_VREDRAW = &H200
Private Const WVR_REDRAW = (WVR_HREDRAW Or WVR_VREDRAW)

' Window Long:
Private Const GWL_STYLE = (-16)
Private Const GWL_EXSTYLE = (-20)
Private Const GWL_USERDATA = (-21)
Private Const GWL_WNDPROC = -4
Private Const GWL_HWNDPARENT = (-8)

'Window Styles:
Private Const WS_BORDER = &H800000
Private Const WS_CAPTION = &HC00000                  '  WS_BORDER Or WS_DLGFRAME
Private Const WS_CHILD = &H40000000
Private Const WS_CLIPCHILDREN = &H2000000
Private Const WS_CLIPSIBLINGS = &H4000000
Private Const WS_DISABLED = &H8000000
Private Const WS_DLGFRAME = &H400000
Private Const WS_GROUP = &H20000
Private Const WS_HSCROLL = &H100000
Private Const WS_MAXIMIZE = &H1000000
Private Const WS_MAXIMIZEBOX = &H10000
Private Const WS_MINIMIZE = &H20000000
Private Const WS_MINIMIZEBOX = &H20000
Private Const WS_OVERLAPPED = &H0&
Private Const WS_POPUP = &H80000000
Private Const WS_SYSMENU = &H80000
Private Const WS_TABSTOP = &H10000
Private Const WS_THICKFRAME = &H40000
Private Const WS_VISIBLE = &H10000000
Private Const WS_VSCROLL = &H200000
Private Const WS_SIZEBOX = WS_THICKFRAME

Private Const WS_EX_TOPMOST = &H8&
Private Const WS_EX_TOOLWINDOW = &H80&
Private Const CW_USEDEFAULT = &H80000000

' SetWIndowPos
Private Const HWND_TOPMOST = -1
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOREDRAW = &H8
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_FRAMECHANGED = &H20        '  The frame changed: send
 WM_NCCALCSIZE
Private Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Private Const SWP_HIDEWINDOW = &H80
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_NOCOPYBITS = &H100
Private Const SWP_NOOWNERZORDER = &H200      '  Don't do owner Z ordering
Private Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Private Const SWP_NOZORDER = &H4

Implements ISubclass

Public Enum ECNCSysCommandConstants
   SC_ARRANGE = &HF110&
   SC_CLOSE = &HF060&
   SC_MAXIMIZE = &HF030&
   SC_MINIMIZE = &HF020&
   SC_MOVE = &HF010&
   SC_NEXTWINDOW = &HF040&
   SC_PREVWINDOW = &HF050&
   SC_RESTORE = &HF120&
   SC_SIZE = &HF000&
End Enum

Public Enum ECNCHitTestConstants
   HTBORDER = 18
   HTBOTTOM = 15
   HTBOTTOMLEFT = 16
   HTBOTTOMRIGHT = 17
   HTCAPTION = 2
   HTCLIENT = 1
   HTGROWBOX = 4
   HTHSCROLL = 6
   HTLEFT = 10
   HTMAXBUTTON = 9
   HTMENU = 5
   HTMINBUTTON = 8
   HTNOWHERE = 0
   HTRIGHT = 11
   HTSYSMENU = 3
   HTTOP = 12
   HTTOPLEFT = 13
   HTTOPRIGHT = 14
   HTVSCROLL = 7
End Enum
Public Enum ECNCDrawMethodConstants
   ECNCModifyNonClientArea = 0
   ECNCUseClientArea = 1
End Enum

' Window handles:
Private m_hWnd As Long
Private m_hWndMDIClient As Long
Private m_bIsMDIChild As Boolean

' Menu handle
Private m_hMenu As Long
' App activate & window activation state:
Private m_bActive As Boolean
Private m_bAppActive As Boolean
' Is our MDI Child zoomed in or not?
Private m_bZoomedMDIChild As Boolean
' MemDC for title bar drawing:
Private m_hDC As Long
Private m_hBmp As Long
Private m_hBmpOld As Long
' Maximized MDI Child?
Private m_bState As Boolean
' Borders:
Private m_lLeft As Long, m_lTop As Long
Private m_lRight As Long, m_lBottom As Long
' Last HitTest result
Private m_eLastHT As ECNCHitTestConstants

Private m_eMethod As ECNCDrawMethodConstants

Public Sub Redraw(hwnd As Long)
   RedrawWindow hwnd, ByVal 0&, 0, RDW_UPDATENOW Or RDW_INVALIDATE Or
    RDW_INTERNALPAINT Or RDW_ALLCHILDREN
End Sub
Public Sub Display(f As Object)
   'f.Show
   On Error Resume Next
   f.Refresh
   SetWindowPos m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOZORDER
    Or SWP_NOOWNERZORDER Or SWP_FRAMECHANGED
End Sub
Public Property Get WindowActive() As Boolean
   WindowActive = m_bActive
End Property
Public Property Get AppActive() As Boolean
   AppActive = m_bAppActive
End Property

Public Sub TitleBarMouseDown()
Dim tPS As POINTS
Dim tP As POINTAPI
   GetCursorPos tP
   tPS.x = tP.x: tPS.y = tP.y
   ReleaseCapture
   SendMessage m_hWnd, WM_NCLBUTTONDOWN, HTCAPTION, tPS
End Sub
Public Sub SysCommand(ByVal eCmd As ECNCSysCommandConstants)
   PostMessage m_hWnd, WM_SYSCOMMAND, eCmd, 0
End Sub

Public Sub Attach(ByVal iTo As INCAreaModifier)
Dim lHDC As Long
   
   Detach
   
   m_hWnd = iTo.hwnd
   m_hMenu = GetMenu(m_hWnd)
   
   m_bIsMDIChild = IsMDIChildForm(m_hWnd)
   
   m_eMethod = iTo.Method
   
   If (m_eMethod = ECNCModifyNonClientArea) Then
   
      ' Allows us to remove menu bar, caption etc:
      AttachMessage Me, m_hWnd, WM_NCCALCSIZE
      ' Handle drawing borders, caption etc ourselves:
      AttachMessage Me, m_hWnd, WM_NCPAINT
      ' Win redraws caption during NCACTIVATE:
      AttachMessage Me, m_hWnd, WM_NCACTIVATE
      ' On NC Button Down, Win redraws the min/max/close buttons:
      AttachMessage Me, m_hWnd, WM_NCLBUTTONDOWN
      ' Check for button up so we can notify client:
      AttachMessage Me, m_hWnd, WM_NCLBUTTONUP
      ' on NC double click, Win redraws the min/max/close buttons:
      AttachMessage Me, m_hWnd, WM_NCLBUTTONDBLCLK
      ' Allows us to use the default implementations
      ' for hittest events:
      AttachMessage Me, m_hWnd, WM_NCHITTEST
      ' Hack:
      AttachMessage Me, m_hWnd, WM_SETCURSOR
      ' On SysMenu Show, Win redraws the min/max/close buttons:
      AttachMessage Me, m_hWnd, WM_INITMENU
      AttachMessage Me, m_hWnd, WM_INITMENUPOPUP
      ' On ChangeStyle, Win redraws the entire caption:
      
      AttachMessage Me, m_hWnd, WM_STYLECHANGED
      
      ' On SetText, Win redraws the entire caption:
      AttachMessage Me, m_hWnd, WM_SETTEXT
      ' Checking for activateapp:
      AttachMessage Me, m_hWnd, WM_ACTIVATEAPP
      
      ' EnterMenuLoop
      AttachMessage Me, m_hWnd, WM_ENTERMENULOOP
      ' ExitMenuLoop
      AttachMessage Me, m_hWnd, WM_EXITMENULOOP
      
      If m_bIsMDIChild Then
         AttachMessage Me, m_hWnd, WM_SIZE
      End If
      
      ' So we can automatically detach ourselves when the parent closes:
      AttachMessage Me, m_hWnd, WM_DESTROY
   
   Else
   
      AttachMessage Me, m_hWnd, WM_NCHITTEST
      AttachMessage Me, m_hWnd, WM_NCLBUTTONDOWN
      AttachMessage Me, m_hWnd, WM_NCLBUTTONUP
      AttachMessage Me, m_hWnd, WM_ACTIVATE
      AttachMessage Me, m_hWnd, WM_DESTROY
   
   
   End If
   
   lHDC = CreateDCAsNull("DISPLAY", ByVal 0&, ByVal 0&, ByVal 0&)
   m_hDC = CreateCompatibleDC(lHDC)
   m_hBmp = CreateCompatibleBitmap(lHDC, Screen.Width \ Screen.TwipsPerPixelX,
    GetSystemMetrics(SM_CYCAPTION) * 4)
   DeleteDC lHDC
   m_hBmpOld = SelectObject(m_hDC, m_hBmp)
   
   m_hWndMDIClient = FindWindowEx(m_hWnd, 0, "MDIClient", ByVal 0&)
      
   SetProp m_hWnd, "vbalCNCImplementation", ObjPtr(iTo)
   
   AttachKeyboardHook Me
   
End Sub
Public Property Get hMenu() As Long
   hMenu = m_hMenu
End Property
Public Sub Detach()
   DetachKeyboardHook Me
   If m_hWnd <> 0 Then
      If (m_eMethod = ECNCModifyNonClientArea) Then
         DetachMessage Me, m_hWnd, WM_NCCALCSIZE
         DetachMessage Me, m_hWnd, WM_NCPAINT
         DetachMessage Me, m_hWnd, WM_NCACTIVATE
         DetachMessage Me, m_hWnd, WM_NCLBUTTONDOWN
         DetachMessage Me, m_hWnd, WM_NCLBUTTONUP
         DetachMessage Me, m_hWnd, WM_NCLBUTTONDBLCLK
         DetachMessage Me, m_hWnd, WM_NCHITTEST
         
         DetachMessage Me, m_hWnd, WM_SETCURSOR
         
         DetachMessage Me, m_hWnd, WM_INITMENU
         DetachMessage Me, m_hWnd, WM_INITMENUPOPUP
         
         
         DetachMessage Me, m_hWnd, WM_STYLECHANGED
         
         DetachMessage Me, m_hWnd, WM_SETTEXT
         
         DetachMessage Me, m_hWnd, WM_ACTIVATEAPP
         
         DetachMessage Me, m_hWnd, WM_ENTERMENULOOP
         DetachMessage Me, m_hWnd, WM_EXITMENULOOP
         
         If m_bIsMDIChild Then
            DetachMessage Me, m_hWnd, WM_SIZE
            m_bIsMDIChild = False
         End If
         
         DetachMessage Me, m_hWnd, WM_DESTROY
      Else
      
         DetachMessage Me, m_hWnd, WM_NCHITTEST
         DetachMessage Me, m_hWnd, WM_NCLBUTTONDOWN
         DetachMessage Me, m_hWnd, WM_NCLBUTTONUP
         DetachMessage Me, m_hWnd, WM_ACTIVATE
         DetachMessage Me, m_hWnd, WM_DESTROY
      
      End If
      
   End If
   If m_hDC <> 0 Then
      If m_hBmpOld <> 0 Then
         SelectObject m_hDC, m_hBmp
         m_hBmpOld = 0
      End If
      If m_hBmp <> 0 Then
         DeleteObject m_hBmp
         m_hBmp = 0
      End If
      If m_hDC <> 0 Then
         DeleteDC m_hDC
         m_hDC = 0
      End If
   End If
   RemoveProp m_hWnd, "vbalCNCImplementation"
   m_hWnd = 0
   m_hWndMDIClient = 0
   m_hMenu = 0
End Sub

Friend Function AltKeyAccelerator(ByVal vKey As KeyCodeConstants) As Long
Dim Implementation As INCAreaModifier
   If GetImplementation(Implementation) Then
      AltKeyAccelerator = Implementation.AltKeyAccelerator(vKey)
   End If
End Function

Private Sub pShowMDIButtons(ByVal hwnd As Long, ByVal bState As Boolean)
   m_bState = bState
End Sub

Private Sub MyMoveWindow()
Dim tPInit As POINTAPI
Dim tPLast As POINTAPI
Dim tP As POINTAPI
Dim tR As RECT
Dim hWndParent As Long
Dim tWRInit As RECT
Dim dX As Long, dy As Long
Dim lStyle As Long
      
   ' Check if window maximised:
   lStyle = GetWindowLong(m_hWnd, GWL_STYLE)
   If ((lStyle And WS_MAXIMIZE) = WS_MAXIMIZE) Then
      Exit Sub
   End If
      
   GetWindowRect m_hWnd, tR
   hWndParent = GetParent(m_hWnd)
   If Not hWndParent = 0 Then
      MapWindowPoints HWND_DESKTOP, hWndParent, tR, 2
   End If
   GetCursorPos tPInit
   LSet tPLast = tPInit
   Do While Not (GetAsyncKeyState(vbLeftButton) = 0) And m_bActive
      GetCursorPos tP
      If tP.x <> tPLast.x Or tP.y <> tPLast.y Then
         ' Moved:
         dX = tP.x - tPLast.x
         dy = tP.y - tPLast.y
         SetWindowPos m_hWnd, 0, tR.left + dX, tR.top + dy, 0, 0, SWP_NOSIZE Or
          SWP_NOZORDER Or SWP_NOOWNERZORDER
         LSet tPLast = tP
         GetWindowRect m_hWnd, tR
         If Not hWndParent = 0 Then
            MapWindowPoints HWND_DESKTOP, hWndParent, tR, 2
         End If
      End If
      DoEvents
      Sleep 1
   Loop
   
End Sub

Private Sub Class_Terminate()
   Detach
End Sub

Private Property Let ISubclass_MsgResponse(ByVal RHS As EMsgResponse)
   '
End Property

Private Property Get ISubclass_MsgResponse() As EMsgResponse
   
   'LogEvent "ISubClass_MsgResponse " & CurrentMessage
   
   If (m_eMethod = ECNCModifyNonClientArea) Then
      Select Case CurrentMessage
      Case WM_NCPAINT, WM_NCLBUTTONDOWN, _
            WM_NCLBUTTONDBLCLK, _
            WM_INITMENUPOPUP, WM_INITMENU, _
            WM_SETCURSOR, _
            WM_STYLECHANGED, WM_SETTEXT, _
            WM_NCHITTEST, WM_SIZE, _
            WM_ENTERMENULOOP, WM_EXITMENULOOP
         ISubclass_MsgResponse = emrConsume
      Case Else
         ' ActiveApp, Destroy:
         ISubclass_MsgResponse = emrPreprocess
      End Select
   Else
      Select Case CurrentMessage
      Case WM_PAINT
         ISubclass_MsgResponse = emrConsume
      Case Else
         ISubclass_MsgResponse = emrPreprocess
      End Select
   End If
   
End Property

Private Function ISubclass_WindowProc(ByVal hwnd As Long, ByVal iMsg As Long,
 ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tNCR As NCCALCSIZE_PARAMS
Dim tWP As WINDOWPOS
Dim tP As POINTAPI
Dim tR As RECT
Dim lhWnd As Long
Dim lpfMaximised As Long
Dim lPtr As Long
Dim hdc As Long
Dim lStyle As Long, lNewStyle As Long
Dim eHt As ECNCHitTestConstants
Static s_dx As Long
Static s_dy As Long
Dim bCanSize As Boolean
Dim Implementation As INCAreaModifier
Dim bHandled As Boolean
Static s_bNoStyleChangeProcessing As Boolean
Static s_bChildActivate As Boolean

   
   'LogEvent "ISubClass_WindowProc " & hwnd & "," & iMsg & "," & wParam & "," &
    lParam
   Select Case iMsg
   
   Case WM_DESTROY
      ' Goodbye!
      Detach
   
   Case WM_ACTIVATEAPP
      '
      ' This is for detecting which app is active
      '
      m_bAppActive = Not (wParam = 0)
   
   Case Else
   
      ' ======================================================
      ' Modify Non-Client Area
      ' ======================================================
      If (m_eMethod = ECNCModifyNonClientArea) Then
   
         Select Case iMsg
         Case WM_NCPAINT
            ' Due to processing elsewhere in this subclass, we
            ' might inadvertently be drawing when the window
            ' is being closed or invisible.  Check before
            ' drawing:
            If Not (IsWindowVisible(hwnd) = 0) Then
            
               m_bZoomedMDIChild = (IsMDIChildForm(hwnd) And (IsZoomed(hwnd) <>
                0))
               If m_bZoomedMDIChild Then
                  'ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam,
                   lParam)
               Else
                  ' Get the non-client DC to draw in:
                  hdc = GetWindowDC(m_hWnd)
                              
                  GetWindowRect m_hWnd, tR
                  OffsetRect tR, -tR.left, -tR.top
                           
                  If GetImplementation(Implementation) Then
                     Implementation.NCPaint hdc, tR.left, tR.top, tR.right,
                      tR.bottom
                  Else
                     DefaultNCPaint hdc, tR.left, tR.top, tR.right, tR.bottom
                  End If
                  
                  ReleaseDC m_hWnd, hdc
               End If
               
            End If
               
         Case WM_NCHITTEST
            
            If GetImplementation(Implementation) Then
               eHt = pGetHitTestCode()
               m_eLastHT = eHt
               If eHt = HTMENU Then
                  ' Cannot allow windows to have this; if you
                  ' mouse down on menu or caption then windows
                  ' redraws the caption on top...
                  ISubclass_WindowProc = HTCLIENT
               Else
                  ISubclass_WindowProc = eHt
               End If
               
            Else
               ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
            End If
            
         Case WM_NCLBUTTONDOWN
            '
            ' a hack.
            '
            ' Win suspends when we do a NC Button down.  It also
            ' redraws the min/max/close buttons. We can force them
            ' to go away by moving the mouse
            '
            If s_dx = 0 Then s_dx = 1
            If s_dy = 0 Then s_dy = 1
            s_dx = -1 * s_dx: s_dy = -1 * s_dy
            mouse_event MOUSEEVENTF_MOVE, s_dx, s_dy, 0, 0
            
            ' We cannot allow Windows to do the default HTCAPTION action,
            ' because it redraws the caption during the move.  THerefore
            ' swallow HTCAPTION events and reimplement window moving
            ' ourselves:
            wParam = pGetHitTestCode()
            If GetImplementation(Implementation) Then
               If m_bActive Then
                  If m_eLastHT = HTCAPTION Then
                     MyMoveWindow
                     Exit Function
                  End If
               Else
                  If m_eLastHT = HTCAPTION Then
                     SetForegroundWindow m_hWnd
                     MyMoveWindow
                     Exit Function
                  End If
               End If
               
               GetCursorPos tP
               GetWindowRect m_hWnd, tR
               tP.x = tP.x - tR.left: tP.y = tP.y - tR.top
               OffsetRect tR, -tR.left, -tR.top
               hdc = GetWindowDC(m_hWnd)
               Implementation.NCMouseDown tP.x, tP.y, bHandled, hdc, tR.left,
                tR.top, tR.right, tR.bottom
               ReleaseDC m_hWnd, hdc
               If bHandled Then
                  Exit Function
               End If
                        
            End If
            
            ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
             lParam)
            
            ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
            
         
         Case WM_NCLBUTTONUP
            If GetImplementation(Implementation) Then
               GetCursorPos tP
               GetWindowRect m_hWnd, tR
               tP.x = tP.x - tR.left: tP.y = tP.y - tR.top
               OffsetRect tR, -tR.left, -tR.top
               hdc = GetWindowDC(m_hWnd)
               Implementation.NCMouseDown tP.x, tP.y, bHandled, hdc, tR.left,
                tR.top, tR.right, tR.bottom
               ReleaseDC m_hWnd, hdc
               Implementation.NCMouseUp tP.x, tP.y, hdc, tR.left, tR.top,
                tR.right, tR.bottom
            End If
               
         Case WM_SETCURSOR
            '
            ' a Very Nasty Hack :)
            ' discovered by watching NeoPlanet and MSOffice
            ' in Spy++
            '
            ' Without this, Win will redraw caption areas and
            ' min/max/close buttons whenever the mouse is released
            ' following a NC mouse down.
            '
            s_bNoStyleChangeProcessing = True
            lStyle = GetWindowLong(m_hWnd, GWL_STYLE)
            lNewStyle = lStyle And Not WS_VISIBLE
            'lNewStyle = lStyle And Not (WS_MAXIMIZEBOX Or WS_MINIMIZEBOX)
            SetWindowLong m_hWnd, GWL_STYLE, lNewStyle
            ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam, lParam)
            If GetMenu(m_hWnd) <> 0 Then
               SetMenu m_hWnd, 0
            End If
            SetWindowLong m_hWnd, GWL_STYLE, lStyle
            s_bNoStyleChangeProcessing = False
         
         Case WM_INITMENU
            ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
             lParam)
            
            ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
            
            
      '   Case WM_CHILDACTIVATE
      '      If Not s_bChildActivate Then
      '         s_bChildActivate = True
      '         ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
       lParam)
      '
      '         ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
      '
      '         s_bChildActivate = False
      '      End If
            
         Case WM_SIZE
            '
            ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
             lParam)
            
            ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
            
         
         Case WM_INITMENUPOPUP
            '
            ' During a WM_INITMENUPOPUP, the system redraws the
            ' min/max/close buttons.
            '
            
            ' Check HiWord of lParam to see whether this is
            ' a SysMenu:
            If Not (lParam And &HFFFF0000) = 0 Then
               ' Sys Menu:
               ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
               
               ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
               
            Else
               ' App Menu:
               ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
               
               ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
               
               If GetImplementation(Implementation) Then
                  Implementation.InitMenuPopup wParam, lParam
               End If
            End If
            
         Case WM_ENTERMENULOOP, WM_EXITMENULOOP
            ISubclass_MsgResponse = CallOldWindowProc(hwnd, iMsg, wParam,
             lParam)
            
            ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
            
            If iMsg = WM_EXITMENULOOP Then
               If GetImplementation(Implementation) Then
                  Implementation.ExitMenuLoop
               End If
            End If
            
         Case WM_SETTEXT, WM_STYLECHANGED, WM_NCLBUTTONDBLCLK
            '
            ' The whole title bar is repainted by the defwindowproc.
            ' Therefore redraw once complete:
            '
            If Not s_bNoStyleChangeProcessing Then
               ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
               
               ISubclass_WindowProc hwnd, WM_NCPAINT, 0, 0
               
            Else
               ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
            End If
            
         Case WM_NCCALCSIZE
            '
            ' No Hacks!
            '
            ' This simply tells windows to modify the client
            ' area to the appropriate size:
            '
            
            ' First set the zoomed MDI Child flag:
            m_bZoomedMDIChild = (IsMDIChildForm(hwnd) And (IsZoomed(hwnd) <> 0))
            If wParam <> 0 Then
            
               ' Get the structure pointed to by lParam:
               CopyMemory tNCR, ByVal lParam, Len(tNCR)
               CopyMemory tWP, ByVal tNCR.lppos, Len(tWP)
               
               'pDebugCalcSize tNCR
               With tNCR.rgrc(0)
                  ' Set these
                  .left = tWP.x
                  .top = tWP.y
                  .right = tWP.x + tWP.cx
                  .bottom = tWP.y + tWP.cy
                              
                  ' Defaults
                  m_lLeft = GetSystemMetrics(SM_CXFRAME)
                  m_lRight = m_lLeft
                  m_lTop = GetSystemMetrics(SM_CYCAPTION) +
                   GetSystemMetrics(SM_CYFRAME)
                  m_lBottom = GetSystemMetrics(SM_CYFRAME)
                  
                  ' If the window in question is an MDI child, then we
                  ' ant to ensure that the standard settings get sent
                  ' back to windows: to prevent drawing additional borders,
                  ' which aren't required:
                  If Not m_bZoomedMDIChild Then
                     ' If the implementation is valid then request the
                     ' physical size of the title bar and borders:
                     If GetImplementation(Implementation) Then
                        Implementation.GetLeftMarginWidth m_lLeft
                        Implementation.GetTopMarginHeight m_lTop
                        Implementation.GetRightMarginWidth m_lRight
                        Implementation.GetBottomMarginHeight m_lBottom
                     End If
                  End If
                  
                  ' Set our physical left/top/right/bottom values:
                  .left = .left + m_lLeft
                  .top = .top + m_lTop
                  .right = .right - m_lRight - 1
                  .bottom = .bottom - m_lBottom - 1
               End With
               
               ' Return the new client area size to windows:
               LSet tNCR.rgrc(1) = tNCR.rgrc(0)
               CopyMemory ByVal lParam, tNCR, Len(tNCR)
               ISubclass_WindowProc = WVR_VALIDRECTS
               
            Else
               ' lParam points to a rectangle
               ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam,
                lParam)
            End If
                     
            ' Check for the active window:
            'lPtr = VarPtr(lpfMaximised)
            'If Not m_hWndMDIClient = 0 Then
            '   lhWnd = SendMessageLong(m_hWndMDIClient, WM_MDIGETACTIVE, 0,
             lPtr)
            '   pShowMDIButtons lhWnd, (lpfMaximised <> 0)
            'End If
            
         Case WM_NCACTIVATE
            '
            ' When we get a NC Activate The title bar is
            ' being redrawn to show active or inactive states.
            '
            ' This processing ensures the title bar is updated
            ' correctly following state change:
            '
            
            ' We must call the defwindowproc otherwise VB goes
            ' funny.  This draws a full titlebar:
            '
            m_bActive = Not (wParam = 0)
            ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam, lParam)
            
            ' Now fix it:
            
            ISubclass_WindowProc m_hWnd, WM_NCPAINT, 0, 0
            
            Redraw m_hWnd
            
         End Select
      
      ' ======================================================
      ' End Modify Non-Client Area
      ' ======================================================
         
      Else
      
      ' ======================================================
      ' Draw on Client Area
      ' ======================================================
         Select Case iMsg
         Case WM_ACTIVATE
            m_bActive = Not (wParam = 0)
            Debug.Print m_bActive
            If GetImplementation(Implementation) Then
               Implementation.NCPaint 0, 0, 0, 0, 0
            End If
            
         Case WM_NCHITTEST
            If GetImplementation(Implementation) Then
               eHt = pGetHitTestCode()
               m_eLastHT = eHt
               If eHt = HTMENU Then
                  ' Cannot allow windows to have this; if you
                  ' mouse down on menu or caption then windows
                  ' redraws the caption on top...
                  ISubclass_WindowProc = HTCLIENT
               Else
                  ISubclass_WindowProc = eHt
               End If
            End If
         
         Case WM_NCLBUTTONDOWN
            If GetImplementation(Implementation) Then
               GetCursorPos tP
               GetWindowRect m_hWnd, tR
               tP.x = tP.x - tR.left
               tP.y = tP.y - tR.top
               hdc = GetWindowDC(m_hWnd)
               Implementation.NCMouseDown tP.x, tP.y, bHandled, hdc, tR.left,
                tR.top, tR.right, tR.bottom
               ReleaseDC m_hWnd, hdc
            End If
         
         Case WM_NCLBUTTONUP
            If GetImplementation(Implementation) Then
               GetCursorPos tP
               GetWindowRect m_hWnd, tR
               tP.x = tP.x - tR.left
               tP.y = tP.y - tR.top
               hdc = GetWindowDC(m_hWnd)
               Implementation.NCMouseUp tP.x, tP.y, hdc, tR.left, tR.top,
                tR.right, tR.bottom
               ReleaseDC m_hWnd, hdc
            End If

         Case WM_PAINT
            ISubclass_WindowProc = CallOldWindowProc(hwnd, iMsg, wParam, lParam)
            If Not (IsWindowVisible(hwnd) = 0) Then
            
               m_bZoomedMDIChild = (IsMDIChildForm(hwnd) And (IsZoomed(hwnd) <>
                0))
               If m_bZoomedMDIChild Then
            
               Else
                  ' Get the non-client DC to draw in:
                  hdc = GetWindowDC(m_hWnd)
                              
                  GetWindowRect m_hWnd, tR
                  OffsetRect tR, -tR.left, -tR.top
                           
                  If GetImplementation(Implementation) Then
                     Implementation.NCPaint hdc, tR.left, tR.top, tR.right,
                      tR.bottom
                  Else
                     DefaultNCPaint hdc, tR.left, tR.top, tR.right, tR.bottom
                  End If
                  
                  ReleaseDC m_hWnd, hdc
               
               End If
            End If
            
         End Select
      
      ' ======================================================
      ' End Draw on Client Area
      ' ======================================================
      
      End If
      
   End Select

End Function
Private Function IsMDIChildForm(ByVal hwnd As Long) As Boolean
Dim hWndP As Long
Dim sBuf As String
Dim iPos As Long
   hWndP = GetParent(hwnd)
   sBuf = String$(260, 0)
   GetClassName hWndP, sBuf, 259
   iPos = InStr(sBuf, vbNullChar)
   If iPos > 1 Then
      If left$(sBuf, iPos - 1) = "MDIClient" Then
         IsMDIChildForm = True
      End If
   End If
End Function
Private Function pGetHitTestCode() As ECNCHitTestConstants
Dim bCanSize As Boolean
Dim Implementation As INCAreaModifier
Dim eHt As ECNCHitTestConstants
Dim tP As POINTAPI
Dim tR As RECT
   
   If GetImplementation(Implementation) Then
            
      bCanSize = Implementation.CanSize
      
      eHt = HTCLIENT
      GetCursorPos tP
      
      GetWindowRect m_hWnd, tR
      tP.x = tP.x - tR.left: tP.y = tP.y - tR.top
      
      OffsetRect tR, -tR.left, -tR.top
      
      eHt = HTCLIENT
      If Not (PtInRect(tR, tP.x, tP.y) = 0) Then
         ' Left
         If tP.x <= m_lLeft Then
            If tP.y <= m_lBottom Then
               If bCanSize Then
                  eHt = HTTOPLEFT
               End If
            ElseIf tP.y >= tR.bottom - m_lBottom Then
               If bCanSize Then
                  eHt = HTBOTTOMLEFT
               End If
            Else
               If bCanSize Then
                  eHt = HTLEFT
               End If
            End If
         ' Right
         ElseIf tP.x >= tR.right - m_lRight Then
            If tP.y <= m_lBottom Then
               If bCanSize Then
                  eHt = HTTOPRIGHT
               End If
            ElseIf tP.y >= tR.bottom - m_lBottom Then
               If bCanSize Then
                  eHt = HTBOTTOMRIGHT
               End If
            Else
               If bCanSize Then
                  eHt = HTRIGHT
               End If
            End If
         ' Top/Bottom?
         ElseIf tP.y <= m_lBottom Then
            If bCanSize Then
               eHt = HTTOP
            End If
         ElseIf tP.y >= tR.bottom - m_lBottom Then
            If bCanSize Then
               eHt = HTBOTTOM
            End If
         ' Caption/Menu
         ElseIf tP.y <= m_lTop Then
            ' We assume for default that the caption
            ' is the same as the system caption etc:
            If tP.y <= m_lBottom + GetSystemMetrics(SM_CYCAPTION) Then
               eHt = HTCAPTION
               If tP.x <= GetSystemMetrics(SM_CYCAPTION) Then
                  eHt = HTSYSMENU
               Else
                  ' todo min/max/close btns
               End If
            ElseIf tP.y > m_lBottom + GetSystemMetrics(SM_CYCAPTION) Then
               eHt = HTCLIENT
            End If
         End If
      End If
      
      Implementation.HitTest tP.x, tP.y, eHt
      
      'Debug.Print "HitTest:"; eHt
      
   End If
   
   pGetHitTestCode = eHt
   
End Function
Public Sub DefaultNCPaint(ByVal hdc As Long, ByVal lLeft As Long, ByVal lTop As
 Long, ByVal lRight As Long, ByVal lBottom As Long)
Dim tR As RECT, tTR As RECT, tSR As RECT, tBR As RECT
Dim lFlag As Long
Dim hBr As Long, hBrButton As Long

   tR.left = lLeft
   tR.top = lTop
   tR.right = lRight
   tR.bottom = lBottom
   LSet tBR = tR

   If m_bActive Then
      lFlag = DC_ACTIVE
      hBrButton = GetSysColorBrush(COLOR_ACTIVECAPTION)
      hBr = GetSysColorBrush(COLOR_ACTIVEBORDER)
   Else
      hBrButton = GetSysColorBrush(COLOR_INACTIVECAPTION)
      hBr = GetSysColorBrush(COLOR_INACTIVEBORDER)
   End If

   ' Titlebar area:
   ' Draw the part between the edge & the client:
   LSet tTR = tR
   ' left edge
   tTR.top = GetSystemMetrics(SM_CYFRAME)
   tTR.bottom = tTR.bottom - GetSystemMetrics(SM_CYFRAME)
   tTR.right = GetSystemMetrics(SM_CXFRAME)
   FillRect hdc, tTR, hBr
   ' top
   LSet tTR = tR
   tTR.bottom = GetSystemMetrics(SM_CYFRAME)
   FillRect hdc, tTR, hBr
   ' right
   LSet tTR = tR
   tTR.top = GetSystemMetrics(SM_CYFRAME)
   tTR.bottom = tTR.bottom - GetSystemMetrics(SM_CYFRAME)
   tTR.left = tTR.right - GetSystemMetrics(SM_CXFRAME)
   FillRect hdc, tTR, hBr
   ' bottom
   LSet tTR = tR
   tTR.top = tTR.bottom - GetSystemMetrics(SM_CYFRAME)
   FillRect hdc, tTR, hBr

   ' Draw the caption into the caption area:

   ' top bit under titlebar:
   LSet tTR = tR
   tTR.top = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CYCAPTION) - 1
   tTR.bottom = tTR.top + 1
   FillRect hdc, tTR, hBr
   DeleteObject hBr

   ' Draw the titlebar into a work DC to prevent flicker:
   lFlag = lFlag Or DC_ICON Or DC_TEXT
   LSet tTR = tR
   tTR.left = tTR.left + GetSystemMetrics(SM_CXFRAME)
   tTR.right = tTR.right - GetSystemMetrics(SM_CXFRAME)
   tTR.top = tTR.top + GetSystemMetrics(SM_CYFRAME)
   tTR.bottom = tTR.top + GetSystemMetrics(SM_CYCAPTION) - 1
   LSet tR = tTR
   OffsetRect tR, -tR.left, -tR.top
   LSet tSR = tR
   tSR.right = tSR.right - (tR.bottom - tR.top) * 3 - 2
   DrawCaptionAPI m_hWnd, m_hDC, tSR, lFlag

   ' Draw the titlebar buttons:
   tSR.left = tSR.right
   tSR.right = tR.right
   FillRect m_hDC, tSR, hBrButton
   DeleteObject hBrButton

   InflateRect tR, 0, -2
   tR.right = tR.right - 2
   tR.left = tR.right - (tR.bottom - tR.top) - 2
   DrawFrameControl m_hDC, tR, DFC_CAPTION, DFCS_CAPTIONCLOSE
   OffsetRect tR, -(tR.right - tR.left + 2), 0
   If IsZoomed(m_hWnd) Then
      DrawFrameControl m_hDC, tR, DFC_CAPTION, DFCS_CAPTIONRESTORE
   Else
      DrawFrameControl m_hDC, tR, DFC_CAPTION, DFCS_CAPTIONMAX
   End If
   OffsetRect tR, -(tR.right - tR.left), 0
   DrawFrameControl m_hDC, tR, DFC_CAPTION, DFCS_CAPTIONMIN

   ' Finished drawing the NC area:
   BitBlt hdc, tTR.left, tTR.top, tTR.right - tTR.left, tTR.bottom - tTR.top,
    m_hDC, 0, 0, vbSrcCopy

   ' Edge 3d
   DrawEdge hdc, tBR, EDGE_RAISED, BF_RECT

End Sub

Public Function GetImplementation(iTo As INCAreaModifier) As Boolean
Dim lPtr As Long
   lPtr = GetProp(m_hWnd, "vbalCNCImplementation")
   If Not lPtr = 0 Then
      Dim iToTemp As INCAreaModifier
      CopyMemory iToTemp, lPtr, 4
      Set iTo = iToTemp
      CopyMemory iToTemp, 0&, 4
      GetImplementation = True
   End If
End Function


#If 0 = 1 Then
Private Sub pDebugCalcSize(ByRef tNCR As NCCALCSIZE_PARAMS)
Dim i As Long
Dim tWP As WINDOWPOS
   ' Use to show what is happening:
   With tNCR
      For i = 1 To 3
         With .rgrc(i - 1)
            Debug.Print .left, .top, .right, .bottom
         End With
      Next i
      CopyMemory tWP, ByVal .lppos, Len(tWP)
      With tWP
         Debug.Print .x, .y, .x + .cx, .y + .cy
      End With
      
   End With
End Sub
#End If