Go to Page... |
Thread Tools | Display Modes |
05-26-06, 03:16 AM | #1 |
How to read text lines out of a ScrollingMessageFrame?
Hi,
is there any way to read the stored text lines our of a ScrollingMessageFrame? WoWWiki lists multiple methods of this frame, but none of them seems to be able to fetch text lines out of such a frame. I intend to write some kind of search tool for searching text in ChatFrame1 to ChatFrame7. I already asked this question in the official German UI forum, but the German UI forum has only limited value for programming questions I regularily read the US UI-Forum for some more adequate information, but unfortunately, I can't post there as owner of an European WoW account. So, does anywone here know a method to extract lines our of this frame or can give me a definite "It's not possible?". In the latter case, I think I'll hook AddMessage or use the CHAT_MSG_* events and buffer the chat data myself. Thanks, Selice |
|
05-26-06, 03:43 PM | #2 |
There is no way to extract lines that have already been added to a MessageFrame. The API simply doesn't support it. Your options are as you mentioned, either hook :AddMessage or monitor the chat events.
If you are looking to record only information that comes from events that are generated from the client, your best option is to monitor the relevent events. If you want to store the exact contents of a MessageFrame then you have to hook :AddMessage When hooking :AddMessage, you have two options: 1) If you only want to monitor select MessageFrames you can create an entry in the Lua table of each MessageFrame you want to monitor 2) If you want to cache the conents of all message frames, you probably want to hook :AddMessage at the metatable level. If you are unsure as to how to proceed with the hooking process, post here and I'll help you through it. |
|
05-28-06, 04:38 AM | #3 |
Hi jbcc,
Thanks for your answer. Since you state that reading lines out of the frame is impossible, the metatable-approach sounds interesting. I have no experience with metattables. According to http://www.lua.org/manual/5.0/manual.html#2.8 I sassume, that I have to hook or add the "__call" key of the metatable? As far as I know, normal hooking of AddMessage in a chatframe would be: Code:
OriginalMethod = ChatFrame1.Addmessage; ChatFrame1.AddMessage = NewMethod; function NewMethod(self, ...) DoSomethingToStoreData(); OriginalMethod(self, unpack(arg)); end So how would I hook AddMessage by using metatables? I already tested, that "getmetattable(ChatFrame1) == getmetatable(ChatFrame2)" is true, so it would indeed affect all chatframes at once. Thanks, Selice Last edited by Selice : 05-28-06 at 05:05 AM. |
|
05-30-06, 12:16 PM | #4 | |
First some background information:
Actually, the metatable key that we would be dealing with is the __index key. This metatable key allows you to provide additional values that, within certain conditions, appear to be in your table when really they keys for those values are nil in your table and the values are actually stored somewhere else. Below is the sample code for what Lua does when you attempt to index a value. As the manual notes, this code is only a reflection of actual behaviour which is coded directly into the Lua interpreter and much more efficient than as it appears here. Code:
function gettable_event (table, key) local h if type(table) == "table" then local v = rawget(table, key) if v ~= nil then return v end h = metatable(table).__index if h == nil then return nil end else h = metatable(table).__index if h == nil then error("..."); end end if type(h) == "function" then return h(table, key) -- call the handler else return h[key] -- or repeat operation on it end end Going back to Blizzard Lua and the interface. As I'm sure you know, all UI widget objects appear in the Lua environment in the form of a Lua table. Each of these tables appears to have a number of member functions the you can call, but if you loop through the values in a widget's table you will notice that the none widget's member functions are actally stored in the Lua table that represents it. The member funcions are retrieved through an __index metatable value that points to a function which returns the appropriate member function for the widget you are working with. Note the following: getmetatable(A) == getmetatable(B) for ALL widgets A, B also, getmetatable(A)["__index"] == getmetatable(B)["__index"] for ALL widgets A, B All widgets use the same handler function for retrieving their member functions, regardless of their type. As it turns out, this handler function is extremely slow (relatively speaking) and Iriel has done some research in the past on speeding up the retrieval process, but that is another topic altogeather. Now for the topic at hand: If you were interested in storing the contents of all ScrollingMessageFrame objects (regardless of their purpose) you could in fact hook the handler function in the widget metatable to provide your own version of the :AddMessage function. However, you MUST be very careful when using this method as you are hooking a function that is used EVERYWHERE throughout the UI and if you do it badly you could cause a massive amount of extra overhead because each and every call to a widget function would incurr the additional cost of your hooked function. If I am reading you right, your purpose is to store the history of each of the default ChatFrame objects in a format that is retrievable. If this is the case, and you don't have any real interest in any other MessageFrames that may exist in the UI, then I suggest that you hook the :AddMessage function by adding a "AddMessage" value to each of the default chat frames as you noted in your code above. </Essay>
|
||
06-10-06, 03:17 AM | #5 | |
Guild raids prevented me from following this topic for the last two weeks, but now I'm back.
I think because of this fact, I will hook AddMessage in ChatFrame1 to ChatFrame7 instead. I found another reason, not to use the metatable approach: Code:
function gettable_event (table, key) local h if type(table) == "table" then local v = rawget(table, key) if v ~= nil then return v end ... A local AddMessage exists, as soon as any addon hooks it. Addons usually use: Old_AddMessage = Frame.AddMessage; Frame.AddMessage = New_AddMessage_Of_Addon; Ther first Addon that does this, will "fetch" the function deliverd by the metatabe to Old_Message, because at this point in time, there is no local AddMessage function in this frame. Any subsequent AddOns, that hook AddMessage in this way, will fetch the AddMessage function of the previous AddOn in the hooking chain. But now the problem: As soon as any AddOn hooked AddMessage, changes to the __index function of the metatable are irrelevant, since the first hooking AddOn now has a static reference to the original AddMessage function. Is my conclusion correct, or am I missing something? Kind regards, Selice |
||
WoWInterface » Developer Discussions » Lua/XML Help » How to read text lines out of a ScrollingMessageFrame? |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|