News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

the listview color lost.

Started by six_L, April 12, 2014, 08:11:20 AM

Previous topic - Next topic

six_L

while the vScroll is being moved, the listview color will missing.
edit: the exe  Attachment for you'll easily test it.
.586
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\include\windows.inc                         
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\gdi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\masm32.lib
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\macros\macros.asm
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.const
IDD_DIALOG equ 1000
IDB_EXIT        equ 1001
IDB_STOP equ 1003
IDC_LIST        equ 1004
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data
ListCap1 db "Index",0
ListCap2 db "RandNum",0
buffer1 db 512 dup (0)
@dwSetTextBKColor dd 0FFff00H
IndexOfList dd 0H
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data?
hInstance dd ?
hList dd ?
lvi LV_ITEM <?>
Buffer db 32 dup(?)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.code
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iRand proc _dwMin:DWORD, _dwMax:DWORD
local @dwRet:dword, @dqFreq:qword
   
pushad
invoke QueryPerformanceCounter,addr @dqFreq
mov eax,dword ptr @dqFreq
mov ecx, 13       
mul ecx           
add eax, 5       
mov ecx, _dwMax   
sub ecx, _dwMin   
inc ecx       
xor edx, edx 
div ecx       
mov @dwRet, edx
popad
mov eax, @dwRet
add eax,_dwMin    ; eax = Rand_Number
ret

iRand endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InsertColumns proc
LOCAL lvc:LV_COLUMN

invoke SendMessage,hList,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT or LVS_EX_FLATSB ,-1
mov lvc.imask,LVCF_TEXT+LVCF_WIDTH
mov lvc.pszText,offset ListCap1
mov lvc.lx,100
invoke SendMessage,hList, LVM_INSERTCOLUMN,0,addr lvc
or lvc.imask,LVCF_FMT
mov lvc.fmt,LVCFMT_LEFT ;CENTER
mov lvc.pszText,offset ListCap2
mov lvc.lx,130
invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc

ret
InsertColumns endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AddItem proc _hList:DWORD, item:DWORD, subitem:DWORD, tdata:DWORD
LOCAL newitem:LV_ITEM
LOCAL lstmsg:DWORD

mov newitem.imask, LVIF_TEXT
m2m newitem.iItem, item
m2m newitem.iSubItem, subitem
m2m newitem.pszText, tdata
invoke lstrlen, tdata
inc eax
mov newitem.cchTextMax, eax

.IF subitem == 0h
mov lstmsg, LVM_INSERTITEM
.ELSE
mov lstmsg, LVM_SETITEM
.ENDIF
invoke SendMessage, _hList, lstmsg, 0h, addr newitem

invoke SendMessage, _hList, LVM_ENSUREVISIBLE, item, FALSE
ret

AddItem endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AddItemInt proc _hList:DWORD,item:DWORD,subitem:DWORD,tdword:DWORD

invoke RtlZeroMemory,addr Buffer,sizeof Buffer
invoke wsprintf,addr Buffer, CTXT('%i'), tdword
invoke AddItem, _hList,item,subitem,addr Buffer
ret

AddItemInt endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CreateButton proc hParent:DWORD,lpText:DWORD,x:DWORD,y:DWORD,w:DWORD,h:DWORD,ID:DWORD
LOCAL hFont :DWORD

invoke  CreateFont,14,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE, \
    ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, \
    DEFAULT_QUALITY,DEFAULT_PITCH, CTXT("Arial")
mov hFont, eax

invoke CreateWindowEx,0,CTXT('BUTTON'),lpText,WS_CHILD or WS_VISIBLE ,
x,y,w,h,hParent,ID,
hInstance,NULL
push eax
invoke SendMessage,eax,WM_SETFONT,hFont, 0
pop eax
ret

CreateButton endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CreateListView proc hParent:DWORD, x:DWORD,y:DWORD,w:DWORD,h:DWORD,ID:DWORD
LOCAL hFont :DWORD

invoke  CreateFont,15,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE, \
    ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, \
    DEFAULT_QUALITY,DEFAULT_PITCH, CTXT("Arial")
mov hFont, eax

