Here is the code. Put the LVM_GETITEM anywhere. Macros follow the first section. Used RadASM for dialog and listview.

.model flat,stdcall
option casemap:none




invoke GetModuleHandle,NULL
mov    hInstance,eax
invoke GetCommandLine
invoke InitCommonControls
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,OFFSET MenuName
mov wc.lpszClassName,OFFSET ClassName
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,addr DlgName,NULL,addr WndProc,NULL
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
mov eax,msg.wParam

WinMain endp

WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
push hWin
pop hWnd
mov hIDC_LSV1,rv(GetDlgItem,hWin,IDC_LSV1)

InsertColumn 60,"Date",0
InsertColumn 60,"Time",1
InsertColumn 150,"Purpose",2        
InsertColumn 150,"Place",3
InsertItem 0,0,"New Item0"
InsertItem 1,0,"New Item1"
SetItemText 0,1,"New subitem0"
SetItemText 1,1,"Newer subitem1"        
.elseif eax==WM_PAINT
invoke BeginPaint,hWnd,addr ps
mov rDC,eax
invoke GetClientRect,hWnd,addr rect
RGB 100,100,0
invoke FillRect,rDC,addr rect,rv(CreateSolidBrush,eax)

.elseif eax==WM_NOTIFY

.elseif eax==WM_COMMAND
mov eax,wParam
and eax,0FFFFh
.if eax==IDM_FILE_EXIT
invoke SendMessage,hIDC_LSV1,LVM_GETCOLUMN,1,addr col
; Here is the crash point. Move this line anywhere...
invoke SendMessage,hIDC_LSV1,LVM_GETITEM,0,addr pitem
invoke SendMessage,hWin,WM_CLOSE,0,0
.elseif eax==IDM_HELP_ABOUT
invoke ShellAbout,hWin,addr AppName,addr AboutMsg,NULL
.elseif uMsg==WM_SIZE
mov eax,lParam
mov edx,eax
and eax,0ffffh
sub eax,10
shr edx,16
sub edx,30
invoke MoveWindow,hIDC_LSV1, 5, 25, eax,edx,TRUE
.elseif eax==WM_CLOSE
invoke DestroyWindow,hWin
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
invoke DefWindowProc,hWin,uMsg,wParam,lParam
xor    eax,eax
WndProc endp

end start


RGB macro red,green,blue
        xor eax,eax
        mov ah,blue
        shl eax,8
        mov ah,green
        mov al,red

InsertColumn MACRO width,colHeader,colPos
LOCAL header
jmp lbl
header db colHeader,0
mov col.imask,LVCF_TEXT or LVCF_WIDTH or LVCF_FMT
mov col.fmt,LVCFMT_LEFT
mov col.lx,width
mov col.pszText,offset header
invoke SendMessage,hIDC_LSV1,LVM_INSERTCOLUMN,colPos,addr col

InsertItem MACRO itemNum,subitemNum,itemText
LOCAL itemTxt
jmp lbl
itemTxt db itemText,0
mov pitem.imask,LVIF_TEXT
mov pitem.iItem,itemNum
mov pitem.iSubItem,subitemNum
mov pitem.pszText,offset itemTxt
invoke SendMessage,hIDC_LSV1,LVM_INSERTITEM,0,addr pitem

SetItemText MACRO itemNum,subitemNum,itemText
LOCAL itemTxt
jmp lbl
itemTxt db itemText,0
mov pitem.imask,LVIF_TEXT
mov pitem.iItem,itemNum
mov pitem.iSubItem,subitemNum
mov pitem.pszText,offset itemTxt
invoke SendMessage,hIDC_LSV1,LVM_SETITEMTEXT,itemNum,addr pitem

GetTextLen Macro
invoke lstrlen,pitem.pszText
mov pitem.cchTextMax,eax
Posted on 2008-09-09 06:31:42 by green
where is pitem defined? is your pitem a ptr to a LV_ITEM struct, or is it the struct itself?
usually the 'p' prefix indicates that the variable concerned is a Pointer - not a Struct.
I am guessing you are passing the address of the pointer to the struct, ie, a pointer to a pointer.
I'd have to see the rest of the code, but I assure you the problem is not LVM_GETITEM.
Posted on 2008-09-09 07:47:53 by Homer
Thanks for your interest Homer and here is the rest from the .inc.

pitem LVITEM <>

This is what Windows API states:

