I have some code that is used to hook into third party code. It goes pretty much like below (mind you CodeWeDontHave can't be posted because we dont have the source). I have an issue where sometimes my code will deadlock on the line commented below. Also, we get a object reference error now and then.
Is this the most effective way to hook into a 3rd party program where we have no source code? Typically, in Winforms we aren't supposed to set controls in this way e.g. Control.Text = "blah"; from another Form, rather via properties & events. In fact, I'm surprised this works at all. Is it safe?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace BrianTests
{//this code requires a Form with a textbox called textBox1
public partial class CodeWeDontHave : Form
{
[DllImport("user32.dll")]
public extern static bool SetForegroundWindow(IntPtr hWnd);
public CodeWeDontHave()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Text = "structured notes entry";
//create another form that will attach to this one.
Form formThatWeOwn = new Form();
Button button = new Button() { Text = "upload text" };
formThatWeOwn.Controls.Add(button);
formThatWeOwn.Load += (a, b) => GetFormWithNoCode();
button.Click += OtherFormButton_Click;
formThatWeOwn.Show(this);
}
void OtherFormButton_Click(object sender, EventArgs e)
{
Button button = sender as Button;
UploadRtfToNoCodeForm();
//Close(); closes the parent...
button.FindForm().Close();//hackjob
}
private static Form GetFormWithNoCode()
{
Form noCodeForm = null;
System.Threading.Thread.Sleep(50);
noCodeForm = Application.OpenForms
.Cast<Form>()
.Where(form => form.Text.ToLower().StartsWith("structured notes entry"))
.FirstOrDefault();
return noCodeForm;
}
private static void UploadRtfToNoCodeForm()
{
Form noCodeForm = GetFormWithNoCode();
var textBox = noCodeForm.Controls
.Cast<Control>()
.GetChildren(c => c.Controls.Cast<Control>())
.Where(c => c is TextBox && String.Compare(c.Name, "textBox1", true) == 0)
.LastOrDefault() as TextBox;
string rtf = "here be some uploaded text";
SetForegroundWindow(noCodeForm.Handle);//Does this handle need memory cleanup?
noCodeForm.Focus();
textBox.Focus();
textBox.ReadOnly = false;//sometimes this line deadlocks...I can't reproduce in this test code
textBox.Text = rtf;
textBox.Update();
textBox.Focus();
textBox.ReadOnly = true;
}
}
static class ExtensionStuff
{
public static IEnumerable<T> GetChildren<T>(this IEnumerable<T> startingParentSet, Func<T, IEnumerable<T>> childrenSelector, bool includeParent = true)
{
foreach (T item in startingParentSet)
{
foreach (T child in item.GetChildren(childrenSelector, includeParent))
yield return child;
}
}
public static IEnumerable<T> GetChildren<T>(this T parent, Func<T, IEnumerable<T>> childrenSelector, bool includeParent = true)
{
if (parent == null) yield break;
if (includeParent)
yield return parent;
IEnumerable<T> children = childrenSelector(parent);
if (children == null) yield break;
foreach (T child in children)
{
foreach (T grandChild in child.GetChildren(childrenSelector, includeParent))
yield return grandChild;
}
}
}
}