LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to determine which line of a textbox that a user clicks on?

I'm putting results, one per line, to a textbox. Is it possible to click on one of those lines in order to act on one of the results? Maybe a textbox isn't the right way to approach this. Any suggestions on an approach?
0 Kudos
Message 1 of 4
(4,040 Views)
In effect, textbox is not the best control to use for this matter. I can suggest you at least two alternatives, each of the with advantages and defects.


First alternative: use a list box instead of a textbox. In a listbox you create rows associating a value to each of them: items can be addressed eithee via their index (the position inside the list of items) or via the value associated to them (as an example: a progressive numberation, a serial number if each row shows results of tests on individual DUTs, a significative value...) When the user clicks on a row, in the callback associated to the control you can retrieve both of these values and use them to manipulate your data.

Text in a list box can be arranged in columns with proper alignment, foreground and background colour, vertical bars to separate logically the fields... you can obtain all of these effects by properly formatting the string to write in the control (see the help for parameters in InsertListItem function for an explanation of how to obtain them).

The main disadvantage of the listbox is that field separation is virtual and items ina row are stored as a unique, long string: which means that if you want to access a single "field" you must either store separately its content in memory and operate on the memory value rather than on the listbox item or retrieve the string and scan it to obtain the desired value. In all cases, it is not possible to operate directly on the control: you'll have to write a little piece of code to edit your values and then update the listbox row.


Second alternative: a table. A table is already separated in cells (rows/columns) each of them can be addressed individually to set its attributes (type of content, colours, fonts, alignment and so on). I personally find the table a little less user friendly from the programmer side: it's long to set attributes for individual cells in a row and not so evident which cell the operator is clicking on when the callback fires.

On the other hand, each field is stored separately in the cell and you can manipulate cell values simply typing in the cell as you do in a spreadsheet.


As you see there are many alternatives: I suggest you run through the example on these two controls to understand qualities and defects of each of them.

Hope this helps
Roberto


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 2 of 4
(4,032 Views)
A List Box! Of course. I was confusing a List Box with a Ring and thinking I'd only see one entry at a time.

And, having implemented it, I can see that eventData1 contains the zero-based index that was committed. Perfect! This is exactly what I needed.

Thank you very much, Roberto!

Jon
0 Kudos
Message 3 of 4
(4,022 Views)
Without knowing the requirements for your application, I agree with Roberto: there can be advantages to using a listbox.
However, if you want the free format afforded by a textbox, there are some CVI functions available to operate on lines within a textbox. From any code window, press Shift-Ctrl-P and search TextBoxLine to see the functions.
To retrieve the line where the cursor is,
Call GetCtrlAttribute on the textbox to get ATTR_TEXT_SELECTION_START. If no text is selected, ATTR_TEXT_SELECTION_START returns the position of the cursor.
Call GetTextBoxLineIndexFromOffset to get the line number (index).
Call GetTextBoxLine to get the line of text.
If you want to retrieve the line of text as soon as the user clicks on it, there are a couple of tricks.
In the callback for the textbox, add a case for EVENT_LEFT_CLICK. However, the event gets fired before the cursor gets moved.
One way to handle this is to use a timer.
1. Enable the timer in the textbox callback on EVENT_LEFT_CLICK.
2. Set the timer interval relatively short, like 0.2 seconds.
3. In the timer callback, disable the timer, then call GetCtrlAttribute, GetTextBoxLineIndexFromOffset, and GetTextBoxLine as described above.
See the attached sample.
0 Kudos
Message 4 of 4
(4,010 Views)