Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Listview with Multiple Checkbox Columns Demo

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

  • Listview with Multiple Checkbox Columns Demo

    RESOURCE SCRIPT:
    Code:
    //FILE: LVCHECKBOX.RC
    // RESOURCE SCRIPT FOR LVCHECKBOX PRogram
    // Author: Michael Mattias Racine WI
    // Use/Redistribution: Placed in public domain by author
    // 2-19-05
    // 02.20.05   1.0.1  Fill the subitem rect with white brush before 
    //                   drawing the checkbox
    
    #include "resource.h"
    #define VERSION_MAJOR   0x0001
    #define VERSION_MINOR   0x0000
    #define VERSION_BUILD   0x0001
    #define VERSION_LITERAL "1.0.1\0"
    #define VERSION_DATE    "February 20 2005\0"
    
    VS_VERSION_INFO VERSIONINFO
    FILEVERSION      VERSION_MAJOR, VERSION_MINOR, 0, VERSION_BUILD
    PRODUCTVERSION   VERSION_MAJOR, VERSION_MINOR, 0, VERSION_BUILD
    FILEOS VOS_WINDOWS32
    FILETYPE VFT_APP
    //* VFT_DLL FOR DLLs
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "040904E4"
        BEGIN
          VALUE "CompanyName",      "Tal Systems Inc.\0"
          VALUE "FileDescription",  "LVCHECKBOX\0"
          VALUE "FileVersion",       VERSION_LITERAL
          VALUE "InternalName",     "lvcheckbox\0"
          VALUE "LegalCopyright",   "Placed in Public Domain by author 2-19-2005\0"
          VALUE "LegalTrademarks",  "None\0"
          VALUE "ProductName",      "None\0"
          VALUE "Comments",         "Demonstration Program\0"
          VALUE "Author",           "Michael C. Mattias Racine WI\0"
          VALUE "VersionDate",       VERSION_DATE
        END
      END
    END
    
    // MAIN DIALOG
    
    #define ID_LV                       101
    #define ID_SAVE                     104
    #define ID_LOAD                     106
    #define ID_EXIT                     102
    #define ID_TITLE                    107
    
    
    #define DLG_STYLE   WS_VISIBLE | WS_CAPTION | WS_SYSMENU|WS_MINIMIZEBOX
    #define DLG_EXSTYLE WS_EX_CLIENTEDGE
    #define LV_STYLE    WS_GROUP|WS_TABSTOP| LVS_REPORT |LVS_SINGLESEL|WS_VISIBLE |WS_BORDER|LVS_SHOWSELALWAYS |LVS_NOSORTHEADER
    
    MAIN DIALOGEX 24, 30, 343, 215
    STYLE DLG_STYLE
    EXSTYLE DLG_EXSTYLE
    CAPTION "Listview with Checkboxes Demo"
    FONT 10, "MS Sans Serif"
    BEGIN
        LTEXT           "Driver Identification and Endorsements", ID_TITLE, 6, 5, 127, 8
        PUSHBUTTON      "&Load", ID_LOAD, 223, 3, 40, 14
        PUSHBUTTON      "&Save", ID_SAVE, 266, 3, 40, 14
        CONTROL         "", ID_LV, "syslistview32", LV_STYLE, 2, 23, 339, 150
        PUSHBUTTON      "E&xit", ID_EXIT, 300, 180, 40, 14
        LTEXT           "Double click checkboxes to toggle endorsements", -1, 6, 180,180, 8
        CTEXT           "Demo Courtesy Michael Mattias Racine WI", -1, 102, 200, 140, 8
    END
    
    // END OF FILE
    DEMO PROGRAM SOURCE CODE
    Code:
    ' lvcheckbox.bas
    ' 2/19/05 Demo: Multiple checkbox columns in a listview control
    ' Author:  Michael Mattias Racine WI
    ' Copyright, redistribution: Placed in public domain by author 2-19-2005.
    ' Compiler: PB/Windows v 7.02
    ' Windows Header File dates:
    ' WIN32API.INC  May   9 2002
    ' COMMCTRL.INC  April 8 2002
    ' -------------------------------------------------------------------------------------------
    ' 02.19.05   1.0.0  Created
    ' 02.20.05   1.0.1  Fill the subitem rect with white brush before 
    '                   drawing the checkbox
    
    #COMPILE  EXE
    #DEBUG    ERROR ON
    #REGISTER NONE
    #DIM      ALL
    #TOOLS    OFF
    
    #RESOURCE "LVCHECKBOX.PBR"
    '=====[Windows API Header Files] ============================
    '  If you don't need all of the functionality supported by these APIs
    '  (and who does?), you can selectively turn off various modules by putting
    '  the following constants in your program BEFORE you #include "win32api.inc":
    '
    '  %NOGDI = 1     ' no GDI (Graphics Device Interface) functions
    '  %NOMMIDS = 1   ' no Multimedia ID definitions
    
    %NOMMIDS = 1      ' this program does not make any MMID or GDI calls
    #INCLUDE "WIN32API.INC"
    '==[End Windows API Header Files]============================
    
    ' ==[Common Controls Include]======
    ' THESE EQUATES MUST BE COMMENTED OUT - NOT SET TO ZERO - TO ACTIVATE THE PARTICULAR CONTROL
        %NOANIMATE       = 1  ' Animate control.
        %NOBUTTON        = 1  ' BUtton_xxx macros
        %NOCOMBO         = 1  ' combobox_xxx macros
        %NODATETIMEPICK  = 1
        %NODRAGLIST      = 1  ' APIs to make a listbox source and sink drag&drop actions.
        %NOEDIT          = 1  ' Edit_xxx macros
        %NOFLATSBAPIS    = 1
        %NOHEADER        = 1  ' Header bar control.
        %NOHOTKEY        = 1  ' HotKey control.
        %NOIMAGELIST     = 1  ' ImageList apis.
        %NOIPADDRESS     = 1
        %NOLIST          = 1  ' listbox_xxx macros
     '***   %NOLISTVIEW      = 1  ' ListView control.
        %NOMENUHELP      = 1  ' APIs to help manage menus, especially with a status bar.
        %NOMONTHCAL      = 1
        %NOMUI           = 1
        %NONATIVEFONTCTL = 1
        %NOPAGESCROLLER  = 1
        %NOPROGRESS      = 1  ' Progress gas gauge.
        %NOREBAR         = 1
        %NOSTATUSBAR     = 1  ' Status bar control.
        %NOTABCONTROL    = 1
        %NOTOOLBAR       = 1  ' Customizable bitmap-button toolbar control.
    '***    %NOTOOLTIPS      = 1
        %NOTRACKBAR      = 1  ' Customizable column-width tracking control.
        %NOTREEVIEW      = 1  ' TreeView control.
        %NOUPDOWN        = 1  ' Up and Down arrow "spin" increment/decrement control.
       #INCLUDE "COMMCTRL.INC"
    ' === END OF COMMON CONTROLS INCLUDE ==========
    
    
    ' main dialog stuff:
    $MAIN_DLG_NAME             = "MAIN"
    %ID_LV                      = 101&
    %ID_SAVE                    = 104&
    %ID_LOAD                    = 106&
    %ID_EXIT                    = 102&
    %ID_TITLE                   = 107&
    
    UNION LvUnion
       NMHDR  AS NMHDR
       NMLV   AS NMLISTVIEW
       NMIA   AS NMITEMACTIVATE
       LVDI   AS LV_DISPINFO
       LVCD   AS NMLVCUSTOMDRAW
       NMTTDI AS NMTTDISPINFO
    END UNION
    
    ' =================================================================
    ' Functions to initialize and add columns to the listview control
    ' =================================================================
    ' column Designations
    %COL_NAME       = 0   ' must have a non-null text!
    ' our text columns:
    %COL_HEIGHT     = 1
    %COL_WEIGHT     = 2
    %COL_HAIR       = 3
    %COL_EYES       = 4
    ' our checkbox columns
    %COL_CYCLE      = 5
    %COL_LTTRUCK    = 6
    %COL_BIGTRUCK   = 7
    %COL_BOAT       = 8
    
    %COL_TEXT_MIN    = %COL_NAME                ' which columns we let Windows draw for us
    %COL_TEXT_MAX   =  %COL_EYES
    
    %COL_CHECK_MIN   = %COL_CYCLE               ' columns we draw ourself
    %COL_CHECK_MAX   = %COL_BOAT
    
    %COL_MIN        = 0
    %COL_MAX        = %COL_BOAT
    
    ' --------------------------------------------------------------------
    ' Initialize the listview control,  called once, before adding any data
    ' hwnd = handle to listview control
    ' ----------------------------------------------------------------------
    FUNCTION InitListview  (BYVAL hWnd AS LONG) AS LONG
     ' set up the column headers
       LOCAL  lvc AS lvcolumn, szText AS ASCIIZ * 128
       LOCAL  LvExStyle AS DWORD
       LOCAL  I AS LONG
    
      ' set the extended style for the control
       lvExStyle =  %LVS_EX_LABELTIP OR %WS_EX_CLIENTEDGE OR %LVS_EX_GRIDLINES OR %LVS_EX_FULLROWSELECT
       I         = SendMessage (hWnd, %LVM_SETEXTENDEDLISTVIEWSTYLE, lvExStyle, lvExStyle)
       ' add the column headers
       lvc.mask       =  %LVCF_FMT OR %LVCF_TEXT OR %LVCF_WIDTH
       lvc.pszText    = VARPTR(szText)
       lvc.iSubItem   =  0
       lvc.iImage     =  0
       lvc.iOrder     =  0
       FOR I = 0 TO  %COL_MAX
           SELECT CASE AS LONG I
               CASE %COL_NAME
                  szText = "Name"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 150
               CASE %COL_HEIGHT
                  szText = "Height"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 60
               CASE %COL_WEIGHT
                  szText = "Weight"
                  lvc.fmt = %LVCFMT_RIGHT
                  lvc.cx  = 60
               CASE %COl_HAIR
                  szText = "Hair Color"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 84
               CASE %COL_EYES
                  szText = "Eye Color"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 84
               ' check box fields start here. Size '60' is result of trial and error
               CASE %COL_CYCLE
                  szText = "Cycle"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 60
                CASE %COL_LTTRUCK
                   szText = "Trk/Lt"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 60
                CASE %COL_BIGTRUCK
                  szText = "Trk/Hvy"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 60
                CASE %COL_BOAT
                   szText = "Boat"
                  lvc.fmt = %LVCFMT_LEFT
                  lvc.cx  = 60
    
          END SELECT
          SendMessage hWnd, %LVM_INSERTCOLUMN, I, BYVAL VARPTR(lvc)
       NEXT I
    END FUNCTION
    
    FUNCTION WINMAIN (BYVAL hInstance     AS LONG, _
                      BYVAL hPrevInstance AS LONG, _
                      lpCmdLine           AS ASCIIZ PTR, _
                      BYVAL iCmdShow      AS LONG) AS LONG
    
    
     LOCAL iccex AS Init_Common_ControlsEx
     LOCAL szDlgName AS ASCIIZ * 64, dwAddr AS DWORD, param AS LONG
    
     ' make sure common controls (listview) is initialized
            iccex.dwSize          = SIZEOF(iccex)
            iccex.dwICC           = %ICC_LISTVIEW_CLASSES
            InitCommonControlsEx    iccex
    ' call our dialog
            szDLGName = $MAIN_DLG_NAME
            dwAddr    = CODEPTR (MainDialogProc)
            param     = %NULL
    
            FUNCTION = DialogBoxParam (hinstance, szDlgName, GetDeskTopWindow(), dwAddr, param)
    
    END FUNCTION  ' winmain
    
    
    FUNCTION MainDialogProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _
                             BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
    
     LOCAL hCtrl AS LONG, szText AS ASCIIZ * %MAX_PATH, plvu AS LvUnion PTR
     LOCAL iSelRow AS LONG, iSelCol AS LONG
    
     LOCAL I AS LONG, J AS LONG
     LOCAL R AS RECT, CheckStatus AS LONG, SetCheckStatus AS LONG
    
       SELECT CASE AS LONG wMsg
           CASE %WM_INITDIALOG
               ' Initialize the listview control (columns and Styles)
               hCtrl         = GetDlgItem (Hwnd, %ID_LV)
               InitListview    hCtrl
               ' load the initial listview data from data statements
               CALL        LoadListviewWithDemoData (hCtrl)
               FUNCTION  = %TRUE       ' accept default keyboard focus
               EXIT        FUNCTION
    
           CASE %WM_COMMAND
    
              SELECT CASE AS LONG LOWRD(wParam)
                  CASE %ID_LOAD, %ID_SAVE
                      GetDlgItemText hWnd, LOWRD(wParam), szText, SIZEOF(szText)
                      szText    =  REMOVE$(szTExt, "&")
                      MSGBOX "'" & szText & "' does not do anything for this demo."  _
                             & $CRLF & "But it could.",_
                             %MB_APPLMODAL OR %MB_ICONINFORMATION, "Listview Demo"
    
                  CASE %ID_EXIT
                      EndDialog hwnd, 0
    
               END SELECT  'of control ID for WM-COMMAND messages
    
    
           '----------------------------------
           ' Messages from Listview Control  '
           ' --------------------------------------------------------------
           ' NM_CUSTOMDRAW: Draw a checkbox with current checked status
           ' NM_DBLCLK    : If double-clicked on a checkbox column (endorsements),
           '                 toggle the status of the check box
           ' --------------------------------------------------------------
           CASE %WM_NOTIFY
                     plvu   = lparam
                     SELECT CASE AS LONG @plvu.nmhdr.idfrom
    
                       CASE %ID_LV
    
                            SELECT CASE AS LONG @plVU.nmhdr.code
    
                               CASE  %NM_CUSTOMDRAW  ' returns LVCD (NMLVCUSTOMDRAW)
    
                                  SELECT CASE AS LONG @plvu.LVCD.nmcd.dwDrawStage
                                      ' return:
                                     CASE %CDDS_PREPAINT
                                         ' tell Windows we want separate notify for each item
                                          SetWindowLong hWnd, %DWL_MSGRESULT, %CDRF_NOTIFYITEMDRAW
                                          FUNCTION = 1
                                          EXIT FUNCTION
                                     ' so when windows notifies us about an item....
                                     CASE %CDDS_ITEMPREPAINT
                                     ' tell Windows we want to be notified for each SUBitem
                                          SetWindowLong  hWnd, %DWL_MSGRESULT, %CDRF_NOTIFYSUBITEMDRAW
                                          FUNCTION = 1
                                          EXIT FUNCTION
                                      ' and when we (finally!) get the notification for each subitem...
                                     CASE (%CDDS_ITEMPREPAINT OR %CDDS_SUBITEM)
    
                                         iSelRow = @plvu.LVCD.nmcd.dwItemSpec      ' which row to draw
                                         SELECT CASE AS LONG @plvu.LVCD.iSubITem   ' which column to draw
    
                                             CASE %COL_TEXT_MIN TO %COL_TEXT_MAX
                                                 ' just let the control text print.
                                                 SetWindowLong hWnd, %DWL_MSGRESULT, %CDRF_DODEFAULT
                                                 FUNCTION = 1
                                                 EXIT FUNCTION
    
                                             CASE %COL_CHECK_MIN TO %COL_CHECK_MAX
                                                ' get current check status based on subitemText
                                                 ListView_GetITemText _
                                                       @plvu.nmhdr.hWndfrom, iSelRow, _
                                                       @plvu.lvcd.iSubItem, szText, SIZEOF(szText)
                                                 CheckStatus = (szText = "Y")
                                                 ' set the status to be used when drawing
                                                 IF ISTRUE Checkstatus   THEN
                                                     SetCheckStatus   = %DFCS_CHECKED
                                                 ELSE
                                                     SetCheckStatus   = %NULL
                                                 END IF
                                                 ' get rectangle in which checkbox must be drawn...
                                                 ListView_getsubItemRect @plvu.nmhdr.hwndFrom, iSelRow, _
                                                     @plvu.lvcd.iSubitem, %LVIR_BOUNDS, BYVAL VARPTR(R)
                                                 ' v 1.0.1 Erase the background
                                                 ' erase the background by filling with white brush
                                                FillRect  @plvu.lvcd.nmcd.hdc, R, GetStockObject (%WHITE_BRUSH)
                                                 ' .. and do it...
                                                 DrawFrameControl @plvu.lvcd.nmcd.hdc, _
                                                                  BYVAL VARPTR(R),_
                                                                  %DFC_BUTTON, _
                                                                  (%DFCS_BUTTONCHECK OR SetCheckStatus)
                                                 ' ...and tell the control not to bother drawing because we handled..
                                                 SetWindowLong  hWnd, %DWL_MSGRESULT, %CDRF_SKIPDEFAULT
                                                 FUNCTION = 1
                                                 EXIT FUNCTION
    
                                         END SELECT   ' of subitem to be drawn
    
                                  END SELECT   ' of draw stage
    
                             ' ---------------------------------------------------------------
                             ' if double-click in a checkbox column, toggle the check status
                             ' ---------------------------------------------------------------
                               CASE %NM_DBLCLK                 ' plvu pointer is to NMITEMACTIVATE
    
                                    iSelRow  = @plvu.nmia.iItem
                                    IF iSelRow    >= 0 THEN   ' if something is selected
    
                                       iSelCol  = @plvu.nmia.iSubItem
                                       SELECT CASE AS LONG iSelCol
                                           CASE %COL_CHECK_MIN TO %COL_CHECK_MAX
                                               ListView_getITemText @plvu.nmhdr.hwndFrom, iSelRow, iSelCol, szText, SIZEOF(szText)
                                               IF szText = "Y" THEN
                                                    szText = "N"
                                                ELSE
                                                    szText  = "Y"
                                                END IF
                                                Listview_setItemText @plvu.nmhdr.hwndFrom, iselRow, iselCol, szText
                                       END SELECT
                                    END IF
                              END SELECT  ' of message in Nmhdr for ID_LV
    
                     END SELECT  ' of nmhdr.IdFrom in WM_NOTIFY
    
       END SELECT                  ' of message
    
    END FUNCTION
    
    
    FUNCTION LoadListViewWithDemoData (BYVAL hWnd AS LONG) AS LONG
      ' this function just reads data from data statements. It could just as easily
      ' load from a file or database
    
        LOCAL MaxRow AS LONG, I AS LONG, J AS LONG, K AS LONG
        LOCAL nData AS LONG
        LOCAL  lvi AS LvItem, szText AS ASCIIZ * 48
    
        nData  = DATACOUNT
        IF nDATA MOD 9 THEN
            MSGBOX  "Data Item count not an integral multiple of 9, faggedaboutit or fix!", %MB_APPLMODAL OR %MB_ICONHAND, "User Error!"
            EXIT FUNCTION
        ELSE
            maxRow  = (nData \ 9) - 1  ' because rows are zero based
        END IF
    
        nData  = 0   ' reset so we can re-use
    
        FOR I = 0 TO maxRow
            lvi.iItem = SendMessage(hWnd, %LVM_GETITEMCOUNT, 0,0)  ' returns row number "next"
            lvi.lparam                        = I   ''   STORE ROW NUMBER AS PARAM
            FOR J = 0 TO %COL_MAX     ' for each column
    
                lvi.iSubItem     = J
                INCR               nData            ' get next data item
                szText           = READ$(nData)
    
                lvi.pszText      = VARPTR(szText)
                IF J = 0 THEN              ' adding the row, subitem=0
                   lvi.mask = %LVIF_TEXT OR %LVIF_PARAM
                   K = SendMessage (hWnd, %LVM_INSERTITEM, 0, VARPTR(lvi))
                   IF K < 0 THEN
                        MSGBOX "LVM_INSERTITEM FAILURE when I=" & STR$(I)
                   END IF
                ELSE ' updating the row, subitems > 0, no lparam for this row
                  lvi.mask         = %LVIF_TEXT
                  K = SendMessage (hWnd, %LVM_SETITEM,0, VARPTR(lvi))
                END IF
            NEXT J  ' next column
         NEXT I       ' next row
    
         EXIT FUNCTION
    ' --------------------------------------------------------------
    ' DEMO DATA STATEMENTS
    ' FORMAT: Name, Height, Weight, Hair, Eyes (text);
    '        Cycle, Light Truck, Big Truck, Boat (Y or N)
    ' ---------------------------------------------------------------
    DATA  "Smith, John"       , 5-10, 145, BLD,BLUE, Y,N,N,N
    DATA  "Jones, Mary"       , 5-2 , 121, BRN,BRN ,  N,Y,Y,N
    DATA  "Kane, Horatio"     , 6-0 , 175, BLD,BLUE, Y,N,N,Y
    DATA  "O'Neal, Shaquille" , 7-1 , 325, SHAVED, BRN, Y,Y,N,N
    DATA  "Gordon, Flash"     , 6-1 , 210, BLD,BLUE, N,Y,N,N
    DATA  "Kent, Clark"       , 6-2 , 225, BLK, GRN, Y,Y,Y,Y
    DATA  "Lane, Lois"        , 5-5 , 134, BLK, BRN, N,N,N,Y
    DATA  "Olson, Jimmy"      , 5-8 , 155, RED,GRN, N,N,N,N
    DATA  "Wayne, Bruce"      , 6-1 , 195, BLD,BLUE, Y,N,N,Y
    DATA  "Parker, Peter"     , 5-10, 168, BLK,GRN, Y,N,N,N
    DATA  "Cartwright, Hoss"  , 6-2 , 307, BLD,BLUE, N,Y,N,N
    DATA  "Banner, Dr. David" , 5-11, 180, BRN,BRN, N,Y,N,Y
    
    END FUNCTION
    
    '  ** END OF FILE LVCHECKBOX.BAS ***
    ------------------
    Michael Mattias
    Tal Systems Inc.
    Racine WI USA
    mailto:[email protected][email protected]</A>
    www.talsystems.com

    [This message has been edited by Michael Mattias (edited February 20, 2005).]
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com
Working...
X