invoke CreateWindowEx, WS_EX_STATICEDGE + WS_EX_TRANSPARENT,\
CTXT("SysListView32"),CTXT("test"),WS_TABSTOP + WS_VSCROLL + CBS_SIMPLE + WS_VISIBLE + WS_CHILD,x,y,w,h,\
hParent,ID,hInstance,NULL
push eax
invoke SendMessage,eax,WM_SETFONT,hFont, 0
pop eax
ret

CreateListView endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
.if eax == WM_CREATE
invoke CreateButton,hWnd,CTXT('Stop'),71,256,56,20,IDB_STOP
invoke CreateButton,hWnd,CTXT('Exit'),7,256,56,20,IDB_EXIT
invoke CreateListView,hWnd,7,16,398,229,IDC_LIST
mov hList,eax
invoke SendMessage,hList,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT or LVS_EX_HEADERDRAGDROP OR LVS_EX_GRIDLINES,-1
invoke InsertColumns
invoke SetTimer,hWnd,0,1000,0
.elseif eax==WM_TIMER
push ebx
invoke iRand,100,800
mov eax,IndexOfList
inc eax
invoke AddItemInt,hList,IndexOfList,0,eax
invoke iRand,100,800
mov ebx,eax
invoke AddItemInt,hList,IndexOfList,1,ebx
.if ebx > 100 && ebx < 150
mov @dwSetTextBKColor,0FFADADH
.elseif ebx >= 150 && ebx < 300
mov @dwSetTextBKColor,0ADFFADH
.elseif ebx >= 300 && ebx < 400
mov @dwSetTextBKColor,0ADADFFH
.elseif ebx >= 400 && ebx < 550
mov @dwSetTextBKColor,0FF00ADH
.elseif ebx >= 550 && ebx < 800
mov @dwSetTextBKColor,000ADFFH
.else
mov @dwSetTextBKColor,0FF0000H
.endif
inc IndexOfList
pop ebx
.elseif eax == WM_COMMAND
.if wParam == IDB_EXIT
invoke DestroyWindow, hWnd
.elseif wParam==IDB_STOP
invoke KillTimer,hWnd,0
.endif
.elseif eax == WM_NOTIFY
mov edi,lParam
assume edi:ptr NMLVCUSTOMDRAW
mov eax,[edi].nmcd.hdr.code
.if eax== NM_CUSTOMDRAW
mov eax,[edi].nmcd.dwDrawStage
.if eax==CDDS_PREPAINT
mov eax,CDRF_NOTIFYITEMDRAW
ret
.elseif eax==CDDS_ITEMPREPAINT
m2m [edi].clrTextBk,@dwSetTextBKColor
mov eax,CDRF_NOTIFYSUBITEMDRAW
ret
.elseif eax==CDDS_SUBITEM or CDDS_ITEMPREPAINT
m2m [edi].clrTextBk,@dwSetTextBKColor
.endif
mov eax,CDRF_NEWFONT
ret
.endif
ASSUME edi:nothing           
.elseif eax == WM_CLOSE
invoke KillTimer,hWnd,0
invoke DestroyWindow, hWnd
.elseif eax == WM_DESTROY
invoke PostQuitMessage, NULL
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
         xor    eax, eax
         ret
DlgProc endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TopXY proc wDim:DWORD, sDim:DWORD

shr sDim, 1     
shr wDim, 1     
mov eax, wDim   
sub sDim, eax   

mov eax, sDim
ret

TopXY endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WinMain proc hInst:DWORD,hPrevInst:DWORD, CmdLine:DWORD, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL Wwd:DWORD
LOCAL Wht:DWORD
LOCAL Wtx:DWORD
LOCAL Wty:DWORD
LOCAL hWnd:HANDLE

        mov wc.cbSize, sizeof WNDCLASSEX
        mov wc.style, CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
        mov wc.lpfnWndProc, offset DlgProc
        mov wc.cbClsExtra, NULL
        mov wc.cbWndExtra, NULL
        m2m wc.hInstance,hInst
        mov wc.hbrBackground, COLOR_BTNFACE+1
        mov wc.lpszClassName, CTXT("test_list")
