LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to manual/auto scroll a listbox ?

Solved!
Go to solution

Hello, hello,

so I have a list box where lines get added at the bottom continuously. I normally call

InsertListItem(pFil, FIL_LISTBOX, -1, Line, 0);

GetNumListItems (pFil, FIL_LISTBOX, &Size);
SetCtrlAttribute(pFil, FIL_LISTBOX, ATTR_CTRL_INDEX, Size-1);

so that the last line is visible at the bottom.

 

But if I add a vertical scroll bar, and I would like to stop the scrolling (while still adding new lines) if the user moves the scroll bar anywhere but the bottom position.

Catching the EVENT_VSCROLL event seems to give me the top index in eventData2 but I don't see how to use that info. First I have to wait for the user to release the mouse (or keyboard ?) This newTopIndex seems different that what I can read with GetCtrlAttribute(...ATTR_CTRL_INDEX...) Why is that ?

0 Kudos
Message 1 of 7
(4,903 Views)

Sounds like the scroll event is received before the control is updated (i.e. drawing events are processed) so if you check event top index and the control actual settings they don't match. Situations like these can normally be addressed by issuing a deferred callback that is in charge of checking control situation. The deferred callback is executed after all pending events have been processed.

 

Alternatively, I suppose you may operate directly in the scroll events knowing that the top index corresponding to the last line being shown is <number of rows in the list - number of visible rows - 1>: if this doesn't match with the scroll top index you should consider the listox has been rolled back some lines. This is to be checked, though: it's just an idea tha seems reasonable to me but I never tried this.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 7
(4,884 Views)

I do the bottom line addition and the auto-scroll in a separate function (timer) than the VSCROLL callback, so I don't really see what a deferred call would bring.

 

And checking that FirstLine+NbLines>=Size-3 or newTopIndex+NbLines>=Size-3 was also my first idea, but it doesn't seem to work reliably so far. Investigating...

0 Kudos
Message 3 of 7
(4,878 Views)
Solution
Accepted by topic author gdargaud

I made a quick and dirty example that uses the number-of-items technique to activate the auto scroll: it works correctly both when the listbox is operated via the keyboard and the mouse.

 

Two side notes: 1. I had to manually set the control index when operating with the mouse otherwise the auto scroll is not deactivated; 2. I noticed that the EVENT_VSCROLL is fired continuously when the mouse is hovering on the scroll bar even if no button is clicked and no scroll is made: this may introduce and overhead in the application so it may be necessary to limit the callback work, e.g. by saving the actual first visible item and operating only if different.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 4 of 7
(4,862 Views)

I'd written a very similar test program but couldn't get it to work. The only noticeable difference with your *working* code was the presence of

            SetCtrlAttribute (panel, control, ATTR_CTRL_INDEX, eventData2);

in the scrollbar callback.

I don't quite understand why this is necessary, but it works. Thanks !

0 Kudos
Message 5 of 7
(4,856 Views)

I have added that call while I noticed that for some reason the control always reverts to displaying the active element when adding a line. The situation can be observed when operating with the mouse.

Try commenting it out and run the program: whe the timer has added a few elements (e.g. 10 lines) move the active element up one line with the up-arrow key and then scroll with the mouse: at the following timer event a new line will be added and the listbox will show the page with line 9 highlighted. From this moment on new elements will be added and the listbox will continue to display line 9 since auto scroll has been disabled. Further mouse scrolls will repeat this sequence. Based on this I resolved to always made the first visible line the active element to keep the list steady at the point selected by the operator.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 7
(4,848 Views)

I was trying to do the same thing with textboxes, but besides replacing GetNumListItems with GetNumTextBoxLines, the problem is that the VSCROLL callback now returns a number of pixels in eventData2 instead of the new top index. Do I have to use the font height and do some calculations or is there a more intelligent method ?

0 Kudos
Message 7 of 7
(4,840 Views)