0

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.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275

1 Answers1

2

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Unfortunately this doesn't appear to work as I'm utilising a .NET framework that this tool can't function under (.NET 4.5), so I'm not readily able to see it in practice. Is there no way in either C# or C++ to get a pointer to the Items property, then get a pointer to the container, then get a pointer to the object in the first index of the container? From what I understand it goes StatusStrip->Items->Container[0].Text - Is it possible to get anything from just the handle of the strip? – Adam Alexander Aug 12 '12 at 14:37
  • Yes, you'll need to target 3.5 or less. You're on your own if you really need to make it work on 4.5. And no, there is no way to get a stable pointer to a managed object out-of-process. That's fundamentally incompatible with the garbage collector. – Hans Passant Aug 12 '12 at 14:39
  • Is there no way in either C# or C++ to get a pointer to the Items property, then get a pointer to the container, then get a pointer to the object in the first index of the container? From what I understand it goes StatusStrip->Items->Container[0].Text - Is it possible to get anything from just the handle of the strip? – Adam Alexander Aug 12 '12 at 14:42
  • At that point, I think you'd be spelunking internal data structures that could change arbitrarily. ToolStripItem is special, as Hans said. You might be able to figure out a way, but it could be different on every version/bitness of .net. Does ToolStrip not support any of the standard ui automation libraries? That would surprise me a bit. A direct window handle isn't req'd to support ui automation. WPF, e.g. – Greg D Sep 12 '15 at 02:04