invoke LoadIcon, NULL, IDI_APPLICATION
        mov wc.hIcon, eax
        mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
        mov wc.hCursor, eax

invoke RegisterClassEx, addr wc
mov Wwd, 425
mov Wht, 320

invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax

invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax

invoke CreateWindowEx, NULL, CTXT("test_list"),CTXT("test_list"), WS_OVERLAPPEDWINDOW,\
Wtx,Wty,Wwd,Wht,NULL, NULL, hInst, NULL
        mov hWnd, eax

invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd

.while TRUE
invoke GetMessage, addr msg, NULL, 0, 0
.break .if (!eax)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
        mov eax, msg.wParam
        ret
WinMain endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke GetCommandLine
invoke WinMain, hInstance ,NULL, eax, SW_SHOWDEFAULT
invoke ExitProcess,0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

end start
Say you, Say me, Say the codes together for ever.

jj2007

To keep the colours to their rows, you need to set them in a WM_PAINT handler, not in WM_TIMER, and you must keep a table that associates rows with colours, e.g. with

   mov newitem.lParam, TheColour
   invoke SendMessage, _hList, lstmsg, 0h, addr newitem


You may use this as a template.

BTW CreateListView failed miserably under XP SP3 until I replaced all headers including macros.asm with my usual one-liner .. MasmBasic.inc - very odd ::)

six_L

thanks your response.
the trouble is still there.
WM_TIMER: creates the random number,set the color of listview cows acorroding to its value. 
Say you, Say me, Say the codes together for ever.

jj2007

Quote from: six_L on April 13, 2014, 11:51:18 AMthe trouble is still there

It won't go away until you do what I proposed above. You might start reading on subclassing and WM_PAINT...

GoneFishing

#4
.

fearless

You'll need to find a way of storing the dwSetTextBKColor var to associate it with a particular row, and then in your NM_CUSTOMDRAW part, recall it. Otherwise as you have seen the call to redraw all visible items (via the scroller being activated/moved) with cause those visible rows to change color to the last known dwSetTextBKColor (which is a global value)

You could use LVIF_PARAM with the lParam value of the row to store info, like the color, or use some memory array that is in sync with listview item indexes.

To get the item and subitem:

        mov ecx, lParam
        mov eax, (NMLVCUSTOMDRAW ptr[ecx]).iSubItem
        mov nSubItem, eax
        mov eax, (NMLVCUSTOMDRAW ptr[ecx]).nmcd.dwItemSpec ; item
        mov nItem, eax

with item indentified you could then call LVM_GETITEM (using item we just obtained) with LVIF_PARAM flag, and recall lParam value. Then store it to a local var, which would change each time the listview calls for custom draw part of your code (which would be once for each visible item when scroller moves). The fetch color part needs to be inside this NMCUSTOMDRAW part of your code for it to work.

Hope that helps

six_L

thanks all for your help.
Quotewith item indentified you could then call LVM_GETITEM (using item we just obtained) with LVIF_PARAM flag, and recall lParam value. Then store it to a local var, which would change each time the listview calls for custom draw part of your code (which would be once for each visible item when scroller moves). The fetch color part needs to be inside this NMCUSTOMDRAW part of your code for it to work.
:t this's helpful.
have tried a lot of times, i'm still failed. can't implement your helpful idea.
Could you show me the part codes?
Say you, Say me, Say the codes together for ever.

ragdog

Hi Six_L

You have for many years send this example here is a part of my colorlistview


OnInitListView  PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT
LOCAL     lvi:LV_ITEM
LOCAL local_buffer[255] :BYTE
mov edx,lParam
    .if wParam==IDC_LISTVIEW
      .if [edx].NMHDR.code==NM_CUSTOMDRAW
assume edx: ptr NMLVCUSTOMDRAW
    .if [edx].nmcd.dwDrawStage == CDDS_PREPAINT
      @@:
invoke SetWindowLong,hWnd,DWL_MSGRESULT,CDRF_NOTIFYITEMDRAW
                ret
              .elseIf [edx].nmcd.dwDrawStage == CDDS_ITEMPREPAINT
      jmp       @B
