News:

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

List View quirk

Started by hutch--, March 06, 2006, 06:58:13 AM

Previous topic - Next topic

hutch--

I usually try and avoid the common controls like the plague as I dislike the interface for most of them but I needed to use a list view set up as close as possible to and old fashion listbox. I created the list view control with CreateWindowEx, set it up with one column and loaded some test items into it. To get the items from the list I made a subclass processing the WM_LBUTTONDBLCLICK message, fed the X Y co-ordinates into a LV_HITTESTINFO.POINT structure, retreived the index of the selected item with LVM_GETITEM and everything works except for one quirk, I must first click on the header button to get the text to display otherwise I get garbage back.

This is the subclass.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

LviewProc proc hCtl   :DWORD,
               uMsg   :DWORD,
               wParam :DWORD,
               lParam :DWORD

    LOCAL pbuf  :DWORD
    LOCAL buffer[128]:BYTE
    LOCAL lvi   :LV_ITEM
    LOCAL lht   :LV_HITTESTINFO

    .if uMsg == WM_COMMAND

    .elseif uMsg == WM_LBUTTONDBLCLK
      movsx eax, word ptr [ebp+20]
      mov lht.pt.x, eax
      movsx eax, word ptr [ebp+22]
      mov lht.pt.y, eax

      lea eax, buffer
      mov lvi.pszText, eax
      mov lvi.cchTextMax, 128

      invoke SendMessage,hLview,LVM_HITTEST,0,ADDR lht  ; get index of selection

      mov lvi.iItem, eax

      invoke SendMessage,hCtl,LVM_GETITEM,0,ADDR lvi
      fn MessageBox,hCtl,lvi.pszText,"Title",MB_OK

    .endif

    invoke CallWindowProc,lpLviewProc,hCtl,uMsg,wParam,lParam

    ret

LviewProc endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««


I want to run the list view control without a header button using the LVS_NOCOLUMNHEADER style but if I remove it, I have no way of activating the text and just get garbage back.

Has anyone run into this problem before ?
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

I haven't run into this specific problem before, but I would be inclined to use LVM_GETNEXTITEM to search for the first selected and focused item rather than a hit-test. I've never had much success using hit-testing methods in VB before.

Cheers,

Zooba :U

PBrennick

Hutch,
Take a look at the attachment to see how I did my old style listbox.  Doubleclick any lineitem to see the text returned.  It may not be exactly what you are looking for but it sure works without a header.

Paul


[attachment deleted by admin]
The GeneSys Project is available from:
The Repository or My crappy website

arafel

Why resort to subclassing? You could catch double clicks from the main message procedure as well. Something like:

        .if uMsg == WM_NOTIFY

        mov     edi, lParam
        mov     eax, [edi.NMHDR].hwndFrom

                .if eax == [hListView]

                        .if [edi.NMHDR].code == NM_DBLCLK

                        invoke  SendMessage, [hListView], LVM_GETNEXTITEM, -1, LVNI_SELECTED
                        cmp     eax, -1
                        je      @f

                        mov     lvi.iItem, eax
                        mov     lvi.iSubItem, 0
                        mov     lvi.imask, LVIF_TEXT
                        lea     eax, tmp_buffer
                        mov     lvi.pszText, eax
                        mov     lvi.cchTextMax, tmp_buffer_size
                        invoke  SendMessage, [hListView], LVM_GETITEM, 0, ADDR lvi
                @@:
.endif
.endif
.endif

PBrennick

Arafel,
That is EXACTLY what I did in the attached project above.  Catch double clicks and no subclassing and return text.  Take a peek at it.  I like it when people think along the same lines.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

arafel

Hehe, sorry Paul. I guess I was too hasty, so I didn't check the attachments.

PBrennick

arafel,
Actually, I was happy to see your posting.  It gives me the idea that my method might be useful.  :U

Paul
The GeneSys Project is available from:
The Repository or My crappy website

donkey

Hi Paul,

I haven't checked the attachments either because I am at work right now but in WinExplorer I do some pretty interesting things to listviews without any subclassing, context menus and the sort. I wrote a whole slew of demos and test beds for them while I was figuring them out, I may just end up doing a little tutorial on listviews from the basics right up to virtual listviews and custom drawn ones. Would you be interested in participating in a tutorial if I do one ? (MASM/GoAsm formats). Actually a full common controls tutorial by control type would be a more ambitious project.
"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

PBrennick

Edgar,
That would be a very useful tutorial for address books, tables and such.  I would be happy to help.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

Shantanu Gadgil

A complete "reading my mind" here!!! Will like to help !!!

