RESOURCE SCRIPT:
DEMO PROGRAM SOURCE CODE
------------------
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).]
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
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).]