.elseIf [edx].nmcd.dwDrawStage == CDDS_ITEMPREPAINT || CDDS_SUBITEM  ;|| CDDS_ITEM

.if [edx].nmcd.uItemState & CDIS_SELECTED
mov         esi,[edx].nmcd.dwItemSpec; Get the item number
    mov         ebx,[edx].nmcd.hdc       ; Get the device context
    mov         [rect.left],LVIR_BOUNDS  ; Get the bounding rect of the item
invoke      SendMessage,hListView,LVM_GETITEMRECT,esi,addr rect
    invoke      FillRect,ebx,addr rect,hCurselColor  ; Draw the background color and frame
invoke      FrameRect,ebx,addr rect,hFramecolor
invoke      SelectObject,ebx,eax
invoke      SetTextColor,ebx,005ADFC1h;IDC_TEXTCOLOR

; Get the item count from the header control
invoke      SendMessage,hListView,LVM_GETHEADER,0,0
invoke      SendMessage,eax,HDM_GETITEMCOUNT,0,0
    mov         ecx,eax
 
    ; Loop through all the labels and draw their text
mov         lvi.iItem,esi
lea         eax, local_buffer
            mov         lvi.pszText,eax
mov         lvi.cchTextMax,255

xor         edi,edi; EDI is no longer needed so we'll use it for a counter

.while edi !=ecx
   push        ecx ; save the item count
   ; Get the bounding rect of the label
   ; the API uses the rect struct to pass parameters
   mov         [rect.left],LVIR_LABEL
   mov         [rect.top],edi
   invoke      SendMessage,hListView,LVM_GETSUBITEMRECT,esi,addr rect
   .if edi!=0
   add         [rect.left],4 ; extra indent for sub items
   .endif
   add         [rect.left],2     ; indent isn't right with LVM_GETITEM
   mov         [lvi.iSubItem],edi
   invoke      SendMessage,hListView,LVM_GETITEMTEXT,esi,addr lvi
   ; Draw the text to the items
   invoke         DrawText,ebx,addr local_buffer,-1,addr rect,DT_LEFT + DT_VCENTER + DT_SINGLELINE
   pop            ecx ; restore the item count
   inc            edi
    .endw
            invoke      SetWindowLong,hWnd,DWL_MSGRESULT,CDRF_SKIPDEFAULT
                ret
.endif
                    mov        [edx].clrText,005ADFC1h;IDC_TEXTCOLOR
                    mov        [edx].clrTextBk,0h;IDC_BACKCOLOR
    assume     edx: nothing
            invoke      SetWindowLong,hWnd,DWL_MSGRESULT,CDRF_DODEFAULT
            ret
        .endif
assume     edx: nothing
  .endif
.endif
xor eax,eax
ret

OnInitListView endp


Greets,

six_L

hi ragdog,thanks your help.
this codes have the same trouble while many colors to be setted in the listview.
Say you, Say me, Say the codes together for ever.

Gunner

I wrote a tutorial on this, here is the code for custom draw listview.
~Rob

six_L

Hi,Gunner.thanks your help.
i used a majority of the codes, the exe attachment shows the same question.
Say you, Say me, Say the codes together for ever.

jj2007

Looks good, Gunner :t

There is also an interesting one on CodeProject, ListView Alternating Row Colours (Using Windows API) - see the comments on WinAPI vs NM_CUSTOMDRAW

fearless

Here is your code as per OP, with the amendment to use the LVM_GETITEM / LVM_SETITEM for storing/recalling backcolor using the lparam value of the listview item. I marked the changed areas with comments. Tested moving the scroller once the list fills up past visible view (then stopped) and the colors remain as they should each listview row. Hope this helps.

.586
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\include\windows.inc                         
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\gdi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\comctl32.inc
include \masm32\include\masm32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\masm32.lib



