ホームページ >バックエンド開発 >C#.Net チュートリアル >C#のSendMessageとPostMessageでのパラメータ受け渡しの詳細説明
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.
DL
L モジュールはターゲット ウィンドウのメッセージ ハンドラーを呼び出し、結果を返します。 SendMessage は、同じスレッドでメッセージを送信しますが、スレッドのメッセージ キューには入れません。 PostMessage がメッセージを送信する場合、メッセージはまずスレッドのメッセージ キューに入れられ、次にメッセージ
ループ
を通じてターゲット ウィンドウ (DispatchMessage) にディスパッチされる必要があります。
異なるスレッドの場合、SendMessageはターゲットウィンドウが属するスレッドのメッセージキューにメッセージを送信し、メッセージを送信するスレッドはターゲットウィンドウが属するまでUSER32.DLL
モジュールでのメッセージ処理を監視して待機します。処理後に戻ります。 SendMessage は、メッセージを送信する他のスレッドに応答するなど、戻る前に多くの作業を実行します。他のスレッドに投稿する場合は、
PostMessage の代わりに PostThreadMessage を使用するのが最善です。PostMessage の hWnd パラメーターには、PostThreadMessage +
Get
Current
ThreadId と同等の NULL を指定できます。 WM_QUIT をポストする場合は、代わりに PostQuitMessage を使用する必要があります。
4. システムはシステム メッセージ (0 から WM_USER までのメッセージ) のみをマーシャリングします。ユーザー メッセージ (WM_USER 以降) を他のプロセスに送信する場合は、自分でメッセージをマーシャリングする必要があります。
PostMessage、SendNot
if
yMessage、SendMessageC
allback、およびその他の非同期関数を使用してシステムメッセージを送信する場合、送信者はメッセージが処理されるのを待たずに返されるため、パラメーターにポインターを使用できません。 、受信側はまだそれを処理していません。ポインタは解放されています。 5. Windows 2000/XP では、各メッセージ キューには最大 10,000 個の Post メッセージしか保存できません。処理されなかった超過メッセージは処理されず、直接破棄されます。この値は、より大きな値に変更できます: [HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows]
USERPostMessageLimit、最小値は 4000 です。 PostMessage は、メッセージをメッセージ キューに入れることのみを担当します。SendMessage をいつ処理するかどうかは不明です。PostMessage は、メッセージ処理の戻りコード (DWordtype) を受信するまで待機する必要があります。 SendMessage は、メッセージが処理されるまで待機する必要があります。 以下は、これら 2 つのパラメーター受け渡し方法の違いを示す小さな例です: //Win32 API クラス
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); /// <summary> /// 自定义的结构 /// </summary> public struct My_lParam { public int i; public string s; } /// <summary> /// 使用COPYDATASTRUCT来传递字符串 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } //消息发送API [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 int lParam //参数2 ); //消息发送API [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 ref My_lParam lParam //参数2 ); //消息发送API [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 ref COPYDATASTRUCT lParam //参数2 ); //消息发送API [DllImport("User32.dll", EntryPoint = "PostMessage")] public static extern int PostMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 int lParam // 参数2 ); //消息发送API [DllImport("User32.dll", EntryPoint = "PostMessage")] public static extern int PostMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 ref My_lParam lParam //参数2 ); //异步消息发送API [DllImport("User32.dll", EntryPoint = "PostMessage")] public static extern int PostMessage( IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 ref COPYDATASTRUCT lParam // 参数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);//传递2个整型参数成功 } if(DateTime.Now.Second % 3 == 0) { Win32API.SendMessage(hwndTest, 0x61, 5, ref lp);//传递整型参数和结构类型成功,这个方法加以改变后可以传递对象 } if(DateTime.Now.Second % 5 == 0) { Win32API.SendMessage(hwndTest, 0x62, 5, ref cds);//传递整型参数和不定长的字符串成功 } if(DateTime.Now.Second % 7 == 0) { Win32API.PostMessage(hwndTest, 0x63, 5, 6);//传递2个整型参数成功 } if(DateTime.Now.Second % 9 == 0) { Win32API.PostMessage(hwndTest, 0x64, 3, ref lp);//传递整型参数成功,但是传递参数lp失败,3可以传递成功。 } if(DateTime.Now.Second % 11 == 0) { Win32API.PostMessage(hwndTest, 0x65, 3, ref cds);//传递整型参数成功,传递参数cds失败,3可以传递成功。 } } } } }
以上がC#のSendMessageとPostMessageでのパラメータ受け渡しの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。