Qt

C#でのSendMessageとPostMessageでのパラメーターの受け渡し



Parameter Passing Sendmessage



この記事のソースダウンロードアドレス:http://download.csdn.net/detail/testcs_dn/5152868

C#では、WindowAPIによって提供されるSendMessageとPostMessageを使用してパラメーターを渡すことができます。 2つの違いを簡単に紹介します。戻り値の違いです。まずMSDNのステートメントを見てみましょう。



LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
4つのパラメーターの意味は同じで、戻り値のタイプが異なります(実際、データからの32ビットの数値ですが、意味は異なります)。LRESULTはメッセージを表します。処理後の戻り値、BOOLはメッセージが投稿であるかどうか。


2、PostMessageは非同期で、SendMessageは同期です。
PostMessageは、メッセージが処理されているかどうかに関係なく、メッセージをキューに入れるだけです。メッセージは処理されない場合があり、SendMessageはメッセージが処理されるのを待ってから戻ります。メッセージが処理されていない場合は、メッセージのスレッドを送信します。常にブロックされます。


3. SendMessageが同じスレッドでメッセージを送信する場合、USER32.DLLによって
モジュールはターゲットウィンドウのメッセージハンドラーを呼び出し、結果を返します。 SendMessageは同じスレッドでメッセージを送信し、スレッドメッセージキューには入りません。 PostMessage
メッセージを送信すると、メッセージはスレッドのメッセージキューに配置され、メッセージループを介してターゲットウィンドウ(DispatchMessage)にディスパッチされます。


別のスレッドにある場合、SendMessageはターゲットウィンドウが属するスレッドのメッセージキューにメッセージを送信し、メッセージを送信したスレッドはUSER32.DLLにあります。
モジュールは、ターゲットウィンドウの処理が完了するまで、メッセージの処理を監視して待機します。 SendMessageは、他のスレッドに応答するなど、戻る前に多くの作業を行います
メッセージを送る。他のスレッドに投稿する場合は、代わりにPostThreadMessageを使用することをお勧めします
PostMessage、PostMessageのhWndパラメータはNULLにすることができ、PostThreadMessage +と同等です。
GetCurrentThreadId。 PostWM_QUITの代わりにPostQuitMessageを使用する必要があります。

4.システムは、システムメッセージ(0からWM_USERまでのメッセージ)のみをマーシャリングします。ユーザーメッセージ(WM_USER以上)を他のプロセスに送信する場合は、自分で再編成を行う必要があります。

PostMessage、SendNotifyMessage、SendMessageCallbackなどの非同期関数を使用してシステムメッセージを送信する場合、送信者はメッセージの処理が返されるのを待たず、受信者はまだポインターを処理していないため、パラメーターでポインターを使用できません。リリースされました。 5. Windows 2000 / XPでは、各メッセージキューは最大10,000の投稿メッセージしか保存できません。処理されない場合、処理されず、直接破棄されます。この値はさらに変更できます。[HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows NT / CurrentVersion / Windows] USERPostMessageLimit、最小値は4000です。PostMessageはメッセージをメッセージキューに入れることのみを担当します。メッセージ処理の戻りコード(DWordタイプ)が続行されるまで、SendMessageをいつ処理するかどうかはわかりません。 PostMessageはSendMessageの直後に戻ります。 SendMessageは、メッセージが処理されるまで待ってから戻る必要があります。これは、パラメーターを渡すための2つの方法の違いを説明するための小さな例です。
// Win32APIクラス