lResult = SendMessage(      // returns LRESULT in lResult   
(HWND) hWndControl,      // handle to destination control   
(UINT) LVM_GETITEM,      // message ID   
(WPARAM) wParam,      // = 0; not used, must be zero   
(LPARAM) lParam      // = (LPARAM) (LPLVITEM) pitem;


      Must be zero.

      Pointer to an LVITEM structure that specifies the information to retrieve and receives information about the list-view item.

Return Value
      Returns TRUE if successful, or FALSE otherwise.

'addr pitem' is the pointer to the struct as I understand it. Remove LVM_GETITEM and the code runs fine.
Posted on 2008-09-09 08:59:32 by green
Looking at some code i have for using a listview i dont use that LVM_GETITEM directly, but use other LV_ messages to retrieve information

Such as getting the currently selected row:
; Get Index of Currently Selected Item in Listview
ListViewGetSelection PROC hWin:DWORD
Invoke SendMessage, hListview,LVM_GETNEXTITEM, -1, LVNI_FOCUSED
ListViewGetSelection endp

Getting text from a list item or sub item:
; Gets the text of the specified index. Stored in LVItemText on return
ListViewGetItemText PROC hWin:DWORD, nItem:DWORD, nSubItem:DWORD
mov eax, nSubItem
mov LVItem.iSubItem, eax
invoke SendMessage, hListview, LVM_GETITEMTEXT, nItem, Addr LVItem
ListViewGetItemText endp

In my data section i have:
LVItemText db MAX_PATH dup (0) ; Buffer to hold text to display when used with LVItem
hListview dd ? ; Listview handle

but im thinking you need to specify in your LVItem variable before hand to tell the message what you are looking to retrieve, so that you will need to set the item index, and mask of the item type to retrieve.

When the message is sent, the iItem and iSubItem members identify the item or subitem to retrieve information about and the mask member specifies which attributes to retrieve.

If the mask member specifies the LVIF_TEXT value, the pszText member must contain the pointer to the buffer that receives the item text and the cchTextMax member must specify the size of the buffer.

If the mask member specifies the LVIF_STATE value, the stateMask member specifies which item states are to be returned.

Not sure if that will help you, ive a few more procs for using listviews if you want.
Posted on 2008-09-09 14:16:21 by keithsrobertson
Hi keithsrobertson, you have evidently got it right. I did some more research after your message and finally came up with this and it did not crash:

mov pitem.iItem,1
mov pitem.iSubItem,1
mov pitem.imask, LVIF_TEXT
lea eax, szBuff
mov pitem.pszText, eax
mov pitem.cchTextMax, 256
invoke SendMessage,hIDC_LSV1,LVM_GETITEM,0,addr pitem

What I have been trying to do is get the current column when it is being resized so that I can save it as a setting and LVM_GETITEM not going to work. Do you have an answer??

Thanks again...
Posted on 2008-09-09 14:48:23 by green
Ive had a look at the list of notification messages passed back to the main window from a listview and cant see an exact one that would allow you to monitor the column resize directly.

Might be better to use the LVM_GETCOLUMNWIDTH message to retrieve the column widths and save them when the user exits the program instead.
Posted on 2008-09-09 16:29:50 by keithsrobertson
Thanks keithsrobertson, I guess we will consider this one as solved at this point. Thanks again.
Posted on 2008-09-09 18:04:31 by green
is the pitem structure defined in the DATA segment or in with the CODE? because writing to that address would cause a GPF due to default page permission for CODE segments.
Posted on 2008-09-10 08:57:58 by Homer
Hello Homer, it is defined in 'data?'. I tried what keithsrobertson said and it worked.
Posted on 2008-09-10 16:29:17 by green
It looks like you're using pitem for every item you add. I think the trouble is that the last time you used it
you left imask=LVIF_TEXT and pszText as the address of a string - which your macro puts in the code section.
When you try to use LVM_GETITEM it uses imask which tells it that pszText points to a buffer in .code -> access violation.

An interesting bit from the sdk
Applications should not assume that the text will necessarily be placed in the specified buffer. The control may instead change the pszText member of the structure to point to the new text, rather than place it in the buffer.

Posted on 2008-09-10 21:54:50 by sinsi
Well think about it - handing the user a pointer to the internal string buffer avoids the need to copy the string into the buffer that the user supplied - if we just grab the pszText pointer after the call, its always going to be valid - even if its not the pointer that we supplied.
Posted on 2008-09-11 02:04:04 by Homer
My usual way of using a buffer is

buffer db 260 dup (?)
 mov pitem.pszText,offset buffer
 invoke SendMessage,hIDC_LSV1,LVM_GETITEM,0,offset pitem
 ;here I would use
 invoke lstrlen,offset buffer
 ;rather than
 invoke lstrlen,pitem.pszText

If the pointer gets changed, who owns the memory it points to?
Posted on 2008-09-11 03:24:53 by sinsi