C# 将消息WM#u SETTEXT发送到文本框不';t触发器TextChanged事件

C# 将消息WM#u SETTEXT发送到文本框不';t触发器TextChanged事件,c#,winapi,C#,Winapi,我有一些代码,可以获取textbox控件的句柄,并使用windows API更改文本。 文本更新时不会触发TextChanged事件 是否有方法使用Windows API触发TextBox.TextChanged事件 [更新] 我认为事件不触发的原因是文本框句柄是通过DCOM接口发送的。 该程序是用c#编写的National Instruments TestStand shell,并使用NI TestStand COM对象作为核心功能。在TS序列文件(一种TS脚本语言)中,我为textbox句柄

我有一些代码,可以获取textbox控件的句柄,并使用windows API更改文本。 文本更新时不会触发TextChanged事件

是否有方法使用Windows API触发TextBox.TextChanged事件

[更新]
我认为事件不触发的原因是文本框句柄是通过DCOM接口发送的。 该程序是用c#编写的National Instruments TestStand shell,并使用NI TestStand COM对象作为核心功能。在TS序列文件(一种TS脚本语言)中,我为textbox句柄创建了一个对象引用,并在shell表单的load事件中使用TS api进行设置。之后,我将句柄发送到我的c#DLL。我使用SendMessage更新文本框,效果很好。问题是TextChanged事件不会触发


我尝试使用TS接口发送textbox和TextChanged委托,但无法使其工作。我认为通过TS COM对象执行此操作时存在AppDomain问题。

正如该程序所证明的,当控件发送
WM_SETTEXT
消息时,
TextChanged
事件确实会触发

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        const uint WM_SETTEXT = 0x000C;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, unit Msg, 
            IntPtr wParam, string lParam);

        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            MessageBox.Show(textBox1.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero,
              textBox1.Text + ", " + textBox1.Text);
        }
    }
}

请注意,此原始版本的答案过于复杂,使用了如下
SendMessage

static extern IntPtr SendMessage(IntPtr hWnd, unit Msg, 
  IntPtr wParam, IntPtr lParam);
因此必须进行人工编组:

IntPtr text = Marshal.StringToCoTaskMemUni(textBox1.Text + ", "
  + textBox1.Text);
SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero, text);
Marshal.FreeCoTaskMem(text);

这个问题()的评论说服了我更新。

正如这个程序所证明的,当控件发送
WM_SETTEXT
消息时,
TextChanged
事件确实会触发

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        const uint WM_SETTEXT = 0x000C;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, unit Msg, 
            IntPtr wParam, string lParam);

        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            MessageBox.Show(textBox1.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero,
              textBox1.Text + ", " + textBox1.Text);
        }
    }
}

请注意,此原始版本的答案过于复杂,使用了如下
SendMessage

static extern IntPtr SendMessage(IntPtr hWnd, unit Msg, 
  IntPtr wParam, IntPtr lParam);
因此必须进行人工编组:

IntPtr text = Marshal.StringToCoTaskMemUni(textBox1.Text + ", "
  + textBox1.Text);
SendMessage(textBox1.Handle, WM_SETTEXT, IntPtr.Zero, text);
Marshal.FreeCoTaskMem(text);

这个问题上的评论()说服了我更新。

我不确定你想更改什么文本,但我在文本框中使用了postmessage和按键(数字)的组合,它会触发TextChangedEvent


看看我们的方法2。它基本上是将鼠标设置为单击文本框,然后将所需文本的按键发送到文本框(一个字母接一个字母)

我不确定您要更改的文本是什么,但我在文本框中使用了postmessage和按键组合(用于数字),它会触发TextChangedEvent


看看我们的方法2。它基本上是将鼠标设置为单击文本框,然后将所需文本的按键发送到文本框(一个字母接一个字母)

我有一个问题,为什么不使用
Marshal.StringToHGlobalUni
?@AppDeveloper您也可以使用它。这两种方式都不重要。我倾向于使用pinvoke的COM堆,因为如果marshaller进行释放,那么它将使用COM堆。对不起,只是出于好奇,COM堆与普通非托管内存指针有何不同?@AppDeveloper它只是一个不同的堆。它还分配一个非托管指针。从概念上讲,它们是一样的。任何进程都可以从COM堆进行分配,然后同一进程中的任何其他代码都可以将该内存释放回公共共享堆。对于HGlobal堆也是如此。它可能有一个真实的名字!还有其他堆。您可以p/invoke
HeapAlloc
。还有
VirtualAlloc
。乱七八糟!如果目标应用程序(带有textBox1)是另一个应用程序,这个示例会发生什么变化?我有一个问题,为什么不使用
Marshal.StringToHGlobalUni
?@AppDeveloper您也可以使用它。这两种方式都不重要。我倾向于使用pinvoke的COM堆,因为如果marshaller进行释放,那么它将使用COM堆。对不起,只是出于好奇,COM堆与普通非托管内存指针有何不同?@AppDeveloper它只是一个不同的堆。它还分配一个非托管指针。从概念上讲,它们是一样的。任何进程都可以从COM堆进行分配,然后同一进程中的任何其他代码都可以将该内存释放回公共共享堆。对于HGlobal堆也是如此。它可能有一个真实的名字!还有其他堆。您可以p/invoke
HeapAlloc
。还有
VirtualAlloc
。乱七八糟!如果目标应用程序(带有textBox1)是另一个应用程序,该示例将如何更改?