Manipulating controls on forms outside of the current app

tempus

Member
Joined
Oct 8, 2013
Messages
11
Programming Experience
10+
It's been way too long since I've lurked around here but now I'm back and in need of some help.

From my app, I have a reference to a third party library that includes a little popup window. That popup window is very simple, a single combobox and two buttons. I'd like to change the appearance of that popup a bit to better blend with my application. I've already gotten the handle to the parent window and the handles to all the child controls however since this popup window is technically running in a separate process, I can't simply do something like the following because btn will always be null.

C#:
[COLOR=blue]var[/COLOR] foo = FindWindow([COLOR=#a31515]"Form Title"[/COLOR]);
[COLOR=blue]var[/COLOR] bar = GetAllChildrenWindowHandles(foo, 50);  [COLOR=green][FONT=Consolas]//bar does contain all the child control handles. I confirmed this with MS Spy++[/FONT][/COLOR]
[COLOR=#2b91af]Control[/COLOR] btn =  [COLOR=#2b91af]Control[/COLOR].FromHandle(([COLOR=#2B91AF]IntPtr[/COLOR])bar[2]);
btn.BackColor = [COLOR=#2b91af]Color[/COLOR].Red;

so... is there anyway to take that handle and set the button Text or the form BackColor or whatever? I'm guessing maybe a SendMessage call is in my future?
 
You start by saying that you have a reference to a third-party library and then you say that the form exists in a different process. Those two do not seem compatible. If you're referencing a library then everything is in the one process. You are referencing the System.Windows.Forms.dll library after all, and things like Buttons and TextBoxes don't exist in different processes. If you need to use API calls then that would suggest that it's an EXE, not a DLL.

Regardless, if you have the handle for a window, you can call the SendMessage API function to affect it in various ways. The message you send will depend on what you're trying to do. For instance, the WM_SETTEXT message enables you to set the text in a window, which might be used on a label or text box.
 
So, here it is. The .NET assembly is referencing a COM assembly. That assembly is then referencing another more robust COM assembly. From what I understand, the reason my code is returning a null object on this line

C#:
[COLOR=#2b91af]Control[/COLOR] btn =  [COLOR=#2b91af]Control[/COLOR].FromHandle(([COLOR=#2B91AF]IntPtr[/COLOR])bar[2]);

is because Control.FromHandle only works for the current process and that popup form just doesn't appear to be running in the same process.

The application is an legacy winforms astronomy tool that I'm going back into to add functionality. The references to support this functionality is via COM objects are part of the core ASCOM library. The ASCOM library is a very big, robust COM library designed to provide a common backbone for control of telescopes, cameras, focusers etc. Equipment manufacturers (or creative developer) create device specific drivers. Developers then make a reference to these drivers from their application which intern reference the main ASCOM libraries. The user therefore MUST have the core ASCOM platform installed and registered before they can use any application written that utilizes the platform. One thing that is often done is astronomical software that is used in the field is to provide a 'night' mode such that all UI elements are drawn in a dark friendly theme. Typically that means everything gets a black background and any text is changed to a shade of red. There are some controls that are more difficult to manage this than others but it can be done (combo/list boxes and scroll bars have been a real pain...).

In this case, that little popup is a form being created by the core ASCOM COM library to get user input as to what equipment they want to connect to. This selection is persisted in the registry. After device selection, that UI will allow the user to show a configuration form that is actually part of the driver DLL to set device specific settings. This will then add additional values to the previously saved configuration in the registry. That second form is actually 100% available to the developer of the driver. That 'chooser' form however is not. so changing its colors have been elusive. The ASCOM support forum suggested the easiest solution is to not allow the user access to that 'chooser' when in night mode. I could do that but at this point it feels like cheating. I figured I'd just get the handles and manipulate the form directly to change the colors. There are a total of 8 controls on that form. One combo, 3 buttons, two labels, a menu with one menu item and one picture box (I'd leave that alone).

To be honest, I'm starting to get to the point of just agreeing with the suggestion to block that functionality.
 
Control.FromHandle can only return a Control instance if the handle belongs to a Control, i.e. a .NET control. If that window is created by a COM library then it's not a .NET control, so Control.FromHandle will return null.
 
Back
Top Bottom