Cannot get insides of the element from other app - c#

I want to find specific button with text(find it by text) and press it.
I'm trying to get insides from 'group'('группа' on screanshot) element of a teleramm desctop app, i know there is defenetly list of buttons there, but i cant find anything with UIA and inspect.exe. I tried both raw automtaion dll and nuget UIAComWrapper.
SendMessage(to get text) and EnumChildWindows didn't help me as well, as SendMessage enum does not return other handles inside of app.
AutomationElementCollection automation_element_collection = group_element.FindAll(TreeScope.Children, Condition.TrueCondition); //empty collection
AutomationElement automation_element_collection = group_element.FindFirst(TreeScope.Children, Condition.TrueCondition); //returns null
TreeWalker raw_view_walker = TreeWalker.RawViewWalker;
AutomationElement automation_element = raw_view_walker.GetFirstChild(group_element); //returns null
What am i doing wrong and may there be any other projects to help me with this?
screanshot from inspector.exe

Telegram Desktop app just doesn't support accessibility features like UIA for ages, look at the Github ticket. Formally, it works, but on a really basic level - there is no option to retrieve the message history textual content, group and contact names, etc.
So, until any of those implemented, there is just no way to programmatically traverse the UI elements. But if you really need it, you could look at OCR.

Related

InlineShapes disappear when the layout of a chart in Word is changed. Where do they go?

I've been developing a Word-AddIn (Office 365 version 1706, Windows 10) which basically stores data in charts so they could be fed updated data from our servelets and ultimately the chart updates itself with all the data it needs.
This works perfectly fine EXCEPT when I alter the layout options for a chart from the default "In Line with Text" to "With Text Wrapping" to have multiple charts next to each other for example.
How this works, as long as you don't alter the layout options, is by accessing the Microsoft.Office.Interop.Word.Application COM object, which has a Selection object, which furthermore has InlineShapes, is like so:
var inlineShapes = Application.Selection.InlineShapes;
if(inlineShapes > 0)
{
for(var i = 1; i < inlineShapes.Count + 1; i++)
{
if (inlShape.HasChart == MsoTriState.msoTrue)
return new WordChart(inlShape);
}
}
For sake of simplicity I spared you the whole ordeal of dealing with COM objects.
Again, this works if you don't tamper with the layout options of the chart, but as soon as the layout has been altered to say "Behind Text" I can't find that chart in any InlineShape.
Has anyone experienced this before?
I've combed through the Application.Selection object and couldn't find anything.
However the InlineShape is still in the Application.InlineShapes object itself, but how would I know which one is to be selected?
I would really appreciate ANY input, because as of now I have no idea on what to do anymore.
Ok, I finally found those little charts!
This Stackoverflow post helped me:
How to check which shapes/objects are selected/active?
More details to what solved my problem:
Once I changed the the layout options (see original question) I wouldn't be able to find Charts as InlineShapes anymore.
Instead they would be listed under Selection.ShapeRange.get_Item(i) (I checked for Shapes/InlineShapes, so I didn't see items as what a chart could be).
Now you could either convert them to InlineShapes, which does exactly that, in Word as well, which you don't want, or convert that Shape to your VSTO.WordChart, which I did.

Calling NvAPI_GPU_SetEDID on Nvidia card

How do you call this method on Nvidia GPU:
NVAPI_INTERFACE NvAPI_GPU_SetEDID (
NvPhysicalGpuHandle hPhysicalGpu,
NvU32 displayOutputId,
NV_EDID * pEDID
)
Src: http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/group__gpu.html#ga6a41b31dd9743120213435d985f8fbcf
I need to execute the above command to remove all EDID set on all DisplayOutputs on our new Quadro Graphics Cards. Based on the API documentation, I tried searching for NvPhysicalGpuHandle and came across this project/library:
https://github.com/openhardwaremonitor/openhardwaremonitor/blob/master/Hardware/Nvidia/NVAPI.cs
This does not have the method I need NvAPI_GPU_SetEDID
I am not hardware programmer, I just need to be able to call this one command. any ideas? Can this be achieved using nvapi.dll/nvapi64.dll via pinvoke or something?
I personally didn't test this, but you can try the library and see if it can set EDID information without any problem, if it fails, please open an issue.
https://github.com/falahati/NvAPIWrapper
Here is how you should do it,
First, you need to find the right DisplayDevice or GPUOutput that you want to write EDID information to. There are multiple ways to do so.
Get a list of all PhysicalGPUs in the system using the NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs() static method, then select the PhysicalGPU you desire based on your logic. After finding the right PhysicalGPU, use the NvAPIWrapper.GPU.PhysicalGPU.GetDisplayDevices() method to get a list of all connected DisplayDevices to that GPU and store the right one in a variable.
Instead of searching for connected DisplayDevices, you can also go for the GPUOutputs. Just like before, you first need to find the right PhysicalGPU and then you can get a list of all GPUOutputs using the NvAPIWrapper.GPU.PhysicalGPU.ActiveOutputs property and store the right GPUOutput in a variable.
Another way to find the right DisplayDevice is to go for a list of all Displays. To do so, you need to use the NvAPIWrapper.Display.Display.GetDisplays() static method. This returns an array of Displays. Then using the NvAPIWrapper.Display.Display.DisplayDevice property, you can get the corresponding DisplayDevice of a Display.
After finding the right DisplayDevice or GPUOutput, you should use the NvAPIWrapper.GPU.PhysicalGPU.WriteEDIDData() method. This method allows you to write EDID data stored in a byte array to the DisplayDevice or the GPUOutput you selected before.
Note: Make sure to capture NVIDIAApiException and check for the NVIDIAApiException.Status property in case something went wrong.

How can I run built-in Revit commands from C#

I am wanting to know if there is a methodology to feed calculated values to a built-in Revit command from inside a C# program, and then possibly (based on results, such as whether this makes an element too short or too long for a known "maximum span" of a particular beam) continue with my C# program and change the beam size). I am told you can invoke the Revit built-in command after execution of your c# external command, but you cannot then return to the c# program
As another example, I want to select an element to trim/extend to, and have the code figure out which "Joist" beams to extend to this element. My program would do extended filtering (such as "Reference Level", or "Workset", or "Comments", or "Mark" parameters (etc.)) and then run the built in function, providing the element to extend to and then each of my beams.
I've tried internet searches, as well as the Revit SDK samples, and nothing obviously used this (but there are a lot of csproj's to look through).
Can anyone verify that you cannot go back and forth between the C# program and the Revit built-in command?
You can programmatically invoke a built in Revit command with the UIApplication.PostCommand() method. Refer to documentation and building coder for more information. It will not execute until after the API context is over, however.
I don't think you'll be able to feed arguments into the command however, short of some kind of Win32 hack. Perhaps you will need to recreate the functionality of the built in command within the Revit API.
Unfortunately, I don't think we can do (command "_line" pnt1 pnt2) type of thing here.
Perhaps start with the SDK sample "MoveLinear". It shows how to modify end points of linear elements (which includes beams).
The main part of the sample's code is
Autodesk.Revit.DB.Line line;
//get start point via "get_EndPoint(0)"
Autodesk.Revit.DB.XYZ newStart = new XYZ(
lineLoc.Curve.GetEndPoint(0).X + 100,
lineLoc.Curve.GetEndPoint(0).Y,
lineLoc.Curve.GetEndPoint(0).Z);
//get end point via "get_EndPoint(1)"
Autodesk.Revit.DB.XYZ newEnd = new XYZ(
lineLoc.Curve.GetEndPoint(1).X,
lineLoc.Curve.GetEndPoint(1).Y + 100,
lineLoc.Curve.GetEndPoint(1).Z);
//get a new line and use it to move current element
//with property "Autodesk.Revit.DB.LocationCurve.Curve"
line = Line.CreateBound(newStart, newEnd);
lineLoc.Curve = line;
Which moves the X of the first point and the Y of the second point 100 feet.
you can try:
RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.PlaceAComponent);
commandData.Application.PostCommand(commandId);