;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include \masm32\macros\macros.asm
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.const
    IDD_DIALOG    equ 1000
    IDB_EXIT        equ 1001
    IDB_STOP    equ 1003
    IDC_LIST        equ 1004
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data
    ListCap1    db "Index",0
    ListCap2    db "RandNum",0
    buffer1        db 512 dup (0)
    @dwSetTextBKColor dd 0FFff00H
    IndexOfList    dd 0H
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.data?
    hInstance    dd ?
    hList        dd ?
    lvi        LV_ITEM <?>
    Buffer        db 32 dup(?)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.code
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
iRand proc _dwMin:DWORD, _dwMax:DWORD
    local @dwRet:dword, @dqFreq:qword
   
    pushad
    invoke QueryPerformanceCounter,addr @dqFreq
    mov eax,dword ptr @dqFreq
    mov ecx, 13       
    mul ecx           
    add eax, 5       
    mov ecx, _dwMax   
    sub ecx, _dwMin   
    inc ecx       
    xor edx, edx 
    div ecx       
    mov @dwRet, edx
    popad
    mov eax, @dwRet
    add eax,_dwMin    ; eax = Rand_Number
    ret

iRand endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InsertColumns proc
    LOCAL lvc:LV_COLUMN

    invoke SendMessage,hList,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT or LVS_EX_FLATSB ,-1
    mov lvc.imask,LVCF_TEXT+LVCF_WIDTH
    mov lvc.pszText,offset ListCap1
    mov lvc.lx,100
    invoke SendMessage,hList, LVM_INSERTCOLUMN,0,addr lvc
    or lvc.imask,LVCF_FMT
    mov lvc.fmt,LVCFMT_LEFT ;CENTER
    mov lvc.pszText,offset ListCap2
    mov lvc.lx,130
    invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc
   
    ret
InsertColumns endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AddItem proc _hList:DWORD, item:DWORD, subitem:DWORD, tdata:DWORD
    LOCAL newitem:LV_ITEM
    LOCAL lstmsg:DWORD

    mov newitem.imask, LVIF_TEXT
    m2m newitem.iItem, item
    m2m newitem.iSubItem, subitem
    m2m newitem.pszText, tdata
    invoke lstrlen, tdata
    inc eax
    mov newitem.cchTextMax, eax

    .IF subitem == 0h
        mov lstmsg, LVM_INSERTITEM
    .ELSE
        mov lstmsg, LVM_SETITEM
    .ENDIF
    invoke SendMessage, _hList, lstmsg, 0h, addr newitem

    invoke SendMessage, _hList, LVM_ENSUREVISIBLE, item, FALSE
    ret

AddItem endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AddItemInt proc _hList:DWORD,item:DWORD,subitem:DWORD,tdword:DWORD
   
    invoke RtlZeroMemory,addr Buffer,sizeof Buffer
    invoke wsprintf,addr Buffer, CTXT('%i'), tdword
    invoke AddItem, _hList,item,subitem,addr Buffer
    ret

AddItemInt endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CreateButton proc hParent:DWORD,lpText:DWORD,x:DWORD,y:DWORD,w:DWORD,h:DWORD,ID:DWORD
    LOCAL hFont :DWORD

    invoke  CreateFont,14,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE, \
            ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, \
            DEFAULT_QUALITY,DEFAULT_PITCH, CTXT("Arial")
    mov    hFont, eax
   
    invoke    CreateWindowEx,0,CTXT('BUTTON'),lpText,WS_CHILD or WS_VISIBLE ,
            x,y,w,h,hParent,ID,
            hInstance,NULL
    push    eax
    invoke    SendMessage,eax,WM_SETFONT,hFont, 0
    pop    eax
    ret

CreateButton endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CreateListView proc hParent:DWORD, x:DWORD,y:DWORD,w:DWORD,h:DWORD,ID:DWORD
    LOCAL hFont :DWORD

    invoke  CreateFont,15,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE, \
            ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, \
            DEFAULT_QUALITY,DEFAULT_PITCH, CTXT("Arial")
    mov    hFont, eax

    invoke    CreateWindowEx, WS_EX_STATICEDGE + WS_EX_TRANSPARENT,\
        CTXT("SysListView32"),CTXT("test"),WS_TABSTOP + WS_VSCROLL + CBS_SIMPLE + WS_VISIBLE + WS_CHILD,x,y,w,h,\
        hParent,ID,hInstance,NULL
    push    eax
    invoke    SendMessage,eax,WM_SETFONT,hFont, 0
    pop    eax
    ret

