TFormLib:

iglobal
  cFormClassName du 'TForm', 0

  property propSplitGrid, 'SplitGrid'
  property propSplitCell, 'SplitCell'

  property propColor, 'Color'
  property propModalResult, 'ModalResult'
  property propModalMode, 'ModalMode'
  property propFont, 'Font'

  property propSplitterResize, 'SplitterResize'
  property propDragOfs, 'DragOffset'

  property propLastFocused, 'LastFocused'
endg



;initialize CreateFormProperties
;begin
;        stdcall CreateProperty, propLastFocused
;        stdcall CreateProperty, propColor
;        stdcall CreateProperty, propModalResult
;        stdcall CreateProperty, propFont
;        return
;endp


;finalize DeleteFormProperties
;begin
;        stdcall DestroyProperty, propLastFocused
;        stdcall DestroyProperty, propColor
;        stdcall DestroyProperty, propModalResult
;        stdcall DestroyProperty, propFont
;        return
;endp


;************************************************************
;*   Form class library                                     *
;*                                                          *
;*   This file is part of Fresh base library                *
;*   This is base window class for "Fresh" created project  *
;*                                                          *
;*   (C)2003, 2004 John Found                               *
;************************************************************

;*********************************************************************************************
; Registers form window class
; Call only once
;*********************************************************************************************
initialize RegisterFormClass

.wc WNDCLASS

begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     ecx, sizeof.WNDCLASS / 4
        rep stosd

        invoke  LoadCursorW, eax, IDC_ARROW
        mov     [.wc.hCursor],eax
        mov     [.wc.style], CS_OWNDC
        mov     [.wc.lpfnWndProc], FormWinProc
        mov     [.wc.cbWndExtra], 32
        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cFormClassName

        lea     eax, [.wc]
        invoke  RegisterClassW, eax

        return
endp




;*********************************************************************************************
; Main window procedure for 'TForm' window class.
;*********************************************************************************************
proc FormWinProc, .hwnd, .wmsg, .wparam, .lparam
  .rect  RECT
begin
        push    ebx edi esi

        dispatch [.wmsg]

.ondefault:

        invoke  DefWindowProcW, [.hwnd],[.wmsg],[.wparam],[.lparam]
        pop     esi edi ebx
        return


;------------------------------------------------------------------------
oncase FM_SETCOLOR
        mov      eax, [.wparam]
        cmp      eax, $ff000000
        jne      .setcolor

        invoke  RemovePropW, [.hwnd], [propColor]
        pop     esi edi ebx
        return

.setcolor:
        or       eax, $ff000000
        invoke   SetPropW, [.hwnd], [propColor], eax
        invoke   InvalidateRect, [.hwnd], NULL, TRUE
        pop     esi edi ebx
        return

;-------------------------------------------------

oncase WM_SETFOCUS

        invoke  GetPropW, [.hwnd], [propLastFocused]

;        OutputValue "Last focused window: ", eax, 16, 8

        test    eax, eax
        jz      .focus_next

        invoke  SetFocus, eax
        jmp     .endsetfocus

.focus_next:
        invoke  GetNextDlgTabItem, [.hwnd], NULL, FALSE

;        OutputValue "GetNextDlgTabItem result: ", eax, 16, 8

        test    eax, eax
        jz      .endsetfocus

        invoke  SetFocus, eax

.endsetfocus:
        xor     eax, eax
        pop     esi edi ebx
        return

;-------------------------------------------------------------------------
oncase WM_NOTIFY

        mov     esi, [.lparam]

        cmp     [esi+NMHDR.code], NM_SETFOCUS
        jne     .ondefault

        invoke  SetPropW, [.hwnd], [propLastFocused], [esi+NMHDR.hwndFrom]

        invoke  GetAncestor, [.hwnd], GA_PARENT
        test    eax, eax
        jz      .ondefault

        mov     ecx, [.hwnd]
        mov     [esi+NMHDR.hwndFrom], ecx
        mov     [esi+NMHDR.idFrom], 0

        invoke  SendMessageW, eax, WM_NOTIFY, 0, esi

        jmp     .ondefault

