Announcement

Collapse
No announcement yet.

Listview Troubles

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Listview Troubles

    I was unable to see the %NM_RETURN message from a listview so I tried to subclass it.
    if you run this code you will see that the subclass proc does not seem to be working
    at all. Actually, it does get called, but nothing makes any sense. The %NM_RETURN message
    is returned in lparam as the code member of a NMHDR structure. Other messages, like
    %NM_RCLICK, can be seen in the default dialog proc. Just not the Return key.

    The following code demonstrates my problem(s).

    Anybody like to take a look??

    Thanks, Harry

    Code:
    ' ** Eliminate unnecessary macros
    %NOANIMATE = 1
    %NODRAGLIST = 1
    %NOHEADER = 1
    %NOIMAGELIST = 1
    %NOTABCONTROL = 1
    %NOTRACKBAR = 1
    %NOTREEVIEW = 1
    %NOUPDOWN = 1
    
    #COMPILE EXE
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    %NUMROWS=100
    %IDOK = 1
    %IDCANCEL = 2
    %IDTEXT = 100
    %BS_DEFAULT = 1
    %IDLISTVIEW = 101
    %IDLISTMSG = 102
    
    GLOBAL MSGREC() AS STRING
    GLOBAL UserName AS STRING
    GLOBAL hListView AS LONG
    GLOBAL hListMSG AS LONG
    GLOBAL lviewSort AS INTEGER
    GLOBAL gHINST AS LONG
    GLOBAL gHDLG AS LONG
    GLOBAL LPADDRESS&
    
    SUB AppendListView (hList AS LONG, Rec() AS STRING )
    DIM z AS INTEGER
    DIM iStatus AS INTEGER
    DIM szStr AS ASCIIZ * 300
    DIM lvi AS LV_ITEM
    LOCAL x AS LONG
    
    lvi.iItem = ListView_GetItemCount(hList)
    lvi.mask = %LVIF_TEXT
    lvi.stateMask = %LVIS_FOCUSED
    lvi.pszText = VARPTR(szStr)
    FOR z = 0 TO UBOUND(Rec)
      szStr = Rec(z)
      lvi.iSubItem = z
      lvi.lParam = lvi.iItem
      IF z = 0 THEN
         lvi.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
         iStatus = ListView_InsertItem (hList, lvi)
      ELSE
         lvi.mask = %LVIF_TEXT
         iStatus = ListView_SetItem (hList, lvi)
      END IF
    NEXT
    'THE FOLLOWING DOESN'T WORK EITHER!!
    IF HLIST=HLISTMSG THEN 'JUST APPENDED TO MSG LISTVIEW
       ICNTR&=LISTVIEW_GETITEMCOUNT(HLIST)'GET ITEM COUNT
       'MAKE SURE LAST ITEM IS VISIBLE
       RET&=LISTVIEW_ENSUREVISIBLE(HLIST,ICNTR&,%FALSE)
    END IF
    END SUB
    
    FUNCTION RetrieveLVData(hList AS LONG, _
              Recno AS LONG, Fieldno AS LONG) AS STRING
    %cchTextMax = 300
    LOCAL lvi AS LV_ITEM
    LOCAL value AS ASCIIZ * 300
    LOCAL x AS LONG
    
    lvi.cchTextMax = %cchTextMax
    lvi.iItem = Recno
    lvi.pszText = VARPTR(value)
    lvi.iSubItem = Fieldno
    lvi.Mask = %LVIF_TEXT
    x = ListView_GetItem (hList, lvi)
    FUNCTION = value
    END FUNCTION
    
    CALLBACK FUNCTION CancelButton()
    
    DIALOG END CBHNDL, 0
    
    END FUNCTION
    
    CALLBACK FUNCTION tstListView()
    LOCAL ID&, hDlg AS LONG
    LOCAL my_LpLvNm AS NM_LISTVIEW PTR
    LOCAL itemselect AS LONG
    LOCAL i AS LONG, sText AS STRING
    STATIC zText AS ASCIIZ * 255
    
    hDlg = CBHNDL
    SELECT CASE CBMSG
       CASE %WM_INITDIALOG
           'SUBCLASS THE LISTVIEW CONTROL
           lpAddress& =SetWindowLong(HLISTVIEW,%GWL_WNDPROC,_
                  BYVAL CODEPTR(LISTVIEWPROCESS))
       CASE %WM_DESTROY
           SetWindowLong HLISTVIEW, %GWL_WNDPROC, LPADDRESS&
       CASE %WM_NOTIFY
          SELECT CASE LOWRD(CBWPARAM)
             CASE %IDLISTVIEW
                my_LpLvNm = CBLPARAM
                IF @my_LpLvNm.hdr.code = %LVN_COLUMNCLICK THEN
                   MSGREC(0)="DEFPROC - COLUMN CLICK " + _
                     STR$(%LVN_COLUMNCLICK)
                   AppendListView hListMSG, MSGRec()
                 ELSEIF @my_LpLvNm.hdr.code = %NM_DBLCLK THEN
                   sText = RetrieveLVData(hListView, _
                     @my_LpLvNm.iItem, @my_LpLvNm.ISubItem)
                   MSGREC(0)="DEFPROC - DBLCLICK " + STEXT
                   AppendListView hListMSG, MSGRec()
                ELSEIF @my_LpLVNM.HDR.code = %NM_RCLICK THEN
                   MSGREC(0)="DEFPROC - RIGHT CLICK "
                   AppendListView hListMSG, MSGRec()
                ELSEIF @my_LpLVNM.HDR.code = %NM_RETURN THEN
                   MSGREC(0)="DEFPROC - RETURN "
                   AppendListView hListMSG, MSGRec()
                ELSE
                  STEXT=STR$(@my_LpLVNM.HDR.code)
                  '  MSGREC(0)="DEFPROC - UNKNOWN " + STEXT
                  '  AppendListView hListMSG, MSGRec()
                END IF
          END SELECT
    END SELECT
    END FUNCTION
    
    
    'SUBCLASS PROC
    FUNCTION LISTVIEWPROCESS (BYVAL hWnd AS LONG, _
            BYVAL wMsg AS LONG, _
            BYVAL wParam AS LONG, _
            BYVAL lParam AS LONG) AS LONG
    LOCAL my_LpLvNm AS NM_LISTVIEW PTR
    LOCAL itemselect AS LONG
    LOCAL i AS LONG, sText AS STRING
    STATIC zText AS ASCIIZ * 255
    SELECT CASE wmsg
      CASE %WM_NOTIFY
           SELECT CASE HWND 'LOWRD(WPARAM)
             CASE HLISTVIEW  '%IDLISTVIEW
                my_LpLvNm = LPARAM
                IF @my_LpLvNm.hdr.code = %LVN_COLUMNCLICK THEN
                     MSGREC(0)="SUBCLASS - COLUMN CLICK"
                     AppendListView hListMSG, MSGRec()
                ELSEIF @my_LpLvNm.hdr.code = %NM_DBLCLK THEN 'Now have Mouse Clicks!
                  sText = RetrieveLVData(hListView, _
                    @my_LpLvNm.iItem,@my_LpLvNm.ISubItem)
                  MSGREC(0)="SUBCLASS - DBLCLICK " + STEXT
                  AppendListView hListMSG, MSGRec()
                ELSEIF @my_LpLVNM.HDR.code = %NM_RCLICK THEN
                  MSGREC(0)="SUBCLASS - RIGHT CLICK"
                  AppendListView hListMSG, MSGRec()
                ELSEIF @my_LpLVNM.HDR.code = %NM_RETURN THEN
                  MSGREC(0)="SUBCLASS - RETURN"
                  AppendListView hListMSG, MSGRec()
                ELSE
                  STEXT=STR$(@my_LpLVNM.HDR.code)
                  MSGREC(0)="SUBCLASS - UNKNOWN " + STEXT
                  AppendListView hListMSG, MSGRec()
                END IF
        END SELECT
    
    END SELECT
    
    FUNCTION=CALLWINDOWPROC(BYVAL LPADDRESS&,HLISTVIEW,WMSG,WPARAM,LPARAM)
    END FUNCTION
    
    
    FUNCTION WINMAIN (BYVAL hInstance     AS LONG, _
                      BYVAL hPrevInstance AS LONG, _
                      lpCmdLine           AS ASCIIZ PTR, _
                      BYVAL iCmdShow      AS LONG) EXPORT AS LONG
    
    $REGISTER NONE
    
    LOCAL hDlg AS LONG
    LOCAL result AS LONG, zText AS ASCIIZ * 255
    LOCAL icc AS INIT_COMMON_CONTROLSEX
    LOCAL LVC AS LV_COLUMN, i AS LONG,r AS LONG, c AS LONG
    %NumCols = 3
    DIM Rec(%NumCols)AS STRING
    REDIM MSGREC(1)
    LOCAL LVI AS LV_ITEM
    LOCAL LSTYLE AS LONG
    gHINST=HINSTANCE
    icc.dwICC = %ICC_DATE_CLASSES OR _
          %ICC_BAR_CLASSES OR %ICC_LISTVIEW_CLASSES
    icc.dwSize = SIZEOF(icc)
    InitCommonControlsEx icc
    
    DIALOG NEW 0, _
     "LISTVIEW TEST OF COLUMN CLICK, DOUBLE CLICK," + _
      "RIGHT CLICK & RETURN KEY", _
     ,, 460, 250, 0, 0 TO hDlg
    GHDLG=HDLG
    ' ** Add controls to it
    CONTROL ADD TEXTBOX, hDlg, %IDTEXT, "", 14, 12, 134, 12, 0
    CONTROL ADD BUTTON, hDlg, %IDCANCEL, "Cancel", 84, 32, 40, _
                14, 0 CALL CancelButton
    CONTROL ADD "SysListView32", hDlg, %IDLISTVIEW,"",0,50,200,180, _
    %WS_border OR %WS_Child OR %WS_visible OR _
    %WS_TABSTOP OR %LVS_Report OR %LVS_SHOWSELALWAYS, _
    %WS_EX_CLIENTEDGE ' CALL ListViewProcess
    
    CONTROL HANDLE hDlg,%IDLISTVIEW TO hListView
    lStyle = SendMessage(hListView, _
     %LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
    lStyle = lStyle OR _
     %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES
    CALL SendMessage(hListView, %LVM_SETEXTENDEDLISTVIEWSTYLE, _
          0, BYVAL lStyle)
    
    lvC.mask = %LVCF_FMT OR %LVCF_WIDTH OR _
               %LVCF_TEXT OR %LVCF_SUBITEM
    lvC.fmt = %LVCFMT_LEFT
    lvC.cx = 90
    LVC.cchTextMax = 255
    FOR c = 1 TO %NumCols
      zText = "Column " + FORMAT$(c - 1)
      LVC.pszText = VARPTR(zText)
      CONTROL SEND hDlg,%IDLISTVIEW,%LVM_INSERTCOLUMN, _
       c, VARPTR(lvc)
    NEXT
    FOR r = 1 TO %NumRows
      FOR c = 1 TO %NumCols
        rec(c-1) = "Row " + FORMAT$(r) + " Col " + FORMAT$(c-1)
      NEXT c
      AppendListView hListView, Rec()
    NEXT r
    
    CONTROL ADD "SysListView32", hDlg, %IDLISTMSG,"",201,50,200,180, _
    %WS_border OR %WS_Child OR %WS_visible OR _
    %WS_TABSTOP OR %LVS_Report OR %LVS_SHOWSELALWAYS, _
    %WS_EX_CLIENTEDGE
    
    CONTROL HANDLE hDlg,%IDLISTMSG TO hListMSG
    lStyle = SendMessage(hListMSG, _
     %LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0)
    lStyle = lStyle OR _
     %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES
    CALL SendMessage(hListMSG, %LVM_SETEXTENDEDLISTVIEWSTYLE, _
     0, BYVAL lStyle)
    
    lvC.mask = %LVCF_FMT OR %LVCF_WIDTH OR %LVCF_TEXT OR %LVCF_SUBITEM
    lvC.fmt = %LVCFMT_LEFT
    lvC.cx = 280
    LVC.cchTextMax = 255
    FOR c = 1 TO 1
      zText = "LISTVIEW MESSAGES "
      LVC.pszText = VARPTR(zText)
     CONTROL SEND hDlg,%IDLISTMSG,%LVM_INSERTCOLUMN, _
        c, VARPTR(lvc)
    NEXT
    
    ' ** Display the dialog
    DIALOG SHOW MODAL hDlg CALL tstListView TO Result
    
    END FUNCTION

  • #2
    Sorry, my apologize!

    Regards, Jules



    [This message has been edited by Jules Marchildon (edited February 09, 2000).]
    Best regards
    Jules
    www.rpmarchildon.com

    Comment


    • #3
      Originally posted by Jules Marchildon:
      The Listview control has to have the focus first for NM_RETURN to work.

      Regards, Jules


      Thanks for the reply Jules, but that doesn't seem to be the problem. Since the
      Listview responds to Up/Dwn PgUp/PgDwn etc. it does have the focus.

      Thanks, Harry

      Comment


      • #4
        NM_RETURN is sent to the parent window if the parent window was created using the win32 api call CreatWindow/Ex()
        and should not require subclassing.

        Because this is really a Dialog running, it has some built in
        default handlers, and that could be the problem. I added the
        following OK button and it will process the return key as you
        would expect a dialog to handle it.

        Code:
        '-------
        CALLBACK FUNCTION OkButtonProc()
         
            msgbox "RETURN KEY FOUND"
         
            DIALOG END CBHNDL, 0
        END FUNCTION
        '---------
        .
        .
        .
        
        '---
            CONTROL ADD BUTTON, _
                        hDlg, %IDOK, "&OK", _
                        160, 10, 40, 14, _
                        %WS_TABSTOP _
                        CALL OkButtonProc
        '---
        I remember some others discussed this awhile back.
        It may be something like adding a style like LV_WANTRETURN ???

        I know there is a general solution for this problem and I'll
        bet Lance remembers this?

        Maybe use a CreateWindow/Ex() function to create your main window
        and create the controls with DDT ?


        Regards, Jules
        --




        [This message has been edited by Jules Marchildon (edited February 09, 2000).]
        Best regards
        Jules
        www.rpmarchildon.com

        Comment


        • #5
          Anyone......

          On further investigation, The NM_RETURN message is processed just fine
          if I use the CREATEWINDOW API rather than DIALOG NEW to create the window.
          I'd like to use the listview control with DDT since I'm adding it to an
          existing app and don't want to make any more changes than neccessary.

          Any thoughts out there??

          Harry

          Comment


          • #6
            I've not had time to try your code, but if DDT does not pass the message on, then you may need to subclass the dialog to intercept the message.

            ------------------
            Lance
            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            Lance
            mailto:[email protected]

            Comment


            • #7
              The answer is above, just be creative.

              Using DDT, create the OK button but don't show it, keep it hidden.

              Now, use the callback procedure to trap your return key. You can
              take it from there...


              HTH
              Regards, Jules

              Best regards
              Jules
              www.rpmarchildon.com

              Comment

              Working...
              X