#include Once "window9.bi"

#ifndef TTN_GETDISPINFO	
    #ifdef UNICODE
        #define TTN_GETDISPINFO    (TTN_FIRST - 10)		
    #else	
        #define TTN_GETDISPINFO    (TTN_FIRST - 0)
    #endif	
#endif

#define FBIDWINDOW 1
#define FBIDLISTBOX 2
#define FBIDCOMBOBOX 3
#define FBIDTABBERBOX 4
#define FBIDSCROLLBAR 5
#define FBIDLISTVIEW 6
#define FBIDTRACKBAR 7
#define FBIDPROGRESSBAR 8
#define SYSDATETIMEPICK32 9
#define SYSMONTHCAL32 10
#define FBIDCOMBOLBOX 13
#define MSCTLS_UPDOWN32 14
#define FBTOOLBAR 15
#define STATICCONTROL 16
#define FBIDTREEVIEW 17

const as Long w9UpDownMessage = &hF1F1
const as Long w9ListEventGadgetMessage = &hF1F2
const as Long w9TreeViewClickMessage = &hF1F3
const as Long w9TabberViewClickMessage = &hF1F4

Declare Function fbguiWinProc(Byval hWnd As HWND, Byval uMsg As UINT, Byval wParam As WPARAM, Byval lParam As LPARAM ) As LRESULT

Type TMessage
    As HWND hWin
    As integer iMsg
    As WPARAM wParam
    As LPARAM lParam
End Type

Extern As Long ERROR_COLOR

Dim Shared As HBRUSH hBrush
Dim Shared As MSG    fbguiMSG
Dim Shared As Long   iEventTreeViewitem
Dim Shared As Long iEventNumberTreeView
Dim Shared As Long pAddressCallbackForLoop
Dim Shared As Long pAddressCallbackForWinProc
Dim Shared As Long iEventNumberListView
Dim Shared As Long iColumnEvent
Dim Shared As Long iFlagKeyListView
Dim Shared As Long iEventItem
Dim Shared As Long iEventSubItem
Dim Shared As Long iEventNumberToolBar
Dim Shared As Long ERROR_COLOR , iBgColor , iTextColor
Dim Shared As Long iSizeY , iSizeX
Dim Shared As Long iEventX, iEventY
Dim Shared As Long iEventNumber
Dim Shared As Long iEventKey
Dim Shared As Long iEventID
Dim Shared As Integer iEVENT_W_PARAM , iEVENT_L_PARAM, iCheckAccelerator , iUboundAccel
Dim Shared As HWND hMDIClient, iEventHwnd
Dim Shared As TMessage  iFbGuiEventBuffer(1)
Dim Shared as NMITEMACTIVATE ptr lpNmAct
Dim Shared as NMLISTVIEW ptr lpNmLV
Dim Shared as NMTREEVIEW ptr lpNmTV

Dim Shared OnWindowProcCallBack    As Function (Byval As HWND,Byval As UINT,Byval As WPARAM,Byval As LPARAM) As Integer Ptr = 0
Dim Shared OnWindowProcCallBack_2  As Function (Byval As HWND,Byval As UINT,Byval As WPARAM,Byval As LPARAM,Byval As Integer,Byval As Point) As Integer Ptr = 0

Redim Shared As ACCELERATOR ArrayAccelerators(0)

if lpNmAct = 0 then
    lpNmAct = callocate(sizeof(NMITEMACTIVATE))
EndIf
if lpNmLV = 0 then
    lpNmLV = callocate(sizeof(NMLISTVIEW))
EndIf
if lpNmTV = 0 then
    lpNmTV = callocate(sizeof(NMTREEVIEW))
EndIf

iColumnEvent=-1

Function win9GetGadgetClass(Byval gadget As HWND) As Long Export
    Dim result As Long
    Dim As USTRING sClass = Getclassname_(gadget)
    Select Case sClass
        Case "ComboBox"
            result=FBIDCOMBOBOX
        Case "ComboLBox"
            result=FBIDCOMBOLBOX
        Case "ListBox"
            result=FBIDLISTBOX
        Case "SysTabControl32"
            result=FBIDTABBERBOX
        Case "msctls_trackbar32"
            result=FBIDTRACKBAR
        Case "ScrollBar"
            result=FBIDSCROLLBAR
        Case "msctls_progress32"
            result=FBIDPROGRESSBAR
        Case "SysDateTimePick32"
            result=SYSDATETIMEPICK32
        Case "SysMonthCal32"
            result=SYSMONTHCAL32
        Case "msctls_updown32"
            result=MSCTLS_UPDOWN32
        Case "ToolbarWindow32"
            result=FBTOOLBAR
        Case "Static"
            result=STATICCONTROL
        Case "SysListView32"
            result=FBIDListView
        case "SysTreeView32"
            result=FBIDTreeView
        Case Else
            result = 0
    End Select
    Return result
