waNone   = 0
waLeft   = 1
waRight  = 2
waTop    = 3
waBottom = 4
waClient = 5


        ; Global variables used from this module.
uglobal
  hMainForm       dd ?  ; MainWindow handle.
  hMainMenu       dd ?  ; handle of main menu.
  hReopenMenu     dd ?  ; handle of the reopen submenu.
  hMainToolbar    dd ?  ; handle of main toolbar
  hIml            dd ?  ; handle of image list for the toolbar/menu
  hImlGray        dd ?  ; handle of image list for disabled buttons/menu
  hDefImageBitmap dd ?

  hCfgFileName    dd ?  ; handle of the string with INI file name
endg


iglobal
  cMainTitle      text 'Fresh ', FRESH_VERSION, 0
  cMainSeparator  text ' : '
  cHintSelectTool text 'Select tool'

  cLayoutSection     text 'Layout'
  cShowPaletteKey    text 'ShowPalette'
  cShowPropertiesKey text 'ShowProperties'
  cMainWindowState   text 'WindowState'
  cMainWindowL       text 'WindowLeft'
  cMainWindowT       text 'WindowTop'
  cMainWindowR       text 'WindowRight'
  cMainWindowB       text 'WindowBottom'
;  cShowListerKey     text 'ShowScratchpad'

  Window MainForm, wtEnd, waNone, 'TForm', cMainTitle,                                          \
                   WS_CAPTION or WS_SIZEBOX or WS_CLIPCHILDREN or                               \
                   WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX,                              \
                   WS_EX_CONTROLPARENT or WS_EX_APPWINDOW, NULL, 0, 0, 800, 600, MainWindowProc


