How to suppress output of SetVariableControl?

I am building a control panel that includes a SetVariable control. Changing the value of this control triggers a procedure that moves the current selection in a table to the row indicated by the variable's new value:

Function moveCurrRow(sva) : setVariableControl
	STRUCT WMSetVariableAction &sva

	NVar gCurrEventRow
	wave eventName
	variable tableRows = numpnts(eventName)

	if (gCurrEventRow >= tableRows)
		gCurrEventRow -= 1
	elseIf (gCurrEventRow < 0)
		gCurrEventRow = 0
	else
		modifyTable /W=eventTable selection=(gCurrEventRow, 0, gCurrEventRow, 0, gCurrEventRow, 0)
	endIf


End	//MoveCurrRow

Every time I click on the control to increment or decrement the variable's value, I get the output below on the history window. How can I suppress this output?

STRUCT WMSetVariableAction
 ctrlName[256]: currRowDisp
 win[401]: eventMarking
 winRect: STRUCT Rect
  top: 0
  left: 0
  bottom: 800
  right: 400
 ctrlRect: STRUCT Rect
  top: 140
  left: 20
  bottom: 154
  right: 110
 mouseLoc: STRUCT Point
  v: 145
  h: 108
 eventCode: 9
 eventMod: 1
 userdata: 
 blockReentry: 0
 isStr: 0
 dval: 14
 sval[2500]: 14
 vName[1298]: gCurrEventRow
 svWave: <null>
 rowIndex: 0
 rowLabel[256]: 
 colIndex: 0
 colLabel[256]: 
 layerIndex: 0
 layerLabel[256]: 
 chunkIndex: 0
 chunkLabel[256]: 
 mousePart: 1
  in fcn moveCurrRow: sva=  

 

This is not the normal behavior of the SetVariable control, so I suppose the problematic behavior happens somewhere else in your code. Can you post a MWE (minimal working example), which compiles and shows the problematic behavior? Also, I see a few other issues with your setVariableControl function. For example, the function executes on all kinds of events such as just moving the mouse. I would restrict that to the relevant events (such as changing the value). Also, it is probably not a good idea in general to use global variables.

"in fcn moveCurrRow: sva=  "

You must have a function called "moveCurrRow" that is triggered when that code executes. Do you have a window hook on the table in question?

I guess gCurrEventRow is the global attached to the SetVariable that holds the value. That used to be the only way to use a SetVariable control, before the internal storage of the value was introduced, so it's natural that folks still use a global. These days, it is preferred to use the internal value rather than a global. 

Your GUI control procedure moveCurrRow should only execute the modifyTable code on a specific event. As it is right now the code is always executed  even when moving the mouse over the control.

Thank you everyone for your explanations. I now understand how to use the setvariablecontrol, i.e. using a switch...case statement based on the eventCode property. The control now works exactly as I had intended it to:

Function moveCurrRow(sva) : setVariableControl
	STRUCT WMSetVariableAction &sva

	NVar gCurrEventRow
	wave eventName
	variable tableRows = numpnts(eventName)


	switch (sva.eventCode)
		case 1: 							// Mouse up

			if (gCurrEventRow >= tableRows)
				gCurrEventRow -= 1
				beep
			elseIf (gCurrEventRow < 0)
				gCurrEventRow = 0
				beep
			else
				modifyTable /W=eventTable selection=(gCurrEventRow, 0, gCurrEventRow, 0, gCurrEventRow, 0)
			endIf
		case 2:							// Enter key
		case 3: 							// Live update
			Variable dval = sva.dval
			String sval = sva.sval
			break
		case -1: 							// Control being killed
			break
	endswitch

	return 0


End	//MoveCurrRow

Regarding the suggested use of the internal value instead of a global, where can I find more information? Is it by any chance a new feature in Igor 9? I am still using Igor 8.

No problem. The feature of internal variables already exists for quite some years. Here is an excerpt of the manual:

value=varOrWaveName    Sets the numeric or string variable or wave element to be controlled. You can have the control store the value internally rather than in a global variable. In place of varName, use _STR:str or _NUM:num. For example: NewPanel;SetVariable sv1,value=_NUM:123

I would also suggest to impose the limits of your table onto the SetVariable control itself instead of checking the limits in the control function (or does the size of the table change? You can of course also update the limits in this case):

wave eventName
SetVariable myTableCtrl ,value=_NUM:0 ,limits={0,numpnts(eventName),1}

Then your control function could be vastly simplified:

Function moveCurrRow(STRUCT WMSetVariableAction &sva) : setVariableControl
	if (sva.eventCode == 1 || sva.eventCode == 2)	// mouse up or enter
		modifyTable/W=eventTable selection=(sva.dval, 0, sva.dval, 0, sva.dval, 0)
	endif
	return 0
End