News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

code samples on sorting a listview?

Started by dacid, February 01, 2010, 10:09:08 AM

Previous topic - Next topic

dacid

Now im triyin to copy a complete line of the listview to the clipboard..   I use GlobalAlloc & GlobalLock but when I call LV_GETITEM in a .WHILE to get the text of every SubItem to addr returned by GlobalLock obviously I overwrite every previous item and the LV_GETITEM call doesnt return the size of the text. Ideas?

Gunner

Wait, you confused me.... that is you on the other board right, just a diff nick?  Post your code so we can see where your problem is
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

donkey

Use LVM_GETITEMTEXT, it will return the number of characters written to the buffer which you can use to update the pointer in order to append the next string returned. At least I think that's what you want to do, I am a bit confused by the question.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dacid

Gunner: Yes.

Donkey: Thats exactly what im trying to do...

              invoke OpenClipboard,hWnd
              invoke EmptyClipboard

              invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,512
              mov    hMemory,eax
              invoke GlobalLock,hMemory

              xor    ecx,ecx             
              .WHILE  ecx!=4
               push   eax
               push   ecx
               
               mov    lvitem.iSubItem,ecx
               mov    lvitem.imask,LVIF_TEXT
               mov    lvitem.pszText,eax
               mov    lvitem.cchTextMax,511
               invoke SendMessage,hListView,LVM_GETITEMTEXT,Index,ADDR lvitem
               mov    edx,eax
                 
              pop    ecx
              pop    eax
              add    eax,edx
              inc    ecx
             .ENDW

              invoke GlobalUnlock,hMemory
              invoke SetClipboardData,CF_TEXT,hMemory
              invoke CloseClipboard


What do you think about this code?  Its ok? How can I add a blank space between subitems? I

dacid

and another question  :red .. how i can get all selected items to copy to clipboard? a loop with LVM_GETNEXTITEM & LVNI_FOCUSED ?

donkey

Hi dacid,

With your code, first I would use other registers than ECX and EAX, EBX and EDI are much better for this application as they are not overwritten by the SendMessage call, eliminating the need to preserve them with push/pop. To add a space just mov a 0x20 byte into the string after the call to SendMessage...

invoke GlobalLock,hMemory
mov edi,eax
xor ebx,ebx
mov esi, 511

.WHILE  ebx!=4
    mov    lvitem.iSubItem,ebx
    mov    lvitem.imask,LVIF_TEXT
    mov    lvitem.pszText,edi
    mov    lvitem.cchTextMax,esi
    invoke SendMessage,hListView,LVM_GETITEMTEXT,Index,ADDR lvitem

    add    edi,eax
    sub    esi,eax
    mov    BYTE PTR [edi],20h ; insert a space
    inc    edi ; update the pointer
    dec    esi
    inc    ebx
.ENDW


Also, by keeping cchTextMax fixed you are allowing the possibility of a bufffer overflow exploit, the size of the buffer passed should reflect the size remaining, I used ESI for that purpose.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

farrier

dacid,

This won't answer your question directly, but ...

I mainly use listview to display a range of choices from a database: customer; item; transaction; etc.  When an item is added to the listview, I include the record number as one of the items in the listview.  This way, when the user selects an item from the listview, I can use the record number to retrieve all the items from the original database.  The advantage to this, is that all the items from the database don't have to be included in the listview, and you only need to include the few items in the listview that make it easy for the user to select on particular record.

hth,

farrier
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

dacid

Thak you very much donkey!!

Farrier I will take your idea in consideration!


Now the next step, copy to clipboard all selected items...


              invoke OpenClipboard,hWnd
              invoke EmptyClipboard

              invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,4096
              mov    hMemory,eax
              invoke GlobalLock,hMemory

              mov    edi,eax

              invoke SendMessage,hListView,LVM_GETSELECTEDCOUNT,0,0
              mov    nselected,eax

              .WHILE nselected!=0
               invoke SendMessage,hListView,LVM_GETNEXTITEM,-1,LVNI_SELECTED          
               .IF    eax!=-1
                mov    Index,eax

                xor    ebx,ebx
                mov    esi,4095

                .WHILE  ebx!=4
                 mov    lvitem.iSubItem,ebx
                 mov    lvitem.imask,LVIF_TEXT
                 mov    lvitem.pszText,edi
                 mov    lvitem.cchTextMax,esi
                 invoke SendMessage,hListView,LVM_GETITEMTEXT,Index,ADDR lvitem

                 add    edi,eax
                 sub    esi,eax
                 mov    BYTE PTR [edi],20h                                                 ; insert a space
                 inc    edi                                                                ; update the pointer
                 dec    esi
                 inc    ebx
                .ENDW
              .ENDIF
               dec  nselected
             .ENDW

              invoke GlobalUnlock,hMemory
              invoke SetClipboardData,CF_TEXT,hMemory
              invoke CloseClipboard


This copy the same item over and over again... Seems that I dont understand how LVM_GETNEXTITEM works...

dacid

I just fixed it this way:

             
              mov    Index,-1

              .WHILE nselected!=0
               invoke SendMessage,hListView,LVM_GETNEXTITEM,Index,LVNI_SELECTED          



This seems to work ... but Im not sure this code is "ok"

donkey

Looks good to me. Be sure to preserve the values of EBX, EDI and ESI, this is usually done in the PROC statement:

MyProcedure PROC uses EBX EDI ESI SomeParam:DWORD
...
MyProcedure ENDP

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dacid

Yep, thanks.  Im triying to "draw" the arrows in the columns when the user clicks on it... Im looking at your example "CustomListview" but I use MASM and this code:

            mov    hditem.mask,HDI_FORMAT+HDI_IMAGE
            mov    hditem.fmt,HDF_IMAGE+HDF_STRING+HDF_BITMAP_ON_RIGHT


gives me this error:

error A2081: missing operand after unary operator


Do youk know why?

donkey

QuoteDo youk (sic) know why?

Yes, as a matter of fact I do, hditem.mask is not allowed in masm, it uses the keyword MASK. I think Hutch changes it to imask, you'll have to check windows.inc.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dacid