I've been asked to create a little tool to help automate a basic 3rd party WinForms application.
So far I've managed to overcome many hurdles but this one is by far one of the most frustrating of them all (And spending 8 hours researching only to find out LVM_GETITEMTEXT was returning an LVITEM struct with 64-bit pointers was very frustrating) - I can't seem to find any way at all to get any kind of reference to a ToolStrupStatusLabel in the third party application's StatusStrip.
The only indication I have that the application has finished it's assigned task is when the StatusStrip is updated to show it has been finished. I can't reliably automate it's operation if I can't find out when it finishes one job and proceeds to another.
Is there any message I can SendMessage() to the application? Any function I can call? Anything that will help me locate the text on this label so I can gain some insight into the application's status?
The automation tool is programmed in C#/Winforms with pInvoke for various Windows functions. I've also created my own DLL in C++ to assist with obtaining data from the LVITEM struct, so C++ workarounds are possible too.
This isn't going to work. The ToolStripItem derived classes are special, they do not derive from Control. They don't have their own window handle, they use the window of their host to draw themselves. Where the host is a Control, like ToolStrip or StatusStrip in your case.
This makes them unusable from traditional UI automation tools that require a window handle. The only way to commandeer them is by injecting a DLL that uses reflection to get a ToolStripItem reference. This exists, the Managed Spy++ tool uses this technique. Source code is provided so you can put your own together, you'll want to leverage the ManagedSpyLib which does the heavy lifting.
Related
I need help. I made a WPF application. Its functionality is that it launches the application when it is launched. But if it is pinned to the taskbar, then a JumpList appears. From which you can also call other applications. I ran into this problem: I do not know how to make the program automatically pinned to the taskbar after the first launch. Please help someone. I read on microsoft's website, but it's not suitable for wpf. Please help with this.
Maybe there is some kind of library? Maybe there is a way with the registry?
Don't ask for support for pinning, here is why.
Microsoft goes in great length to prevent applications altering user preferences. Why? Because otherwise, every application would do it. Giving access to user preferences via API means developers start exploiting it. It means applications fighting for screen space. You install compnay A product and it unpins company B product.
If such API existed, that is malware.
And an API for only the calling executable is not viable, it would mean that somewhere deep in the operating system the function call to do it for any executable exists. And then somebody finds it and calls it directly. Besides, it has been a big trouble for Microsoft to decouple the shell as it is.
Instead, explorer handles it.
Further reading Why is there no programmatic access to the Start menu pin list?.
Some application do manage to pin.
Regardless of what, it is a bad practice.
It is not guaranteed to work, much less in the next Windows update.
One way is to mimic user input. It is hard to consider all cases (what if the taskbar is hidden, what if it is not in the usual place, what if explorer is not running, etc.), but you can imagine setting the pointer position and sending keys.
Another way would be to write directly to the list. You might have found out that the pinned items are at:
%AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar
And they are regular, good old, shortcuts. And you could add your own. And it would not work.
Thus, the answer is "Please don't do it".
For a more detailed explanation, you can try to refer here.
I am writing a glassing program, similar to Glass2k (see image below) as I often need to view my pdf tutorials while working on the program in question.
I have so far been able to write the program that glasses the windows I want (via a global keyboard shortcut).
I now need a way to replicate Glass2k's feature which makes glassed windows stay on top of all windows irrespective of which program I switch to (more like setting a WinForm's TopMost property to True. Is there any way of doing this in .NET?
I'm prepared to get down and dirty with DllImports and all so any suggestion is welcome as long as it is in VB.NET or C#.
Edit
This is just based on a whim but I could also do with code that allows me to minimize, maximise restore and close any window as is done in Process Explorer? (see image)
I found out that a lot of work had been done by Michael Schierl on wrapping PInvokes in managed code. This is his site: Managed Windows API.
It turns out that the library is quite extensive and covers a lot of the commonly used PInvokes, makikng it very useful in Upper-Intermediate application development.
Those two useful classes are both under the System.Windows.Forms reference....
I can't see much relation between those and winforms.. Does anybody know why they're there?
thanks.
They internally use Win32 platform APIs, on which WinForm was built.
Windows Forms was, when it was made, the ONLY (Microsoft) means of creating a graphical user interface on the desktop.
SendKeys and the Clipboard are both using the Windows API in order to manipulate GUI applications. When this was created, it was reasonable to assume that these would be used from within a GUI program, which (then) meant a Windows Forms application.
Neither of these would typically be used from a Console application, but if you were doing so, including the "windowing" assemblies (which, at the time, meant windows forms) was a reasonable thing to do, since you're working with the Windowing system.
I do agree, though, that now that WPF exists, it would be nicer to have these in a separate assembly. However, Microsoft is very good about maintaining backwards compatibility.
To this end, they left this in the Windows Forms namespaces, but also implemented System.Windows.Clipboard for WPF applications. (I believe they decided that SendKeys was not required in modern development, since it's kind of abused, and just left it out by design.)
Generally speaking, you would not use Clipboard or SendKeys with an ASP.Net application or a console application, so it makes total sense for them to be in System.Windows.Forms.
Where would you expect them to be? In System.ClipboardAndSendKeys?
SendKeys can be handy for highlighting of textboxes. SendKeys "{HOME}+{END}" is a typical technique carried over from Visual Basic once a textbox has focus.
The Clipboard class is useful because it allows you to get data stored on a machine's clipboard, especially useful if it's data that comes from another application running. The clipboard is expected behavior in almost all applications that have any copy/paste semantic.
I am trying to do my winform application dock and follow another application, like IE or word. My full plan is run the program underground and then this specific application is running, my winform will maximize and dock, will follow if moved, minimize if this application is minimized.
Can you guys show me some ideas about how to do it?
thanks
You will have to get the messages send to the other application and analyze them. Here are some resources on window system hooks on MSDN and in the MSDN Magazin. So you will have to use good old P/Invoke because there is no managed API.
Hooks can work; however, both the programs you mention (IE & Word) provide APIs that allow you to customize the user interface. I would first look there. BTW, Due to IE's restricted environment your going to have a lot of trouble getting the standard hook APIs to work.
When using Office Interop in C#, if you insert a chart object into a MS Word document, the Grap application loads up very briefly and then goes away. Is there a way to prevent this from happening? I have tried setting the Visible property of the application instance to false to no effect.
EDIT: The Visible property does take effect when used against Word when interopping, and it does not pop up. I would expect there is a similar way to do this for MS Graph.
This is common behaviour for a lot of component hosted in an executable binary. The host application will startup and then do the job. I don't know if there is a surefire way to prevent that since you have no control over the component nor over the process until the application is started and is responding.
A hack I tried in the past (for something totally unrelated) was starting a process and constantly detecting if its main windows was created. As soon as it was created, I was hiding it. You could do this with the main module of the faulty application and hope it will be fast enough to hide the window before the user notices. Then you instanciate your component; the component will usually recycle an existing process, hopefuly the one with the hidden main window.
I can't garentee you this will work in your situation, but it's worth a try it the issue is that important, or if you don't find a better way of course.