;<ff
Window frmLabelProp, 3, 0, 'TForm', 'TForm window', $56000000, $10000, 0, 597, 232, 377, 318, frmLabelPropWinProc;
Window NONE, 0, 5, 'SysListView32', 'ListView', $5000800D, $200, 201, 0, 104, 369, 187, 0;
Window NONE, 3, 3, 'TForm', 'Form', $50000000, $0, 1, 0, 0, 369, 104, 0;
Window NONE, 0, 0, 'STATIC', 'Value:', $5000000B, $0, 0, 8, 4, 64, 16, 0;
Window NONE, 0, 0, 'EDIT', '', $50800884, $0, 10, 8, 20, 180, 17, 0;
Window NONE, 0, 0, 'STATIC', 'Size | Flags | type', $5000000B, $0, 0, 8, 44, 88, 16, 0;
Window NONE, 0, 0, 'EDIT', '', $50800884, $0, 11, 8, 60, 180, 17, 0;
Window NONE, 2, 0, 'STATIC', 'Reference list:', $50000000, $0, 0, 8, 88, 80, 16, 0;
;ff>


idLabelProp = 33
idXRefList = 201


winmessage LPR_DISPLAY     ; wparam = hparent - handle of string with the name of the parent label; lparam = pointer to the TLabel;


uglobal
  hXRefFont dd ?
endg


iglobal
  cXRefFont text 'Courier New'
endg


initialize InitLabelProperties
begin
        invoke  CreateFontA, -12, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, cXRefFont
        mov     [hXRefFont], eax
        return
endp


finalize FinalizeLabelProperties
begin
        invoke  DeleteObject, [hXRefFont]
        return
endp




winproc frmLabelPropWinProc
begin

ondefault
        stc
        return


onmessage WM_NOTIFY
locals
  .dblitem LVITEM
  .line    dd ?
endl

        cmp     [.wparam], idXRefList
        jne     .ondefault

        mov     esi, [.lparam]
        cmp     [esi+NMLISTVIEW.hdr.code], LVN_ITEMACTIVATE
        jne     .ondefault

        stdcall GetMem, 2048    ; buffer for the filename
        mov     edi, eax

        lea     ebx, [.dblitem]

        mov     [ebx+LVITEM.mask], LVIF_PARAM or LVIF_TEXT
        mov     eax, [esi+NMLISTVIEW.iItem]     ; list item double clicked
        mov     [ebx+LVITEM.iItem], eax
        mov     [ebx+LVITEM.iSubItem], 2        ; file name pointer
        mov     [ebx+LVITEM.pszText], edi
        mov     [ebx+LVITEM.cchTextMax], 2000

        invoke  SendMessageA, [esi+NMLISTVIEW.hdr.hwndFrom], LVM_GETITEM, 0, ebx

        stdcall PosEditor, edi, [ebx+LVITEM.lParam]

        stdcall FreeMem, edi
        clc
        return



onmessage FM_AFTERCREATE

locals
  .col LVCOLUMN
endl
        invoke  GetDlgItem, [.hwnd], idXRefList
        mov     ebx, eax

        lea     ecx, [.col]

        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnSymbolName
        mov     [ecx+LVCOLUMN.iSubItem], 0

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 0, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnSource
        mov     [ecx+LVCOLUMN.iSubItem], 1

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 1, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnFilename
        mov     [ecx+LVCOLUMN.iSubItem], 2

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 2, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnLineNum
        mov     [ecx+LVCOLUMN.iSubItem], 3

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 3, ecx
        invoke  SendMessageA, ebx, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT or LVS_EX_INFOTIP
        invoke  SendMessageA, ebx, WM_SETFONT, [hXRefFont], FALSE
        clc
        return

iglobal
  cColumnSymbolName text 'Symbol'
  cColumnSource     text 'Source line'
  cColumnFilename text 'File'
  cColumnLineNum  text 'Line'
endg



onmessage LPR_DISPLAY

        invoke  GetDlgItem, [.hwnd], 1
        mov     ebx, eax

; Pointer to TLabel structure of given label.
        mov     edi, [.lparam]
        test    edi, edi
        jz      .finish

        stdcall NumToStr, [edi+TLabel.ValueLo], ntsUnsigned or ntsHex
        push    eax
        push    eax

        stdcall NumToStr, [edi+TLabel.ValueHi], ntsUnsigned or ntsHex
        stdcall StrCharInsert, eax, '$', 0
        stdcall StrCharCat, eax, ':'

        stdcall StrCat, eax     ; second from the stack
        stdcall StrDel
        push    eax

        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, ebx, 10, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack

        movzx   eax, [edi+TLabel.DataSize]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 2
        mov     edx, eax
        stdcall StrCat, edx, cStrDelimiter
        movzx   eax, [edi+TLabel.flags]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 4
        push    eax
        stdcall StrCat, edx, eax
        stdcall StrDel ; from the stack
        stdcall StrCat, edx, cStrDelimiter
        movzx   eax, [edi+TLabel.type]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 2
        push    eax
        stdcall StrCat, edx, eax
        stdcall StrDel ; from the stack

        stdcall StrPtr, edx
        push    edx
        invoke  SetDlgItemTextA, ebx, 11, eax
        stdcall StrDel ; from the stack

; cross reference
        invoke  GetDlgItem, [.hwnd], idXRefList
        mov     ebx, eax

        cmp     [.wparam], 0
        jne     @f

        invoke  SendMessageA, ebx, LVM_DELETEALLITEMS, 0, 0

