SendMessage WM_SETTEXT到TextBox不会触发TextChanged事件

时间:2013-01-31 20:01:36

标签: c# winapi

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

有没有办法使用Windows API触发TextBox.TextChanged事件?

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

我尝试使用TS接口发送文本框和TextChanged委托,但我无法使其工作。我认为通过TS COM对象有一个AppDomain问题。

2 个答案:

答案 0 :(得分:4)

正如此程序所证明的那样,TextChanged事件会在控件发送WM_SETTEXT消息时触发。

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);

此问题的评论(Automatic casting for string DllImport arguments vs Marshal.StringToCoTaskMemUni)说服我更新。

答案 1 :(得分:0)

我不确定您尝试更改的文字是什么,但是我将PostMessages和按键(对于数字)组合使用到文本框中,它会触发TextChangedEvent。

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