uglobal
hCCList dd 0
endg
idCCList = 763
proc CreateCCList, .parent
begin
push ebx
invoke CreateWindowExA, 0, cFormClassName, 0, WS_POPUP or WS_SIZEBOX or WS_CLIPSIBLINGS or WS_CLIPCHILDREN, \
0, 0, 300, 120, 0, 0, [hInstance], 0
mov [hCCList], eax
invoke SetWindowLongA, [hCCList], GWL_HWNDPARENT, [.parent]
stdcall SubclassWindow, [hCCList], CCParentProc
invoke CreateWindowExA, 0, cListboxClassName, 0, \
WS_CHILD or WS_VISIBLE or WS_VSCROLL or LBS_NOINTEGRALHEIGHT or LBS_OWNERDRAWFIXED or LBS_NODATA, \
0, 0, 300, 120, [hCCList], idCCList, [hInstance], 0
mov ebx, eax
stdcall SubclassWindow, ebx, CCListProc
stdcall SetAlign, ebx, waClient
invoke GetStockObject, DEFAULT_GUI_FONT
invoke SendMessageA, ebx, WM_SETFONT, eax, TRUE
pop ebx
return
endp
proc AddCCListItem, .hStr, .ptrLabel
begin
push eax ecx edx
invoke GetWindowLongA, [hCCList], GWL_USERDATA
stdcall AddArrayItems, eax, 1
pushd [.ptrLabel]
popd [eax]
invoke SetWindowLongA, [hCCList], GWL_USERDATA, edx
pop edx ecx eax
return
endp
; returns pointer to the string in ebx
proc GetCCListSelected
begin
push eax ecx edx
invoke SendMessageA, [hCCList], LB_GETCURSEL, 0, 0
add eax, 1
jc .err
mov ebx, eax
invoke GetWindowLongA, [hCCList], GWL_USERDATA
cmp [eax+TArray.count], ebx
jb .err
mov ebx, [eax+TArray.array+4*ebx-4]
mov ebx, [ebx+TLabel.iName]
add ebx, [ptrNames]
clc
.err:
pop edx ecx eax
return
endp
proc ClearCCList
begin
invoke SendMessageA, [hCCList], LB_SETCOUNT, 0, 0
invoke GetWindowLongA, [hCCList], GWL_USERDATA
stdcall FreeMem, eax
stdcall CreateArray, 4 ; dword array.
invoke SetWindowLongA, [hCCList], GWL_USERDATA, eax
return
endp
proc SelectCCList, .hStr
begin
push ebx esi edi
stdcall StrPtr, [.hStr]
mov edi, eax
invoke GetWindowLongA, [hCCList], GWL_USERDATA
mov ebx, [eax+TArray.count]
lea esi, [eax+TArray.array]
or eax, -1
.matchloop:
inc eax
cmp eax, ebx
je .notfound
mov ecx, [esi]
lea esi, [esi+4]
mov ecx, [ecx+TLabel.iName]
add ecx, [ptrNames]
stdcall StringMatch, ecx, edi
jnc .matchloop
invoke SendMessageA, [hCCList], LB_SETCURSEL, eax, 0
clc
return
.notfound:
invoke SendMessageA, [hCCList], LB_SETCURSEL, 0, 0
stc
return
endp
winproc CCParentProc
begin
cmp ebx, WM_KEYDOWN
je .relay
cmp ebx, LB_ADDSTRING
jl .process
cmp ebx, LB_ITEMFROMPOINT
ja .process
.relay:
invoke SendDlgItemMessageA, [.hwnd], idCCList, [.wmsg], [.wparam], [.lparam]
clc
return
.process:
ondefault
stc
return
onmessage AM_INITWINDOW
stdcall CreateArray, 4 ; dword array.
invoke SetWindowLongA, [.hwnd], GWL_USERDATA, eax
clc
return
onmessage WM_SIZE
invoke GetDlgItem, [.hwnd], idCCList
invoke InvalidateRect, eax, 0, 0
xor eax, eax
clc
return
onmessage WM_CLOSE
invoke GetWindowLongA, [.hwnd], GWL_HWNDPARENT
invoke SetFocus, eax
invoke DestroyWindow, [.hwnd]
xor eax, eax
mov [hCCList], 0
clc
return
onmessage WM_DESTROY
invoke GetWindowLongA, [.hwnd], GWL_USERDATA
stdcall FreeMem, eax
stc
return
onmessage WM_MEASUREITEM
locals
.ccrect RECT
endl
mov esi, [.lparam]
cmp [esi+MEASUREITEMSTRUCT.CtlType], ODT_LISTBOX
jne .ondefault
cmp [esi+MEASUREITEMSTRUCT.CtlID], idCCList
jne .ondefault
invoke GetDlgItem, [.hwnd], idCCList
mov ebx, eax
lea ecx, [.ccrect]
invoke GetClientRect, ebx, ecx
push [.ccrect.right]
pop [esi+MEASUREITEMSTRUCT.itemWidth]
or eax, -1
clc
return
onmessage WM_DRAWITEM
locals
.rectL RECT
.rectR RECT
.bkbrush dd ?
.buffer rb 32
endl
cmp [.wparam], idCCList
jne .ondefault
mov esi, [.lparam]
mov eax, [esi+DRAWITEMSTRUCT.hwndItem]
mov eax, COLOR_HIGHLIGHT
mov ebx, COLOR_HIGHLIGHTTEXT
test [esi+DRAWITEMSTRUCT.itemState], ODS_SELECTED or ODS_FOCUS
jnz @f
mov eax, COLOR_WINDOW
mov ebx, COLOR_WINDOWTEXT
@@:
invoke GetSysColor, eax
invoke CreateSolidBrush, eax
mov [.bkbrush], eax
invoke GetSysColor, ebx
invoke SetTextColor, [esi+DRAWITEMSTRUCT.hDC], eax
invoke SetBkMode, [esi+DRAWITEMSTRUCT.hDC], TRANSPARENT
; First fill the background
lea eax, [esi+DRAWITEMSTRUCT.rcItem]
invoke FillRect, [esi+DRAWITEMSTRUCT.hDC], eax, [.bkbrush]
; then compute the rectangles
mov eax, [esi+DRAWITEMSTRUCT.rcItem.left]
mov ecx, [esi+DRAWITEMSTRUCT.rcItem.right]
mov [.rectL.left], eax
mov [.rectL.right], ecx
mov [.rectR.left], ecx
mov [.rectR.right], ecx
sub ecx, eax
shr ecx, 2 ; 1/4 of the field for the value.
sub [.rectL.right], ecx
sub [.rectR.left], ecx
mov eax, [esi+DRAWITEMSTRUCT.rcItem.top]
mov ecx, [esi+DRAWITEMSTRUCT.rcItem.bottom]
mov [.rectL.top], eax
mov [.rectL.bottom], ecx
mov [.rectR.top], eax
mov [.rectR.bottom], ecx
add [.rectL.left], 4
add [.rectR.left], 4
invoke GetSysColor, COLOR_BTNFACE
invoke CreatePen, PS_SOLID, 0, eax
invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC], eax
push eax
invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.top], NULL
invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.bottom]
mov edi, [.rectL.bottom]
dec edi
invoke MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [esi+DRAWITEMSTRUCT.rcItem.left], edi, NULL
invoke LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectR.right], edi
invoke SelectObject, [esi+DRAWITEMSTRUCT.hDC] ; from the stack
invoke DeleteObject, eax
; then write the text
mov edi, [esi+DRAWITEMSTRUCT.itemID]
cmp edi, -1
je .cleanup
invoke GetWindowLongA, [.hwnd], GWL_USERDATA
cmp edi, [eax+TArray.count]
jae .cleanup
mov edi, [eax+TArray.array + 4*edi]
mov eax, [edi+TLabel.iName]
add eax, [ptrNames]
lea ecx, [.rectL]
invoke DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS
cNotDefined text 'undefined'
cVirtual text 'virtual'
; then write the value
test [edi+TLabel.flags], lfDefined
jz .notdefined
cmp [edi+TLabel.SIBEx], 0
jne .virtual
stdcall NumToStr, [edi+TLabel.ValueLo], ntsHex or ntsSigned
jmp .printvalue
.notdefined:
stdcall StrDup, cNotDefined
jmp .printvalue
.virtual:
stdcall StrDup, cVirtual
.printvalue:
push eax
stdcall StrPtr, eax
lea ecx, [.rectR]
invoke DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER
stdcall StrDel ; from the stack.
.cleanup:
invoke DeleteObject, [.bkbrush]
or eax, -1
clc
return
endwp
winproc CCListProc
begin
ondefault
stc
return
; This makes CCList to never get the focus.
;onmessage WM_SETFOCUS
; invoke GetParent, [.hwnd]
; invoke SetFocus, eax
; xor eax, eax
; clc
; return
;-----------------------------------------------------------------------
onmessage WM_LBUTTONDBLCLK
invoke SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
invoke PostMessageA, eax, WM_KEYDOWN, VK_RETURN, 0
clc
return
;-----------------------------------------------------------------------
onmessage WM_KEYDOWN
mov ebx, [.wparam]
call JumpTo
MessageList \
VK_DOWN, .ondefault, \
VK_UP, .ondefault, \
VK_PRIOR, .ondefault, \
VK_NEXT, .ondefault, \
VK_HOME, .ondefault, \
VK_END, .ondefault
invoke SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
invoke PostMessageA, eax, [.wmsg], [.wparam], [.lparam]
clc
return
endwp
proc UpdateCCPosition
.aepos AEPOS
.caret AECARETXY
.rect RECT
.workrect RECT
.word rb $100
.aedit dd ?
begin
cmp [hCCList], 0
je .finish
invoke GetWindowLongA, [hCCList], GWL_HWNDPARENT
mov [.aedit], eax
lea ebx, [.caret]
invoke SendMessageA, [.aedit], AEM_GETCARETXY, ebx, 0
invoke ClientToScreen, [.aedit], ebx
add ebx, 8
invoke ClientToScreen, [.aedit], ebx
sub ebx, 8
lea eax, [.rect]
invoke GetWindowRect, [hCCList], eax
mov eax, [.rect.right]
mov ecx, [.rect.bottom]
sub eax, [.rect.left]
sub ecx, [.rect.top]
mov [.rect.right], eax
mov [.rect.bottom], ecx
lea ebx, [.workrect]
invoke SystemParametersInfoA, SPI_GETWORKAREA,0,ebx,0
mov eax, [.workrect.right]
sub eax, [.rect.right]
mov ecx, [.caret.x0]
cmp eax, ecx
jle @f
mov eax, ecx
@@:
mov edx, [.workrect.bottom]
sub edx, [.rect.bottom]
mov ecx, [.caret.y1]
add ecx, 1
cmp edx, ecx
jg @f
mov ecx, [.caret.y0]
sub ecx, [.rect.bottom]
sub ecx, 2
@@:
invoke SetWindowPos, [hCCList], NULL, eax, ecx, 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOCOPYBITS
lea ebx, [.word]
invoke SendMessageA, [.aedit], AEM_GETWORDATCARET, $100, ebx
stdcall ClearCCList
stdcall SearchTree, ebx, ptrLabels
test eax, eax
jz .destroycc
mov esi, [eax]
test esi, esi
jz .destroycc
mov ebx, [esi+TArray.count]
lea esi, [esi+TArray.array]
test ebx, ebx
jz .destroycc
mov edi, edx ; The last word
xor ecx, ecx
.fillloop:
mov eax, [ptrNames]
add eax, [esi+TLabel.iName]
stdcall StringMatch, eax, edi
jnc .next
stdcall AddCCListItem, eax, esi
inc ecx
.next:
add esi, sizeof.TLabel
dec ebx
jnz .fillloop
test ecx, ecx
jz .destroycc
invoke SendMessageA, [hCCList], LB_SETCOUNT, ecx
stdcall SelectCCList, edi
stdcall StrDel, edi
invoke SetWindowPos, [hCCList], NULL, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_SHOWWINDOW or SWP_NOACTIVATE
.finish:
return
.destroycc:
invoke PostMessageA, [hCCList], WM_CLOSE, 0, 0
return
endp
proc StringMatch, .str1, .str2
begin
push esi edi eax
stdcall StrPtr, [.str1]
mov esi, eax
stdcall StrPtr, [.str2]
mov edi, eax
.loop:
mov al, [esi]
inc esi
mov ah, [edi]
inc edi
test ah,ah
jz .match
test al,al
jz .notmatch
or eax, $2020
cmp al,ah
je .loop
.notmatch:
clc
pop eax edi esi
return
.match:
stc
pop eax edi esi
return
endp