;-------------------------------------------------------------------------
;oncase WM_NEXTDLGCTL
;;          int3
;        cmp     [.lparam], FALSE
;        je      .nextprev
;
;        invoke  SetFocus, [.wparam]
;        xor     eax, eax
;        pop     esi edi ebx
;        return
;
;.nextprev:
;        stdcall GetFocusedControl, [.hwnd]
;        test    eax, eax
;        jz      .focusok
;
;        invoke  GetNextDlgTabItem, [.hwnd], eax, [.wparam]
;        invoke  SetFocus, eax
;
;.focusok:
;        pop     esi edi ebx
;        return

;------------------------------------------------------------------------

oncase WM_ERASEBKGND

        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax

        invoke  GetPropW, [.hwnd], [propColor]
        test    eax, eax
        jnz     .colorok

        invoke  GetSysColor, COLOR_BTNFACE

.colorok:
        and     eax, $ffffff
        invoke  CreateSolidBrush, eax
        push    eax
        lea     ecx, [.rect]
        invoke  FillRect, [.wparam], ecx, eax
        invoke  DeleteObject ; from the stack.

        xor     eax, eax
        inc     eax
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
oncase WM_COMMAND

        movzx   eax, word [.wparam]
        cmp     eax, MODAL_MIN
        jb      .post_to_parent
        cmp     eax, MODAL_MAX
        ja      .post_to_parent

        invoke  SetPropW, [.hwnd], [propModalResult], eax

        xor     eax, eax
        pop     esi edi ebx
        return


.post_to_parent:

        invoke  GetParent, [.hwnd]
        test    eax, eax
        jz      .ondefault

        invoke  PostMessageW, eax, [.wmsg], [.wparam], [.lparam]
        xor     eax, eax
        pop     esi edi ebx
        return


;------------------------------------------------------------------------
oncase WM_CLOSE

        invoke  GetPropW, [.hwnd], [propModalMode]
        test    eax, eax
        jz      .ondefault

        invoke  SetPropW, [.hwnd], [propModalResult], MR_CANCEL

        xor     eax, eax
        pop     esi edi ebx
        return

;------------------------------------------------------------------------

if defined GUILib & defined CreateCoolMenu.__info.codesize
;------------------------------------------------------------------------
oncase WM_MEASUREITEM
        stdcall OnMeasureItem,[.hwnd],[.lparam]
        mov     eax, TRUE
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
oncase WM_DRAWITEM
        stdcall OnDrawItem, [.lparam]
        mov     eax, TRUE
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
oncase WM_MENUCHAR
        stdcall OnMenuChar, [.wparam], [.lparam]
        jc      .ondefault
        pop     esi edi ebx
        return

end if

;------------------------------------------------------------------------
oncase WM_GETFONT
        invoke  GetPropW, [.hwnd], [propFont]
        test    eax, eax
        jnz     @f

;        invoke  GetStockObject, DEFAULT_GUI_FONT

        stdcall GetDefaultFont, gdfMenu

@@:
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
oncase WM_PARENTNOTIFY
        cmp     word [.wparam], WM_CREATE
        jne     @f

        invoke  GetPropW, [.lparam], [propOwnFont]
        test    eax, eax
        jnz     @f

        invoke  SendMessageW, [.hwnd], WM_GETFONT, 0, 0
        invoke  SendMessageW, [.lparam], WM_SETFONT, eax, 0     ;TRUE

@@:
        xor     eax, eax
        pop     esi edi ebx
        return

        enddispatch
endp



proc GetFocusedControl, .hwnd
begin
        push    esi ebx
        invoke  GetFocus
        mov     esi, eax

.parentloop:
        mov     ebx, eax
        invoke  GetParent, eax
        test    eax, eax
        jnz     .parentloop

;        xor     eax, eax     ; eax is zero here...
        cmp     ebx, [.hwnd]
        jne     .endfocused
        mov     eax, esi
.endfocused:
        pop     ebx esi
        return
endp


;*********************************************************************************************
; Shows given form in modal form.
; Returns modal result
; This is first version so behaviour is not very proper.
;*********************************************************************************************

proc ShowModal, .hwnd, .flags

.info MONITORINFO
.rect RECT

begin
        push    esi edi ebx

;        invoke  GetFocus
;        push    eax      ; the parameter for SetFocus at the end of the procedure.

;if defined AppLib
;        mov     eax, [hApplication]
;else
;  if defined hMainForm
;        mov eax, [hMainForm]
;  else
;        mov eax, [.hwnd]
;  end if
;end if

        invoke  GetWindow, [.hwnd], GW_OWNER
