WoW:Hooking functions: Difference between revisions
Jump to navigation
Jump to search
→How to Hook a Function: Better example, imo.
No edit summary |
(→How to Hook a Function: Better example, imo.) |
||
| Line 14: | Line 14: | ||
Let's say we wanted to show the target's level instead of the skull for players and monsters much higher level than us. The function responsible for hiding the level is TargetFrame_CheckLevel(), so we need to hook that function to make it un-hide the level. | Let's say we wanted to show the target's level instead of the skull for players and monsters much higher level than us. The function responsible for hiding the level is TargetFrame_CheckLevel(), so we need to hook that function to make it un-hide the level. | ||
Let's assume our AddOn is named "MyAddOn", and that is has an OnLoad handler that gets called from its XML <OnLoad> event. In the Lua file we would have: | |||
local | local MyAddOn_Orig_TargetFrame_CheckLevel; | ||
function | |||
function MyAddOn_OnLoad() | |||
MyAddOn_Orig_TargetFrame_CheckLevel = TargetFrame_CheckLevel; -- Remember old function | |||
TargetFrame_CheckLevel = MyAddOn_TargetFrame_CheckLevel; -- Hook in ours | |||
end | end | ||
So what the above does is that it | So what the above does is that it remembers the reference to the original "TargetFrame_CheckLevel" in "MyAddOn_Orig_TargetFrame_CheckLevel". Then it puts our function in place of the old one, so that anyone calling TargetFrame_CheckLevel() is now actually invoking MyAddOn_TargetFrame_CheckLevel() instead. | ||
The next step is to create our | The next step is to create our MyAddOn_TargetFrame_CheckLevel(). Let's assume we want it to show target levels. | ||
function | function MyAddOn_TargetFrame_CheckLevel() | ||
local retval = MyAddOn_Orig_TargetFrame_CheckLevel(); -- Call original function! | |||
TargetLevelText:Show(); | |||
TargetHighLevelTexture:Hide(); | |||
return retval; | |||
end | end | ||
So in this function, we first invoke the old function to let it do what it needs to do. Next, un-hide the level and hide the skull. Pretty simple right? | So in this function, we first invoke the old function to let it do what it needs to do. Next, un-hide the level and hide the skull. Pretty simple right? | ||
== An Easier Way to Hook a Function? == | == An Easier Way to Hook a Function? == | ||
| Line 71: | Line 72: | ||
This can be tricky, and really depends on what you are writing. By default you should probably call the old function first, and then do whatever you need. However, in some instances, you will want to call the old function last, call it conditionally, or not even call it at all. | This can be tricky, and really depends on what you are writing. By default you should probably call the old function first, and then do whatever you need. However, in some instances, you will want to call the old function last, call it conditionally, or not even call it at all. | ||
* Note: Not calling the old function at all can have ''very'' interesting effects if another addon hooked it before you did. What you will be doing then, is not letting that addon see the function call. This is where hook libraries do help. | |||
== Functions that Take Arguments == | == Functions that Take Arguments == | ||
| Line 138: | Line 141: | ||
== Notes == | == Notes == | ||
* | * If you use a ''local'' variable to store the old function, its name matters less. But often in bigger addons, you may need to call it from several of your addon's files, and local variables won't work. Use a syntax that uniquely identifies your previous function reference, like: | ||
::<tt>Pre_''addon''_''functionname''</tt> or | |||
::<tt>''addon''_Orig_''functionname''</tt>. | |||
* An alternative is to store the old function as a member of a global variable, a la MyAddOn.FunctionToBeHooked = FunctionToBeHooked; FunctionToBeHooked = function() ... | * An alternative is to store the old function as a member of a global variable, a la MyAddOn.FunctionToBeHooked = FunctionToBeHooked; FunctionToBeHooked = function() ... | ||
* Warning! Blizzard has moved some pieces of the UI to be loaded on demand. The functions in those pieces cannot be hooked until they are loaded. | * Warning! Blizzard has moved some pieces of the UI to be loaded on demand. The functions in those pieces cannot be hooked until they are loaded. | ||
* Warning! Blizzard '''does''' add new arguments and return values to their functions. See [[HOWTO: Hook functions in a safer way]] for a solution! | |||
[[Category: HOWTOs|Hook a Function]] | [[Category: HOWTOs|Hook a Function]] | ||