@@:
        mov     esi, [edi+TLabel.pXRefArray]
        test    esi, esi
        jz      .finish

        mov     ecx, [esi+TArray.count]
        test    ecx, ecx
        jz      .finish

        mov     [.count], ecx
        lea     esi, [esi+TArray.array]

locals
  .count dd ?
  .line_num dd ?
  .lvitem LVITEM
endl

.loop_xref:
        mov     ecx, [esi+TXRefInfo.ofsSource]
        add     ecx, [ptrPreprocessed]

.search_filename:
        mov     eax, [ecx+TIntLine.LineNumber]
        test    eax, eax
        jns     .direct

; the name of the macro
        mov    eax, [ecx+TIntLine.ofsGenerator]
        add    eax, [ptrPreprocessed]
        cmp    word [eax+1], '__'          ; internal macro definition... for example __UGlobalBlock or __IGlobalBlock
        je    .searchdown

        mov    ecx, [ecx+TIntLine.ofsSourceLine]
        add    ecx, [ptrPreprocessed]
        jmp   .search_filename

.searchdown:
        mov     ecx, [ecx+TIntLine.ofsMacroLine]
        add     ecx, [ptrPreprocessed]
        jmp     .search_filename

.direct:
        mov     [.line_num], eax

        mov     eax, [ecx+TIntLine.ofsGenerator]
        add     eax, [ptrPreprocessed]
        cmp     eax, [ptrPreprocessed]
        jne     .found

        stdcall StrPtr, [hStrFileName]

.found:
        push    eax     ; pointer to the filename

        mov     eax, [edi+TLabel.iName]
        add     eax, [ptrNames]

        lea     ecx, [.lvitem]
        mov     [ecx+LVITEM.mask], LVIF_PARAM or LVIF_TEXT
        mov     [ecx+LVITEM.iItem], $7fffffff
        mov     [ecx+LVITEM.iSubItem], 0
        mov     [ecx+LVITEM.pszText], eax
        mov     eax, [.line_num]
        mov     [ecx+LVITEM.lParam], eax

        invoke  SendMessageA, ebx, LVM_INSERTITEM, 0, ecx

        lea     ecx, [.lvitem]
        mov     [ecx+LVITEM.iItem], eax


        mov     eax, [esi+TXRefInfo.ofsSource]
        add     eax, [ptrPreprocessed]
        stdcall RestoreSourceLine, eax
        push    eax

        stdcall StrPtr, eax
        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 1
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        lea     ecx, [.lvitem]

        stdcall StrDel ; from the stack

        pop     eax

        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 2
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        lea     ecx, [.lvitem]

        stdcall NumToStr, [.line_num], ntsUnsigned or ntsDec
        push    eax
        stdcall StrPtr, eax

        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 3
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        stdcall StrDel ; from the stack

        add     esi, sizeof.TXRefInfo
        dec     [.count]
        jnz     .loop_xref

        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 2, 100
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 3, LVSCW_AUTOSIZE_USEHEADER

; add the children labels to the cross reference list
        mov    edi, [edi+TLabel.Children]
        test   edi, edi
        jz     .finish

        mov     ebx, [edi+TArray.count]
        lea     edi, [edi+TArray.array]

.children_loop:
        dec     ebx
        js      .finish

        invoke  SendMessageA, [.hwnd], LPR_DISPLAY, 1, edi
        add     edi, sizeof.TLabel
        jmp     .children_loop


.finish:
        clc
        return



endwp



iglobal
  cSizeConst    text 'const',0
  cSizeByte     text 'byte', 0
  cSizeWord     text 'word', 0
  cSizeDword    text 'dword', 0
  cSizeQword    text 'qword', 0
  cStrDelimiter text ' | ', 0
endg




; there is another similar procedure "CreateLineString" in debug.asm file.
; TODO: these two procedures should be replaced by only one with common interface.

proc RestoreSourceLine, .ptrPreprocessedLine
.char dd ?
begin
        push    esi edi ebx

        stdcall StrNew
        mov     edi, eax

        mov     esi, [.ptrPreprocessedLine]
        lea     esi, [esi+TIntLine.PreprocessedLine]

        mov     [.char], $20202020

.getloop:
        xor     eax, eax
        lodsb
        test    al, al
        jz      .eol
        cmp     al, $3b
        je      .ignore
        cmp     al, $1a         ; prefix of token
        je      .token
        cmp     al, $22         ; quoted text.
        je      .quoted

        stdcall StrCharCat, edi, eax

        cmp     al,','
        jne     .getloop

        mov     al,$20
        stdcall StrCharCat, edi, eax
        jmp     .getloop

.quoted:
        stdcall StrCharCat, edi, "'"

        lodsd                   ; length
        xor     edx, edx
        xchg    [esi+eax], edx
        stdcall StrCat, edi, esi
        xchg    [esi+eax], edx
        add     esi, eax

        stdcall StrCharCat, edi, "'"
        jmp     .getloop

.token:
        lodsb                   ; length
        xor     edx, edx
        xchg    [esi+eax], edx
        stdcall StrCat, edi, esi
        xchg    [esi+eax], edx
        add     esi, eax

        cmp     byte [esi], '['
        je      .tab
        cmp     byte [esi], $1a
        jne     .getloop

.tab:
        stdcall StrCharCat, edi, [.char]
        mov     byte [.char], $20
        jmp     .getloop

.ignore:
.eol:
        mov     eax, edi        ; string handle
        pop     ebx edi esi
        return
endp





