How to call a structure-based control procedure
Nasser
I am wondering if it is possible to execute a procedure that is intended to be called by a button, when this procedure is written using
WMButtonAction
.I mean, the problem is that the parameter is a structure. Using the old style, it would be many parameters instead, for instance,
ctrlName
, eventCode
... Here, I think only one parameter is allowed, and when I try to call the ButtonProc_RedefineCoords_M procedure
like that :ButtonProc_RedefineCoords_M(Button_Coords_Acetic_M_Pos)
Igor tells me that a local variable name is expected...
To sum up, I'd like to execute this procedure, normally executed when the button is clicked, but without clicking it.
Would you have any idea ?
Thank you in advance
Function Display_BtnRedefineCoords(instance_locale)
STRUCT class_VFA &instance_locale
SVAR Polarity = root:Polarity
variable y
string str_Button_RedefineCoords
string strStruct4UserData
SetActiveSubWindow $"MAIN_CAPTIVOCS_Panel#CAPTIVOCS_Panel_"+Polarity
str_Button_RedefineCoords = "Button_Coords_" + instance_locale.str_Analyte
y = instance_locale.numero
StructPut /S instance_locale, strStruct4UserData //we save the structure instance in a string
Button $str_Button_RedefineCoords+"_M_" + Polarity, pos={600,460+20*y},size=17,18},proc=ButtonProc_RedefineCoords_M,title="M", userdata=strStruct4UserData
End
//- - - - - - - - - - Function to execute when the button is clicked - - - - - - - - - - -
Function ButtonProc_RedefineCoords_M(ba) : ButtonControl
STRUCT WMButtonAction &ba
STRUCT class_VFA myVFA
switch( ba.eventCode )
case 2: // mouse up
StructGet/S myVFA, ba.userdata // written out to control
RedefineCoords(myVFA,1) // click code here
break
endswitch
return 0
End
STRUCT class_VFA &instance_locale
SVAR Polarity = root:Polarity
variable y
string str_Button_RedefineCoords
string strStruct4UserData
SetActiveSubWindow $"MAIN_CAPTIVOCS_Panel#CAPTIVOCS_Panel_"+Polarity
str_Button_RedefineCoords = "Button_Coords_" + instance_locale.str_Analyte
y = instance_locale.numero
StructPut /S instance_locale, strStruct4UserData //we save the structure instance in a string
Button $str_Button_RedefineCoords+"_M_" + Polarity, pos={600,460+20*y},size=17,18},proc=ButtonProc_RedefineCoords_M,title="M", userdata=strStruct4UserData
End
//- - - - - - - - - - Function to execute when the button is clicked - - - - - - - - - - -
Function ButtonProc_RedefineCoords_M(ba) : ButtonControl
STRUCT WMButtonAction &ba
STRUCT class_VFA myVFA
switch( ba.eventCode )
case 2: // mouse up
StructGet/S myVFA, ba.userdata // written out to control
RedefineCoords(myVFA,1) // click code here
break
endswitch
return 0
End
STRUCT WVButtonAction ba
ba.eventCode = 2
ba.userData = // set the userData here as needed
ButtonProc_RedefineCoords_M(ba)
return 0
end
Function ButtonProc_RedefineCoords_M(ba) : ButtonControl
STRUCT WMButtonAction &ba
STRUCT class_VFA myVFA
switch( ba.eventCode )
case 2: // mouse up
StructGet/S myVFA, ba.userdata // written out to control
RedefineCoords(myVFA,1) // click code here
break
endswitch
return 0
End
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
September 15, 2011 at 08:45 am - Permalink
If the action procedure is part of someone else's package, and you want to use their functionality in your code, you may be better off copying the "engine" code from their action procedure and re-packaging it in your own function. Naturally, you will respect any copyright :)
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
September 15, 2011 at 09:01 am - Permalink
Thank you for your reply.
@Johnweeks : what you suggest makes sense, but I'm afraid that's tricky. Indeed, a button that calls the procedure of interest contains a
userdata
. Moreover, there are many button instancies, each containing a specificuserdata
(consisting of a structure passed as a string)If I want to do so, I'd have to write a function that has
STRUCT WMButtonAction &ba
as a parameter.@jjweimer : I'm going to try it in parallel to the above solution.
Thank you !
Best Regards
September 16, 2011 at 02:14 am - Permalink
:-D EDIT : After a good mug of coffee high in caffeine, I've realized that it was not necessary to retrieve the structures from their associated buttons. The confusion came from the fact a structure cannot be global, but using
StructPut
, it is possible to save it in a global string (that's actually what I did to store it in the button's userdata).Thus, those global strings are used as parameters to call the procedure of interest.
Hope it will be useful for anyone.
Thanks
(It's still not working.) EDIT: Actually, it's OK..
@jjweimer : I've slightly modified your code, to that :
STRUCT WMButtonAction &Button_Coords_Acetic_M_Pos
Button_Coords_Acetic_M_Pos.eventCode = 2
ButtonProc_RedefineCoords_M(Button_Coords_Acetic_M_Pos)
return 0
end
But... I got this message during compilation :
"ERROR : Local variable expected"
Indeed, in the manual it's written that :
"When a Structure is passed to a user function, it can only be passed by reference, so in the declaration within the function you must use &localStructName to define the function input parameter."
That's why I've added the '&'.
Otherwise, if I wrote this, as you firstly suggested :
STRUCT WMButtonAction Button_Coords_Acetic_M_Pos
Button_Coords_Acetic_M_Pos.eventCode = 2
//Button_Coords_Acetic_M_Pos.userdata = ... //shouldn't be necessary
ButtonProc_RedefineCoords_M(Button_Coords_Acetic_M_Pos)
return 0
end
it would be impossible to know to which button (=parameter of the procedure of interest) we refer.
Moreover, a button already contains the userdata, so it shouldn't be necessary to redefine it.
@johnweeks : I've split the button procedure :
Function RedefineCoords_M(ba)
STRUCT WMButtonAction &ba
STRUCT class_VFA myVFA
switch( ba.eventCode )
case 2:
StructGet/S myVFA, ba.userdata // written out to control
RedefineCoords(myVFA,1) // click code here
break
endswitch
return 0
End
//*************************(Part 2)*******************************
Function ButtonProc_RedefineCoords_M(ba) : ButtonControl
STRUCT WMButtonAction &ba
RedefineCoords_M(ba)
End
The problem is that the data that has to be updated is contained in the button's
userdata
.Indeed, a structure cannot be global. That's why I've stored it in a button made to update it.
So, if I directly execute
RedefineCoords_M(ba)
(for instance, a button can be named "Button_Coords_Acetic_M_Pos", so I executeRedefineCoords_M(Button_Coords_Acetic_M_Pos)
)Then I get this error : "Local variable expected"
To sum up
Is it correct to reference the button (defined as a structure) using its name ?
If it is possible to do so, how should I proceed ?
I hope my explanations are not too confusing...
Thank you
Best Regards
September 16, 2011 at 08:07 am - Permalink
Then you can get the userdata like this:
Naturally, these lines have references to your local string variables; you need a way to retrieve those later if you are to do anything with all this stuff.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
September 16, 2011 at 12:05 pm - Permalink
Thank you, I'll test this too.
Best Regards
September 17, 2011 at 01:31 am - Permalink