Announcement

Collapse
No announcement yet.

Listview with %LVS_EX_CHECKBOXES style

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

  • Michael Mattias
    replied
    When you do "unset" a check box because there are too many rows already checked, you might want to give the user a cue.

    A MSGBOX is pretty instrusive, but you can give an audio cue using..

    Code:
    MessageBeep   %MB_ICONHAND
    (The MB_ICONHAND sound is the "something bad happened" sound; versus the MB_OK sound which means, well, "Okay.")

    Leave a comment:


  • colin glenn
    replied
    You can refine it a bit further than that, if you maintain a static state variable indicating the number of items checked, and use the notification on checking / un-checking to increment / decrement this variable, you can be rid of the loop and do fancier things like clearing the checkbox just checked if it exceeds the limit, or clearing the first checkbox checked.

    Leave a comment:


  • Daniel Vanhee
    replied
    Originally posted by Michael Mattias View Post
    'That's because the selection state is changed by Windows AFTER the click notification

    Try processing WM_NOTIFY/LVN_ITEMCHANGING That will also handle changes made by pressing the the spacebar. (Assuming you are toggling the check status of the selected row when the user hits the spacebar). (Or double-clicking).

    MCM
    I'am using now the folowing code and it works fine

    CASE %WM_NOTIFY
    hdr = CbLParam
    SELECT CASE @hdr.code
    CASE %LVN_ITEMCHANGED
    A_GeChecked = 0
    CONTROL HANDLE ghDlg, %IDCDC_LISTVIEW1 TO hLstv
    LISTVIEW GET COUNT ghDlg, %IDC_LISTVIEW1 TO A_Items
    FOR x = 0 TO A_Items - 1
    Found = Listview_GetCheckState(hLstv, x)
    IF Found = -1 THEN incr A_GeChecked
    IF A_GeChecked > 4 THEN
    MsgBox "You can only check 4 items!",
    %MB_ICONEXCLAMATION OR %MB_OK, "Test"
    Listview_SetCheckState(hLstv, x, %FALSE)
    EXIT FOR
    END IF
    NEXT x
    END SELECT
    Walter, John & Walter, thanks for the support!

    Leave a comment:


  • John Montenigro
    replied
    Daniel,
    You don't show the flags being used when creating the listbox, but I'm going to take a guess that you don't have multiple selections enabled.

    If you did, the user could select multiple items (without the need for checkboxes), then click a button to process the selections. That would make the code you did show a little simpler.

    Here's a snippet from my own code. I've chopped out some non-relevant stuff, so this may need dependencies to be edited, but it's actually doing the kind of thing you said you want to do.

    To limit the number of lines selected, you'd have to trap the listview change message and keep count, but that's before this code would run.


    Code:
       ListBox Get Selcount hDlg, %LISTBOX To NumSelLines 
       MsgBox "NumSelLines: " & Str$(NumSelLines) ,,"Number of Selected Lines"   'just during code development 
    
       If NumSelLines = 0 Then
          MsgBox "Nothing selected!",,"What?!?"
       Else
          ListBox Get Select hDlg, %LISTBOX To j     'get the index of the first selected item
          For i = 1 To NumSelLines
             ListBox Get Text   hDlg, %LISTBOX, j To SourceFile
    
             '(for testing) show that we have the line:
             MsgBox "Index:" & Str$(j) & " - " & SourceFile,,"Item " & Str$(i)
    
             'Set the storage name from the SourceFile name
             StorageName = gStorageLocation & "\" & PathName$(Namex, SourceFile) 
    
             MsgBox SourceFile & $CrLf & StorageName ,,"SourceFile and StorageName"   'just during development
    
             'do the work...
             dRet = DoWork(SourceFile, StorageName)
    
             ListBox Get Select hDlg, %LISTBOX, j+1 To j     'get the index of the next selected item
          Next i
       End If
    Hope this helps!
    -John
    Last edited by John Montenigro; 5 Feb 2009, 07:03 AM. Reason: edited out superfluous code fragment

    Leave a comment:


  • Michael Mattias
    replied
    'That's because the selection state is changed by Windows AFTER the click notification

    Try processing WM_NOTIFY/LVN_ITEMCHANGING That will also handle changes made by pressing the the spacebar. (Assuming you are toggling the check status of the selected row when the user hits the spacebar). (Or double-clicking).

    MCM

    Leave a comment:


  • Daniel Vanhee
    replied
    Hello Michael,

    If you think the above is straightforward, give me a call next time you are looking for a job
    I'm 62 now and looking for a job isn't really an option!!

    In my application I want to show the sales values for a specific range of products. As there are around 20 different products I can't show them all on one graph. So I must limit the number of products the user can see.
    For the moment I'm using two Listviews. The first has all the products, the second only those the user wants to see in a graph. By clicking on a item in the first listview the user can put it in the second listview. In a listview I can limit the number of selected products.

    But I think it will be nicer to use a listview with checkboxes (?).
    I'm trying now the folowing code under the %WM_NOTIFY but it doesn't work

    CASE %WM_NOTIFY
    local hdr As NMHDR Ptr
    hdr = CbLParam
    SELECT CASE @hdr.code
    CASE %NM_CLICK
    CONTROL HANDLE ghDlg, %IDC_LISTVIEW1 TO hLstv
    LISTVIEW GET COUNT ghDlg, %IDC_LISTVIEW1 TO A_Items
    FOR x = 0 TO A_Items - 1
    Found = Listview_GetCheckState(hLstv, x)
    IF Found = -1 THEN INCR A_Checked
    IF A_Checked > 1 THEN
    Listview_SetCheckState(hLstv, x, %FALSE)
    EXIT FOR
    END IF
    NEXT x
    END SELECT

    Leave a comment:


  • Michael Mattias
    replied
    > want to limit the allowable to two or tree checkboxes

    Or, you could draw your own checkboxes, and only draw them on the rows where you want to allow them. Demo here: Listview with Multiple Checkbox Columns Demo 2-20-05

    MCM

    Leave a comment:


  • Michael Mattias
    replied
    >I think it must be done in the %WM_NOTIFY, but how

    Well, yes, you do have to do it under WM_NOTIFY. But..

    What you have to to is process the WM_NOTIFY/LVN_ITEMCHANGING notfication. If the uchange member of the NMHEADER structure indicates a State change, then if that change is an LVIS_STATEIMAGEMASK change, and the new state is to be checked, then you count how many rows are already checked; if this would put you over your limit, you prevent the change by returning TRUE.

    However, I'm not so sure using a listview control with checkboxes would be the optimal choice here. This is maybe why detecting this - while 'do-able' - is not very straightforward at all. (If you think the above is straightforward, give me a call next time you are looking for a job).

    And, users don't expect to "not" be able to either click or press spacebar to be able to check a row of a list control with checkboxes.

    Maybe you could explain your application a little more and someone will have another idea you can play with.

    MCM

    Leave a comment:


  • Daniel Vanhee
    replied
    Hallo Michael,
    I changed my code and now it is working.
    Thanks.

    CONTROL HANDLE ghDlg, %IDC_LISTVIEW1 TO hLstv
    LISTVIEW GET COUNT ghDlg, %IDC_LISTVIEW1 TO A_Items
    FOR x = 0 TO A_Items - 1
    Found = Listview_GetCheckState(hLstv, x)
    IF Found = -1 THEN
    ? "Row nr " & str$(x + 1) & " is checked"
    END IF
    NEXT x
    But I have an other question.
    I want to limit the allowable to two or tree checkboxes.
    I think it must be done in the %WM_NOTIFY, but how?

    Leave a comment:


  • Michael Mattias
    replied
    This code can not give me the selected row when the I'm using only the checkbox to select a item
    That's because the "checked status" is a completely different state from "selected status."

    With a listview it's perfectly acceptable for a row to be checked but not selected and vice-versa. FWIW, "focused" is ALSO a separate status.

    I don't see a "LISTVIEW GET CHECK" function, so if you are trying to found which row(s) are checked, you can use the ListView_GetCheckState MACRO/FUNCTION. You can find details of using this in your Windows' API documentation.

    MCM

    Leave a comment:


  • Daniel Vanhee
    replied
    I'm using the folowing code to test which row has been selected.
    As you can see I'm using 0 as value for col&.
    This code can not give me the selected row when the I'm using only the checkbox to select a item
    If I select the whole row, it works fine.

    LISTVIEW GET COUNT ghDlg, %IDC_LISTVIEW1 to A_Items
    FOR x = 1 TO A_Items
    LISTVIEW GET STATE ghDlg, %IDC_LISTVIEW1, x, 0 to Found
    IF Found = -1 THEN
    ? "Row nr " & str$(x) & " is selected"
    END IF
    NEXT x

    Leave a comment:


  • Walt Thompson
    replied
    Hi Daniel;

    You don't need to specify a column number for the checkboxes. Here is a functioning code snippet.

    Code:
        CONTROL ADD LISTVIEW, hDlg, %List1, "", 12, 246, 800, 500, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %LVS_REPORT _
            OR %LVS_SHOWSELALWAYS OR %LVS_NOCOLUMNHEADER OR %LVS_SINGLESEL OR %WS_EX_RIGHTSCROLLBAR, , 
        LISTVIEW SET STYLE hDlg, %List1, %LVS_EX_ONECLICKACTIVATE OR %LVS_EX_GRIDLINES OR %LVS_EX_CHECKBOXES 
        CONTROL SET COLOR hDlg, %List1, %BLUE, %WHITE
        LISTVIEW INSERT COLUMN hDlg, %List1, 1, "", 800, 0

    Leave a comment:


  • Michael Mattias
    replied
    >I would like to know witch row is selected, using LISTVIEW GET STATE.

    LISTVIEW GET State does not tell you which row is selected, it tells you if a particular row is or is not selected.

    LISTVIEW GET STATE hDlg, id&, row&, col& TO datav&

    A data item is tested to see if it is currently selected. The values of row&/col& specify the position of the data item (1=first, 2=second, etc.). If the item is selected, -1 (true) is assigned to the variable specified by datav&. Otherwise, 0 (false) is assigned to it.
    Don't ask me why you need to specify a column number in that statement, since column number has absolutely nothing to do with the selected state of a row of a standard listview control. But I'd try column zero (that's in API-speak, with PB the first column is probably column one)

    If you want to know which row(S) is (are) selected, you can send the LVM_GETNEXTITEM message to the control, asking for the first item which is selected. I use this function
    Code:
    FUNCTION ListView_GetSelection (BYVAL hWnd AS LONG) AS LONG
      FUNCTION = SendMessage(hWnd, %LVM_GETNEXTITEM, -1, %LVNI_SELECTED)
    END FUNCTION
    Checkboxes added with LVS_EX_CHECKBOXES are associated only with a row; they have no column. (standard listview)

    MCM

    Leave a comment:


  • Daniel Vanhee
    started a topic Listview with %LVS_EX_CHECKBOXES style

    Listview with %LVS_EX_CHECKBOXES style

    Hi guys,

    I would like to know witch row is selected, using LISTVIEW GET STATE. What is the value for col& when i'm using LVS_EX_CHECKBOXES as style?
Working...
X