From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to move to next input box from one box by pressing an enter key only

Solved!
Go to solution

Hello,

I use 4 string Controls to input 4 serial number of 4 boards individually,but it must press Tab key to next input box.  I need to press an enter key to move to next input box only. I don't know how to do. Please see the attached file for my question specification

 

 

Thank.

0 Kudos
Message 1 of 7
(4,229 Views)
Solution
Accepted by topic author shunfu

I'd suggest making those input boxes "Hot" and in the callback function for the controls (on EVENT_COMMIT) you could use SetActiveCtrl() to move focus to the next control. The last one could send the focus on the button.

0 Kudos
Message 2 of 7
(4,212 Views)

Ian.W,

 

Thank you for your solution, and I have solved this problem by your support.

 

Thank. 

0 Kudos
Message 3 of 7
(4,202 Views)

Another option is to use a table control. The table automatically moves to edit the next cell when the user hits the enter key.

 

image.png

I've attached a UIR with an example table. Note that the ATTR_AUTO_EDIT is enabled and 

ATTR_ENABLE_COLUMN_SIZING is disabled.

 

Also, if you use the SetActiveCtrl() on the EVENT_COMMIT, you might get some unintended behavior. For instance,

- you only get a commit event if you make some change in the string control before hitting <enter>.

- you'll get a commit event if you make some change in the string control and then use the mouse to click on a different control. This case would probably be a weird user experience since the user might click on a previous control, but then your callback would make the next control be the active one.

- if the user does hit <tab> then you'll get a commit event, and that might interfere with your intended behavior.

Message 4 of 7
(4,185 Views)

Good point about those potentially unwanted behaviors, Jared. 

 

However in the past I have always found that input to a table has its own quirks that confuses some users. The ATTR_AUTO_EDIT attribute is helpful, but even then users might try to place the cursor within the text of a selected cell to make a correction. Unless they double-click first that second (slow) click won't work, and to them the cell seems uneditable. (In Excel the formula bar accepts that cursor-placing click, but in a CVI table we do not have the equivalent of the formula bar.)

 

That said, the table may still be a better choice, especially if one does not catch other events beyond EVENT_COMMIT and refine the textbox behavior accordingly.

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

Yeah, I agree that getting the table into edit mode could be a little quirky for the user. In this case, it would be nice if the table were always in edit mode. Having a table callback like this would help....

 

 

static void ActivateNextTabOrderCtrl(int panel, int control)
{
	int nextCtrl;
	GetCtrlAttribute(panel, control, ATTR_NEXT_CTRL, &nextCtrl);
	if (nextCtrl == 0)
		GetPanelAttribute(panel, ATTR_PANEL_FIRST_CTRL, &nextCtrl);
	SetActiveCtrl(panel, nextCtrl);
}

static void ActivateNextTabOrderCtrlIfNecessary(int panel, int control)
{
	Point activeCell;
	int numRows;
	GetActiveTableCell(panel, control, &activeCell);
	GetNumTableRows(panel, control, &numRows);
	if (activeCell.y == numRows)
	{
		ActivateNextTabOrderCtrl(panel, control);
	}
}

static void ActivatePrevTabOrderCtrl(int panel, int control)
{
	int numCtrls, currentCtrl, tabPosition, targetTabPosition;
	GetCtrlAttribute(panel, control, ATTR_CTRL_TAB_POSITION, &targetTabPosition);
	GetPanelAttribute(panel, ATTR_NUM_CTRLS, &numCtrls);
	if (targetTabPosition == 0)
		targetTabPosition = numCtrls-1;
	else
		targetTabPosition--;
	GetPanelAttribute(panel, ATTR_PANEL_FIRST_CTRL, &currentCtrl);
	for (int i=0; i<numCtrls; i++)
	{
		GetCtrlAttribute(panel, currentCtrl, ATTR_CTRL_TAB_POSITION, &tabPosition);
		if (tabPosition == targetTabPosition)
			break;
		GetCtrlAttribute(panel, currentCtrl, ATTR_NEXT_CTRL, &currentCtrl);
	}
	SetActiveCtrl(panel, currentCtrl);
}

static void ActivatePrevTabOrderCtrlIfNecessary(int panel, int control)
{
	Point activeCell;
	GetActiveTableCell(panel, control, &activeCell);
	if (activeCell.y == 1)
	{
		ActivatePrevTabOrderCtrl(panel, control);
	}
}

int CVICALLBACK TableCB (int panel, int control, int event,
						 void *callbackData, int eventData1, int eventData2)
{
	int runState;
	switch (event)
	{
		case EVENT_ACTIVE_CELL_CHANGE:
		case EVENT_GOT_FOCUS:
			GetCtrlAttribute(panel, control, ATTR_TABLE_RUN_STATE, &runState);
			if (runState != VAL_EDIT_STATE)
			{
				SetCtrlAttribute(panel, control, ATTR_TABLE_RUN_STATE, VAL_EDIT_STATE);
			}
			break;
		case EVENT_KEYPRESS:
			if (eventData1 == VAL_ENTER_VKEY || eventData1 == VAL_TAB_VKEY)
			{
				ActivateNextTabOrderCtrlIfNecessary(panel, control);
			}
			else if (eventData1 == (VAL_SHIFT_MODIFIER | VAL_TAB_VKEY))
			{
				ActivatePrevTabOrderCtrlIfNecessary(panel, control);
			}
			break;
	}
	return 0;
}

 

Message 6 of 7
(4,169 Views)

Thanks, Jared!  Next time I need table input I'm going to try this out.

 

Ian

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