News:

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

List View in-place editing of sub-items

Started by Mr Earl, June 16, 2005, 03:07:15 PM

Previous topic - Next topic

Mr Earl

I can edit in-place the first item of a list view row using LVM_EDITLABEL.
How do I edit in-place the sub-items for that row?

donkey

I have often just used an edit control placed over the item then used the sub item hittest to find out if it has been double clicked. You create the edit when it is double clicked then destroy it when done. This peice of code is from my current project, it will create a combo box for drop down selections when a sub item is double clicked. The code is in the WM_NOTIFY handler and there are a few constants and proc calls that I have not included but you should get the general idea. It is in GoAsm syntax...

.NM_DBLCLK
cmp D[edi+NMHDR.code],NM_DBLCLK
jnz >>.NM_RCLICK
// If a combo is already open then close it
invoke SendDlgItemMessage,[hListView],999,WM_CLOSE,0,0

// Get the mouse position at the time the message was queued
invoke GetMessagePos

// Convert the returned value to dwords in a POINT structure
mov ecx,eax
and ecx,0ffffh
mov [lvhi.pt.x],ecx
shr eax,16
mov [lvhi.pt.y],eax

// The coordinate system used by GetMessagePos is screen, convert it to
// listview client coordinates
invoke ScreenToClient,[hListView],OFFSET lvhi.pt

// Get the index of the subitem (column) that has been clicked
invoke SendMessage,[hListView],LVM_SUBITEMHITTEST,0,OFFSET lvhi

// If it is -1 then no valid column was clicked
cmp D[lvhi.iItem],-1
je >>.WMN_DONE

// Columns 4 and 5 display a combo when double clicked
// all others react normally so they go to the defproc
cmp D[lvhi.iSubItem],4
je >D0
cmp D[lvhi.iSubItem],5
jne >>.DEFPROC
D0:
// Display the update group combo box

// First we need to find the current bounding rectangle of the
// subitem we want to draw the combo over
mov eax,[lvhi.iSubItem]
mov [rect.top],eax
mov D[rect.left],LVIR_LABEL
invoke SendMessage,[hListView],LVM_GETSUBITEMRECT,[lvhi.iItem],OFFSET rect

; Get the current selection number
mov D[lvi.imask],LVIF_TEXT
mov eax,[lvhi.iItem]
mov [lvi.iItem],eax
mov eax,[lvhi.iSubItem]
mov [lvi.iSubItem],eax
mov D[lvi.pszText],OFFSET szBuffer
mov D[lvi.cchTextMax],255
invoke SendMessage,[hListView],LVM_GETITEMTEXT,[lvhi.iItem],OFFSET lvi

// The bounding rectangle of the combo must fit exactly into the
// item selected so calculate the size and convert to x,y,cx,cy
mov eax,[rect.bottom]
sub eax,[rect.top]
// push the top of the combo, we''ll use it later
push eax
mov ecx,[rect.right]
sub ecx,[rect.left]
sub D[rect.top],1
invoke CreateWindowEx,NULL,"ComboBox",NULL, LV_CB_STYLE,[rect.left],\
[rect.top],ecx,100,[hListView],999,[hInstance],NULL
mov ebx,eax

// Subclass the combo to handle some special situations
invoke SetWindowLong,ebx,GWL_WNDPROC,OFFSET ComboboxProc
mov [cbparams.pOldProc],eax

// Pass some critical data in a structure, store the pointer in
// the combo's userdata field
mov eax,[hListView]
mov [cbparams.hParent],eax
mov eax,[lvhi.iItem]
mov [cbparams.iItem],eax
mov eax,[lvhi.iSubItem]
mov [cbparams.iSubitem],eax
mov D[cbparams.fType],0
invoke SetWindowLong,ebx,GWL_USERDATA,OFFSET cbparams
invoke SendMessage,ebx,WM_SETFONT,[hSmallFont],TRUE

// Select the data that will be displayed based on what subitem
// was double clicked
mov eax,[pGroupArray]
cmp D[lvhi.iSubItem],4
je >
mov eax,[pFolderArray]
:
invoke PopComboBox,ebx,eax

invoke SendMessage,ebx,CB_SELECTSTRING,-1,OFFSET szBuffer

// Pop the top of the combo we pushed earlier
pop eax
// Subtract the borders and set the item height
sub eax,4
invoke SendMessage,ebx,CB_SETITEMHEIGHT,-1,eax
// Make sure the combo has the KB focus
invoke SetFocus,ebx
jmp >.WMN_DONE
"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

Mr Earl

Thanks Donkey.  Your example is a great help.