Attribute VB_Name = "Module1"
'    Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
'    Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
'    Me.Width = GetSetting(App.Title, "Settings", "MainWidth", 6500)
'    Me.Height = GetSetting(App.Title, "Settings", "MainHeight", 6500)
'
'    SaveSetting App.Title, "Settings", "MainLeft", Me.Left
'    SaveSetting App.Title, "Settings", "MainTop", Me.Top
'    SaveSetting App.Title, "Settings", "MainWidth", Me.Width
'    SaveSetting App.Title, "Settings", "MainHeight", Me.Height


Option Explicit

Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (ByVal cChar As Byte) As Integer

'This is so the progress bar is always on top
Public 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
    Global Const HWND_TOPMOST = -1
    Global Const HWND_NOTOPMOST = -2
    Global Const SWP_NOMOVE = &H2
    Global Const SWP_NOSIZE = &H1

'refer to the MSDN for more detailed information regarding the
'constants used in this sample.
Public Const IMAGE_BITMAP = &O0   ' used with LoadImage to load
                                  ' a bitmap
Public Const LR_LOADFROMFILE = 16    ' used with LoadImage
Public Const LR_CREATEDIBSECTION = 8192 ' used with LoadImage
'  Ternary raster operations
Public Const SRCCOPY = &HCC0020 ' (DWORD) dest = source
Public Const SRCPAINT = &HEE0086        ' (DWORD) dest = source OR dest
Public Const SRCAND = &H8800C6  ' (DWORD) dest = source AND dest
Public Const SRCINVERT = &H660046       ' (DWORD) dest = source XOR dest
Public Const SRCERASE = &H440328        ' (DWORD) dest = source AND (NOT dest )
Public Const NOTSRCCOPY = &H330008      ' (DWORD) dest = (NOT source)
Public Const NOTSRCERASE = &H1100A6     ' (DWORD) dest = (NOT src) AND (NOT dest)
Public Const MERGECOPY = &HC000CA       ' (DWORD) dest = (source AND pattern)
Public Const MERGEPAINT = &HBB0226      ' (DWORD) dest = (NOT source) OR dest
Public Const PATCOPY = &HF00021 ' (DWORD) dest = pattern
Public Const PATPAINT = &HFB0A09        ' (DWORD) dest = DPSnoo
Public Const PATINVERT = &H5A0049       ' (DWORD) dest = pattern XOR dest
Public Const DSTINVERT = &H550009       ' (DWORD) dest = (NOT dest)
Public Const BLACKNESS = &H42 ' (DWORD) dest = BLACK
Public Const WHITENESS = &HFF0062       ' (DWORD) dest = WHITE
'Public Const PI = PI
Public Const PI = 3.14159265358979

'Refer to the MSDN for more detailed information regarding the
'structures used in this sample.
Type BITMAP '14 bytes
     bmType As Long
     bmWidth As Long
     bmHeight As Long
     bmWidthBytes As Long
     bmPlanes As Integer
     bmBitsPixel As Integer
     bmBits As Long
End Type

' Refer to the MSDN for more detailed information regarding the API's
' used in this sample.

Public Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Public 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
Public Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Public Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long


'Constants for mouse cursor
Global Const MNORMAL = 0
Global Const MRESIZE = 15

'API declares
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

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

Declare Function ClientToScreen& Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI)
Declare Function GetCursorPos& Lib "user32" (lpPoint As POINTAPI)

'API structure
Type POINTAPI
    X As Long
    Y As Long
End Type

'Constants for event firing
Global Const g_cEndResizeEvent = 10
Global Const g_cStartResizeEvent = 20
Global Const g_cUnHookEvent = 30
Global Const g_cHookEvent = 40

'Constants for API calls
Global Const Sg_cXSCREEN = 0
Global Const Sg_cYSCREEN = 1
Global Const GWL_WNDPROC = -4

