You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
>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)
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
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
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.
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?
>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.
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
'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).
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, 08:03 AM.
Reason: edited out superfluous code fragment
'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
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.
Furcadia, an interesting online MMORPG in which you can create and program your own content.
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment