Announcement

Collapse
No announcement yet.

Listview Question

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

  • Steve Bouffe
    replied
    Thanks everyone for the posts. I'm unsure how to implement your suggestions,

    I have put together a complete executable example of what I have so far.

    Code:
    ' SED_PBWIN
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    %SelectListEntryListBox = 974		' ----------- SELECT LIST ENTRY EQUATES ----------
    %SelectListEntrySearchTextBox = 975
    %SelectListEntryCancelButton = 976
    %SelectListEntryOKButton = 977		' ----------- END OF SELECT LIST ENTRY EQUATES ----------
    %MOD_ALT = &H00000001		' Keyboard Hook
    %MOD_CONTROL = &H00000002		' Keyboard Hook
    %MOD_SHIFT = &H00000004		' Keyboard Hook
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    #COMPILE EXE
    #DIM ALL
    #DEBUG ERROR ON
    #TOOLS ON
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    DECLARE FUNCTION Show_Get_List_Selection_Dialog( BYVAL hParent AS DWORD, DialogTitle AS STRING, CursorLine AS LONG, BYVAL DiagWidth AS LONG _
      , BYVAL DiagHeight AS LONG, GetListSelectArray_GL( ) AS STRING, BYVAL IncLineNums AS LONG, BYVAL AllowMulSel AS LONG ) AS LONG
    DECLARE CALLBACK FUNCTION Get_List_Selection_Proc( )
    DECLARE FUNCTION Get_ListBox_Rows_Selected( BYVAL Winhandle AS DWORD, BYVAL ListBoxID AS LONG ) AS STRING
    DECLARE FUNCTION Convert_Keyboard_Hook_Code( BYVAL CBLPARAM_PARSED AS DWORD, BYVAL CBWPARAM_PARSED AS DWORD, BYVAL Return_Alt_Shift_Etc AS LONG ) AS STRING
    DECLARE SUB Add_Columns_To_List_View( BYVAL WinHandle AS DWORD, BYVAL ListViewID AS LONG, BYVAL ListBoxHeaders AS STRING )
    DECLARE SUB Populate_List_View( BYVAL WinHandle AS DWORD, ListViewID AS LONG, ListViewDataArray( ) AS STRING, BYVAL ListViewArrayQty AS QUAD, BYVAL ListViewColQty AS LONG, BYVAL CursorLine AS LONG )
    DECLARE FUNCTION KeyBoardProc( BYVAL iCode AS INTEGER, BYVAL wParam AS DWORD, BYVAL lParam AS LONG ) AS DWORD
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    GLOBAL CallBack_SR_String1_GL AS STRING
    GLOBAL TempListArray_Row_Qty_GL AS LONG
    GLOBAL TempListArray_Col_Qty_GL AS LONG
    GLOBAL TempListArray_GL( ) AS STRING
    GLOBAL GetListSelectArray_GL( ) AS STRING
    GLOBAL Current_Keyboard_Hook_DlgHan_GL AS DWORD
    GLOBAL ghKeyb AS DWORD		' global handles for keyboard hook
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    FUNCTION PBMAIN
      '
      LOCAL TL1 AS LONG
      '
      ghKeyb = SETWINDOWSHOOKEX( %WH_KEYBOARD, CODEPTR( KeyBoardProc ), 0, GETCURRENTTHREADID )		' Keyboard Hook
      '
      REDIM TempHeldDispArray( 1 TO 10, 1 TO 3 ) AS STRING
      '
      FOR TL1 = 1 TO 10
        '
        TempHeldDispArray( TL1, 1 ) = FORMAT$( RND( 1, 100 ))
        TempHeldDispArray( TL1, 2 ) = PARSE$( "Anita Smith/Andrew/Alex/Amanda/Adrian/Ciaran/Christopher Smith/Christopher Brown/Andrew Green/Anita Brown", "/", TL1 ) + STR$( RND( 1, 10 ))
        TempHeldDispArray( TL1, 3 ) = FORMAT$( RND( 1, 100 ))
        '
      NEXT TL1
      '
      CALL Show_Get_List_Selection_Dialog( 0, "Test List" + $CR + "Created,Company / Surname,Value*," + $CR + $CR + "1,2,3", 1, 465, 310, TempHeldDispArray( ), %FALSE, %FALSE )
      '
      IF CallBack_SR_String1_GL = "" THEN
        MSGBOX "Canelled Select"
      ELSE
        MSGBOX "Selected Line " + CallBack_SR_String1_GL
      END IF
      '
      UNHOOKWINDOWSHOOKEX ghKeyb
      '
    END FUNCTION
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    FUNCTION Show_Get_List_Selection_Dialog( BYVAL hParent AS DWORD, DialogTitle AS STRING, CursorLine AS LONG, BYVAL DiagWidth AS LONG, BYVAL DiagHeight AS LONG, GetListSelectArray_GL( ) AS STRING, BYVAL IncLineNums AS LONG, BYVAL AllowMulSel AS LONG ) AS LONG
      '
      ON ERROR GOTO Show_Get_List_Selection_Dialog_Error_Handler
      '
      ' first entry is the default list view cursor
      LOCAL hDlg AS DWORD
      LOCAL TL1 AS LONG
      LOCAL TL2 AS LONG
      LOCAL TS1 AS STRING
      '
      ' Parse$( DialogTitle, $CR, 1) = Dialog Title
      ' Parse$( DialogTitle, $CR, 2) = List Of Column Headers
      ' Parse$( DialogTitle, $CR, 3) = Overiding Font Handle
      ' Parse$( DialogTitle, $CR, 4) = Columns To Perform Quick Lookup On [ 1,4,5,7 ] : If None Then Then Use All
      '
      CallBack_SR_String1_GL = PARSE$( DialogTitle, $CR, 4 )
      '
      TempListArray_Row_Qty_GL = UBOUND( GetListSelectArray_GL( ), 1 )
      TempListArray_Col_Qty_GL = UBOUND( GetListSelectArray_GL( ), 2 ) + 2
      '
      REDIM TempListArray_GL( 1 TO TempListArray_Row_Qty_GL, 1 TO TempListArray_Col_Qty_GL ) AS GLOBAL STRING
      '
      FOR TL1 = 1 TO TempListArray_Row_Qty_GL
        '
        IF IncLineNums = %TRUE THEN
          TempListArray_GL( TL1, 1 ) = FORMAT$( TL1 )
        END IF
        '
        FOR TL2 = 1 TO UBOUND( GetListSelectArray_GL( ), 2 )
          '
          TempListArray_GL( TL1, TL2 - ( IncLineNums = %TRUE )) = GetListSelectArray_GL( TL1, TL2 )
          '
        NEXT TL2
        '
      NEXT TL1
      '
      DIALOG NEW hParent, PARSE$( DialogTitle, $CR, 1 ),,, DiagWidth, DiagHeight, _
        %WS_POPUP OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
        %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
        %WS_EX_WINDOWEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
        %WS_EX_RIGHTSCROLLBAR, TO hDlg
      '
      CONTROL ADD "SysListView32", hDlg, %SelectListEntryListBox, "SysListView32_1", 10, 10, DiagWidth - 20, DiagHeight - 40, _
        %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP OR %LVS_REPORT OR - %LVS_SINGLESEL * ( AllowMulSel = %FALSE ) OR _
        %LVS_SHOWSELALWAYS, %WS_EX_LEFT OR %WS_EX_RIGHTSCROLLBAR
      TS1 = PARSE$( DialogTitle, $CR, 3 )
      IF TS1 <> "" THEN
        CONTROL SEND hDlg, %SelectListEntryListBox, %WM_SETFONT, VAL( TS1 ), 0
      END IF
      CALL Add_Columns_To_List_View( hDlg, %SelectListEntryListBox, PARSE$( DialogTitle, $CR, 2 ))
      '
      CONTROL ADD TEXTBOX, hDlg, %SelectListEntrySearchTextBox, "", 10, DiagHeight - 25, DiagWidth - 160, 12, _
        %WS_CHILD OR %WS_VISIBLE OR %ES_LEFT OR %ES_READONLY OR %WS_GROUP OR %WS_TABSTOP, %WS_EX_CLIENTEDGE OR _
        %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
      '
      CONTROL ADD BUTTON, hDlg, %SelectListEntryCancelButton, "Cancel", DiagWidth - 140, DiagHeight - 25, 60, 20
      CONTROL ADD BUTTON, hDlg, %SelectListEntryOKButton, "Select", DiagWidth - 70, DiagHeight - 25, 60, 20, %BS_DEFPUSHBUTTON
      CALL Populate_List_View( hDlg, - %SelectListEntryListBox, TempListArray_GL( ), TempListArray_Row_Qty_GL, UBOUND( GetListSelectArray_GL( ), 2 ) - ( IncLineNums = %TRUE ), CursorLine )
      '
      DIALOG SHOW MODAL hDlg, CALL Get_List_Selection_Proc
      '
      EXIT FUNCTION
      '
    Show_Get_List_Selection_Dialog_Error_Handler :
      '
      MSGBOX "Show_Get_List_Selection_Dialog Error" + STR$( ERR ), %MB_ICONERROR OR %MB_TASKMODAL, "Epos"
      '
    END FUNCTION
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    CALLBACK FUNCTION Get_List_Selection_Proc( )
      '
      ON ERROR GOTO Get_List_Selection_Proc_Error_Handler
      '
      LOCAL TL1 AS LONG
      LOCAL TL2 AS LONG
      LOCAL TL3 AS LONG
      LOCAL TS1 AS STRING
      LOCAL TS2 AS STRING
      LOCAL TS3 AS STRING
      LOCAL MS AS STRING
      LOCAL SM AS STRING
      LOCAL SearchWordsQty AS LONG
      '
      SELECT CASE AS LONG CBMSG
          '
        CASE %WM_INITDIALOG
          '
          DIM ListPos_ST AS STATIC LONG
          DIM XCursor_ST AS STATIC LONG
          DIM CursorFlag_ST AS STATIC LONG
          DIM IDT_TIMER_ST AS STATIC LONG
          DIM InpString AS STATIC STRING
          '
          InpString = ""
          '
          IDT_TIMER_ST = %WM_USER + 2500
          SETTIMER CBHNDL, IDT_TIMER_ST, 500, BYVAL %NULL
          '
          Current_Keyboard_Hook_DlgHan_GL = CBHNDL
          '
          ListPos_ST = VAL( Get_ListBox_Rows_Selected( CBHNDL, %SelectListEntryListBox ))
          '
        CASE %WM_NOTIFY
          '
          '
        CASE %WM_DESTROY
          '
          KILLTIMER CBHNDL, IDT_TIMER_ST
          '
        CASE %WM_TIMER
          '
          CursorFlag_ST = CursorFlag_ST XOR 1
          '
          IF CursorFlag_ST = 0 THEN
            CONTROL SET TEXT CBHNDL, %SelectListEntrySearchTextBox, InpString
          ELSE
            IF XCursor_ST = LEN( InpString ) THEN
              TS1 = InpString + "_"
            ELSE
              TS1 = InpString
              MID$( TS1, XCursor_ST + 1, 1 ) = "_"
            END IF
            CONTROL SET TEXT CBHNDL, %SelectListEntrySearchTextBox, TS1
          END IF
          '
        CASE %WM_NCACTIVATE
          '
        CASE %WM_SYSCOMMAND
          '
          SELECT CASE CBWPARAM AND &hFFF0
            CASE %SC_CLOSE
              CallBack_SR_String1_GL = ""
              DIALOG END CBHNDL
          END SELECT
          '
        CASE %WM_HELP
          '
          MSGBOX "Help"
          '
        CASE %WM_USER + 101
          '
          TS3 = InpString
          '
          TS2 = Convert_Keyboard_Hook_Code( CBLPARAM, CBWPARAM, %FALSE )
          '
          IF LEN( TS2 ) = 1 THEN
            InpString = InpString + TS2
            IF RIGHT$( TS1, 2 ) = "  " THEN
              InpString = LEFT$( InpString, - 1 )
            END IF
            XCursor_ST = LEN( InpString )
          ELSEIF TS2 = "BackSpace" THEN
            InpString = LEFT$( InpString, LEN( InpString ) - 1 )
            XCursor_ST = LEN( InpString )
          ELSEIF TS2 = "Up Arrow" THEN
            DECR ListPos_ST
            IF ListPos_ST = 0 THEN
              ListPos_ST = 1
            END IF
          ELSEIF TS2 = "Down Arrow" THEN
            INCR ListPos_ST
            IF ListPos_ST > TempListArray_Row_Qty_GL THEN
              ListPos_ST = TempListArray_Row_Qty_GL
            END IF
          ELSEIF TS2 = "Left Arrow" AND InpString <> "" AND 1 = 2 THEN
            DECR XCursor_ST
            IF XCursor_ST < 0 THEN
              XCursor_ST = 0
            END IF
          ELSEIF TS2 = "Right Arrow" AND InpString <> "" AND 1 = 2 THEN
            INCR XCursor_ST
            IF XCursor_ST > LEN( InpString ) THEN
              XCursor_ST = LEN( InpString )
            END IF
          END IF
          '
          InpString = LTRIM$( InpString )
          '
          IF InpString <> "" AND InpString <> TS3 THEN
            '
            SM = UCASE$( TRIM$( InpString ))
            '
            SearchWordsQTY = PARSECOUNT( SM, $SPC )
            '
            FOR TL1 = 1 TO TempListArray_Row_Qty_GL
              '
              MS = ""
              '
              FOR TL2 = 1 TO TempListArray_Col_Qty_GL
                '
                IF CallBack_SR_String1_GL = "" OR INSTR( CallBack_SR_String1_GL + ",", FORMAT$( TL2 ) + "," ) <> 0 THEN
                  '
                  MS = MS + UCASE$( TempListArray_GL( TL1, TL2 )) + $SPC
                  '
                END IF
                '
              NEXT TL2
              '
              FOR TL3 = 1 TO SearchWordsQTY
                '
                IF INSTR( MS, PARSE$( SM, $SPC, TL3 )) = 0 THEN
                  EXIT FOR
                END IF
                '
              NEXT TL3
              '
              IF TL3 = SearchWordsQTY + 1 THEN
                EXIT FOR
              END IF
              '
            NEXT TL1
            '
            IF TL1 <> TempListArray_Row_Qty_GL + 1 THEN
              ListPos_ST = TL1
            END IF
            '
          END IF
          '
          CONTROL SET TEXT CBHNDL, %SelectListEntrySearchTextBox, InpString
          '
          DIALOG POST CBHNDL, %WM_USER + 102, 1, 1
          '
        CASE %WM_USER + 102
          '
          CONTROL HANDLE CBHNDL, %SelectListEntryListBox TO TL1
          Listview_SetItemState( TL1, ListPos_ST - 1, %LVIS_SELECTED OR %LVIS_FOCUSED, %LVIS_SELECTED OR %LVIS_FOCUSED )
          CONTROL SET FOCUS CBHNDL, %SelectListEntryListBox
          '
        CASE %WM_COMMAND
          '
          IF CBCTLMSG = %BN_CLICKED THEN
            '
            SELECT CASE CBCTL
                '
              CASE %SelectListEntryOKButton
                '
                TL1 = VAL( Get_ListBox_Rows_Selected( CBHNDL, %SelectListEntryListBox ))
                CallBack_SR_String1_GL = FORMAT$( TL1 )
                DIALOG END CBHNDL
                '
              CASE %SelectListEntryCancelButton, %IDCANCEL
                '
                CallBack_SR_String1_GL = ""
                DIALOG END CBHNDL
                '
            END SELECT
            '
          END IF
          '
      END SELECT
      '
      EXIT FUNCTION
      '
    Get_List_Selection_Proc_Error_Handler :
      '
      MSGBOX "Get_List_Selection_Proc Error" + STR$( ERR ), %MB_ICONERROR OR %MB_TASKMODAL, "Epos"
      '
    END FUNCTION
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    FUNCTION Get_ListBox_Rows_Selected( BYVAL Winhandle AS DWORD, BYVAL ListBoxID AS LONG ) AS STRING
      '
      ON ERROR GOTO Get_ListBox_Rows_Selected_Error_Handler
      '
      LOCAL ListViewHandle AS DWORD
      DIM tLV_Item AS LOCAL LV_ITEM
      LOCAL ListViewRow AS LONG
      LOCAL hLV_Item AS DWORD
      LOCAL Selected AS STRING		' ",1,5,8,9" etc
      '
      ListViewHandle = GETDLGITEM( WinHandle, ListBoxID )
      '
      ListViewRow = SENDMESSAGE( ListViewHandle, %LVM_GETITEMCOUNT, 0, 0 )
      tLV_Item.isubitem = 0
      tLV_Item.mask = %LVIF_STATE
      tLV_Item.statemask = %LVIS_SELECTED
      hLV_Item = VARPTR( tLV_Item )
      '
      WHILE ListViewRow > 0
        DECR ListViewRow
        tLV_Item.iitem = ListViewRow
        IF SENDMESSAGE( ListViewHandle, %LVM_GETITEM, 0, BYVAL hLV_Item ) = 0 THEN
          ITERATE
        END IF
        IF tLV_Item.State = %LVIS_SELECTED THEN
          Selected = "," + FORMAT$( ListViewRow + 1 ) + Selected
        END IF
      WEND
      '
      FUNCTION = MID$( Selected, 2 )
      '
      EXIT FUNCTION
      '
    Get_ListBox_Rows_Selected_Error_Handler :
      '
      MSGBOX "Get_ListBox_Rows_Selected Error" + STR$( ERR ), %MB_ICONERROR OR %MB_TASKMODAL, "Epos"
      '
    END FUNCTION
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    FUNCTION Convert_Keyboard_Hook_Code( BYVAL CBLPARAM_PARSED AS DWORD, BYVAL CBWPARAM_PARSED AS DWORD, BYVAL Return_Alt_Shift_Etc AS LONG ) AS STRING
      '
      LOCAL TS1 AS STRING
      '
      ' check shift mode info by processing lParam
      '
      IF Return_Alt_Shift_Etc = %TRUE THEN
        '
        IF ( CBLPARAM_PARSED AND %MOD_ALT ) THEN
          TS1 = "Alt+"
        END IF
        '
        IF ( CBLPARAM_PARSED AND %MOD_CONTROL ) THEN
          TS1 = TS1 + "Ctrl+"
        END IF
        '
        IF ( CBLPARAM_PARSED AND %MOD_SHIFT ) THEN
          TS1 = TS1 + "Shift+"
        END IF
        '
      END IF
      '
      ' now check which key (virt. key code or ASCII code) has been pressed
      '
      SELECT CASE AS LONG CBWPARAM_PARSED
          '
        CASE 8
          '
          TS1 = TS1 + "BackSpace"
          '
        CASE 9
          '
          TS1 = TS1 + "Tab"
          '
        CASE %VK_PGUP
          '
          TS1 = TS1 + "PgUp"
          '
        CASE %VK_PGDN
          '
          TS1 = TS1 + "PgDn"
          '
        CASE %VK_END
          '
          TS1 = TS1 + "End"
          '
        CASE %VK_HOME
          '
          TS1 = TS1 + "Home"
          '
        CASE %VK_LEFT
          '
          TS1 = TS1 + "Left Arrow"
          '
        CASE %VK_UP
          '
          TS1 = TS1 + "Up Arrow"
          '
        CASE %VK_RIGHT
          '
          TS1 = TS1 + "Right Arrow"
          '
        CASE %VK_DOWN
          '
          TS1 = TS1 + "Down Arrow"
          '
        CASE %VK_INSERT
          '
          TS1 = TS1 + "Ins"
          '
        CASE %VK_DELETE
          '
          TS1 = TS1 + "Del"
          '
        CASE %VK_F1
          '
          SELECT CASE AS LONG CBLPARAM_PARSED
              '
            CASE 0, _		' no shift keys pressed
                %MOD_CONTROL, _		' Ctrl pressed
                %MOD_SHIFT, _		' Shift pressed
                %MOD_CONTROL + %MOD_SHIFT, _		' Ctrl + Shift pressed
                %MOD_ALT + %MOD_CONTROL + %MOD_SHIFT		' Alt + Ctrl + Shift pressed
              ' NOTE: F1, Ctrl/F1, Shift/F1, Ctrl/Shift/F1 and Alt/Ctrl/Shift/F1 fire the %WM_HELP message
              ' so let %WM_HELP do the job and exit here
              EXIT FUNCTION
              '
          END SELECT
          '
          TS1 = TS1 + "F1"
          '
        CASE %VK_F2 TO %VK_F11		' function keys F2 - F12
          '
          TS1 = TS1 + "F" + FORMAT$( CBWPARAM_PARSED - %VK_F1 + 1 )
          '
          ' numpad keys
          '
        CASE %VK_NUMPAD0 TO %VK_NUMPAD9
          '
          TS1 = TS1 + CHR$( CBWPARAM_PARSED - %VK_NUMPAD0 + 48 )
          '
          IF Return_Alt_Shift_Etc = %TRUE THEN
            TS1 = TS1 + " (numpad)"
          END IF
          '
        CASE %VK_MULTIPLY
          '
          IF Return_Alt_Shift_Etc = %TRUE THEN
            TS1 = TS1 + "Multiply (numpad)"
          ELSE
            TS1 = TS1 + "*"
          END IF
          '
        CASE %VK_ADD
          '
          IF Return_Alt_Shift_Etc = %TRUE THEN
            TS1 = TS1 + "Add (numpad)"
          ELSE
            TS1 = TS1 + "+"
          END IF
          '
        CASE %VK_SUBTRACT
          '
          IF Return_Alt_Shift_Etc = %TRUE THEN
            TS1 = TS1 + "Substract (numpad)"
          ELSE
            TS1 = TS1 + "-"
          END IF
          '
        CASE %VK_DECIMAL
          '
          IF Return_Alt_Shift_Etc = %TRUE THEN
            TS1 = TS1 + "Decimal (numpad)"
          ELSE
            TS1 = TS1 + "."
          END IF
          '
          ' end numpad keys
          ' printable chars
          '
        CASE 32, 48 TO 57, 65 TO 90		' Space, 0 - 9, A - Z (ASCII codes)
          '
          TS1 = TS1 + CHR$( CBWPARAM_PARSED )
          '
        CASE ELSE
          '
          EXIT FUNCTION
          '
      END SELECT
      '
      FUNCTION = TS1
      '
    END FUNCTION
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    SUB Add_Columns_To_List_View( BYVAL WinHandle AS DWORD, BYVAL ListViewID AS LONG, BYVAL ListBoxHeaders AS STRING )
      '
      ON ERROR GOTO Add_Columns_To_List_View_Error_Handler
      '
      LOCAL TS1 AS STRING
      LOCAL lCol AS LONG
      LOCAL hCtl AS DWORD
      LOCAL tLVC AS LV_COLUMN
      LOCAL szBuf AS ASCIIZ * 128
      LOCAL lStyle AS LONG
      '
      CONTROL HANDLE WinHandle, ListViewID TO hCtl
      '
      lStyle = ListView_GetExtendedListViewStyle( hCtl )
      ListView_SetExtendedListViewStyle( hCtl, lStyle OR %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES )
      ' Load column headers.
      tLVC.mask = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM
      tLVC.pszText = VARPTR( szBuf )
      '
      FOR lCol = 1 TO PARSECOUNT( ListBoxHeaders )
        '
        TS1 = PARSE$( ListBoxHeaders, lCol )
        IF RIGHT$( TS1, 1 ) = "*" THEN
          tLVC.fmt = %LVCFMT_RIGHT
        ELSE
          tLVC.fmt = %LVCFMT_LEFT
        END IF
        szBuf = RTRIM$( TS1, "*" )
        tLVC.iOrder = lCol
        ListView_InsertColumn( hCtl, lCol, tLVC )
        '
      NEXT lCol
      '
      ' Auto size columns to fit headers
      FOR lCol = 0 TO PARSECOUNT( ListBoxHeaders )
        '
        ListView_SetColumnWidth( hCtl, lCol, %LVSCW_AUTOSIZE_USEHEADER )
        '
      NEXT lCol
      '
      EXIT SUB
      '
    Add_Columns_To_List_View_Error_Handler :
      '
      MSGBOX "Add_Columns_To_List_View Error" + STR$( ERR ), %MB_ICONERROR OR %MB_TASKMODAL, "Epos"
      '
    END SUB
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    SUB Populate_List_View( BYVAL WinHandle AS DWORD, ListViewID AS LONG, ListViewDataArray( ) AS STRING, BYVAL ListViewArrayQty AS QUAD, BYVAL ListViewColQty AS LONG, BYVAL CursorLine AS LONG )
      '
      ON ERROR GOTO Populate_List_View_Error_Handler
      '
      ' If ListViewID is -ve then set focus to it on exit
      LOCAL lCol AS LONG
      LOCAL lRow AS LONG
      LOCAL hCtl AS DWORD
      '  LOCAL tLVC AS LV_COLUMN
      LOCAL tLVI AS LV_ITEM
      LOCAL szBuf AS ASCIIZ * 512
      ' LOCAL lStyle AS LONG
      DIM ColDataFlagArray( 0 TO ListViewColQty - 1 ) AS BYTE
      '
      CONTROL HANDLE WinHandle, ABS( ListViewID ) TO hCtl
      '
      IF ListViewID < 0 THEN
        CONTROL SET FOCUS WinHandle, ABS( ListViewID )
      END IF
      '
      CALL ListView_DeleteAllItems( hCtl )
      ' Load data
      FOR lRow = 0 TO ListViewArrayQty - 1
        tLVI.stateMask = %LVIS_FOCUSED
        tLVI.pszText = VARPTR( szBuf )
        tLVI.iItem = lRow
        FOR lCol = 0 TO ListViewColQty - 1
          IF ListViewDataArray( lRow + 1, lCol + 1 ) <> "" THEN
            ColDataFlagArray( lCol ) = 1
          END IF
          szBuf = ListViewDataArray( lRow + 1, lCol + 1 )
          tLVI.iSubItem = lCol
          tLVI.lParam = lRow
          IF lCol = 0 THEN
            tLVI.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
            ListView_InsertItem( hCtl, tLVI )
          ELSE
            tLVI.mask = %LVIF_TEXT
            ListView_SetItem( hCtl, tLVI )
          END IF
        NEXT lCol
      NEXT lRow
      '
      IF ListViewArrayQty <> 0 THEN
        ' Auto size columns (only if it contains data)
        FOR lCol = 0 TO ListViewColQty - 1
          IF ColDataFlagArray( lCol ) = 1 THEN
            ListView_SetColumnWidth( hCtl, lCol, %LVSCW_AUTOSIZE )
          END IF
        NEXT lCol
      END IF
      '
      ' if row select asked for then automatically select the cursor row required
      IF CursorLine > ListViewArrayQty THEN
        CursorLine = ListViewArrayQty
      END IF
      ' set focus row
      Listview_SetItemState( hCtl, CursorLine - 1, %LVIS_SELECTED OR %LVIS_FOCUSED, %LVIS_SELECTED OR %LVIS_FOCUSED )
      ' ensure row is visible
      Listview_EnsureVisible( hCtl, CursorLine - 1, %TRUE )
      '
      EXIT SUB
      '
    Populate_List_View_Error_Handler :
      '
      MSGBOX "Populate_List_View Error" + STR$( ERR ), %MB_ICONERROR OR %MB_TASKMODAL, "Epos"
      '
    END SUB
    
    
    
    '----------------------------------------------------------------------------(')
    
    
    
    FUNCTION KeyBoardProc( BYVAL iCode AS INTEGER, BYVAL wParam AS DWORD, BYVAL lParam AS LONG ) AS DWORD
      '
      LOCAL lShiftMode AS LONG
      '
      IF ISFALSE( lParam AND &H80000000 ) THEN		' bit 31 (2^31) NOT set: some key is pressed
        IF ISTRUE( lParam AND &H20000000 ) THEN
          lShiftMode = %MOD_ALT		' bit 29 (2^29) set: Alt-key is down
        END IF
        IF ( GETASYNCKEYSTATE( %VK_CONTROL ) AND &H8000 ) THEN _
          lShiftMode = lShiftMode + %MOD_CONTROL		' eventually add Ctrl
        IF ( GETASYNCKEYSTATE( %VK_SHIFT ) AND &H8000 ) _
          THEN lShiftMode = lShiftMode + %MOD_SHIFT		' eventually add Shift
        POSTMESSAGE Current_Keyboard_Hook_DlgHan_GL, %WM_USER + 101, wParam, lShiftMode		' wParam holds virtual keycode
      END IF
      '
      FUNCTION = CALLNEXTHOOKEX( ghKeyb, iCode, wParam, lParam )		' proceed
      '
    END FUNCTION

    Leave a comment:


  • Chris Boss
    replied
    There are two ways to approach this:

    You could trap keyboard messages destined for the listview control in the message loop and reroute them to another control or the dialog itself. You have to change the Msg structure so it has a different window handle for the message than the listview.

    Second, you could subclass the listview control and then process the WM_GETDLGCODE message and return the value:

    %DLGC_STATIC

    The Dialog will send this message to the control which has the focus, to determine whether it wants the keyboard input or not and what specific keys are needed. By returning DLGC_STATIC the listview should be able to tell the dialog it does not want any keys. I haven't tried this, but in theory it should work.

    Leave a comment:


  • Michael Mattias
    replied
    If the listview stays focused, it gets all keyboard input, which means you get notifucation messages.

    If you're not interested in them, ignore them or subclass the control to eat 'em. (No I will not show you how, because A) there are examples elsewhere and B) I'm almost ashamed of myself for suggesting something this silly).

    Why not let the user type into an edit control? That handles delete keys, it shows what has been typed, and if the user tries to set the focus to the listview control, you can just redirect focus to that edit control.

    Seems to me you are doing something not just the hard way, but the REALLY hard way.

    You can do everything you want to do without a kyeboard hook. If you want to pick up up and down arrow from the edit control you'll have to subclass it, but as I said there are examples of this here.

    Leave a comment:


  • Steve Bouffe
    replied
    The idea is that the listview stays focussed.

    The control that is displaying the "typed string" is just a static label. I test for backspace in the keyboard hook and delete characters etc.

    The keyhook also tests for up and down arrow and the moves the selected row in the listview to suit.

    As each character is typed the static label is updated and a quick search of the contents of the listview is performed and the best match is then automatically selected.

    Leave a comment:


  • Michael Mattias
    replied
    >How can I stop a listview from receiving commands from the keyboard when its in focus

    ???

    The whole idea of keyboard focus is to get those notification messages. If you don't want 'em, ignore 'em. Or, don't let the listview get the keyboard focus. (On WM_NOTIFY/NM_SETFOCUS, just set the focus elsewhere).

    I have the keyboard hook routine working....Only problem is that when I start to type the listview selected row changes depending on the last key pressed.
    I might suggest that perhaps your hook routine is not working as well as you might like it.

    Into what control are these keypresses being entered? You should not need a keyboard hook to update a static control and select a different row of the listview control based on user-entered keys; even the lowly edit control will send a notification message every time a character is changed and you can "do stuff" at that time.

    Leave a comment:


  • Steve Bouffe
    started a topic Listview Question

    Listview Question

    Hi All,

    How can I stop a listview from receiving commands from the keyboard when its in focus.

    I'm trying to generate a dialog with a listview and a static label box, using a keyboard hook routine I want to be able to intercept the keypresses + update the text in the static label box and then depending on whats in this box show the closest match in the list view.

    So far I've got the dialog created with all of the controls and I have the keyboard hook routine working. Only problem is that when I start to type the listview selected row changes depending on the last key pressed.
Working...
X
😀
🥰
🤢
😎
😡
👍
👎