4

I have two WinForms applications and I need to add text to TextBox in Application1 from Application2. I've successfully done this using named pipes and WCF. I can successfuly call a method in Application1 from Application2 but I'm getting either "Invoke or BeginInvoke cannot be called on a control until the window handle has been created.” error or the textbox is not updated at all.

Here's my basic code. GetMessage is called by Application2. This one doesn't update TextBox at all:

public void GetMessage(string msg)
{
    UpdateTextbox(msg);
}

private void UpdateTextbox(string msg)
{
    this.textBox1.Text += msg + Environment.NewLine;
}

This one throws Invoke error:

public void GetMessage(string msg)
{
    Action a = () => UpdateTextbox(msg);
    textBox1.BeginInvoke(a);
}

I tried to cheat my way by forcing creation of the handle with this, but it doesn't update TextBox either:

public void GetMessage(string msg)
{
    IntPtr handle = textBox1.Handle;
    Action a = () => UpdateTextbox(msg);
    textBox1.BeginInvoke(a);
}

What should I do?

dstr
  • 8,362
  • 12
  • 66
  • 106
  • 1
    Check the answer on [this question](http://stackoverflow.com/questions/808867), it might be helpful. – Torbjörn Kalin Apr 16 '12 at 10:34
  • If I understand you correctly, you have two distinct applications (exe), and you are trying to change something in application1 from application2. This can't be done without some interprocess comunication system. (WCF, NamedPipes as you have already done) – Steve Apr 16 '12 at 11:26
  • Torbjörn: I tried textBox1.SafeInvoke(a, false/true); but it doesn't update the textbox. No error and the textbox text remains same.. – dstr Apr 17 '12 at 11:13

1 Answers1

2

Solved the problem thanks to this answer.

The problem is that the TextBox of the Form1 was on another instance of the Form1. Observe this code from Application1.Form1 which starts the named pipe service:

private void Form1_Load(object sender, EventArgs e)
{
    ServiceHost host = new ServiceHost(typeof(Form1), new Uri[] { new Uri("net.pipe://localhost") });
    host.AddServiceEndpoint(typeof(ISmsService), new NetNamedPipeBinding(), "PipeReverse");
    host.Open();
}

If I am understanding it right, this starts an instance of Form1. Thus, when Application2 calls Application1.GetMessage, it calls ServiceHost-instance-Form1.GetMessage.

To access main instance of Form1 I changed my code to this:

public Form1()
{
    InitializeComponent();

    if (mainForm == null)
    {
        mainForm = this;
    }
}

private static Form1 mainForm;
public static Form1 MainForm
{
    get
    {
        return mainForm;
    }
}

private void UpdateTextbox(string msg)
{
    MainForm.textBox1.Text += msg + Environment.NewLine;
}

It works correctly now..

Community
  • 1
  • 1
dstr
  • 8,362
  • 12
  • 66
  • 106