于 2013-11-13 4:48, Geoff Smith 写道:
I am really hoping someone could help me with this
question please as I am totally stuck on it for now.
I am trying to implement a userdata via the C API, to give me
this type of functionality
btn1 = graphics.newButton(x,y,width,ht, "pressMe")
btn1:setText("Different Text")
btn1:setFont("Arial")
That's OK I think I have got that figured out and largely
working, but the next thing I want to do is call a user defined
Lua action function on the button instance. For example
In Lua
function btn1:action(someArbitrayParamBackFromC)
print("ouch someone just poked btn1")
end
How can I call that Lua button instance function from C when I
have detected the key is pressed ?
I have done something vaguely similar in the past when I have
created a custom timer on the Lua side, but the difference was I
had a timer create function in Lua such as
myNewTimer = createTimer( period, luaFunctionCallback)
So I was passed the callback function into the C code which
meant I could stash it away in the registry and then when the
timer elapsed on the C side, I did this
// push function indexed by registryRef from the registry back
onto the stack
// the lua callback function in this case
lua_rawgeti(local_L, LUA_REGISTRYINDEX, registryRef);
/* the first function argument is the timerID */
lua_pushinteger(local_L, myTimerID);
/* call the function with 1 argument, return 0 result */
pcallResult = lua_pcall(local_L,1,0,0); // pops 2 params from
stack
I am guessing the solution is somewhat similar but cant figure
it out.
Many thanks for any assistance
Geoff
You are right. The solution is similar.
In your Timer example, you retrieved the callback Lua function which
was passed to the C side
when the timer was created. While in your button press example, you
should retrieve the button
object first, then call the specified method on that object.
Thus said, I assumed you had used some method (e.g.
GetWindowLongPtr) to associate the
button object (from Lua) with the *native* button object of the
underlying GUI system.
Following is an imaginary example to illustrate this idea to bind
Lua to Win32 message system.
Just as an illustration, can't claim the correctness.
----------------------------------------------------------------------------------
[inside the window procedure of the button]
[...]
case WM_LBUTTONUP:
// first retrive the associated object of the Lua side.
// the following is just an demo method using GWLP_USERDATA to
store L
// and the registry to store the Lua object (this time a Lua
table).
lua_State * L = GetWindowLongPtr(hwnd, GWLP_USERDATA);
lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)hwnd);
// then call the "action" method on the button object
lua_getfield(L, -1, "action");
// do some check
if (!lua_isnil(L, -1)) {
// push the self parameter
lua_pushvalue(L, -2);
lua_pcall(L, 1, 1, 0);
// check the callback return value and do some processing
[...]
}
case WM_XXXX:
[...]
-------------------------------------------------------------------------------------
|