-
Active Member
getting IUiElement Properties (String)?
IUiElement FilterInput = Hud.Render.GetUiElement("Root.NormalLayer.stash_dialog_mainPage.StashFilter.Filt erInput");
for example obtaining properties from stash filter,
typed hellfire into filter, dump returns
1493 7837529633344601573 300 161 485 202 -1 Root.NormalLayer.stash_dialog_mainPage.StashFilter.FilterInput 'hellfire'
-
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Post Thanks / Like - 1 Thanks
iThinkiWin (1 members gave Thanks to KillerJohn for this useful post)
-
Active Member
https://i.imgur.com/hCB4CmX.png
I want to retrieve the text from a UIElement, sort of like the onchatlinechanged
Code:
using Turbo.Plugins.Default;
using System;
using System.Drawing;
namespace Turbo.Plugins.iWin
{
public class iWin_StashFilter : BasePlugin, IInGameTopPainter
{
public IFont FilterFont { get; set; }
public iWin_StashFilter()
{
Enabled = true;
}
public override void Load(IController hud)
{
base.Load(hud);
FilterFont = Hud.Render.CreateFont("tahoma", 6, 255, 255, 255, 0, true, false, 192, 0, 0, 0, true);
}
public void PaintTopInGame(ClipState clipState)
{
if (Hud.Render.UiHidden) return;
if (clipState != ClipState.Inventory) return;
bool visible = Hud.Inventory.StashMainUiElement.Visible;
IUiElement filter = Hud.Render.GetUiElement("Root.NormalLayer.stash_dialog_mainPage.StashFilter.FilterInput");
if (visible){
//test if any information
var filtertext = filter.ReadText(System.Text.Encoding.Default, false);
//var filtertext = "test";
var layout = FilterFont.GetTextLayout(filtertext);
FilterFont.DrawText(layout, 340 + 0.5f - layout.Metrics.Width*1.5f, 190 + 0.5f + layout.Metrics.Height);
}
}
}
}
all this does is throw errors endlessly currently, dump shows 'hellfire'
2019.09.16 03:26:08.939 19.9.6.0 overlay paint error (System.NullReferenceException: Object reference not set to an instance of an object.
at Turbo.Plugins.iWin.iWin_StashFilter.PaintTopInGame(ClipState clipState)
at ***********.******** **.**********()
at ***********.********* **(IPlugin , String , Action )
at ***********.************* **(Object , EventArgs )
at ******.************** **())
2019.09.16 03:26:08.965 19.9.6.0 overlay paint notification (SharpDX.SharpDXException: HRESULT: [0x88990001], Module: [SharpDX.Direct2D1], ApiCode: [D2DERR_WRONG_STATE/WrongState], Message: The object was not in the correct state to process the method.
at SharpDX.Result.CheckError()
at ******.************** **())
-
Contributor
filter must be NULL.
Hud.Render.GetUiElement can return NULL if IUiElement is not present (not null).
Press Ctrl-Alt-D and checks logs/dump_ui_visible.txt whether it is there or not.
For me this worked:
var text = uiElement.ReadText(Encoding.ASCII, removeColors: true);
In your case it is even easier to verify "it works" as you can type to text that you can check from dump_ui_visible.txt where it is.
Last edited by JarJarD3; 09-16-2019 at 05:28 AM.
Reason: clarified
-
Post Thanks / Like - 1 Thanks
iThinkiWin (1 members gave Thanks to JarJarD3 for this useful post)
-
Contributor
I have to post my whole test code I used a while ago to make it clear how "it works for me".
I don't rember if Hud.Render.RegisterUiElement was required or not.
Code:
private bool firstTime = true;
private static string[] uiElementNames = new string[]
{
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_1",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_1.stackcount",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_2",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_2.stackcount",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_3",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_3.stackcount",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_4",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_skill_hotbar_4.stackcount",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_activeSkillLeft",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_activeSkillLeft.stackcount",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_activeSkillRight",
"Root.NormalLayer.game_dialog_backgroundScreenPC.game_activeSkillRight.stackcount",
};
private string checkForSomething()
{
if (firstTime)
{
firstTime = false;
var skill = 0;
for (var i = 0; i < uiElementNames.Length; i += 2) // Even elements are skill button IUiElement.
{
skill += 1;
var name = uiElementNames[i];
var uiElement = Hud.Render.GetUiElement(name);
if (uiElement != null)
{
Hud.Debug(string.Format("IUiElement {0} {1},{2}", name, uiElement.Rectangle.X, uiElement.Rectangle.Y));
var nameText = uiElementNames[i + 1];
Hud.Render.RegisterUiElement(nameText, uiElement, null);
Hud.Debug(string.Format("RegisterUiElement {0}", nameText));
}
if (skill == 4)
{
break;
}
skill += 1;
}
}
var builder = new StringBuilder("Stacks ");
for (var i = 1; i < uiElementNames.Length; i += 2) // Odd elements are skill button stack IUiElement.
{
var uiElement = Hud.Render.GetUiElement(uiElementNames[i]);
if (uiElement != null)
{
var text = uiElement.ReadText(Encoding.ASCII, removeColors: true);
if (text?.Length > 0)
{
builder.Append((i / 2) + 1).Append('=').Append(text).Append(' ');
}
}
}
var curLine = builder.ToString();
if (curLine != line2)
{
line1 = line2;
line2 = curLine;
}
return line1 + "\r\n" + line2;
}
... and there are easier ways to read stack counter than this.
-
Post Thanks / Like - 1 Thanks
iThinkiWin (1 members gave Thanks to JarJarD3 for this useful post)
-
Active Member
already was using dumps to get the roots, as my top post showed, problem i am having even though its clearly showing address rect attributes and the dump even displays the string
It always returns null :|
Left it out hoping for some chance that it could find it anyway but to no avail.
Last edited by iThinkiWin; 09-16-2019 at 09:27 AM.
-
Contributor
Originally Posted by
iThinkiWin
already was using dumps to get the roots, as my top post showed, problem i am having even though its clearly showing address rect attributes and the dump even displays the string
It always returns null :|
Left it out hoping for some chance that it could find it anyway but to no avail.
It works here:
Code:
private bool registered = false;
private string checkForSomething()
{
var builder = new StringBuilder("FilterInput: ");
IUiElement input = Hud.Render.GetUiElement("Root.NormalLayer.stash_dialog_mainPage.StashFilter.FilterInput");
if (input == null)
{
builder.Append("null");
if (!registered)
{
registered = true;
Hud.Render.RegisterUiElement("Root.NormalLayer.stash_dialog_mainPage.StashFilter.FilterInput", input, null);
}
}
else if (!input.Visible)
{
builder.Append("!visible");
}
else
{
builder.Append(" text='").Append(input.ReadText(Encoding.ASCII, removeColors: true)).Append("'");
}
return builder.ToString();
}
I'm calling checkForSomething() in ClipState.AfterClip but IMO it should not matter.
-
Post Thanks / Like - 1 Thanks
iThinkiWin (1 members gave Thanks to JarJarD3 for this useful post)
-
-
Contributor
Originally Posted by
iThinkiWin
thank you for your time
this worked i kept trying to do everything with if != null.
I's say that sometimes the non existing documentation can be a bit frustrating
I got the clue from IRenderController interface:
Code:
IUiElement GetUiElement(string path);
IUiElement RegisterUiElement(string path, ...);
Obviously reading all UI elements is waste of resources, so you have tell those elements you are interested in.
-
Active Member
Yeah i've noticed it on my search before, just wasn't sure how to use it
-
Originally Posted by
JarJarD3
I's say that sometimes the non existing documentation can be a bit frustrating
I got the clue from IRenderController interface:
Code:
IUiElement GetUiElement(string path);
IUiElement RegisterUiElement(string path, ...);
Obviously reading all UI elements is waste of resources, so you have tell those elements you are interested in.
If you call GetUiElement in a Paint method then it is a waste of resource because it is always created and read from memory when you call it.
Instead you can register the ui element in the load method and it will be automatically maintained (collected) for the game before every paint (or aftercollect) method so you just use it and it is always up to date.
BUT if you use a ui element only rarely, then registering it gives an unecessary overhead to the collector.
The choice is yours
Do not send me private messages unless it is absolutely necessary or the content is sensitive or when I ask you to do that...
-
Post Thanks / Like - 1 Thanks
iThinkiWin (1 members gave Thanks to KillerJohn for this useful post)