Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29234 Discussions

Unable to obtain value from a win32 ListView control column

brianreinhold
Novice
693 Views

I am trying to read the value from a list view control that I created. To add rows and columns to the list view I have to call 

bret = SendMessage(hwndList, LVM_SETITEM, 0, LOC(lvi))

passing in a

type(T_LV_ITEM) :: lvi

structure.


This works fine. I am able to add rows to the two column report style ListView.
However, I cannot read them.

The method I use is

subroutine EditSubItemValue(hList, hDlg, row, col, newValue) !result(newValue)
use ifwinty
use user32
use comctl32
use iso_c_binding
use NlevelQGModelGlobals
use ifport ! For GetLastError()

implicit none
integer(HANDLE), intent(in) :: hList, hDlg
integer, intent(in) :: row, col
integer, intent(out) :: newValue

character(len = 16) :: newValueStr
type(T_LVITEM) :: lvi
integer(BOOL) :: bret
integer :: err

newValueStr = ''
lvi%mask = LVIF_TEXT
lvi%iItem = row ! from NM_CLICK
lvi%iSubItem = col ! from NM_CLICK
lvi%pszText = LOC(newValueStr)
lvi%cchTextMax = len(newValueStr)

bret = SendMessage(hList, LVM_GETITEMTEXT, 0, loc(lvi))
if (bret == 0) then
err = GetLastError()
endif

! Convert newValueStr string to integer
read(newValueStr, *) newValue
end subroutine EditSubItemValue

The 

SendMessage(hList, LVM_GETITEMTEXT, 0, loc(lvi))

 or

SendMessage(hList, LVM_GETITEM, 0, loc(lvi))

approaches fail. From the debugger I can tell that the row and column values are valid. GetLastError() isn't helpful either. It returns 0.

Does anyone know how to retrieve the value from a list view?

 

Another question. When setting the value do I have to provide a text value that remains in scope for the life of the listview (in order to retrieve it)?

0 Kudos
1 Reply
andrew_4619
Honored Contributor III
651 Views

well the second question having set a value in the dialog windows is storing that so the variable that held it can go out of scope.

The routine I am using is slightly different

module function ListViewGetItemDataText(hwnd, controlId, iindex, iisubitem) RESULT(gvalu)
    ! Retrieves text  associated with a list view item. If the operation fails, -1 is returned.
    use, intrinsic :: ISO_C_BINDING, only: C_LOC
    use ccfwin, only: handle, LRESULT, T_LV_ITEM, SendDlgItemMessage, FWPARAM, LVM_GETITEM, LVIF_TEXT
    IMPLICIT NONE
    character(len=:), allocatable  :: gvalu
    INTEGER(HANDLE), INTENT(IN)    :: hwnd
    INTEGER, INTENT(IN)            :: controlId
    INTEGER, INTENT(IN)            :: iindex
    INTEGER, INTENT(IN),optional   :: iisubitem
    INTEGER(LRESULT)               :: ival
    INTEGER                        :: IP
    TYPE(T_LV_ITEM),target         :: item
    integer(handle)                :: loc_item
    character(256), target         :: gbuf
    gbuf = achar(0) ! init
    item%iItem      = iindex - 1
    if(present(iisubitem) ) then
        item%iSubitem   = iisubitem
    else
        item%iSubitem   = 0
    endif
    item%mask       = LVIF_TEXT ! LVIF_PARAM
    item%pszText    = transfer(C_LOC(gbuf),0_handle) ! buffer to recieve text
    item%cchTextMax = len(gbuf)
    loc_item      = transfer(C_LOC(item),0_handle)
    ival = SendDlgItemMessage(hwnd, controlId, LVM_GETITEM, 0_FWPARAM, loc_item)
    IF(ival /= -1_LRESULT ) THEN
        ip = index( gbuf, achar(0) )
        if( ip > 1 ) then
            gvalu = gbuf(1:ip-1)
        else
            gvalu = ''
        endif
    ELSE
        CALL ControlError("ListViewGetItemDataText", controlId, "LVM_GETITEM")
        gvalu = ''
    END IF
END FUNCTION ListViewGetItemDataText
0 Kudos
Reply