End Function

Sub win9GetAcceleratorInfo(Byval aa As ACCELERATOR Ptr)
    iCheckAccelerator=1
    Dim As ACCELERATOR Ptr ACCELERATORSTRUCT=aa
    Dim As Integer c=Ubound(ArrayAccelerators)
    For a As Integer=0 To c
        If ArrayAccelerators(a).hwnd=ACCELERATORSTRUCT->hwnd Then
            ArrayAccelerators(a).hAccel=ACCELERATORSTRUCT->hAccel
            Exit Sub
        Endif
    Next
    If ArrayAccelerators(0).hwnd=0 Then
        c=0
    Else
        c+=1
        Redim Preserve As ACCELERATOR ArrayAccelerators(c)
    End If
    ArrayAccelerators(c).hwnd=ACCELERATORSTRUCT->hwnd
    ArrayAccelerators(c).hAccel=ACCELERATORSTRUCT->hAccel
    iUboundAccel=c
End Sub

Function win9GetGuiWinProc() As Integer
    Return Cast(Integer,@fbguiWinProc)
End Function

Function win9GetGuiMSG() As Integer
    Return Cast(Integer,@fbguiMSG)
End Function

Sub win9SetMDIClient(Byval MDI As HWND)
    hMDIClient=MDI
End Sub

Sub Setpagestepscrollbar Overload(Byval iGadget As Long , Byval iParamScroll As Integer) Export
    SetProp(Gadgetid(iGadget),"pagestep", Cast(HANDLE,iParamScroll))
End Sub

Sub Setpagestepscrollbar Overload(Byval hw As HWND, Byval iParamScroll As Integer) Export
    SetProp(hw,"pagestep", Cast(HANDLE,iParamScroll))
End Sub

Function win9SetCurrentColors(Byval iBgParamColor As Integer, Byval iTextParamColor As Integer) As Integer Export
    iBgColor = iBgParamColor
    iTextColor = iTextParamColor
    Return 1
End Function

Function win9SetErrorColor(Byval iColor As Integer) As Integer Export
    ERROR_COLOR = iColor
    Return 1
End Function

Function Eventnumber() As Integer Export
    Return iEventNumber
End Function

Function Eventnumbertoolbar() As Integer Export
    Return iEventNumberToolBar
End Function

Function Eventnumberlistview() As Integer Export
    Function= iEventNumberListView
    iEventNumberListView=0
End Function

Function Mousex() As Integer Export
    Return iEventX
End Function

Function Mousey() As Integer Export
    Return iEventY
End Function

Function w9SizeWidth() As Integer Export
    Return iSizeX
End Function

Function w9SizeHeight() As Integer Export
    Return iSizeY
End Function

Function Eventhwnd() As HWND Export
    Return iEventHwnd
End Function

Function Eventkey() As Integer Export
    Return iEventKey
End Function

Function Eventwparam() As WPARAM Export
    Return Cast(WPARAM,iEVENT_W_PARAM)
End Function

Function EventLParam() As LPARAM Export
    Return Cast(LPARAM,iEVENT_L_PARAM)
End Function

Function Getsubitemlistview() As Integer Export
    Return iEventSubItem
End Function

Function Getitemlistview() As Integer Export
    Return iEventItem
End Function

Function Getcolumnlistview() As Long Export
    Function= iColumnEvent
    iColumnEvent=-1
End Function

Function Flagkeylistview(iState As Long = -1) As Integer Export
    Return iFlagKeyListView
End Function

Function Getitemtreeview(Byval iGadget As Long = 0) As Integer Export
    Return iEventTreeViewitem
End Function

Function Eventnumbertreeview() As Integer Export
    Function= iEventNumberTreeView
    iEventNumberTreeView=0
End Function

Function Setwindowcallback(Byval pAddressFunction As Integer,Byval iFlag As Integer) As Integer Export
    If iFlag=0 Then
        pAddressCallbackForWinProc=100
        OnWindowProcCallBack=Cast(Function (Byval As HWND,Byval As UINT,Byval As WPARAM,Byval As LPARAM) As Integer Ptr,pAddressFunction)
    Elseif iFlag=1 Then
        pAddressCallbackForLoop=100
        OnWindowProcCallBack_2=Cast(Function (Byval As HWND,Byval As UINT,Byval As WPARAM,Byval As LPARAM,Byval As Integer,Byval As Point) As Integer Ptr,pAddressFunction)
    Endif
    Return 1
End Function

Function Freecallback(Byval iFlag As Integer) As Integer Export
    Select Case iFlag
        Case 0
            pAddressCallbackForWinProc=0
        Case 1
            pAddressCallbackForLoop=0
    End Select
    Return 1
End Function