Get Application Icon Id - Monodroid

I need to get the int id of my application icon. Is there any way I can do this?
I'm aware that there's GetApplicationIcon in PackageManager, but this returns a drawable. How can I get the Id of the drawable?
Drawable drawable = ApplicationContext.PackageManager.GetApplicationIcon(applicationInfo);
I was thinking of looping through all the resources in Android, but I'm not sure how, and I think it would be expensive. Any efficient way I can get the icon id?
EDIT: I understand that I can just easily get the resource id from R.drawable.myicon, but I was hoping to get the Id with the use of PackageManager or ApplicationContext.Resources.
EDIT #2: I got it. See my answer below.
R.drawable.ic_launcher (or other name you gave it) should represent the id you need.
Okay, I got it.
Intent intent = context.PackageManager.GetLaunchIntentForPackage(context.PackageName);
ResolveInfo resolveInfo = context.PackageManager.ResolveActivity(intent, PackageInfoFlags.MatchDefaultOnly);
int appIcon = resolveInfo.IconResource;
Well, since it's your application, you can just look in your manifest. Your icon appears in the <application> tag, in the android:icon attribute. Just look at that file and see what it says.
You don't need to program that, just do it yourself one time.

sending keys to a Java application's textbox from C#

I am trying to make an automation application that basically send some keys to a textbox in a java application and, if possible, based on the text that is in the textbox. Also I would like to select a certain option for a combobox. Can someone direct me to the right path? some code, an example, anything...
thank you,
denis
hello i think you're looking something like this
"winApiHelper" is a class made by me that help me to implement Win Api's methods, take a look here http://msdn.microsoft.com/en-us/library/ms633539(v=vs.85).aspx
private void SendKeys()
//String sText , String sWindow
//alternate you can have a parameters
{
string stab = "{TAB}";
string skey = rtFilename.Text.Trim();
int iHandle = winApiHelper.FindWindow(null, cboWindows.Text.Trim());
winApiHelper.SetForegroundWindow(iHandle);
System.Windows.Forms.SendKeys.Send(skey.Trim() + stab.ToString().Trim());
}
First, java.awt.Robot allows you to emulate keyboard and mouse events. Unfortunately it works in absolute screen coordinates. Right now java does not have API that allows to access windows beyond current application.
But if you can find the absolute location of text box where you wish to write "hello, world" you can do it using Robot.
If you cannot get absolute coordinates you have to use other tools like JNI or JNA. Please see the following post for details: Windows: how to get a list of all visible windows?
Good luck1

Categories