'Constants for Message types, mostly not used now
Global Const WM_LBUTTONUP = &H202 '514
Global Const WM_LBUTTONDOWN = &H201 '513
Global Const WM_MOUSEACTIVITY = &H21 '33
'Global Const WM_?? = &H20 '32 Cursor Change... useless
Global Const WM_PARENTNOTIFY = &H210 '528
Global Const WM_MOUSEMOVE = &H200 '???

Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Declare Function GetKeyState Lib "user32.dll" (ByVal nVirtKey As Long) As Integer
  
'Parse out the low word
Function LoWord(DWord As Long) As Integer

    If DWord And &H8000& Then ' &H8000& = &H00008000
        LoWord = DWord Or &HFFFF0000
    Else
        LoWord = DWord And &HFFFF&
    End If
    
End Function
'Seperate out the HiWord
Function HiWord(DWord As Long) As Integer
    
    HiWord = (DWord And &HFFFF0000) \ &H10000
    
End Function

'Set the container of a control
Public Sub SetContainer(oCont As Control, sCont As String)

    Dim i As Integer

    'step through all containers until we find the one for this control
    If sCont = oCont.Parent.Name Then
        Set oCont.Container = oCont.Parent
    Else
    
        For i = 0 To oCont.Parent.Controls.Count - 1
    
            'If this container is the right one, move onto it
            If oCont.Parent.Controls(i).Name = sCont Then
                Set oCont.Container = oCont.Parent.Controls(i)
            End If
        
        Next i
        
    End If

End Sub

'Set the demensions of a control
Public Sub SetShape(oCont As Control, nTop As Long, nLeft As Long, _
        nWidth As Long, nHeight As Long)
        
    On Error Resume Next
        
    'Set the easy one
    oCont.Top = nTop
    oCont.Left = nLeft
    oCont.Width = nWidth
    oCont.Height = nHeight

End Sub


'Save the form to a file.  There are going to be to many objects to use
'the registry.  I would obviously prefer that due to performance.
Public Sub SaveControlLayout(oForm As Form, sFileName As String)

    On Error GoTo ErrorHandler

    Dim i As Integer
    Dim nFileNum
    Dim nTop, nLeft, nWidth, nHeight, nTab
    
    nFileNum = FreeFile   ' Get unused file
    Open sFileName For Output As #nFileNum
        
        ''Write down the form information in the file
        'Write #nFileNum, oForm.Top, oForm.Left, oForm.Width, oForm.Height
        
        'Step through all the controls on the form
        For i = 0 To oForm.Controls.Count - 1
        
            If TypeOf oForm.Controls(i) Is SSTab Or TypeName(oForm.Controls(i)) = "SSTab" Then
                Write #nFileNum, oForm.Controls(i).Top, _
                    oForm.Controls(i).Left, oForm.Controls(i).Width, _
                    oForm.Controls(i).Height, oForm.Controls(i).Tab, _
                    oForm.Controls(i).Container.Name, oForm.Controls(i).Name
            Else
                Write #nFileNum, oForm.Controls(i).Top, _
                    oForm.Controls(i).Left, oForm.Controls(i).Width, _
                    oForm.Controls(i).Height, 0, _
                    oForm.Controls(i).Container.Name, oForm.Controls(i).Name
            End If
                       
        Next i 'Move to the next control
   
    Close #nFileNum


    Exit Sub
ErrorHandler:
    'Y,X,Width,Height,SSTab,Container,Name
    Write #nFileNum, 0, 0, 0, 0, 0, "NoOne(Means The Form)", oForm.Controls(i).Name
    Resume Next

End Sub

