To send a message and return immediately, use the SendMessageCallback or SendNotifyMessage function. To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage function.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, StringBuilder lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, String lParam);
//Also can add 'ref' or 'out' ahead 'String lParam'
// -- Do not use 'out String', use '[Out] StringBuilder' instead and initialize the string builder
// with proper length first. Dunno why but that is the only thing that worked for me.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern void SendMessage(IntPtr hWnd, Int32 msg, IntPtr wParam, ref RECT lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 msg, IntPtr wParam, ref POINT lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, Int32 lParam);
//If you want to prevent an (unreferenced) managed object from possibly being garbage collected
//during a call to SendMessage, you can wrap the handle in a HandleRef structure.
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(HandleRef hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Function SendMessage( _
ByVal hWnd As HandleRef, _
ByVal Msg As UInteger, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As IntPtr
End Function
Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, _
ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Declare Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As IntPtr, ByRef lParam As StringBuilder) As IntPtr
Declare Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As IntPtr, ByRef RECT As IntPtr) As IntPtr
Declare Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer,
ByVal wParam As IntPtr, ByRef POINT As IntPtr) As IntPtr
1) Use IntPtr instead of UIntrPtr: The UIntPtr type is not CLS-compliant
2) NEVER use "int" or "integer" as lParam. Your code WILL crash on 64-bit windows. ONLY use IntPtr, a "ref" structure, or an "out" structure.
3) NEVER use "bool", "int", or "integer" as the return value. Your core WILL crash on 64-bit windows. ONLY use IntPtr. It's not safe to use bool - pInvoke cannot marshal an IntPtr to a boolean.
4) Use "IntPtr" as the return value, EVEN if the message says it doesn't return any useful information.
5) Microsoft defines the Msg member of the System.Windows.Forms.Message structure to be System.Int32[1]. At the same time the SendMessage native API defines message as type UINT[2], which is a 32-bit unsigned value.[3]
A listing of common Msg codes can be found here: http://www.vbcode.com/Asp/showsn.asp?theID=11797
6) You can replace "hWnd" with "IntPtr" instead of "HandleRef". However, you are taking a risk in doing this - it may cause your code to crash with race conditions - .NET can and will dispose your window handles out from under your message causing all sorts of nasty problems!
:::Question, for someone more knowledgable than me: Can't this last issue be addressed with marshaling, specifically pinning?
7) When passing integer values to lParam and wParam, use IntPtr as they get <MarshalAs(UnmanagedType.SysInt)> attributes by default. You should avoid mixing IntPtr and Integer as parameter types. Use IntPtr.
1) As the number of messages are varied, just keep overloading the function as you need.
2) C# - SendMessage() to Turn the Screensaver On or Off :
[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
public const Int32 WM_SYSCOMMAND = 0x112;
public const Int32 SC_SCREENSAVE = 0xF140;
private void button1_Click(object sender, EventArgs e)
{
// Start the screen saver.
SendMessage(this.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
}
1. Message.Msg Property (http://msdn.microsoft.com/en-us/library/system.windows.forms.message.msg.aspx)
2. SendMessage function (http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx)
3. Windows Data Types (http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx)
Do you know one? Please contribute it!..