Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der Parameterübergabe in SendMessage und PostMessage in C#

Detaillierte Erläuterung der Parameterübergabe in SendMessage und PostMessage in C#

黄舟
黄舟Original
2017-03-14 13:57:513915Durchsuche

In C# können Sie SendMessage und PostMessage verwenden, die von der Window-API bereitgestellt werden, um Parameter zu übergeben. Der Unterschied zwischen den beiden wird kurz vorgestellt: Für den Unterschied im Rückgabewert werfen wir zunächst einen Blick auf die Anweisung in MSDN:

LRESULT SendMessage(

HWND hWnd,

UINT Msg,


WPARAM wParam,

LPARAM lParam

);


BOOL PostMessage(

HWND hWnd,

UINT Msg,


WPARAM wParam,

LPARAM lParam

);


Die Bedeutung der vier Parameter ist die gleich und der Rückgabewerttyp ist unterschiedlich (aus Datensicht handelt es sich tatsächlich um dieselbe 32-Bit-Zahl, aber die Bedeutung ist unterschiedlich), LRESULT stellt den Rückgabewert dar, nachdem die Nachricht verarbeitet wurde, und BOOL stellt dar, ob Die Nachricht wurde erfolgreich gepostet.


2. PostMessage ist asynchron und SendMessage ist synchron.
PostMessage stellt die Nachricht nur in die Warteschlange und kehrt zurück, unabhängig davon, ob die Nachricht verarbeitet wird. Wenn die Nachricht verarbeitet wird, wartet sie möglicherweise nicht nicht verarbeitet, Der Thread, der die Nachricht sendet wird immer blockiert.


3. Wenn SendMessage eine Nachricht im selben Thread sendet, ruft das Modul USER32.DLL
den Nachrichtenhandler des Zielfensters auf und gibt das Ergebnis zurück. SendMessage sendet eine Nachricht im selben Thread und stellt sie nicht in die Thread-Nachrichtenwarteschlange. Wenn PostMessage
eine Nachricht sendet, muss die Nachricht zuerst in die Nachrichtenwarteschlange des Threads gestellt und dann über die Nachricht-Schleife an das Zielfenster (DispatchMessage) gesendet werden.


Wenn in verschiedenen Threads, sendet SendMessage die Nachricht an die Nachrichtenwarteschlange des Threads, zu dem das Zielfenster gehört, und dann überwacht der Thread, der die Nachricht sendet, die Nachrichtenverarbeitung in der USER32.DLL und wartet darauf
Modul bis zum Zielfenster Rückkehr nach der Verarbeitung. SendMessage erledigt vor der Rückkehr auch eine Menge Arbeit, z. B. das Antworten auf andere Threads
SendMessage darauf. Beim Posten in anderen Threads ist es am besten, PostThreadMessage anstelle von
PostMessage zu verwenden. Der hWnd-Parameter von PostMessage kann NULL sein, was PostThreadMessage +
GetCurrentThreadId. Bei Post WM_QUIT sollte stattdessen PostQuitMessage verwendet werden.
4. Das System stellt nur Systemnachrichten (Nachrichten zwischen 0 und WM_USER) bereit. Wenn Sie Benutzernachrichten (über WM_USER) an andere Prozesse senden, müssen Sie diese selbst bereitstellen.

Bei Verwendung von PostMessage, SendNot
ifyMessage, SendMessageCallback und anderen asynchronen Funktionen zum Senden von Systemnachrichten können in der keine Zeiger verwendet werden Parameter, weil Der Absender wartet nicht auf die Verarbeitung der Nachricht, bevor er zurückkehrt, und der Zeiger wird freigegeben, bevor der Empfänger ihn verarbeitet. 5. Unter Windows 2000/XP kann jede Nachrichtenwarteschlange nur bis zu 10.000 Post-Nachrichten speichern. Die überschüssigen Nachrichten, die nicht verarbeitet wurden, werden nicht verarbeitet und direkt verworfen. Dieser Wert kann in einen größeren Wert geändert werden: [HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit, das Minimum kann 4000 sein. PostMessage ist nur für das Platzieren von Nachrichten in der Nachrichtenwarteschlange verantwortlich. Es ist nicht sicher, wann und ob SendMessage verarbeitet werden soll. Es muss warten, bis der Rückgabecode der Nachrichtenverarbeitung (Typ DWord) empfangen wird SendMessage muss warten, bis die Nachricht gesendet wurde. Sie wird nach der Verarbeitung zurückgegeben. Das Folgende ist ein kleines Beispiel, um die Unterschiede zwischen diesen beiden Methoden der Parameterübergabe zu veranschaulichen: //Win32 API-Klasse


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
        );


    }
}

//Hauptform, senden Nachricht

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可以传递成功。
                }
            }
            
            
        }
    }
}

//Unterformular
Nachricht empfangen und Parameter

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Parameterübergabe in SendMessage und PostMessage in C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn