Is it possible to get a control at the current mouse location if its in a window not known by the application? (not in Application.OpenForms)
I implemented a low level mouse hook which can get the mouse location anywhere on the screen, but I can't seem to access controls outside of my application. What I want to be able to do is get a button in an OpenFileDialog. I can get a Handle to the dialog, but I can't get the control from the dialog using Control.FromHandle() since this only works for controls that are in the Application.
It's possible with the Win32 API. You need GetDlgItem() to get a handle to button you are looking for. Use Spy++ to find the control ID. An example of the kind of code you need is available in my post in this thread. That example is for an in-process dialog, it would work out-of-process as well.
Beware that your code is liable to break on the next version of Windows.
If you are trying to get a .NET Control, this is not possible. The reason for this is that the Control IS the HWND. With "HWND" here I mean the actual Windows window item. It is not possible to e.g. automatically wrap a new control instance around an existing window, much less as it's possible to get the Control instance from the other .NET application, if it were one.
If you are trying to insert a .NET Control into an OpenFileDialog, this also will not be possible because the OpenFileDialog is not a .NET form.
If you really want the HWND from the mouse location, you can use pinvoke to get it using the WindowFromPoint function.
Related
I want to create an application that will run in the background and track the click actions of the mouse, and when the user clicks on an external WPF or Winforms app, the background app should be able to detect the clicked control and display its ID/name/text.
I'm not sure if this is possible, but since there are automation tools that can perform similar actions, I think it should be possible. For example, with some tools it is possible to get the "window" object using the external app's PID, and then the controls (for example a button) can be accessed by providing the ID of the control. However in my case it is the other way around. I need to get ID/name/text of the control the user has clicked.
I can obtain the mouse position using windows Hook
I can obtain the hwnd and Process ID of the window the user has clicked
So is it possible to obtain the information about the element clicked? Any help and advice is appreciated, thanks in advance.
I have whipped up a C# clipboard application that stores multiple 'clippings' for later use. I use low-level keyboard hooks to pop open my application's window(s) on command. When the window is closed (or a clipping is double-clicked), it is supposed to paste the selected clipping into the last active window (the window prior to my application's window). I use low-level WINAPI methods to determine the last active application, snag its handle, and then return focus to it before simulating a Ctrl+V keystroke to paste.
This typically works except in one very unique scenario: I am in a WPF application project, Quick Finding in a XAML file, the cursor automatically switches to the body text, not the Quick Find textbox, and pastes it there. It seems to have something to do with the loss of focus/activation, as it moves the cursor whenever I activate another window, regardless of my own application's running.
VB files, C# files, what have you, and XAML opened in WinForm projects do not steal the Quick Find focus when switching between the VS2013 application and my own; upon returning to the last active application, the text pastes into the Quick Find box.
Only the XAML in WPF application projects gives me this problem.
So far. I know it is a fringe case, but I expect to run into more. This program is meant to be used in a coding environment and it's pretty important that it be able to handle these kinds of scenarios.
I've tried getting the internal control handle using code from http://www.codeproject.com/Articles/34752/Control-in-Focus-in-Other-Processes, so that I can return the focus to it, but it seems that the handle for the body text and the handle for the Quick Find text box are the same.
A partial solution is found in: How do I prevent the original form from losing focus when I show another form? The popup window I use is navigated primarily through my low-level shortcuts, and therefore has no need of explicit activation.
Using the mouse on it or any of my other windows (as I expect my users will sometime), will cause it to gain activation and circumvent this fix. However, it's such a fringe case it doesn't seem to matter. Hopefully this helps anyone in a similar situation (if not necessarily specifically this one).
Well, the project has moved along rather nicely and we have a pretty darn good product, but a wrench has been thrown into the gear works.
We have a C# 2012 application that interacts with another application (written in VB 6 of all things) and we can do a good bit with it so far, but we have a problem.
We need to select a button on a toolbar at the top of this particular application's window, but the button is not available through an API search. We have the main window's handle and can see all of its children, but I think the Toolbar is a User type control that we can't access through the API Calls. This application is very poorly designed and we had to do a LOT of work just to discover TWO User ID text boxes on the logon screen.
Anyway, my question is this: How would I set up a call to the main window and click a certain X, Y coordinate of that window's viewable area? I am using SendMessage to send mouse clicks to press a button control already, but if I can't get access to that button control, the idea was to send mouse clicks to a specific coordinate of the window.
Any ideas folks? Thanks!
It looks like the solution will be to get the Window's rectangle and add the offset in order to use the mouse event API call.
Thank you to #Idle_Mind for the suggestion. It is at least working on our test environment. It will be next week before we can test the solution out in our client's environment.
I have a Silverlight control containing an image. I want the user to be able to drag the image out of the Silverlight application and drop it anywhere they would be able to drop an image. For example, to the Desktop or to a PowerPoint slide or Word document. Everything that I have read thus far says it cannot be done but I find that hard to believe. I'm very new to Silverlight and RIA development so any help would be much appreciated.
Below is the code sample in my WinForm Form but the drag never starts.
string[] aString = { imagePath };
DataObject data = new DataObject(DataFormats.FileDrop, aString);
data.SetData(DataFormats.StringFormat, imagePath);
DoDragDrop(data, DragDropEffects.Copy);
Well the trouble is that a drag operation in Silverlight doesn't have simple access to anything outside the browser (by design). Depending on the user's settings you even have to get explicit permission for clipboard operations and sandboxed temporary file storage. This really sounds like a task better suited to a WPF application (perhaps with web deployment?) or some other desktop application technology.
However, that being said here are some things you could try/consider:
Silverlight/Javascript/ActiveX combination hosted in Internet Explorer
Silverlight 5 "Out of Brower" & P/Invoke (I heard P/Invoke will be supported when Silverlight 5 comes out)
Silverlight connecting to a web service running on the same computer (crazy, but you didn't ask for "not crazy", you asked for possible)
I am not very familiar with drag and drop in the Win32 API so it would take a lot of research and experimentation before I could confirm that this was even possible (and I can already tell you it isn't practical).
Edit: Based on the extra information you provided about the question I suspect it is possible to do what you are attempting. First, are you using WPF or WinForms? I assume WPF but one of your comments says WinForms. I wasn't very familiar with WPF drag/drop operations, but having looked into it, I think your code is on the right path. I created a WPF application and initiated a drag during a KeyDown event. This meant that the mouse button was not necessarily pressed. If I initiated the DragDrop while the button was down it worked. If I initiated while the mouse button wasn't down, I had to push the mouse button down and the drag operation would start (this was unexpected since I assumed the mouse would have to already be down). If I pressed the mouse down outside the application, then gave the WPF app focus (ALT+Tab), then initiated the DragDrop while the mouse button was still down, it didn't work. I got a reference to the MouseDevice and checked the LeftButton property, and the state was showing as "Released" even though the button was still being held down. It seems the key here is the way drag/drop interacts with internal mouse state. You might have to find a way to set the mouse state (maybe with the UI Automation API?). At this point it should be painfully obvious that this whole thing is a hack (even though it is probably possible to get it to work somehow).
The solution we came up with was as follows. The RIA i.e. Silverlight sends a message to our Desktop application WinForms with the path of the image to drag along with the bounding rectangle in screen coordinates that we want to start the drag from. The Desktop code creates and places a Panel over the area that we want to drag from. This panel is where we use DoDragDrop to initiate the native drag when the user left clicks. Since this panel is placed outside and above the silverlight control, everything works perfect. Sandbox defeated.
I have been working on some Silverlight apps for the past few months and fully investigated your exact requirements only to find it was not possible. I believe you can drag from the file system, from Silverlight control to control, but not to the file system.
Does Silverlight 4 support drag and drop from app to desktop?
http://msdn.microsoft.com/en-us/library/dd772166%28v=vs.95%29.aspx
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.