2013-01-31 84 views
0

我有代碼獲取文本框控件的句柄,並使用Windows API來更改文本。 更新文本時,TextChanged事件不會觸發。SendMessage WM_SETTEXT到文本框不觸發TextChanged事件

有沒有辦法使用Windows API觸發TextBox.TextChanged事件?

[更新]
我認爲事件不火,因爲文本框手柄雖然DCOM接口發送的原因。該程序是用C#編寫的NI TestStand外殼,並使用NI TestStand COM對象來實現核心功能。在TS序列文件(一種TS腳本語言)中,我爲文本框句柄創建了一個對象引用,並在shell表單的加載事件中使用TS api進行設置。之後,我將句柄發送到我的c#DLL。我使用SendMessage來更新文本框,這很好。問題是TextChanged事件不會觸發。

我嘗試使用TS接口發送文本框和TextChanged委託,我無法讓它工作。我認爲有一個AppDomain問題通過TS COM對象來完成。

回答

3

如本程序所證明的,當控件發送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); 

對這個問題的評論(Automatic casting for string DllImport arguments vs Marshal.StringToCoTaskMemUni)說服我更新。

+0

我有一個問題,爲什麼不使用'Marshal.StringToHGlobalUni'? –

+0

@AppDeveloper你也可以使用它。兩種方式都無關緊要。我傾向於使用pinvoke來進行COM堆棧,因爲如果編組人員會解除分配,那麼它會使用COM堆棧。 –

+0

對不起,但只是爲了好奇,COM堆是如何區別於正常的非託管內存指針的? –

0

我不確定你想要改變什麼文本,但是我在文本框中使用了PostMessages和按鍵(用於數字)的組合,並且它觸發了TextChangedEvent。

請看this的方法2。它基本上將鼠標設置爲單擊文本框,然後將所需文本的按鍵發送到文本框(逐個字母)。

相關問題