Groups | Blog | Home
all groups > dotnet interop > march 2008 >

dotnet interop : C# and SendMessageCallback


ME
3/28/2008 9:32:57 PM
What is the proper way to use the User32 function SendMessageCallback with
in C# so that it will call back a C# delegate? Seems all I can find is
people talking about how SendMessageCallback returns immediately but will
callback a delegate. I can't seem to find any examples though of how this
done in C#. Pinvoke.net only had the signature, but lacked the delegate
definition. An example of how to use this function would be very helpful if
you know how.

Thanks,

Matt

Adam
3/29/2008 10:46:00 PM
ME,

If you look at MSDN for the SendMessageCallback function, you'll be directed
to the SendAsyncProc function definition for the callback function:

http://msdn2.microsoft.com/en-us/library/ms644949(VS.85).aspx

From there, you can derive the delegate:

delegate void SendAsyncProc(IntPtr hwnd, uint uMsg, UIntPtr dwData, IntPtr
lResult);

Here is a simple example:

[DllImport("user32.dll")]
private static extern bool SendMessageCallback(IntPtr hWnd, uint Msg, IntPtr
wParam, IntPtr lParam, SendAsyncProc lpCallback, UIntPtr dwData);
private delegate void SendAsyncProc(IntPtr hwnd, uint uMsg, UIntPtr dwData,
IntPtr lResult);
private const uint WM_USER = 0x400;

private void button1_Click(object sender, EventArgs e)
{
SendAsyncProc del = new SendAsyncProc(SendMessage_Callback);
SendMessageCallback(this.Handle, WM_USER, IntPtr.Zero, IntPtr.Zero, del,
UIntPtr.Zero);
}

private void SendMessage_Callback(IntPtr hwnd, uint uMsg, UIntPtr dwData,
IntPtr lResult)
{
// Here is your callback!
return;
}

I just used a button click event to show this work. I send the WM_USER
message to the form, which does nothing special to handle it.

Hope this helps.

Adam

[quoted text, click to view]
ME
3/30/2008 10:34:32 AM
Thank you that is exactly what I was looking for.

Thanks,

Matt
[quoted text, click to view]

Deepak Shrivastav
4/7/2008 12:20:53 PM


Hi Adam,

I read your portion of this reply.But I am unable to understand this
callback fucntionality.
Can you spare sometime and walkthrough with the piece of code you just
showed as an example.I mean adding comments to the code and the
advantages we receive with callbacks with respect to threads.

Thanks,
Deepak

ME
4/13/2008 11:00:17 PM
Deepak,

I am certainly not Adam, but I will give it a go for you:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

//Declare the external method
[DllImport("user32.dll")]
private static extern bool SendMessageCallback(
IntPtr hWnd,
uint Msg,
IntPtr wParam,
IntPtr lParam,
SendAsyncProc lpCallback, //Call back delegate used
UIntPtr dwData); //data that the call back will return when the
delegate is called.

//internal delegate used to facilitate the callback. When the
message is
//processed by the window this call back will get called.
private delegate void SendAsyncProc(
IntPtr hwnd,
uint uMsg,
UIntPtr dwData,
IntPtr lResult);

//A simple message that most windows can process
//(its result is typically nothing. The window just process the
message and is done)
//The message does not have to be WM_USER and
//can be any valid Windows message. Adam used
//this message for the sake of simplicity in his
//example.
private const uint WM_USER = 0x400;


private void button1_Click(object sender, EventArgs e)
{
//declare the delegate
SendAsyncProc del = new SendAsyncProc(SendMessage_Callback);

//call the external method, sending the message and returning
immediately.
//The callback will get called when the message is processed.
Use this method
//in a similar fashion as the standard "SendMessage" with the
understanding that the
//message may not be processed immediately. You would need to
provide
//valid values for wParam and lParam; in this case zeros are
allowed with WM_USER
SendMessageCallback(
this.Handle,
WM_USER,
IntPtr.Zero,
IntPtr.Zero,
del,
UIntPtr.Zero);
}

//Method called by the delegate when the call back occurs
private void SendMessage_Callback(
IntPtr hwnd,
uint uMsg,
UIntPtr dwData,
IntPtr lResult)
{
// Here is your callback!
//return;
MessageBox.Show("Test");
}

private void label1_MouseDoubleClick(object sender, MouseEventArgs
e)
{
MessageBox.Show("DOUBLE CLICK");
}
}


[quoted text, click to view]

AddThis Social Bookmark Button