Function fbguiWinProc(Byval hWnd As HWND, Byval uMsg As UINT, Byval wParam As WPARAM, Byval lParam As LPARAM) As LRESULT Export
    
    If pAddressCallbackForWinProc<>0 Then
        Var res = OnWindowProcCallBack(hwnd,umsg,wParam,lParam)
        If  res<>0 Then
            Return Cast(Integer,res)
        End If
    End If
    
    Select Case uMsg
            
        case WM_CTLCOLORSTATIC , WM_CTLCOLOREDIT , WM_CTLCOLORLISTBOX , WM_CTLCOLORSCROLLBAR
            dim as long iGadget = win9GetGadgetClass(Cast(HWND,lparam))
            If iGadget=FBIDCOMBOLBOX Then
                SetBkColor(Cast(HDC,wparam),iBgColor)
                SetTextColor(Cast(HDC,wParam),iTextColor)
                Return Cast(Integer,hBrush)
            Else
                Static As COLORREF iCurentColor
                Static As hwnd iHwndBackup
                Static As Integer iPrevMsg
                Dim As Integer iSetupColor
                If (iGadget=FBIDSCROLLBAR) Andalso (Getgadgetcolor(lparam,4)=0) Then
                    iSetupColor = &hf0f0f0
                Else
                    iSetupColor = Getgadgetcolor(lparam,3)
                Endif
                If ERROR_COLOR = 0 Then
                    If (iSetupColor <> iCurentColor) Orelse (iHwndBackup<>hWnd) Orelse (iPrevMsg <> uMsg) Then
                        iCurentColor = iSetupColor
                        iHwndBackup = hWnd
                        iPrevMsg = uMsg
                        DeleteObject(hBrush)
                        hBrush = CreateSolidBrush(iCurentColor)
                        SetBkColor(Cast(HDC,wparam),iCurentColor)
                    Else
                        SetBkColor(Cast(HDC,wparam),iCurentColor)
                    End If
                    SetTextColor(Cast(HDC,wParam),Cast(COLORREF,Getgadgetcolor(lparam,4)))
                Else
                    ERROR_COLOR = 0
                End If
            End If
            
            Return Cast(Integer,hBrush)
            
        Case WM_TIMER, WM_HSCROLL,WM_VSCROLL,_
            WM_MOUSEMOVE,WM_MOUSEWHEEL,WM_CLOSE, _
            WM_KEYDOWN,WM_KEYUP,WM_SYSKEYDOWN,WM_SYSKEYUP, _
            WM_COMMAND,WM_SYSCOMMAND, _
            WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDBLCLK, _
            WM_RBUTTONDOWN,WM_RBUTTONUP,WM_RBUTTONDBLCLK, _
            WM_MBUTTONDOWN,WM_MBUTTONUP,WM_MBUTTONDBLCLK, _
            WM_HOTKEY,WM_USER,WM_PARENTNOTIFY,WM_VKEYTOITEM, _
            WM_ACTIVATE,WM_SETFOCUS,WM_KILLFOCUS, _
            WM_MENUSELECT,WM_DROPFILES
            iFbGuiEventBuffer(0).hWin  = hWnd
            iFbGuiEventBuffer(0).iMsg = uMsg
            iFbGuiEventBuffer(0).wParam  = wParam
            iFbGuiEventBuffer(0).lParam  = lParam
        case WM_SIZE
            iFbGuiEventBuffer(1).hWin  = hWnd
            iFbGuiEventBuffer(1).iMsg = uMsg
            iFbGuiEventBuffer(1).wParam  = wParam
            iFbGuiEventBuffer(1).lParam  = lParam
    End Select
    
    Dim sinf As SCROLLINFO
    Dim nPos As Integer
    static iFlagTvKey as long
    
    Select Case uMsg
        Case WM_GETMINMAXINFO
            If GetProp(hwnd,"MINMAXFLAG") = 1 Then
                Dim As Point ptMin = Type(_
                Cast(Integer,GetProp(hwnd,"MINIMALWIDTH")),_
                Cast(Integer,GetProp(hwnd,"MINIMALHEIGHT")))
                Dim As Point ptMax = Type(_
                Cast(Integer,GetProp(hwnd,"MAXIMALWIDTH")),_
                Cast(Integer,GetProp(hwnd,"MAXIMALHEIGHT")))
                Dim MINMAX As MINMAXINFO Ptr = Cast(MINMAXINFO Ptr,lparam)
                MINMAX->ptMinTrackSize = ptMin
                MINMAX->ptMaxTrackSize = ptMax
                Return 0
            Endif
        Case 1029 'WM_SHELLNOTIFY
            SetForegroundWindow(hwnd)
            PostMessage(hwnd,lparam,wparam,-1)
        case WM_ACTIVATE
            if LOWORD(wParam) then
                dim as HWND hwProp = getprop(hwnd , "tabstopcurentgadget")
                if hwProp then
                    dim as Integer iGadget = ID_In_Number(hwProp)
                    if iGadget then
                        setprop(hwnd , "tabstop_act_win" , hwProp)
                    EndIf
                endif 
            EndIf
        case WM_SETFOCUS
            dim as HWND hwProp = getprop(hwnd , "tabstop_act_win")
            if hwProp then
                setprop(hwnd , "tabstop_act_win" , 0)
                setfocus(hwProp)
            EndIf
        Case WM_HSCROLL
            iEventHwnd =Cast(hwnd,lParam)
            Dim As Integer iPageLength = Cint(GetProp(iEventHwnd,"pagestep"))
            If iPageLength = 0 Then iPageLength = 10
            sinf.cbSize=Sizeof(sinf)
            sinf.fMask=SIF_RANGE Or SIF_PAGE
            If GetScrollInfo(iEventHwnd,SB_HORZ,@sinf)=0 Then
                GetScrollInfo(Hwnd,SB_HORZ,@sinf)
            Endif
            Select Case Loword(wParam)
                Case SB_THUMBPOSITION,SB_THUMBTRACK
                    nPos=Hiword(wParam)
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        SetScrollPos(Hwnd,SB_HORZ,nPos,True)
                    Endif
                Case SB_LINEDOWN
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos+=1
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_HORZ)
                        npos+=1
                        SetScrollPos(Hwnd,SB_HORZ,nPos,True)
                    Endif
                Case SB_LINEUP
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos-=1
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_HORZ)
                        npos-=1
                        SetScrollPos(Hwnd,SB_HORZ,nPos,True)
                    Endif
                Case SB_PAGEDOWN
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos+=iPageLength
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_HORZ)
                        npos+=iPageLength
                        SetScrollPos(Hwnd,SB_HORZ,nPos,True)
                    Endif
                Case SB_PAGEUP
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos-=iPageLength
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_HORZ)
                        npos-=iPageLength
                        SetScrollPos(Hwnd,SB_HORZ,nPos,True)
                    Endif
            End Select
        Case WM_VSCROLL
            iEventHwnd =Cast(hwnd,lParam)
            Dim As Integer iPageLength = Cint(GetProp(iEventHwnd,"pagestep"))
            If iPageLength = 0 Then iPageLength = 10
            sinf.cbSize=Sizeof(sinf)
            sinf.fMask=SIF_RANGE Or SIF_PAGE
            If GetScrollInfo(iEventHwnd,SB_VERT,@sinf)=0 Then
                GetScrollInfo(Hwnd,SB_VERT,@sinf)
            Endif
            Select Case Loword(wParam)
                Case SB_THUMBPOSITION,SB_THUMBTRACK
                    nPos=Hiword(wParam)
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        SetScrollPos(Hwnd,SB_VERT,nPos,True)
                    Endif
                Case SB_LINEDOWN
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos+=1
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_VERT)
                        npos+=1
                        SetScrollPos(Hwnd,SB_VERT,nPos,True)
                    Endif
                Case SB_LINEUP
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos-=1
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_VERT)
                        npos-=1
                        SetScrollPos(Hwnd,SB_VERT,nPos,True)
                    Endif
                Case SB_PAGEDOWN
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos+=iPageLength
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_VERT)
                        npos+=iPageLength
                        SetScrollPos(Hwnd,SB_VERT,nPos,True)
                    Endif
                Case SB_PAGEUP
                    nPos=GetScrollPos(iEventHwnd,SB_CTL)
                    npos-=iPageLength
                    If SetScrollPos(iEventHwnd,SB_CTL,nPos,True)=0 Then
                        nPos=GetScrollPos(Hwnd,SB_VERT)
                        npos-=iPageLength
                        SetScrollPos(Hwnd,SB_VERT,nPos,True)
                    Endif
            End Select
        Case WM_CLOSE
            Return 0
        Case WM_SIZE
            Dim As HWND HWNDSTATUSBAR = GetProp(hwnd,"STATUSBARWINDOW")
            If HWNDSTATUSBAR<>0 Then
                SendMessage(HWNDSTATUSBAR,WM_SIZE,0,0)
            End If
            iSizeX = Loword(lParam)
            iSizeY = Hiword(lParam)
        Case WM_NOTIFY
            Dim As LPNMHDR pnm
            pnm =Cast( LPNMHDR,lParam)
            select case pnm->code
                case NM_CLICK , NM_RCLICK , NM_DBLCLK
                    select case win9GetGadgetClass(pnm->hwndFrom)
                        case FBIDTREEVIEW 
                            iFlagTvKey = 0
                            select case pnm->code
                                Case NM_CLICK
                                    PostMessage(hwnd , WM_USER, w9TreeViewClickMessage , makelparam(pnm->idFrom , eventlbdown))
                                case NM_RCLICK
                                    PostMessage(hwnd , WM_USER, w9TreeViewClickMessage , makelparam(pnm->idFrom , eventrbdown))
                                case NM_DBLCLK
                                    PostMessage(hwnd , WM_USER, w9TreeViewClickMessage , makelparam(pnm->idFrom , eventdblclick))
                            End Select
                        case FBIDTABBERBOX
                            select case pnm->code
                                Case NM_CLICK
                                    PostMessage(hwnd , WM_USER, w9TabberViewClickMessage , makelparam(pnm->idFrom , eventlbdown))
                                case NM_RCLICK
                                    PostMessage(hwnd , WM_USER, w9TabberViewClickMessage , makelparam(pnm->idFrom , eventrbdown))
                                case NM_DBLCLK
                                    PostMessage(hwnd , WM_USER, w9TabberViewClickMessage , makelparam(pnm->idFrom , eventdblclick))
                            End Select
                        case FBIDLISTVIEW
                            if lpNmAct then zeromemory(lpNmAct, sizeof(NMITEMACTIVATE))
                            if lpNmAct then memcpy( lpNmAct , pnm , sizeof(NMITEMACTIVATE))
                            iFbGuiEventBuffer(0).hWin  = hWnd
                            iFbGuiEventBuffer(0).iMsg = uMsg
                            iFbGuiEventBuffer(0).wParam  = wParam
                            iFbGuiEventBuffer(0).lParam  = cast(LPARAM,lpNmAct)
                            PostMessage(hwnd , WM_USER,w9ListEventGadgetMessage , cast(lparam,lpNmAct) )
                    end select
                case TVN_KEYDOWN
                    iFlagTvKey = 1
                case TTN_GETDISPINFO
                    Dim As LPNMTTDISPINFO pdi
                    pdi =  Cast(LPNMTTDISPINFO,pnm)
                    #ifdef UNICODE
                        Dim As Wstring Ptr Sptr = GetProp(hwnd,Str(pdi->hdr.idFrom))
                    #else	
                        Dim As Zstring Ptr Sptr = GetProp(hwnd,Str(pdi->hdr.idFrom))
                    #endif
                    If Sptr<>0 Then
                        pdi->szText = *Sptr
                    Endif
                    iFbGuiEventBuffer(0).hWin  = hWnd
                    iFbGuiEventBuffer(0).iMsg = uMsg
                    iFbGuiEventBuffer(0).wParam  = wParam
                    iFbGuiEventBuffer(0).lParam  = lParam
                case LVN_COLUMNCLICK , LVN_ITEMCHANGING
                    if lpNmLV then zeromemory(lpNmLV , sizeof(NMLISTVIEW))
                    if lpNmLV then memcpy( lpNmLV , pnm , sizeof(NMLISTVIEW))
                    iFbGuiEventBuffer(0).hWin  = hWnd
                    iFbGuiEventBuffer(0).iMsg = uMsg
                    iFbGuiEventBuffer(0).wParam  = wParam
                    iFbGuiEventBuffer(0).lParam  = cast(LPARAM,lpNmLV)
                case TVN_SELCHANGED
                    if lpNmTV then zeromemory(lpNmTV , sizeof(NMTREEVIEW))
                    if lpNmTV then memcpy( lpNmTV , pnm , sizeof(NMTREEVIEW))
                    iFbGuiEventBuffer(0).hWin  = hWnd
                    iFbGuiEventBuffer(0).iMsg = uMsg
                    iFbGuiEventBuffer(0).wParam  = wParam
                    iFbGuiEventBuffer(0).lParam = cast(LPARAM,lpNmTV)
                    if iFlagTvKey then
                        PostMessage(hwnd , WM_USER,w9ListEventGadgetMessage , cast(lparam,lpNmTV) )                   
                        iFlagTvKey = 0
                    endif
                case TCN_SELCHANGE
                    Dim As TC_ITEM TI
                    TI.mask=TCIF_PARAM
                    SendMessage(pnm->hwndFrom,TCM_GETITEM,SendMessage(pnm->hwndFrom,TCM_GETCURSEL,0,0),Cast(LPARAM,@TI))
                    PostMessage(hwnd , WM_USER, w9TabberViewClickMessage , makelparam(pnm->idFrom , eventGadget))
                    ShowWindow(Cast(HWND,TI.lparam),1)
                case TCN_SELCHANGING
                    Dim As TC_ITEM TI
                    TI.mask=TCIF_PARAM
                    SendMessage(pnm->hwndFrom,TCM_GETITEM,SendMessage(pnm->hwndFrom,TCM_GETCURSEL,0,0),Cast(LPARAM,@TI))
                    ShowWindow(Cast(HWND,TI.lparam),0)
                case NM_CUSTOMDRAW , LVN_ITEMCHANGED , LVN_KEYDOWN , LVN_ITEMACTIVATE , NM_SETFOCUS
                case UDN_DELTAPOS
                    if id_in_number(getProp(pnm->hwndFrom,"addparam60000")) = pnm->idFrom then ' check conflict with panelgadget
                        PostMessage(hwnd , WM_USER, w9UpDownMessage , pnm->idFrom)
                    EndIf
            End Select
    End Select
    
    If hMDIClient<>0 Then
        If GetParent(hMDIClient)=hWnd Then
            Return DefFrameProc(hWnd,hMDIClient , uMsg, wParam, lParam)
        End If
    End If
    Return DefWindowProc(hWnd,uMsg,wParam,lParam)
