Assigning a component to a variable


ariesgo

Recommended Posts

Hi. I'm a newbie here and I'm still not too familiar with the forums so I apologise in advance if this has been asked before. Basically, I've been trying to pass a reference to a GUI component to a function, but I've been unable to find a way of doing this. What I'd like to do is something like the following:

function MySequence()
  //(...)

  private oButton = Component.MyButton

  private oButtonHighlighter = new(ButtonHighlighter)
  oButtonHighlighter.Initialise(oButton)

  // (...) 
endfunction

class ButtonHighlighter

  local moButton = NULL
  local miOriginalBackgroundColour = RGB(0, 0, 0)

  function Initialise(oButton)
	if(!IsEmpty(oButton))
	  moButton = oButton
	  miOriginalBackgroundColour = moButton.BackColor
	  moButton.BackColor = RGB(255, 0, 0)
	endif
  endfunction

  // (...)
endclass

In the above code, "IsEmpty(oButton)" evaluates to false and the code in the if block in the Initialise method doesn't get executed. The problem seems to be that Component.MyButton can't be treated like an object that can be freely assigned to variables or passed as a parameter to functions. In fact, I've found that, surprisingly, "IsEmpty(Component.MyButton)" evaluates to true whereas "IsEmpty(Component.MyButton.BackColor)" evaluates to false.

Is there any way I can do this sort of thing? The obvious workaround consists in hard-coding button references like "Component.MyButton" within the code of classes like the ButtonHighlighter example, but I'd rather be able to keep it more generic.

Link to comment
Share on other sites

The answer is no and yes. No, DAQFactory doesn't have pointers / references for most internal objects, so they can't be assigned to variables, or at least if you do, you just get NULL. User objects, of course, are passed around by reference, so can be assigned to variables. A few internal objects can be instantiated dynamically as referencable objects (namely comm related stuff).

And yes, there is an easy workaround: use execute() and evaluate() and strings. So, instead of trying to pass a reference / pointer to a screen component, pass a string containing the name of the screen component. Then your initialize function might change to:

function Initialize(string oButton)
   if (oButton != "")
	  miOriginalBackgroundColour = evaluate("component. " + oButton + ".BackColor")
	  execute("component." + oButton + ".BackColor = RGB(255,0,0)")
   endif
endfunction

There are of course some standard programming techniques you can use to simply this. Typically, you'll use evaluate() whenever you need to retrieve a variable from a screen component, and execute() whenever you need to set a variable or call a member function of the object.

Link to comment
Share on other sites

Thanks a lot. Great answer, as I expected. I had read about execute and evaluate in the user's guide but it didn't occur to me that I could use those functions for this.

Now in order to avoid littering my code with calls to these functions, I've encapsulated their use in a new class "MyComponent" that I then use to manage the components as references that I can assign to variables, as was my initial intention. This new utility class now looks as follows:

class MyComponent

  local string msComponentName = ""

  function Initialise(string sComponentName)
	  msComponentName = sComponentName
  endfunction

  function GetText()
	private string sText = ""
	if(msComponentName != "")
	  sText = evaluate("Component." + msComponentName + ".strText")
	endif
	return sText
  endfunction

  function SetText(string sText)
	if(msComponentName != "")
	  execute("Component." + msComponentName + ".strText = " + Chr(34) + sText + Chr(34))
	endif
  endfunction

  function GetBackgroundColour()
	private iColour = RGB(0, 0, 0)
	if(msComponentName != "")
	  iColour = evaluate("Component." + msComponentName + ".BackColor")
	endif
	return iColour
  endfunction

  function SetBackgroundColour(iColour)
	if(msComponentName != "")
	  execute("Component." + msComponentName + ".BackColor = " + iColour)
	endif
  endfunction

  // (...) Some more similar methods for other properties I need t access follow here 

endclass

Now while writing this code I came across the problem of escaping the double quote (") character in the SetText implementation. I initially tried to escape it as in C by prepending a backslash, but that didn't work, so I've ended up resorting to the expression "Chr(34)". My question is: is this the simplest way to escape the quote characters within a string? Or is there some other escape syntax for such characters that I've missed?

Link to comment
Share on other sites

There is no escape character for quotes, but its rarely needed anyway because single and double quotes can be used interchangeably (though they have to line up of course). So you can just do:

"Component." + msComponentName + ".strText = '" + sText + "'"

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.