I have a third party application I'm writing an add-in for and I need to be able to modify a specific dialog if possible. That dialog has many controls and groups that are .. it seems, owner drawn and thus don't expose window handles to tools like spy++ and others. I welcome any insight into how I might disable controls on the this dialog.
Since I am running in-process, I can use detours (https://www.microsoft.com/en-us/research/project/detours/) to intercept functions and use calls like enumwindows/enumchildwindows to find handles to controls that I can then use techniques like NativeWindow (C#) to override wndproc messages and do manipulation. I'm also familiar with setwindowshookex and hooking the message queues.
Just looking for some ideas and patterns for working with owner drawn controls. Thanks!
[Edit1] I am also familiar with the UI Automation (C#/C++) and IAccessible frameworks. Those will allow me some control (potentiall), like detecting mouse clicks and such, but I was hoping for something more elegant. For example: with a normal combobox, if I have a handle, I can use sendmessage() to send it CB_* messages to manipulate its contents. How do you do that with a combobox if you can't get the handle ... given that it is owner drawn (presumably) and part of another owner drawn parent.
thus don't expose window handles to tools like spy++ and others
Then they are not real controls as far as the OS is concerned, and so there is nothing you can do to access/manipulate them directly. The app would have to expose an API or UI Automation interface for them. Presumably the app will not provide more access than it really wants an add-on to have.
You should contact the app author for help fulfilling your goal.
Related
How does one go about reading another applications listview and sub-listviews? This program has a main listview with a few other mini listviews once an item is clicked on the main view.
I want to create an application that can read the all of the listviews, how do I go about doing that? What is the best way to achieve this?
There are a number of ways to do this.
The supported way is to use an automation API like UIAutomation which is very simple to program. If the other application is using the standard Windows list view control then it should be accessible through UIAutomation. If the other application is using non-windowed controls (e.g. WPF, Qt) then you are dependent on the application implementing support for UIAutomation.
The other commonly attempted approach is to send windows messages to the list view control. This first of all involves enumerating the child windows of the application's main window in order to find the list view window. You can then send the control messages to obtain its contents. This sounds easy, but is actually rather tricky. The reason is that the messages require you to supply pointers to structures that are meaningful in the other process address space. This involves calls to OpenProcess, VirtualAlloc, WriteProcessMemory, ReadProcessMemory etc. It's quite tricky to get it right.
In my view, you should choose the automation API.
I'm wondering if their is any way to see what's currently being dragged by the mouse. I don't mean over a winforms as i can handle events and get it that way but has anyone been able to invoke some of the win api to read the object or information about it?
I'm trying 'monitor' (probably not the best choice of words) the cursor and see whats being dragged and then potentially read that object.
C# / C++ idea's all welcome !
Thanks in advance
One way to do this by design is to inject code into all applications, by means of a hook.
Using Hooks (Windows): http://msdn.microsoft.com/en-us/library/windows/desktop/ms644960(v=vs.85).aspx
This will allow you to detect when dragging is occurring, and you can use the standard windows APIs that the application itself can use to find out what is being dragged.
SetWindowsHookEx: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
A second way is to use Windows UI automation. This will not give you exactly what the application sees, or give you access to the exact data being dragged or dropped, but it may give you enough information for whatever your purposes are.
UI Automation support for drag and drop: http://msdn.microsoft.com/en-us/library/windows/desktop/hh707386(v=vs.85).aspx
Try using UISpy or Inspect.exe to see UI Automation events.
https://stackoverflow.com/questions/1848721/where-do-i-get-ui-spy
I have to write an application that observes another application and extracts information from the window. What is the best way to access windows from other applications and get data from their controls?
You'll need to P/Invoke the FindWindow and FindWindowEx functions to retrieve a handle to the other application's parent window and child controls.
Then you will need to use something like GetWindowText to access the text for a particular control.
Visit pinvoke.net for the definitions you'll need to call these functions from C#.
Be warned that this is not a completely straightforward pursuit. You should stop to consider whether you really have a good reason for wanting to do this, and if your goal couldn't be achieved in a simpler way.
In the past I've used the (P/Invoke) method GetWindowText to grab the window title text of a running application, regardless of it being Win32, .NET or otherwise.
What I'm trying to figure out is if there is a way to access text on actual controls, inside a form. I realize that this would probably be difficult and I will likely be address the controls by some random hex value or something and that it could break if the software every changes at all (it's something I have no control over). But, I'm just trying to do this to add some data polling to my media center setup and would like to be able to pull some information from a media player for which there is no API.
So, is there any sort of API (I'd imagine I would have to P/Invoke into it) that allows you to do this? Code examples would be greatly appreciated.
I believe GetWindowText takes the window handle as parameter, many controls ( but not all of them ) also have the window handle and you should be able to use the same API to get the text out of them.
How to get the handles of child controls is then another story but Win32 has all you need for it.
Send the WM_GETTEXT message to the control once you know its handle.
To work out its handle first of all use Spy++ or some such tool to find the name of the top level window and its window class name. Send this to FindWindow to get the top level window handle. Finally call EnumChildWindows to walk the children. Spy++ can also tell you how to identify which child is of interest.
Of course you may be unlucky and find that the control of interest is implemented without its own window handle, but Spy++ will tell you that too.
Hey, I am trying to make a program that minimises any program to the system tray instead of normally minimising it. Is this possible? I have been looking around on google but cant find anything.
Icons in the system tray are called "Notification Icons".
To do this to your own application, If your using WinForms you can use the NotifyIcon class to display icons in the system tray. Then all you have to do it set the window to not be displayed in the task bar.
If you're using WPF there isn't a replacement, you still have to use the old WinForms NotifyIcon class, check out this MSDN sample for more information on this.
If you want to hide another app, what you need to do is use API calls to make the changes to the state of the applications window.
You can use FindWindow to get a handle to the window you want to hide, then you can use GetWindowLong to get the windows state. Then you need to remove the WS_EX_APPWINDOW flag from the state and use the SetWindowLong method to apply the new style, this will remove it from the task bar. You can then use the Get/SetWindowState methods to find out the state of the window and hide/minimise it.
You still just need to use the NotifyIcon class to display your own icon in the systray.
Good luck with all of that. It's not something I've tried personally, but I've used all these method calls in other ways. If you haven't done API stuff from C# before you might find you need to do a bit of googling to figure out your DllImports for the version API methods. Shouldn't be anything too hard though.
Crazyd22 has found a codeproject article that uses a slightly different set of API methods but achieves pretty much the same effect. (See comments below.)