End Function

Private Function w9DoEvents(iParamNoWait As Long) As Long
    
    Dim uMsg As UINT, WParam As WPARAM, lParam As LPARAM, hWnd As HWND
    
    iEventID=0
    iEventHwnd=0
    iEventNumber=0
    iEventX = 0
    iEventY = 0
    
    if iFbGuiEventBuffer(0).iMsg = 0 andalso iFbGuiEventBuffer(1).iMsg then
        hWnd   = Cast(HWND,iFbGuiEventBuffer(1).hWin)
        uMsg   = iFbGuiEventBuffer(1).iMsg
        wParam = iFbGuiEventBuffer(1).wParam
        lParam = iFbGuiEventBuffer(1).lParam
        iFbGuiEventBuffer(1).iMsg = 0
    else
        hWnd   = Cast(HWND,iFbGuiEventBuffer(0).hWin)
        uMsg   = iFbGuiEventBuffer(0).iMsg
        wParam = iFbGuiEventBuffer(0).wParam
        lParam = iFbGuiEventBuffer(0).lParam
        iFbGuiEventBuffer(0).iMsg = 0
    EndIf
    
    iEVENT_W_PARAM=wParam
    iEVENT_L_PARAM=lParam
    
    Select Case uMsg
        case 0
        Case WM_CLOSE
            iEventID    = Eventclose
            iEventHwnd = hWnd
        Case WM_SIZE
            iEventID    = Eventsize
            iEventHwnd = hWnd
        Case WM_COMMAND
            iEventHwnd = Cast(HWND,lParam)
            If iEventHwnd = 0 Then
                iEventNumber = Loword(wParam)
                iEventID      = Eventmenu
                iEventHwnd   = hWnd
                Select Case iEventNumber
                    Case 65525 To 65527
                        win9SwitchTabStop(hWnd , iEventNumber)
                End Select
            Else
                If GetFocus = iEventHwnd Or win9GetGadgetClass(Cast(hwnd,lparam)) = STATICCONTROL _
                Or win9GetGadgetClass(Cast(hwnd,lparam)) = FBTOOLBAR Then
                    iEventID             = Eventgadget
                    iEventNumber        = Loword(wParam)
                    iEventNumberToolBar = iEventNumber
                Endif
            End If
        Case WM_KEYDOWN
            iEventID    = Eventkeydown
            iEventHwnd = hWnd
            iEventKey  = Loword(wParam)
        Case WM_KEYUP
            iEventID      = Eventkeyup
            iEventHwnd   = hWnd
            iEventNumber = Loword(wParam)
        Case WM_MOUSEMOVE
            iEventID    = Eventmousemove
            iEventHwnd = hWnd
            iEventKey  = wParam
            iEventX     = Loword(lParam)
            iEventY     = Hiword(lParam)
        Case WM_MOUSEWHEEL
            iEventID     = Eventmousewheel
            iEventHwnd  = hWnd
            iEventKey   = wParam
            iEventX      = Loword(lParam)
            iEventY      = Hiword(lParam)
        Case WM_LBUTTONDOWN
            'If GetProp(hwnd,"panelevent") <> 1 Then
            iEventID    = Eventlbdown
            iEventHwnd = hWnd
            iEventKey  = wParam
            iEventX     = Loword(lParam)
            iEventY     = Hiword(lParam)
            If lParam=-1 Then
                iEventNumber  = wParam
            Else
                iEventNumber  = 0
            Endif
            'Endif
        Case WM_RBUTTONDOWN
            'If GetProp(hwnd,"panelevent") <> 1  Then
            iEventID    = Eventrbdown
            iEventHwnd = hWnd
            iEventKey  = wParam
            iEventX     = Loword(lParam)
            iEventY     = Hiword(lParam)
            If lParam=-1 Then
                iEventNumber        = wParam
            Else
                iEventNumber        = 0
            Endif
            'Endif
        Case WM_MBUTTONDOWN
            'If GetProp(hwnd,"panelevent") <> 1  Then
            iEventID    = Eventmbdown
            iEventHwnd = hWnd
            iEventKey  = wParam
            iEventX     = Loword(lParam)
            iEventY     = Hiword(lParam)
            If lParam=-1 Then
                iEventNumber = wParam
            Else
                iEventNumber = 0
            Endif
            'Endif
        Case WM_LBUTTONUP
            'If GetProp(hwnd,"panelevent") <> 1  Then
            iEventID      = Eventlbup
            iEventHwnd   = hWnd
            iEventKey    = wParam
            iEventX       = Loword(lParam)
            iEventY       = Hiword(lParam)
            'Endif
        Case WM_RBUTTONUP
            'If GetProp(hwnd,"panelevent") <> 1  Then
            iEventID      = Eventrbup
            iEventHwnd   = hWnd
            iEventKey    = wParam
            iEventX       = Loword(lParam)
            iEventY       = Hiword(lParam)
            'Endif
        Case WM_MBUTTONUP
            'If GetProp(hwnd,"panelevent") <> 1  Then
            iEventID      = Eventmbup
            iEventHwnd   = hWnd
            iEventKey    = wParam
            iEventX       = Loword(lParam)
            iEventY       = Hiword(lParam)
            'Endif
        Case WM_HSCROLL
            select case win9GetGadgetClass(Cast(hwnd,lParam))
                case FBIDTRACKBAR
                    iEventID = Eventgadget
                    iEventNumber = id_in_number(Cast(hwnd,lParam))
                case FBIDSCROLLBAR
                    iEventID = WM_HSCROLL
            End Select
            iEventHwnd   = Cast(hwnd,lParam)
        Case WM_VSCROLL
            select case win9GetGadgetClass(Cast(hwnd,lParam))
                case FBIDTRACKBAR
                    iEventID = Eventgadget
                    iEventNumber = id_in_number(Cast(hwnd,lParam))
                case FBIDSCROLLBAR
                    iEventID      = WM_VSCROLL
            End Select
            iEventHwnd   = Cast(hwnd,lParam)
        Case WM_TIMER
            iEventID      = Eventtimer
            iEventHwnd   = hWnd
            iEventNumber = wParam
        Case WM_ACTIVATE
            If Loword(wParam) = WA_CLICKACTIVE Then
                iEventID    = Eventactivate
                iEventHwnd = hWnd
            Endif
        case WM_USER
            select case wparam
                Case w9UpDownMessage
                    iEventID = Eventgadget
                    iEventNumber = lparam
                case w9ListEventGadgetMessage
                    Dim As LPNMHDR pnm
                    pnm = Cast( LPNMHDR,lParam)
                    dim pAct as LPNMITEMACTIVATE = Cast(LPNMITEMACTIVATE,pnm)
                    iEventItem       = pAct->iItem
                    iEventSubItem    = pAct->iSubItem
                    iFlagKeyListView = pAct->uKeyFlags
                    iEventID    = EventGadget
                    iEventNumber        = pnm->idFrom
                    iEventNumberListView = pnm->idFrom
                    iEventNumberTreeView = pnm->idFrom
                case w9TreeViewClickMessage
                    iEventID = Hiword(lparam)
                    iEventNumber = loword(lparam)
                    iEventNumberTreeView = loword(lparam)
                case w9TabberViewClickMessage
                    iEventID = Hiword(lparam)
                    iEventNumber = loword(lparam)
            End Select
        Case WM_NOTIFY
            Dim As LPNMHDR pnm
            pnm =Cast( LPNMHDR,lParam)
            if pnm then
                select case pnm->code
                    Case NM_CLICK
                        dim pAct as LPNMITEMACTIVATE = Cast(LPNMITEMACTIVATE,pnm)
                        iEventItem       = pAct->iItem
                        iEventSubItem    = pAct->iSubItem
                        iFlagKeyListView = pAct->uKeyFlags
                        iEventID    = Eventlbdown
                        If win9GetGadgetClass(pnm->hwndFrom) = FBIDTABBERBOX Then
                            iEventHwnd = hWnd
                            iEventKey  = 0
                        else
                            iEventNumber        = pnm->idFrom
                            iEventNumberToolBar = pnm->idFrom
                            iEventNumberListView = pnm->idFrom
                        EndIf
                    case NM_RCLICK
                        If win9GetGadgetClass(pnm->hwndFrom) <> FBIDTABBERBOX Then
                            dim pAct as LPNMITEMACTIVATE = Cast(LPNMITEMACTIVATE,pnm)
                            iEventItem       = pAct->iItem
                            iEventSubItem    = pAct->iSubItem
                            iEventNumber        = pnm->idFrom
                            iEventNumberListView = pnm->idFrom
                            iEventID    = Eventrbdown
                            iEventHwnd = hWnd
                        EndIf						
                    case NM_DBLCLK
                        dim pAct as LPNMITEMACTIVATE = Cast(LPNMITEMACTIVATE,pnm)
                        iEventItem       = pAct->iItem
                        iEventSubItem    = pAct->iSubItem
                        iEventNumber        = pnm->idFrom
                        iEventNumberListView = pnm->idFrom
                        iEventID    = WM_LBUTTONDBLCLK
                        iEventHwnd = hWnd
                    case LVN_COLUMNCLICK
                        iEventNumberListView = pnm->idFrom
                        Dim As LPNMLISTVIEW pNMLW = Cast(LPNMLISTVIEW,pnm)
                        iColumnEvent = pNMLW->iSubItem
                        iEventItem = pNMLW->iItem
                        iEventSubItem = pNMLW->iSubItem
                        iEventID             = Eventgadget
                        iEventNumber        = pnm->idFrom
                        iEventNumberToolBar = pnm->idFrom
                    case LVN_ITEMCHANGING
                        dim as LPNMLISTVIEW pNMLW = Cast(LPNMLISTVIEW,pnm)
                        if pNMLW->uNewState = 3 andalso pNMLW->uoldState = 0 then
                            iEventNumber        = pnm->idFrom
                            iEventID             = Eventgadget
                            iEventItem = pNMLW->iItem
                        EndIf
                    case TVN_SELCHANGED
                        Dim As NMTREEVIEW Ptr pNMTW = Cast(NMTREEVIEW Ptr,lparam)
                        iEventNumberTreeView = pnm->idFrom
                        iEventTreeViewitem = Cast(Integer,pNMTW->itemNew.hItem)
                    case TCN_SELCHANGE
                        iEventID             = Eventgadget
                        iEventNumber        = pnm->idFrom
                        iEventNumberToolBar = pnm->idFrom
                End Select
            endif
        Case WM_PARENTNOTIFY
            Select Case  Loword(wParam)
                Case WM_LBUTTONDOWN,WM_RBUTTONDOWN,WM_MBUTTONDOWN
                    If GetProp(hwnd,"eventmousebutton") <> 1 Then ' для контейнера
                        If GetProp(hwnd,"panelevent")<> 1 Then
                            iEventID = Loword(wParam)
                        Endif
                        iEventX = Loword(lParam)
                        iEventY = Hiword(lParam)
                    Else
                        SetProp(hwnd,"eventmousebutton",Cast(handle,0)) ' для контейнера
                    Endif
            End Select
        Case WM_VKEYTOITEM
            iEventKey    = Loword(wParam)
            iEventID      = Eventgadget
            iEventNumber = Id_in_number(Cast(HWND,lparam))
        Case Else
            iEventID=UMSG
    End Select	
    
    if iEventID = 0 then
        
        Dim As Integer iRet
        
        If iParamNoWait Then
            iRet = PeekMessage(@fbguiMsg,0,0,0,PM_REMOVE)
        Else
            iRet = GetMessage(@fbguiMsg,0,0,0)
        Endif
        
        If iRet > 0 Then
            If iCheckAccelerator=1 Then
                Dim As HWND   hWinACC
                Dim As HACCEL hACC
                For i As Integer = 0 To iUboundAccel
                    If ArrayAccelerators(i).hwnd = fbguiMsg.hwnd Then
                        hWinACC = fbguiMsg.hwnd
                        hACC = ArrayAccelerators(i).hAccel
                    Else
                        Dim As HWND iParentHwnd1 , iParentHwnd2 = fbguiMsg.hwnd
                        Do
                            iParentHwnd1=GetParent(iParentHwnd2)
                            If iParentHwnd1<>0 Then iParentHwnd2 = iParentHwnd1
                        Loop Until iParentHwnd1=0
                        If ArrayAccelerators(i).hwnd = iParentHwnd2 Then
                            hWinACC = iParentHwnd2
                            hACC = ArrayAccelerators(i).hAccel
                        End If
                    End If
                Next
                If TranslateAccelerator( hWinACC , hACC , @fbguiMsg) = 0 Then
                    TranslateMessage(@fbguiMsg)
                    DispatchMessage(@fbguiMsg)
                End If
            Else
                TranslateMessage(@fbguiMsg)
                DispatchMessage(@fbguiMsg)
            End If
            
            If pAddressCallbackForLoop<>0 Then
                OnWindowProcCallBack_2(fbguiMSG.hwnd,fbguiMSG.message,fbguiMSG.wParam,fbguiMSG.lParam,fbguiMSG.Time,fbguiMSG.pt)
            End If
        Endif	
        
    endif
    
    Return iEventID
End Function

Function Waitevent() As Long Export
    Return w9DoEvents(0)
End Function

Function Windowevent() As Long Export
    Return w9DoEvents(1)
End Function
