In short: I have a VB6 form with ActiveX control that contains buttons, and I would like to create automatic tool that can click this buttons using C#.
I tried to use reflection for this issue, but I cannot access the form.
The general direction I was suggested was to use window API to access the form, but it seem very "expensive" solution.
Does anyone familiar with this subject?
Thank you
Can you use AutomationElement from .net?
To test this:
download UiSpy.zip link taken from this question
Get the form open, activate the hover mode. If you "see" the button it should be easy to use ] AutomationElement to actually send a click to it.
How about sending/hooking window messages (e.g. sending WM_MOUSEDOWN or WM_MOUSEMOVE)? Short/simplified example can be found here.
If your goal is to automate the UI for testing, I would suggest TestComplete from SmartBear Software which can directly access your VB6 forms, controls and properties. They're basically hooking into the process and accessing the "Forms" object and "Screen" object to get access to the loaded forms.
Related
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.
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
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.
I recently started using C# and WPF for one of my projects.
Is there a quick way of getting an input from the user? I have not been able to find one for WPF projects.
I don't want have to create another window, add OK and Cancel buttons, and add event handlers for everything. I can do it, but I wanted to know a simpler way of doing it.
AFAIK, that was possible in win forms. You can get user input with just one single line of code. Can I do it in WPF as well?
If you add the Microsoft.VisualBasic dll to your application, you can use the InputBox method to get a single value from the user.
Microsoft.VisualBasic.Interaction.InputBox("Prompt here",
"Title here",
"Default data",
-1,-1);
(Put -1,-1 in for the XPos,YPos to get it centred on the screen)
If your talking about basic yes/no input then there is a wpf MessageBox that works in pretty much the same way as the winforms one - see System.Windows.MessageBox
Is that what you are thinking of?
Also, all winforms classes can still be used in WPF apps, you just need to add a reference to the appropriate assembly.
My C# application includes an embedded web browser, which is made possible by the System.Windows.Forms.WebBrowser class. Users are able to navigate to websites using the app, however, when they encounter a page that includes a pop-up window, the pop-up window is opened by Internet Explorer.
Does anyone know how to suppress that behavior?
NOTE: I'm new to C#, so please take that into consideration when responding.
Are you looking to actively block popups or handle them in your application? If you're wanting to customize the blocking, then you'll have to implement the DWebBrowserEvents2 interface, specifically the NewWindow3 method. NewWindow3 method has specific functionality for blocking window popups (i.e. setting the Cancel parameter to true). These methods will also let you show your own window if you wish, though you'll have to provide your own Form to host yet another WebBrowser.
If you'd like to see some real C# source code providing advanced functionality with the WebBrowser control, I'd have to say that this article on CodeProject provided almost everything I know about the WebBrowser control. Be sure to download the source!
#Kramii is correct that you can also use the NewWindow2 event to prevent the popup. NewWindow3 provides additional parameters for if you're looking to inspect the URL or other data about the navigate to actually sometimes block and sometimes handle the popup yourself.
IIRC you can trap the NewWindow2 event on the WebBrowser control and set Cancel = true to prevent the pop-up.
This article may help:
http://www.codeproject.com/KB/cpp/ExtendedWebBrowser.aspx#GoalBlock