'Save the form to a file.  There are going to be too many objects to use
'the registry.  I would obviously prefer that due to performance.
Public Sub LoadControlLayout(oForm As Form, sFileName As String)

    'trap errors in case the file gets cut off
    On Error GoTo EndThisSub
    
    Dim i, j As Integer
    Dim sContainer As String, sName As String
    Dim nTop As Long, nLeft As Long, nWidth As Long, nHeight As Long, nTab As Long
    'Dim nFTop As Long, nFLeft As Long, nFWidth As Long, nFHeight As Long
    Dim nFileNum
    
    'Check to see if the file is actually there to open
    If Dir(sFileName) = "" Or sFileName = "" Then Exit Sub
         
    'Open the first free file
    nFileNum = FreeFile   ' Get unused file
    Open sFileName For Input As #nFileNum
             
        'Input #nFileNum, nFTop, nFLeft, nFWidth, nFHeight
         
        'Step through all the controls on the form
        For i = 0 To oForm.Controls.Count - 1
             
            'Make it easier for when we are checking boundries
            With oForm.Controls(i)
                
                Input #nFileNum, nTop, nLeft, nWidth, nHeight, nTab, sContainer, sName
                 
                'Set the objects location
                Call SetShape(oForm.Controls(i), nTop, nLeft, nWidth, nHeight)
                
                'If its a FOTAResizer then disable it
                If TypeOf oForm.Controls(i) Is FOTAFormResize Or _
                    TypeName(oForm.Controls(i)) = "FOTAFormResize" Then
                        .Tag = .Enabled
                        .Enabled = False
                ElseIf TypeOf oForm.Controls(i) Is SSTab Or _
                    TypeName(oForm.Controls(i)) = "SSTab" Then
                        oForm.Controls(i).Tab = nTab
                End If
                
                Call SetContainer(oForm.Controls(i), sContainer)
                 
            End With 'End of gForm.Controls(i)
             
        Next i 'Move to the next control
        
        'Now set the forms size
        'oForm.Top = nFTop
        'oForm.Left = nFLeft
        'oForm.Width = nFWidth
        'oForm.Height = nFHeight
        
        'Step through all the controls and enable any resizers
        For i = 0 To oForm.Controls.Count - 1
            
            If TypeOf oForm.Controls(i) Is FOTAFormResize Or _
               TypeName(oForm.Controls(i)) = "FOTAFormResize" Then
                    oForm.Controls(i).Enabled = oForm.Controls(i).Tag
                    If oForm.Controls(i).Enabled = True Then
                        oForm.Controls(i).ReLoad
                    End If
            End If
            
        Next i
        
EndThisSub:
        
    Close #nFileNum

End Sub


Public Sub FindHighestControl(oForm As Form, nCont As Integer, _
            ByRef nNewHighest As Integer, ByRef nNewHeight As Integer, _
            nX As Long, nY As Long, Optional ByRef nXClick As Long, Optional ByRef nYClick As Long)

    On Error GoTo NextControl

    Dim nCalcHeight As Integer
    Dim hContainer
    'Temporary click location storage
    Dim nTx As Long
    Dim nTy As Long
        
    With oForm.Controls(nCont)
    
        Set hContainer = .Container
    
        nTx = nX
        nTy = nY
        'Is his parent the form?
        nCalcHeight = 1
        While hContainer.hwnd <> oForm.hwnd
            'Record his left and top so we can tell where
            '(if anywhere) we clicked in him
            nTx = nTx - hContainer.Left
            nTy = nTy - hContainer.Top
            nCalcHeight = nCalcHeight + 1
        
            'Step back to HIS parent
            Set hContainer = hContainer.Container
        Wend
    
        'Did we click within his borders?
        If nTx > .Left And nTx < .Left + .Width And nTy > .Top And nTy < .Top + .Height Then
        
                'Now see if its farther up than the one in memory
                If nNewHighest = -1 Or nCalcHeight > nNewHeight Then
                    nNewHighest = nCont
                    nNewHeight = nCalcHeight
                    nXClick = nTx - .Left
                    nYClick = nTy - .Top
                End If 'Is this the highest control?
            
        End If 'End of border check

    End With

NextControl:

End Sub
