The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Mr Earl on June 16, 2005, 03:07:15 PM

Title: List View in-place editing of sub-items
Post by: Mr Earl on June 16, 2005, 03:07:15 PM
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?
Title: Re: List View in-place editing of sub-items
Post by: donkey on June 17, 2005, 04:15:56 AM
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
Title: Re: List View in-place editing of sub-items
Post by: Mr Earl on June 17, 2005, 09:07:37 AM
Thanks Donkey.  Your example is a great help.