;  macro Split type, width, pos, min, max \{
;   macro Cell name \{

  SplitStart MainLayout
    Split stVert or stJustGap or stAutosize, 2, 100, 0, 1000
      Cell cellMainToolbar                                ; main toolbar
      Split stVert or stJustGap, 2, 64, 0, 64
        Cell cellPalette                                  ; components palette
        Split stHoriz, 4, 200, 32, 600                    ; left/right pane of the window.
          Split stVert or stRelative, 4, 10000, 0, 32768  ; up - properties; down - project manager.
            Cell cellPropEditor
            Cell cellProjectManager
          Split stVert or stOriginBR or stHidden, 4, 100, 0, 600
            Split stVert or stOriginBR or stJustGap, 0, 22, 22, 22
              Split stHoriz or stOriginBR or stRelative or stHidden, 4, 10240, 0, 24576
                Cell cellEditorHost
                Cell cellLister
              Cell cellStatus
            Cell cellMessages
  SplitEnd

endg


;**************************************************
; Creates form for main window.
;**************************************************

proc InitMainWindow
.wp WINDOWPLACEMENT
begin
        push    ebx

        xor     ebx,ebx
        stdcall CreateForm, MainForm, 0
        mov     [hMainForm], ebx

; Create the tool palette
        stdcall OnReloadVCL, 0, [hMainForm]

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cShowPaletteKey, 1
        test    eax, eax
        setnz   al
        movzx   eax, al

        push    eax eax
        invoke  ShowWindow, [hToolPalette], eax
        stdcall ActionSetCheck, actViewPalette ; from the stack
        stdcall SetCellHidden, [hMainForm], MainLayout.cellPalette ; from the stack

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cShowPropertiesKey, 1
        test    eax, eax
        setnz   al
        movzx   eax, al

        push    eax
        invoke  ShowWindow, [hPropEditor], eax
        stdcall ActionSetCheck, actViewPropEditor ; from the stack

        stdcall __RefreshLeftPane

        mov     [.wp.length], sizeof.WINDOWPLACEMENT
        lea     eax, [.wp]
        invoke  GetWindowPlacement, ebx, eax

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cMainWindowState, SW_SHOWNORMAL
        mov     [.wp.showCmd], eax

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cMainWindowL, [.wp.rcNormalPosition.left]
        mov     [.wp.rcNormalPosition.left], eax

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cMainWindowT, [.wp.rcNormalPosition.top]
        mov     [.wp.rcNormalPosition.top], eax

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cMainWindowR, [.wp.rcNormalPosition.right]
        mov     [.wp.rcNormalPosition.right], eax

        stdcall CfgGetInt, [hCfgFileName], cLayoutSection, cMainWindowB, [.wp.rcNormalPosition.bottom]
        mov     [.wp.rcNormalPosition.bottom], eax

        lea     eax, [.wp]
        invoke  SetWindowPlacement, ebx, eax

        pop     ebx
        return
endp




;**************************************************************************
; Main window message callback procedure
;**************************************************************************
proc MainWindowProc, .hwnd, .wmsg, .wparam, .lparam

.rect   RECT
.tci    TCITEM
.tce    TEditorTab
.tbb    TToolbarButton
.mii    MENUITEMINFO
.msg    TFreshMsg
.wp     WINDOWPLACEMENT
.str    rb 1024

.pnt    POINT
.tchi   TCHITTESTINFO

begin
        dispatch [.wmsg]

.default:
        stc
        return


oncase WM_DROPFILES

        DebugMsg "WM_DROPFILES in main window"

        clc
        return


oncase WM_CLOSE

        stdcall OnCloseAll, 0, 0

        mov     eax, [listFiles]
        cmp     [eax+TArray.count], 0
        je      .closeit

; Cancel the close.

        xor     eax, eax
        clc
        return

.closeit:

; Save the window placement

        mov     [.wp.length], sizeof.WINDOWPLACEMENT
        lea     eax, [.wp]
        invoke  GetWindowPlacement, [.hwnd], eax

        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cMainWindowState, [.wp.showCmd]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cMainWindowL, [.wp.rcNormalPosition.left]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cMainWindowT, [.wp.rcNormalPosition.top]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cMainWindowR, [.wp.rcNormalPosition.right]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cMainWindowB, [.wp.rcNormalPosition.bottom]


; Save the visual layout

        invoke  IsWindowVisible, [hToolPalette]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cShowPaletteKey, eax

        invoke  IsWindowVisible, [hPropEditor]
        stdcall CfgSetInt, [hCfgFileName], cLayoutSection, cShowPropertiesKey, eax

; and quit

        invoke  PostQuitMessage
        stc
        return


;----- FM_ONIDLE -------------------------------------

oncase FM_ONIDLE

        stdcall OnIdle
        clc
        return


;-----WM_INITMENUPOPUP--------------------------------

oncase WM_INITMENUPOPUP

        mov     eax, [.wparam]
        cmp     eax, [hReopenMenu]
        jne     .qtrue

        stdcall FillMRUMenu, [.wparam], [ptrMRUProj], FirstMRU, 1
        stdcall FillMRUMenu, [.wparam], [ptrMRUFiles], FirstMRU, 2
        jmp     .qfalse

;---- WM_SETTEXT -------------------------------------

oncase WM_SETTEXT

        stdcall StrDup, cMainTitle
        mov     ebx, eax

        mov     eax, [.lparam]
        test    eax, eax
        jz      .setit

        cmp     word [eax], 0
        je      .setit

        stdcall StrCat, ebx, cMainSeparator

        stdcall WideCharToUtf8, [.lparam]
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

.setit:
        stdcall utf8ToWideChar, ebx
        push    eax

        invoke  DefWindowProcW, [.hwnd], WM_SETTEXT, 0, eax
        stdcall FreeMem ; from the stack
        clc
        return


;--- WM_NOTIFY ------------------------------------------------

oncase WM_NOTIFY

        mov     edi, [.lparam]
        mov     ebx, [edi+NMHDR.code]

;        OutputValue "Notification code: ", ebx, 16, 8

        call    JumpTo
        MessageList                             \
            TTN_NEEDTEXTW,   .tooltipneedtext,  \
            TCN_SELCHANGE,   .tab_selchange,    \
            TCN_SELCHANGING, .tab_selchanging,  \
            TBN_DROPDOWN,    .dropdown,         \
            NM_RCLICK,       .rclick
        jmp     .default


.get_tab_from_mouse:

        lea     ebx, [.pnt]
        invoke  GetCursorPos, ebx

        mov     ecx, [.pnt.x]
        mov     edx, [.pnt.y]
        mov     [.tchi.pt.x], ecx
        mov     [.tchi.pt.y], edx

        lea     ebx, [.tchi]
        invoke  ScreenToClient, esi, ebx
        invoke  SendMessageW, esi, TCM_HITTEST, 0, ebx
        test    eax, eax

        retn


; right click somewhere...

.rclick:
        mov     esi, [hEditorsHost]
        cmp     esi, [edi+NMHDR.hwndFrom]
        jne     .default

        call    .get_tab_from_mouse
        js      .qfalse

        invoke  SendMessageW, esi, _EHM_SETACTIVETAB, eax, 0
        invoke  TrackPopupMenu, [hTabMenu], TPM_LEFTALIGN or TPM_RIGHTBUTTON, [.pnt.x], [.pnt.y] , 0, [.hwnd], NULL
        jmp     .qfalse


; Opens drop-down menu for reopen files.
.dropdown:
        lea     ebx, [.rect]
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TB_COMMANDTOINDEX, [edi+NMTOOLBAR.iItem], 0
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TB_GETITEMRECT, eax, ebx
        invoke  ClientToScreen, [edi+NMHDR.hwndFrom], ebx
        add     ebx, 8
        invoke  ClientToScreen, [edi+NMHDR.hwndFrom], ebx
        invoke  TrackPopupMenu, [hReopenMenu], TPM_LEFTALIGN, [.rect.left], [.rect.bottom], 0, [.hwnd], NULL
        jmp     .qfalse


.tooltipneedtext:

; Get hint text for toolbars and other controls.

;        DebugMsg "Tooltip needs text..."

;        OutputValue "Tooltip needs text ID: ", [edi+TOOLTIPTEXTW.hdr.idFrom], 16, 8
;        OutputValue "Tooltip needs text HWND: ", [edi+TOOLTIPTEXTW.hdr.hwndFrom], 16, 8

        mov     esi, [hEditorsHostTooltips]
        cmp     esi, [edi+TOOLTIPTEXTW.hdr.hwndFrom]
        je      .editor_host

        cmp     [edi+NMHDR.idFrom], FirstID
        jae     .maintoolbar


; the tooltip text for a toolbar from the component palette.

.components:

        invoke  SendMessageW, [hToolPalette], TCM_GETCURSEL, 0, 0
        mov     [.tci.mask], TCIF_PARAM
        lea     ebx, [.tci]
        invoke  SendMessageW, [hToolPalette], TCM_GETITEMW, eax, ebx

        lea     eax, [.tbb]
        mov     ecx, [edi+NMHDR.idFrom]
        inc     ecx                             ; index of the button is ID+1, because of the separator.

        invoke  SendMessageW, [.tci.lParam], TB_GETBUTTON, ecx, eax

        mov     ecx, cHintSelectTool
        mov     eax, [.tbb.dwData]
        and     eax, $7fffffff
        test    eax, eax
        jz      @f

        mov     ecx, [eax+TDesignTimeInfo.ControlHint]
@@:
        lea     eax, [edi+TOOLTIPTEXTW.char]
        mov     [edi+TOOLTIPTEXTW.lpszText], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, ecx, -1, eax, 78

        mov     [edi+TOOLTIPTEXTW.hinst], 0
        jmp     .qfalse


; tooltip text for the tabs of the editors host - the full filename of the file.

.editor_host:

        mov     esi, [hEditorsHost]

        call    .get_tab_from_mouse
        js      .qfalse

        mov     [.tce.mask], TCIF_PARAM

        lea     ecx, [.tce]
        invoke  SendMessageW, esi, TCM_GETITEMW, eax, ecx

        stdcall GetEditorFile, [.tce.hEditor]
        test    eax, eax
        jz      .qfalse

        stdcall StrDup, [eax+TOpenFile.hFileName]
        mov     ebx, eax
        stdcall StrLenUtf8, ebx, -1
        jc      .free_name

        sub     eax, 79
        jle     .lengthok

        add     eax, 4
        stdcall StrByteUtf8, ebx, eax

        stdcall StrSplit, ebx, eax
        stdcall StrDel, ebx
        mov     ebx, eax

        stdcall StrCharInsert, ebx, "...", 0

.lengthok:

        lea     ecx, [edi+TOOLTIPTEXTW.char]
        mov     [edi+TOOLTIPTEXTW.lpszText], ecx
        mov     [edi+TOOLTIPTEXTW.hinst], 0

        stdcall StrPtr, ebx
        invoke  MultiByteToWideChar, CP_UTF8, 0, eax, -1, ecx, 79

.free_name:
        stdcall StrDel, ebx
        jmp     .qfalse


; tooltip text for the buttons from the main toolbar.

.maintoolbar:

        mov     ebx, [edi+NMHDR.idFrom]
        sub     ebx, FirstID
        stdcall GetHintText, MainActionList, ebx

        stdcall StrDupMem, eax
        mov     esi, eax

        stdcall StrCharCat, esi, $0a0d
        stdcall StrCharCat, esi, "["

        imul    ebx, sizeof.TAction
        lea     ecx, [.str]
        stdcall AccelToStr, [MainActionList + ebx + TAction.ptrAccel], ecx

        lea     ecx, [.str]
        stdcall StrCat, esi, ecx
        stdcall StrCharCat, esi, "]"

        stdcall StrPtr, esi
        lea     ecx, [edi+TOOLTIPTEXTW.char]
        mov     [edi+TOOLTIPTEXTW.lpszText], ecx
        invoke  MultiByteToWideChar, CP_UTF8, 0, eax, -1, ecx, 78

        stdcall StrDel, esi

        mov     [edi+TOOLTIPTEXTW.hinst], 0
        jmp     .qfalse


; TAB control notifications.

.tab_selchange:

        mov     eax, [edi+NMHDR.hwndFrom]
        cmp     eax, [hToolPalette]
        je      .plt_selchange

        cmp     eax, [hEditorsHost]
        je      .edt_selchange

        jmp     .qfalse

.tab_selchanging:

        mov     eax, [edi+NMHDR.hwndFrom]
        cmp     eax, [hToolPalette]
        je      .plt_selchanging

        cmp     eax, [hEditorsHost]
        je      .edt_selchanging

        jmp     .qfalse


.edt_selchanging:

;        DebugMsg "Editors host, selection changing!"

        invoke  SendMessageW, [hEditorsHost], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .qfalse

        lea     ebx, [.tce]
        mov     [.tce.mask], TCIF_PARAM
        invoke  SendMessageW, [hEditorsHost], TCM_GETITEMW, eax, ebx

;        stdcall AttachToCell, [.tce.hEditor], [hEditorsHost], 0

uglobal
  hEditorToHide dd ?
endg

; the idea here is to hide the current editor later in order to reduce the flicker.
        push    [.tce.hEditor]
        pop     [hEditorToHide]
        jmp     .qfalse



.edt_selchange:

        invoke  SendMessageW, [hEditorsHost], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .qfalse

        mov     ebx, eax
        lea     ecx, [.tce]
        mov     [.tce.mask], TCIF_PARAM
        invoke  SendMessageW, [hEditorsHost], TCM_GETITEMW, ebx, ecx

        invoke  SendMessageW, [edi+NMHDR.hwndFrom], SGM_REALIGN, 0, 0
        stdcall AttachToCell, [.tce.hEditor], [hEditorsHost], EditorLayout.cellEditor
        invoke  ShowWindow, [.tce.hEditor], SW_SHOWNORMAL

        mov     ecx, [hEditorToHide]
        jecxz   .hideok

        cmp     ecx, [.tce.hEditor]
        je      .hideok

        invoke  GetPropW, [hEditorToHide], [propWinTemplate]
        test    eax, eax
        jz      .form_ok

        mov     eax, [eax+TWinTemplateDT.hwnd]
        test    eax, eax
        jz      .form_ok

        invoke  ShowWindow, eax, SW_HIDE

.form_ok:
        invoke  SendMessageW, [hEditorToHide], _CEM_GETASMEDIT, 0, 0
        invoke  ShowWindow, eax, SW_HIDE

.hideok:
        mov     [hEditorToHide], 0
        invoke  InvalidateRect, [hEditorsHost], 0, TRUE

;        invoke  SetFocus, 0                             ; work around for ASMEDIT bug (highly obscure)
        invoke  SetFocus, [.tce.hEditor]

        stdcall GetEditorFile, [.tce.hEditor]
        mov     ebx, eax
        stdcall SetCurrentFile, ebx

        stdcall utf8ToWideChar, [ebx+TOpenFile.hFileName]
        push    eax

        invoke  SendMessageW, [hStatus], SB_SETTEXTW, 6, eax
        stdcall FreeMem ; from the stack.

        jmp     .qfalse



; Tool palette tab control, selection changed.
.plt_selchange:
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], SGM_REALIGN, 0, 0

        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TCM_GETCURSEL, 0, 0
        mov     [.tci.mask], TCIF_PARAM
        lea     ebx, [.tci]
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TCM_GETITEMW, eax, ebx

        invoke  ShowWindow, [.tci.lParam], SW_SHOWNORMAL
        stdcall AttachToCell, [.tci.lParam], [hToolPalette], PaletteLayout.cellPalette
        invoke  SendMessageW, [.tci.lParam], TB_CHECKBUTTON, 0, TRUE
        jmp     .qfalse

.plt_selchanging:
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TCM_GETCURSEL, 0, 0
        lea     ebx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageW, [edi+NMHDR.hwndFrom], TCM_GETITEMW, eax, ebx

        stdcall AttachToCell, [.tci.lParam], [hToolPalette], 0
        invoke  ShowWindow, [.tci.lParam], SW_HIDE
        jmp     .qfalse



;--------- AM_INITWINDOW -------------------------------------------

oncase AM_INITWINDOW

; Create string with the filename of the INI file.

        stdcall GetMem, 4096
        mov     ebx, eax

        invoke  GetModuleFileNameW, NULL, ebx, 2048

        stdcall WideCharToUtf8, ebx
        stdcall FreeMem, ebx
        push    eax

        stdcall StrChangeExt, eax, txt '.cfg'
        stdcall StrDel ; from the stack

        mov     [hCfgFileName], eax
        mov     [procCfgMatchPattern], StrMatchPatternNoCase

; Set the main splitgrid

        stdcall SetSplitGrid, [.hwnd], MainLayout

; Create image lists for toolbar and menus
        stdcall ImageList_LoadGif, [hInstance], resBmpAll, 16, FALSE
        mov     [hIml], eax

        stdcall ImageList_LoadGif, [hInstance], resBmpAll, 16, TRUE
        mov     [hImlGray],eax

; Create main menu
        stdcall CreateCoolMenu, MainMenu, FALSE
        mov     [hMainMenu], eax
        invoke  SetMenu, [.hwnd], [hMainMenu]

        invoke  GetSubMenu, [hMainMenu], 0      ; Get file menu
        invoke  GetSubMenu, eax, 3              ; Get reopen menu
        mov     [hReopenMenu], eax

; Create the main toolbar
        stdcall CreateCoolToolbar, MainActionList, MainToolbar, [.hwnd], $2000, [hIml], [hImlGray]
        mov     [hMainToolbar],eax

        stdcall AttachToCell, [hMainToolbar], [.hwnd], MainLayout.cellMainToolbar
        stdcall AttachToCell, [hMainToolbar], [.hwnd], 0

; Set Main window icon.
        invoke  LoadImageW, [hInstance], resAppIcon, IMAGE_ICON, 0, 0, 0
        invoke  SendMessageW, [.hwnd], WM_SETICON, ICON_SMALL, eax

        invoke  LoadImageW, [hInstance], resAppIcon, IMAGE_ICON, 0, 0, 0
        invoke  SendMessageW, [.hwnd], WM_SETICON, ICON_BIG, eax

; Init of the windows and systems in the application...

        mov     [passes_limit], $80

        stdcall InitEditorHost, [.hwnd]
        stdcall InitMessageWindow, [.hwnd]
        stdcall CheckParams

        stdcall InitSourceEditor  ; Create source editor.
        stdcall InitDumperWindow, [frmMsg]
        stdcall InitListerWindow, [.hwnd]

        stdcall InitPropEditor, [.hwnd]         ; Create property editor
        stdcall InitProjectManager              ; Create project manager

        stdcall InitFileManager

        stdcall InitFindOptions, [.hwnd]
        stdcall InitHelp


        jmp     .qfalse



;---------- WM_DESTROY ------------------------------------

oncase WM_DESTROY

        cmp     [comp_handle], 0
        je      @f

        invoke  TerminateThread, [comp_handle], 0
        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0
@@:
        invoke  DestroyWindow, [hEditorsHost]
        stdcall FinalizeSourceEditor
        stdcall FinalizeProjectManager
        stdcall CloseFileManager

        stdcall DestroyToolPalette

        stdcall FreeLabelsTree, [ptrLabels]
        mov     [ptrLabels], 0

        stdcall ClearDebugInfo
        stdcall FreePreprocessed

        invoke  DestroyWindow, [hFindHistory]

        invoke  ImageList_Destroy,[hIml]
        invoke  ImageList_Destroy,[hImlGray]

        invoke  SendMessageW, [.hwnd], WM_GETICON, TRUE, 0
        invoke  DestroyIcon, eax
        invoke  SendMessageW, [.hwnd], WM_GETICON, FALSE, 0
        invoke  DestroyIcon, eax

        invoke  DeleteObject, [hDefImageBitmap]
        invoke  DestroyMenu, [hMainMenu]

        stdcall StrDel, [hCfgFileName]

        jmp     .qfalse

;---------- WM_SYSCOMMAND -----------------------

oncase WM_SYSCOMMAND

        DebugMsg "WM_SYSCOMMAND to the main window!"
        OutputValue "wparam = ", [.wparam], 16, 8
        OutputValue "lparam = ", [.lparam], 16, 8

        stc
        return


;---------- WM_COMMAND -----------------------

oncase WM_COMMAND

;        DebugMsg "WM_COMMAND to the main window!"
;        OutputValue "wparam = ", [.wparam], 16, 8
;        OutputValue "lparam = ", [.lparam], 16, 8


        movzx   esi, word [.wparam]

        cmp     esi, IDCANCEL
        je      .close_something

        cmp     esi, IDOK
        je      .key_enter

        cmp     esi, FirstID
        jl      .maybeMRU

        sub     esi,FirstID
        cmp     esi,[MainActionList.Number]
        jge     .default

        imul    esi,sizeof.TAction
        add     esi,MainActionList

        xor     eax,eax
        cmp     [esi+TAction.OnExecute],eax
        je      .qfalse

        stdcall [esi+TAction.OnExecute], [.wparam], [.lparam]
        jmp     .qtrue


.maybeMRU:
        sub     esi, FirstMRU
        js      .default

        invoke  GetMenuItemCount, [hReopenMenu]
        cmp     esi, eax
        jge     .default

        mov     [.mii.cbSize], sizeof.MENUITEMINFO
        mov     [.mii.fMask], MIIM_TYPE
        mov     [.mii.fType], MFT_STRING
        lea     ebx, [.str]
        mov     [.mii.dwTypeData], ebx
        mov     [.mii.cch], 512

        lea     eax, [.mii]
        invoke  GetMenuItemInfoW, [hReopenMenu], esi, TRUE, eax
        test    eax, eax
        jz      .default

        stdcall WideCharToUtf8, ebx
        push    eax

        stdcall OpenFileByName, eax, NULL, TRUE       ; inteligent open project/file.
        stdcall StrDel ; from the stack.
        jmp     .qtrue


.key_enter:

        invoke  GetFocus
        mov     ebx, eax

        invoke  GetAncestor, ebx, GA_PARENT
        test    eax, eax
        jz      .default

        cmp     eax, [.hwnd]
        je      .default

; post it back to the sender parent with lparam == focused control handle.

        invoke  PostMessageW, eax, WM_COMMAND, [.wparam], ebx
        jmp     .qfalse


.close_something:
        invoke  GetFocus
        cmp     eax, [tvMessagesWin]
        je      .close_messages


        cmp     [hCCList], 0
        je      .ccok

        invoke  PostMessageW, [hCCList], WM_CLOSE, 0, 0
        jmp     .qfalse

.ccok:
        cmp     [hPAHint], 0
        je      .phok

        invoke  PostMessageW, [hPAHint], WM_CLOSE, 0, 0
        jmp     .qfalse

.phok:
        cmp     [hEHelp], 0
        je      .ehok

        invoke  PostMessageW, [hEHelp], WM_CLOSE, 0, 0
        jmp     .qfalse

.ehok:
        cmp     [hLabelInfo], 0
        je      .qfalse

        invoke  PostMessageW, [hLabelInfo], WM_CLOSE, 0, 0
        jmp     .qfalse


.close_messages:
        invoke  SendMessageW, [frmMsg], MWM_SHOWMESSAGES, 0, 0
        invoke  SetFocus, [hEditorsHost]
        jmp     .qfalse


; ..... return constants .......................

.qfalse:
        xor     eax,eax
        clc
        return

.qtrue:
        xor     eax,eax
        inc     eax
        clc
        return


;----------------------------------------------------------------------------------------------------
;      DEBUGGER MESSAGES.
;----------------------------------------------------------------------------------------------------

oncase DM_STATUSCHANGED

        mov     ecx, cStatusRunning
        cmp     [dbgStatus], dsRunning
        je      .statusok
        mov     ecx, cStatusPaused
        cmp     [dbgStatus], dsPaused
        je      .statusok
        mov     ecx, cStatusTerminated
        cmp     [dbgStatus], dsFinished
        je      .statusok
        mov     ecx, cStatusUnknown

.statusok:
        invoke  SendMessageW, [hStatus], SB_SETTEXTW, 5, ecx
        clc
        return


iglobal
  cStatusRunning    du  ' Running...', 0
  cStatusPaused     du  ' Paused', 0
  cStatusTerminated du  ' Finished', 0
  cStatusUnknown    du  ' Unknown', 0
endg


oncase DM_EVENTRAISED

        cmp     [.wparam], 0
        jne     .exception

        mov     esi, [dbgEvent.dwDebugEventCode]
        cmp     esi, 9
        jbe     @f
        xor     esi, esi
@@:
        stdcall [TblDebugEvents+4*esi]
        test    eax, eax
        jz      .loggingOK

        lea     edi, [.msg]
        mov     [edi+TFreshMsg.type], mtDebug
        mov     [edi+TFreshMsg.hMessage], eax
        mov     [edi+TFreshMsg.link.hFileName], 0

        invoke  SendMessageW, [frmMsg], MWM_ADDMESSAGE, edi, TVI_ROOT
        stdcall StrDel, [edi+TFreshMsg.hMessage]

.loggingOK:
        cmp     esi, EXCEPTION_DEBUG_EVENT
        je      .exception

        cmp     esi, CREATE_PROCESS_DEBUG_EVENT
        je      .createprocess

        cmp     esi, EXIT_PROCESS_DEBUG_EVENT
        je      .exitprocess

.continue:
        mov     eax, dbgcContinue
        clc
        return


;--------- Exception debug event ------------------------
.exception:
        mov     [dbgContext.ContextFlags], CONTEXT_FULL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext

        invoke  SendMessageW, [hPropEditor], PRM_UPDATEPROP, 0, 0

        stdcall FindAddressPosition, [dbgContext.regEip]
        test    eax,eax
        jz      .unknownposition

        mov     [LastKnownLine], eax
        stdcall PosEditor, [eax+TDebugLine.ptrFile], [eax+TDebugLine.LineNum]
        invoke  SendMessageW, [hLister], LM_SHOWLIST, eax, 0

        invoke  ShowWindow, [hPropEditor], SW_SHOW

        xor      eax, eax
        clc
        return

.unknownposition:
        invoke  ShowWindow, [hPropEditor], SW_HIDE

        mov     eax, dbgcContinue
        cmp     [dbgEvent.Exception.ExceptionRecord.ExceptionCode], EXCEPTION_BREAKPOINT
        je      @f
        mov     eax, dbgcContinueNotHandled   ; Pass these kind of exceptions to the code.
@@:
        clc
        return


.createprocess:
        invoke  SendMessageW, [hPropEditor], PEM_SETCONTROL, dbgContext, DebuggerProperties
        invoke  SendMessageW, [hPropEditor], PEM_SETUPDATEPROC, 0, UpdateThreadContext

        invoke  SendMessageW, [hLister], LM_SHOW, SW_SHOWNORMAL, 0
        invoke  SendMessageW, [Dumper.hwnd], DMM_SHOW, SW_SHOWNORMAL, 0

        mov     eax, [dbgEvent.CreateProcessInfo.hFile]
        mov     [hDebugFileImage], eax
        mov     eax, dbgcContinue
        clc
        return

.exitprocess:
        invoke  CloseHandle, [hDebugThread]
        mov     [hDebugThread], 0

        invoke  CloseHandle, [hDebugFileImage]
        mov     [hDebugFileImage], 0

        invoke  SendMessageW, [hPropEditor], PEM_SETCONTROL, 0, 0

        invoke  ShowWindow, [hPropEditor], SW_SHOW

        invoke  SendMessageW, [hLister], WM_SETTEXT, 0, 0
        invoke  SendMessageW, [hLister], LM_SHOW, SW_HIDE, 0
        invoke  SendMessageW, [Dumper.hwnd], DMM_SHOW, SW_HIDE, 0

        mov     eax, dbgcFinish
        clc
        return


        enddispatch

endp