CreateListView endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    ;---------------------------------------------------------
    ; Added some local vars here
    ;---------------------------------------------------------
    LOCAL lvitem:LV_ITEM ; local var for listview item used for LVM_GETITEM and LVM_SETITEM
    LOCAL nItem:DWORD ; temp var for our listview item index used during NMCUSTOMDRAW - could use a reg instead of a var if you wanted
    ;---------------------------------------------------------
   
    mov    eax,uMsg
    .if eax == WM_CREATE
        invoke    CreateButton,hWnd,CTXT('Stop'),71,256,56,20,IDB_STOP
        invoke    CreateButton,hWnd,CTXT('Exit'),7,256,56,20,IDB_EXIT
        invoke    CreateListView,hWnd,7,16,398,229,IDC_LIST
        mov    hList,eax
        invoke    SendMessage,hList,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT or LVS_EX_HEADERDRAGDROP OR LVS_EX_GRIDLINES,-1
        invoke    InsertColumns
        invoke    SetTimer,hWnd,0,1000,0
     .elseif eax==WM_TIMER
        push    ebx
        invoke    iRand,100,800
        mov    eax,IndexOfList
        inc    eax
        invoke    AddItemInt,hList,IndexOfList,0,eax
        invoke    iRand,100,800
        mov    ebx,eax
        invoke    AddItemInt,hList,IndexOfList,1,ebx
        .if ebx > 100 && ebx < 150
            mov    @dwSetTextBKColor,0FFADADH
        .elseif ebx >= 150 && ebx < 300
            mov    @dwSetTextBKColor,0ADFFADH
        .elseif ebx >= 300 && ebx < 400
            mov    @dwSetTextBKColor,0ADADFFH
        .elseif ebx >= 400 && ebx < 550
            mov    @dwSetTextBKColor,0FF00ADH
        .elseif ebx >= 550 && ebx < 800
            mov    @dwSetTextBKColor,000ADFFH
        .else
            mov    @dwSetTextBKColor,0FF0000H
        .endif
       
        ;---------------------------------------------------------
        ; Here we set the backcolor to the listview item we created
        ; using lParam to store the backcolor value for later on       
        ;---------------------------------------------------------
        mov eax, LVIF_PARAM
        mov lvitem.imask, eax
        mov eax, IndexOfList
        mov lvitem.iItem, eax
        mov lvitem.iSubItem, 0
        mov eax, @dwSetTextBKColor
        mov lvitem.lParam, eax
        Invoke SendMessage, hList, LVM_SETITEM, 0, Addr lvitem
        ;---------------------------------------------------------
       
        inc IndexOfList
        pop    ebx
    .elseif eax == WM_COMMAND
        .if wParam == IDB_EXIT
            invoke    DestroyWindow, hWnd
        .elseif wParam==IDB_STOP
            invoke    KillTimer,hWnd,0
        .endif
    .elseif eax == WM_NOTIFY
   
        ;---------------------------------------------------------
        ; i changed this a little bit
        ;---------------------------------------------------------
        mov ecx, lParam
        mov eax, ( [ecx].NMHDR.code)
        mov ebx, ( [ecx].NMHDR.hwndFrom)
        .IF ebx == hList ; in case we have other listview controls, we check which one we are going to modify nmcustomdraw for
            .IF eax == NM_CUSTOMDRAW
                mov ecx, lParam
                mov eax, (NMLVCUSTOMDRAW ptr[ecx]).nmcd.dwDrawStage
                .IF eax == CDDS_PREPAINT
                    mov eax, CDRF_NOTIFYITEMDRAW
                    ret
                     
                .ELSEIF eax == CDDS_ITEMPREPAINT
                    mov eax, CDRF_NOTIFYSUBITEMDRAW
                    ret
                   
                .ELSEIF eax == CDDS_ITEMPREPAINT or CDDS_SUBITEM
                    mov ecx, lParam
                    mov eax, (NMLVCUSTOMDRAW ptr[ecx]).nmcd.dwItemSpec ; listview item
                    mov nItem, eax ; could use a reg instead of a var for this i suppose
                   
                    mov eax, LVIF_PARAM
                    mov lvitem.imask, eax
                    mov eax, nItem
                    mov lvitem.iItem, eax
                    mov lvitem.iSubItem, 0
                    Invoke SendMessage, hList, LVM_GETITEM, 0, Addr lvitem ; fetch lparam which holds color to use
                    mov eax, lvitem.lParam ; we have it now in eax
                    mov ecx, lParam
                    mov (NMLVCUSTOMDRAW ptr[ecx]).clrTextBk, eax ; set color of listview item

                    mov eax, CDRF_NOTIFYSUBITEMDRAW
                    ret
                   
                .ELSE
                    mov eax, CDRF_DODEFAULT
                    ret
                .ENDIF   

            .ENDIF
        .ENDIF
        ;---------------------------------------------------------
       
         
    .elseif eax == WM_CLOSE
        invoke    KillTimer,hWnd,0
        invoke    DestroyWindow, hWnd
    .elseif eax == WM_DESTROY
        invoke    PostQuitMessage, NULL
    .else
        invoke DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .endif
         xor    eax, eax
         ret
