首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# SendMessage 與 PostMessage 參數傳遞完整實作指南

     編輯:關於C#

SendMessage vs PostMessage 差異

特性SendMessagePostMessage
回傳值LRESULT(訊息處理後的回傳值)BOOL(是否成功放入佇列)
同步性同步:等待處理完成才回傳非同步:放入佇列即回傳
同執行緒行為直接呼叫視窗程序,不進佇列放入執行緒訊息佇列,經迴圈分派
跨執行緒行為放入目標執行緒佇列並等待放入目標執行緒佇列不等待
系統自動封送系統訊息(0~WM_USER)自動封送系統訊息自動封送
使用者訊息(WM_USER+)需自行封送需自行封送
指標參數安全性安全(等待處理)不安全(發送者可能提早釋放記憶體)

Win32 API 宣告 (C#)

public class Win32API {
  [DllImport("User32.dll", EntryPoint = "FindWindow")]
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  [DllImport("User32.dll", EntryPoint = "SendMessage")]
  public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
  [DllImport("User32.dll", EntryPoint = "SendMessage")]
  public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref My_lParam lParam);
  [DllImport("User32.dll", EntryPoint = "SendMessage")]
  public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

  [DllImport("User32.dll", EntryPoint = "PostMessage")]
  public static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
  [DllImport("User32.dll", EntryPoint = "PostMessage")]
  public static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, ref My_lParam lParam);
  [DllImport("User32.dll", EntryPoint = "PostMessage")]
  public static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

  public struct My_lParam { public int i; public string s; }

  [StructLayout(LayoutKind.Sequential)]
  public struct COPYDATASTRUCT {
    public IntPtr dwData;
    public int cbData;
    [MarshalAs(UnmanagedType.LPStr)] public string lpData;
  }
}

傳遞不同類型參數實測

  • 兩個整數:SendMessage/PostMessage 皆成功(wParam/lParam 直接傳 int)。
  • 整數 + 結構體:SendMessage 成功;PostMessage 結構體傳遞失敗(指標失效)。
  • 整數 + 字串 (COPYDATASTRUCT):SendMessage 成功;PostMessage 失敗。

結論:跨執行緒/進程傳遞結構體或字串必須用 SendMessage,PostMessage 僅適合簡單整數參數。

接收端處理 (Override DefWndProc)

protected override void DefWndProc(ref Message m) {
  switch (m.Msg) {
    case 0x60: // 兩個 int
      label1.Text = m.WParam.ToInt32() + "-" + m.LParam.ToInt32(); break;
    case 0x61: // 結構體
      My_lParam ml = (My_lParam)m.GetLParam(typeof(My_lParam));
      label2.Text = ml.i + ":" + ml.s; break;
    case 0x62: // COPYDATASTRUCT
      COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
      label3.Text = cds.lpData; break;
    // PostMessage 對應 0x63/0x64/0x65 僅整數成功
    default: base.DefWndProc(ref m); break;
  }
}

原始碼下載

SendMessage/PostMessage 參數傳遞完整範例

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved