uglobal
  hApplication dd 0     ; Only one application window can exists.
endg

iglobal
  cApplicationClassName du 'TApplication', 0
  property propMainForm,'MainForm'
  property propOnIdle, 'OnIdle'
  property propAccelerators, 'Accelerators'
endg

;initialize CreateAppPropertyes
;begin
;        stdcall CreateProperty, propMainForm
;        stdcall CreateProperty, propOnIdle
;        stdcall CreateProperty, propAccelerators
;        return
;endp
;
;
;finalize DeleteAppProperties
;begin
;        stdcall DestroyProperty, propMainForm
;        stdcall DestroyProperty, propOnIdle
;        stdcall DestroyProperty, propAccelerators
;        return
;endp
;

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

        mov     [.wc.style], CS_OWNDC
        mov     [.wc.lpfnWndProc], ApplicationWinProc
        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cApplicationClassName

        sub     edi, sizeof.WNDCLASS
        invoke  RegisterClassW, edi
        return
endp


proc InitApplication, .idIcon, .ptrCaption
begin
        pushad

        stdcall utf8ToWideChar, [.ptrCaption]
        mov     esi, eax

        xor     eax, eax
        invoke  CreateWindowExW, 0, cApplicationClassName, esi,                       \
                                WS_SYSMENU or WS_CAPTION or WS_POPUPWINDOW or         \
                                WS_VISIBLE or WS_CLIPSIBLINGS or WS_MINIMIZEBOX,      \
                                eax, eax, eax, eax,                                   \
                                eax, eax, [hInstance], eax
        mov     [hApplication], eax

        cmp     [.idIcon], 0
        je      .finish

        invoke  LoadImageW, [hInstance], [.idIcon], IMAGE_ICON, 16, 16, 0
        invoke  SendMessageW, [hApplication], WM_SETICON, ICON_SMALL, eax
        invoke  LoadImageW, [hInstance], [.idIcon], IMAGE_ICON, 32, 32, 0
        invoke  SendMessageW, [hApplication], WM_SETICON, ICON_BIG, eax

.finish:
        stdcall FreeMem, esi

        popad
        return
endp



proc ApplicationWinProc, .hwnd, .wmsg, .wparam, .lparam
.rect   RECT
.str    rb 1024
begin
        push    esi edi ebx

        dispatch [.wmsg]

.ondefault:
        invoke  DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]
        jmp     .finish

;-------------------------------------------------------------------------
oncase WM_ENABLE
        stdcall EnableAllOwnedWindows, [.hwnd], [.wparam]
        jmp     .ondefault

;;-------------------------------------------------
oncase WM_SETFOCUS

        DebugMsg "Application get focus"

        jmp     .ondefault

oncase WM_KILLFOCUS

        DebugMsg "Application lost focus"

        jmp     .ondefault


;-------------------------------------------------------------------------
oncase WM_CREATE
; hide window.
;        invoke  GetSystemMetrics, SM_CXSCREEN
;        mov     ebx, eax
;        invoke  GetSystemMetrics, SM_CYSCREEN
;        shr     ebx, 3
;        shr     eax, 3

        mov     ebx, -500
        mov     eax, -500

        xor     ecx,ecx
        invoke  SetWindowPos, [.hwnd], ecx, ebx, eax, ecx, ecx, SWP_NOZORDER or SWP_SHOWWINDOW
        jmp     .qfalse

;-------------------------------------------------------------------------
oncase WM_NCDESTROY
        invoke  GetPropW, [.hwnd], [propAccelerators]
        test    eax, eax
        jz      .accelok

        invoke  DestroyAcceleratorTable, eax

.accelok:
        invoke  SendMessageW, [.hwnd], WM_GETICON, ICON_SMALL, 0
        invoke  DestroyIcon, eax
        invoke  SendMessageW, [.hwnd], WM_GETICON, ICON_BIG, 0
        invoke  DestroyIcon, eax

        invoke  PostQuitMessage, 0
        jmp     .ondefault

;-------------------------------------------------------------------------
oncase AM_TRANSACCEL

        invoke  GetPropW, [.hwnd], [propAccelerators]
        test    eax, eax
        jz      .qfalse ; false - no accelerators table.
        mov     ebx, eax

        invoke  GetPropW, [.hwnd], [propMainForm]
        test    eax, eax
        jz      .qfalse ; false - no main form.
        mov     esi, eax

        invoke  IsWindowEnabled, esi
        test    eax, eax
        jz      .qfalse  ; false - the main form is disabled

        invoke  TranslateAcceleratorW, esi, ebx, [.wparam]    ; Accelerators handling.
        jmp     .finish

;-------------------------------------------------------------------------
oncase AM_ONIDLE
        invoke  GetPropW, [.hwnd], [propOnIdle]
        test    eax, eax
        jz      .qfalse

        call    dword eax

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

.qtrue:
        xor     eax, eax
        inc     eax
        jmp     .finish

.qfalse:
        xor     eax,eax

.finish:
        pop     ebx edi esi
        return

        enddispatch
endp