DlgProc endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TopXY proc wDim:DWORD, sDim:DWORD

    shr sDim, 1     
    shr wDim, 1     
    mov eax, wDim   
    sub sDim, eax   

    mov eax, sDim
    ret

TopXY endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WinMain proc hInst:DWORD,hPrevInst:DWORD, CmdLine:DWORD, CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL Wwd:DWORD
    LOCAL Wht:DWORD
    LOCAL Wtx:DWORD
    LOCAL Wty:DWORD
    LOCAL hWnd:HANDLE

        mov    wc.cbSize, sizeof WNDCLASSEX
        mov    wc.style, CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
        mov    wc.lpfnWndProc, offset DlgProc
        mov    wc.cbClsExtra, NULL
        mov    wc.cbWndExtra, NULL
        m2m    wc.hInstance,hInst
        mov    wc.hbrBackground, COLOR_BTNFACE+1
        mov    wc.lpszClassName, CTXT("test_list")
    invoke    LoadIcon, NULL, IDI_APPLICATION
        mov    wc.hIcon, eax
        mov    wc.hIconSm, eax
    invoke    LoadCursor, NULL, IDC_ARROW
        mov    wc.hCursor, eax

    invoke    RegisterClassEx, addr wc
    mov    Wwd, 425
    mov    Wht, 320

    invoke    GetSystemMetrics,SM_CXSCREEN
    invoke    TopXY,Wwd,eax
    mov    Wtx, eax

    invoke    GetSystemMetrics,SM_CYSCREEN
    invoke    TopXY,Wht,eax
    mov    Wty, eax

    invoke    CreateWindowEx, NULL, CTXT("test_list"),CTXT("test_list"), WS_OVERLAPPEDWINDOW,\
            Wtx,Wty,Wwd,Wht,NULL, NULL, hInst, NULL
        mov    hWnd, eax

    invoke    ShowWindow, hWnd, SW_SHOWNORMAL
    invoke    UpdateWindow, hWnd

    .while TRUE
        invoke GetMessage, addr msg, NULL, 0, 0
        .break .if (!eax)
        invoke TranslateMessage, addr msg
        invoke DispatchMessage, addr msg
    .endw
        mov eax, msg.wParam
        ret
WinMain endp
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
start:
    invoke    GetModuleHandle,NULL
    mov    hInstance,eax
    invoke    GetCommandLine
    invoke    WinMain, hInstance ,NULL, eax, SW_SHOWDEFAULT
    invoke    ExitProcess,0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

end start





six_L

it's ok!
Hi,fearless.thanks your help.
thank you very much!
:t :t :t
Say you, Say me, Say the codes together for ever.

Gunner

Forgot to post the link to the my tutorial yesterday... MASM - Custom Draw Listview and Header
~Rob