After struggling with listviews, treeviews, owner drawn buttons, toolbars (and having succeded beacuse of the gracious helping on MASM Forum and of course Iczelion's tutorials) I was thinking the same.

What I was thinking was a bit more evil  :green2 ...take each and every control, rip it to shreds, chew it up and explain it nicely as to what it is...how it works, etc...more on the lines from a UI Designer perspective

Obviously the first "control", if any should be the dialog itself. I remember many hours spent because either some teeny-tiny style was not set or (the DlgProc not written correctly)
To ret is human, to jmp divine!

Gustav


Hutch,

as you surely know but possibly forgot: the LVITEM structure has a "mask" (or "imask") field where you have to tell windows what fields you want to be filled. Seems this field isn't filled in your code.

Regards



hutch--

This scruffy mess actually works, probably one of the worst interfaces to a control i have ever seen.


      case WM_NOTIFY
        mov edx, lParam
        mov eax, (NMHDR PTR [edx]).hwndFrom
        .if eax == hLview
          mov eax, (NMHDR PTR [edx]).code
          .if eax == NM_DBLCLK
            invoke GetCursorPos,ADDR pt
            invoke ScreenToClient,hLview,ADDR pt
            mov ecx, pt.x
            mov edx, pt.y
            mov lht.pt.x, ecx
            mov lht.pt.y, edx
            invoke SendMessage,hLview,LVM_HITTEST,0,ADDR lht  ; get index of selection
            mov lvi.imask, LVIF_TEXT
            lea eax, buffer
            mov lvi.pszText, eax
            mov lvi.cchTextMax, 128
            mov lvi.iSubItem, 0
            invoke SendMessage,hLview,LVM_GETITEMTEXT,lht.iItem,ADDR lvi
            fn MessageBox,hWin,lvi.pszText,str$(lht.iItem),MB_OK
          .endif
        .endif


Microsoft YUK !
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

farrier

#12
hutch--,

Instead of code between GetCursorPos thru LVM_HITTEST, you should be able to use:

invoke SendMessage, [hList], LVM_GETNEXTITEM, -1, LVNI_FOCUSED ;find the item that has the focus
mov [lvi.iItem], eax


hth,

farrier

Edit: This will only give the row, and not the row and column which is what you wanted :red
ReEdit: Actually, it might work, since you specify mov lvi.iSubItem, 0 :red
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

zcoder

Is there a reason your doing a hittest?
I do it like this:


        .elseif uMsg == WM_NOTIFY
                  mov esi,lParam
                  assume esi:ptr NMHDR
                  .if [esi].NMHDR.code == NM_DBLCLK
                      mov eax,[esi].NMHDR.hwndFrom
                      .if eax == hListView
                          invoke SendMessage,hListView,LVM_GETNEXTITEM,-1,LVNI_FOCUSED
                          or eax,eax
                          js No_Good
                          push eax
                          mov [lvi.iItem],eax
                          mov [lvi.iSubItem],0
                          mov [lvi.imask],LVIF_PARAM or LVIF_TEXT
                          mov [lvi.pszText],offset szFileName
                          mov [lvi.cchTextMax],MAX_PATH
                          mov byte ptr[szFileName],0
                          invoke SendMessage,hListView,LVM_GETITEM,0,addr lvi
                          pop eax
                          mov [lvi.iItem],eax
                          mov [lvi.iSubItem],2
                          mov [lvi.imask],LVIF_PARAM or LVIF_TEXT
                          mov [lvi.pszText],offset szFileType
                          mov [lvi.cchTextMax],MAX_PATH
                          mov byte ptr[szFileType],0
                          invoke SendMessage,hListView,LVM_GETITEM,0,addr lvi
                         ; at this point the item string is in szFileName
                    .endif
               .endif
No_Good:



If there is a reason for doing a hittest then ignore this code. :bg


Zcoder....
Back in 1979, My computer ran so fine.
And there was no such thing,
As a Microsoft Crashed Machine.
http://zcoder.110mb.com
http://www.dietzel.com/partner/idevaffiliate.php?id=345_6  Free Domain Names

donkey

Hi Hutch,

I have found that with listviews the CLICK messages can be slightly delayed, making GetCursorPos unreliable. I use the following for a hit test in WM_NOTIFY where EDI contains the value in lParam (for listviews only - treeviews do not seem to suffer from the same issue)

invoke GetMessagePos
movzx edx,ax
mov D[lvhi.pt.x],edx
shr eax,16
and eax,0FFFFh
mov D[lvhi.pt.y],eax
invoke ScreenToClient,[edi+NMHDR.hwndFrom],OFFSET lvhi.pt
invoke SendMessage,[edi+NMHDR.hwndFrom],LVM_HITTEST,0,OFFSET lvhi
mov eax,[lvhi.iItem]
test eax,eax
js >.NOITEM
; perform a LVM_GETNEXTITEM to determine which item if any has the focus
invoke SendMessage,[edi+NMHDR.hwndFrom],LVM_GETNEXTITEM,-1,LVNI_FOCUSED
test eax,eax
js >.NOITEM


BTW if you use GetCursorPos there is no need for 2 POINT structures...

invoke GetCursorPos,ADDR lht.pt
invoke ScreenToClient,hLview,ADDR lht.pt
invoke SendMessage,hLview,LVM_HITTEST,0,ADDR lht  ; get index of selection
"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