;        invoke  GetWindowLongW, [.hwnd], GWL_HWNDPARENT
        invoke  MonitorFromWindow, eax, 2

        mov     [.info.cbSize], sizeof.MONITORINFO
        lea     ebx, [.info]
        invoke  GetMonitorInfoW, eax, ebx

        lea     eax, [.rect]
        invoke  GetWindowRect, [.hwnd], eax

        mov     esi, [.rect.left]
        mov     edi, [.rect.top]

        test    [.flags], MSF_HCENTER
        jz      @f

        mov     eax, [.info.rcWork.right]
        sub     eax, [.info.rcWork.left]
        sub     eax, [.rect.right]
        add     eax, [.rect.left]
        sar     eax, 1
        add     eax, [.info.rcWork.left]
        mov     esi, eax

@@:
        test    [.flags], MSF_VCENTER
        jz      @f

        mov     eax, [.info.rcWork.bottom]
        sub     eax, [.info.rcWork.top]
        sub     eax, [.rect.bottom]
        add     eax, [.rect.top]
        sar     eax, 1
        add     eax, [.info.rcWork.top]
        mov     edi, eax

@@:
        invoke  SendMessageW, [.hwnd], WM_INITDIALOG, 0, 0
        invoke  SetWindowPos, [.hwnd], HWND_TOP, esi, edi, 0, 0, SWP_NOSIZE
        invoke  ShowWindow, [.hwnd], SW_SHOW

        invoke  GetWindow, [.hwnd], GW_OWNER
        mov     ebx, eax

; Disables window owner and all other windows owned by window owner.

        invoke  EnableWindow, ebx, FALSE
        stdcall EnableAllOwnedWindows, ebx, FALSE       ; This is useless if all top level windows
                                                        ; are TForm, but it is important if not...

        invoke  EnableWindow, [.hwnd], TRUE              ; IMPORTANT: re-enable modal window.

        invoke  GetNextDlgTabItem, [.hwnd], NULL, FALSE
        test    eax, eax
        jz      @f
        invoke  SetFocus, eax
@@:
        invoke  SetPropW, [.hwnd], [propModalResult], MR_NONE
        invoke  SetPropW, [.hwnd], [propModalMode], 1

; Special message loop for modal window. It not finish until window becomes invisible.
.modalloop:
        call    ProcessMessages

        invoke  IsWindowVisible, [.hwnd]
        test    eax,eax
        jz      .endloop

        invoke  GetPropW, [.hwnd], [propModalResult]
        test    eax,eax              ; mrNone = 0
        jnz     .endloop

        invoke  SendMessageW, [.hwnd], FM_ONIDLE, 0, 0

        invoke  WaitMessage
        jmp     .modalloop

.endloop:
        invoke  RemovePropW, ebx, [propModalMode]

        stdcall EnableAllOwnedWindows, ebx, TRUE
        invoke  EnableWindow, ebx, TRUE
        invoke  ShowWindow, [.hwnd], SW_HIDE

        invoke  GetPropW, [.hwnd], [propModalResult]
        pop     ebx edi esi
        return
endp


;-------------------------------------------------------------
; Enables or disables all windows owned by specifyed window.
;
; fEnable - TRUE = enable
;           FALSE = disable
;-------------------------------------------------------------
proc EnableAllOwnedWindows, .hwnd, .fEnable
        begin

        mov     eax, _EnableOwnedProc
        cmp     [.fEnable], FALSE
        jne     @f
        mov     eax, _DisableOwnedProc
@@:
        invoke  EnumWindows, eax, [.hwnd]
        return
endp


; callback procedure used in EnableAllOwnedWindows
proc _EnableOwnedProc, .hwnd, .owner
begin

        invoke  GetWindow, [.hwnd], GW_OWNER
        cmp     eax, [.owner]
        jne     .ready
        invoke  EnableWindow, [.hwnd], TRUE

.ready:
        mov     eax, 1
        return
endp


; callback procedure used in EnableAllOwnedWindows
proc _DisableOwnedProc, .hwnd, .owner
begin
        invoke  GetWindow, [.hwnd], GW_OWNER

        cmp     eax, [.owner]
        jne     .ready
        invoke  EnableWindow, [.hwnd], FALSE
.ready:
        mov     eax, 1
        return
endp




DispSize 'TForm class library', $ - TFormLib