using System using System.Runtime.InteropServices namespace TestHwnd { public class Win32API { [DllImport('User32.dll', EntryPoint = 'FindWindow')] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName) [DllImport('User32.dll', EntryPoint = 'FindWindowEx')] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName) /// /// Custom structure /// public struct My_lParam { public int i public string s } /// /// Use COPYDATASTRUCT to pass a string /// [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData public int cbData [MarshalAs(UnmanagedType.LPStr)] public string lpData } //Message Sending API [DllImport('User32.dll', EntryPoint = 'SendMessage')] public static extern int SendMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Int lParam // parameter 2 ) //Message Sending API [DllImport('User32.dll', EntryPoint = 'SendMessage')] public static extern int SendMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Ref My_lParam lParam // parameter 2 ) //Message Sending API [DllImport('User32.dll', EntryPoint = 'SendMessage')] public static extern int SendMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Ref COPYDATASTRUCT lParam // parameter 2 ) //Message Sending API [DllImport('User32.dll', EntryPoint = 'PostMessage')] public static extern int PostMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Int lParam // parameter 2 ) //Message Sending API [DllImport('User32.dll', EntryPoint = 'PostMessage')] public static extern int PostMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Ref My_lParam lParam // parameter 2 ) / / Asynchronous messaging API [DllImport('User32.dll', EntryPoint = 'PostMessage')] public static extern int PostMessage( IntPtr hWnd, // handle to the window to which the message is sent Int Msg, // message ID Int wParam, // parameter 1 Ref COPYDATASTRUCT lParam // parameter 2 ) } }
//メインフォーム、メッセージを送信
using System using System.Collections.Generic using System.ComponentModel using System.Data using System.Drawing using System.Linq using System.Text using System.Windows.Forms using System.Runtime.InteropServices namespace TestHwnd { public partial class Main : Form { public IntPtr hwndTest public int IwndTest public IntPtr hwndfrmTest public Main() { InitializeComponent() } private void button1_Click(object sender, EventArgs e) { Test test = new Test() test.Show(this) } private void timer1_Tick(object sender, EventArgs e) { string strTest = '25425' Win32API.COPYDATASTRUCT cds cds.dwData = (IntPtr)100 cds.lpData = strTest byte[] sarr = System.Text.Encoding.UTF8.GetBytes(strTest) int len = sarr.Length cds.cbData = len + 1 Win32API.My_lParam lp=new Win32API.My_lParam() lp.i=3 lp.s='test' if(hwndTest!=(IntPtr)0) { if (DateTime.Now.Second % 2 == 0) { Win32API.SendMessage(hwndTest, 0x60, 1, 3) / / passed 2 integer parameters successfully } if(DateTime.Now.Second % 3 == 0) { Win32API.SendMessage(hwndTest, 0x61, 5, ref lp)//pass the integer parameter and structure type successfully, this method can be changed to pass the object } if(DateTime.Now.Second % 5 == 0) { Win32API.SendMessage(hwndTest, 0x62, 5, ref cds) / / pass integer parameters and string of variable length success } if(DateTime.Now.Second % 7 == 0) { Win32API.PostMessage(hwndTest, 0x63, 5, 6) / / passed 2 integer parameters successfully } if(DateTime.Now.Second % 9 == 0) { Win32API.PostMessage(hwndTest, 0x64, 3, ref lp) / / Pass the integer parameter successfully, but the parameter lp failed to pass, 3 can be passed successfully. } if(DateTime.Now.Second % 11 == 0) { Win32API.PostMessage(hwndTest, 0x65, 3, ref cds) / / Passing the integer parameter successfully, passing the parameter cds failed, 3 can be passed successfully. } } } } }
//サブフォームはメッセージとパラメータを受信します
using System using System.Collections.Generic using System.ComponentModel using System.Data using System.Drawing using System.Linq using System.Text using System.Windows.Forms using System.Runtime.InteropServices namespace TestHwnd { public partial class Test : Form { Main main public Test() { InitializeComponent() } private void Test_Load(object sender, EventArgs e) { main = this.Owner as Main main.hwndTest = this.Handle } / / / Rewrite the form's message handler DefWndProc, from which to add their own defined message detection processing entry protected override void DefWndProc(ref Message m) { switch (m.Msg) { / / Receive custom message MYMESSAGE, and display its parameters case 0x60: { label1.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + m.LParam.ToInt32().ToString() } break case 0x61: { Win32API.My_lParam ml = new Win32API.My_lParam() Type t = ml.GetType() ml = (Win32API.My_lParam)m.GetLParam(t) label2.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + ml.i.ToString()+':'+ml.s } break case 0x62: { Win32API.COPYDATASTRUCT mystr = new Win32API.COPYDATASTRUCT() Type mytype = mystr.GetType() mystr = (Win32API.COPYDATASTRUCT)m.GetLParam(mytype) string str2 = mystr.lpData label3.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + str2 } break case 0x63: { label4.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + m.LParam.ToInt32().ToString() } break case 0x64: { Win32API.My_lParam ml = new Win32API.My_lParam() Type t = ml.GetType() ml = (Win32API.My_lParam)m.GetLParam(t) label5.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + ml.i.ToString()+':'+ml.s } break case 0x65: { Win32API.COPYDATASTRUCT mystr = new Win32API.COPYDATASTRUCT() Type mytype = mystr.GetType() mystr = (Win32API.COPYDATASTRUCT)m.GetLParam(mytype) string str2 = mystr.lpData label6.Text = DateTime.Now.ToString() + '-' + m.WParam.ToInt32().ToString() + '-' + str2 } break default: base.DefWndProc(ref m) break } } private void button1_Click(object sender, EventArgs e) { main.hwndTest = (IntPtr) (0) this.Close() } } }

この記事のソースダウンロードアドレス:http://download.csdn.net/detail/testcs_dn/5152868




この記事は、Linux Commune Webサイト(www.linuxidc.com)からのものです。元のリンク:http://www.linuxidc.com/Linux/2012-01/51557.htm