C# 将消息WM#u SETTEXT发送到文本框不';t触发器TextChanged事件
我有一些代码,可以获取textbox控件的句柄,并使用windows API更改文本。 文本更新时不会触发TextChanged事件 是否有方法使用Windows API触发TextBox.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句柄
我认为事件不触发的原因是文本框句柄是通过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/invokeHeapAlloc
。还有VirtualAlloc
。乱七八糟!如果目标应用程序(带有textBox1)是另一个应用程序,这个示例会发生什么变化?我有一个问题,为什么不使用Marshal.StringToHGlobalUni
?@AppDeveloper您也可以使用它。这两种方式都不重要。我倾向于使用pinvoke的COM堆,因为如果marshaller进行释放,那么它将使用COM堆。对不起,只是出于好奇,COM堆与普通非托管内存指针有何不同?@AppDeveloper它只是一个不同的堆。它还分配一个非托管指针。从概念上讲,它们是一样的。任何进程都可以从COM堆进行分配,然后同一进程中的任何其他代码都可以将该内存释放回公共共享堆。对于HGlobal堆也是如此。它可能有一个真实的名字!还有其他堆。您可以p/invokeHeapAlloc
。还有VirtualAlloc
。乱七八糟!如果目标应用程序(带有textBox1)是另一个应用程序,该示例将如何更改?