How to send a window message to the window that handle I know?
How to send a window message to the window that handle I know?
I.E. I need a .Net analog of SendMessage() or PostMessage() of WinAPI.
Thanks,
Alex.
Re: How to send a window message to the window that handle I know?
Why not just use the windows API ? That's what platform invoke (P/Invoke) is all about.
Code:
public class Win32Methods
{
[DllImport("user32.dll")]
public static extern uint SendMessage(IntPtr hWnd, uint nMessage, uint wParam, uint lParam);
[DllImport("user32.dll")]
public static extern uint PostMessage(IntPtr hWnd, uint nMessage, uint wParam, uint lParam);
public static uint SendMessage(Control control, uint nMessage, uint wParam, uint lParam)
{
HandleRef refHandle = new HandleRef(control, control.Handle);
return SendMessage(refHandle.Handle, nMessage, wParam, lParam);
}
public static uint PostMessage(Control control, uint nMessage, uint wParam, uint lParam)
{
HandleRef refHandle = new HandleRef(control, control.Handle);
return PostMessage(refHandle.Handle, nMessage, wParam, lParam);
}
}
Should be enough to start you off.... (HWNDs are treated as IntPtr's as you should realise from above).
I have to say these are NOT shortcuts for doing things the .NET way. If there is a way of doing something in .NET then you should always use it rather than jumping into using raw Windows API calls.
Darwen.
Re: How to send a window message to the window that handle I know?
you already have access to message sending in .NET. System.Windows.Forms is a HUGE wrapper around win32. there's no need to pinvoke for message sending.
each control which inherits from System.Windows.Control contains WndProc and DefWndProc which takes a System.Windows.Message structure. this is where you can create your message and pass it directly into the message queue.
invoking WndProc with its parent handle (Parent.Handle) will send the message into its queue.
ex:
Code:
// this does the same as calling Invalidate();
private const int WM_PAINT = 0x000F;
private bool InternalInvalidate() {
Message paint = Message.Create(Handle, WM_PAINT, IntPtr.Zero, IntPtr.Zero);
WndProc(ref m);
return m.Result.ToInt32() == 0;
}
Here's a great resource on that:
good luck.
Re: How to send a window message to the window that handle I know?
how can I broadcast a message?
const int HWND_BROADCAST = 0xFFFF;
Message.Create(new IntPtr(HWND_BROADCAST),
...
Re: How to send a window message to the window that handle I know?
you have to import user32's RegisterWindowMessage function to obtain the message, then you send it through wndproc like normal.
Re: How to send a window message to the window that handle I know?
oh. i just made up a message using the GetHashCode
SendMessage(new IntPtr(HWND_BROADCAST), Application.ProductName.GetHashCode(),
but it didn't show up at all in my other wndproc
Re: How to send a window message to the window that handle I know?
supposedly you should be able to use WndProc to send this, but it looks like the only way to get a broadcast is to use PostMessage
Code:
[System.Runtime.InteropServices.DllImport("User32")]
private static extern IntPtr PostMessage(
IntPtr hWnd,
int msg,
IntPtr wparam,
IntPtr lparam
);
I'm sure there is a way to do this natively from whats provided, but if not, than this will work.
Re: How to send a window message to the window that handle I know?
maybe my wndproc is wrong then?
protected override void WndProc(ref Message m)
{
if((int)m.WParam == 15) <- tried matching the msg too, but that didn't work either. also tried hwnd against HWND_BROADCAST.
{
MessageBox.Show("...");
}
// TODO: Add Form1.WndProc implementation
base.WndProc (ref m);
}
Re: How to send a window message to the window that handle I know?
OK. it works better with a proper RegisterWindowMessage
There's no easy way of passing strings to wndproc right.
I don't want to mess with task mem allocation so may have to revert to the registry
Re: How to send a window message to the window that handle I know?
I doubt it. The platform sdk it says to use RegisterWindowMessage to create the message, so I'm assuming this isnt something that WindowProc / WndProc would handle on its own.
Re: How to send a window message to the window that handle I know?
its all OK now.
but is there a way to get the
protected override void WndProc(ref Message m) into a class
rather than manually adding the override in every form. its so messy.
Re: How to send a window message to the window that handle I know?
System.Windows.Forms is a big wrapper around the Win32 Platform (no need to waste all that good work).
each component that inherits from System.Windows.Forms.Control wraps a window. each window contains a WndProc and DefWndProc (relitive to WindowProc and DefWindowProc of Win32). each window uses the win32 message queue and contains quite a bit of code to enable events and the like.
you dont have to override the function to send the message, but if you're going to listen for something and raise your own events, then yes. I'd suggest creating a base window type that listens for whatever you're sending, and just using that class (this way you wont have to do any further listening, you can just work with the data on a .NET event level).
if your class doesnt atleast inherit from Control or NativeWindow (the class ued to subclass windows in .NET), then you'll have to wrap some user32 functionality to send and listen to the message pump...
Re: How to send a window message to the window that handle I know?
You mean like have:
Form
which contains members
Class A - does the PostMessage
listener class - inherits System.Windows.Forms.Control and overrides WndProc instead of the Form?
I guess System.Windows.Forms.Control is as far up as you can go.
I'll give it a try.
Thanks.
Re: How to send a window message to the window that handle I know?
to simplify things (there is a preformance cost though), you can create the listener class as an IMessageFilter. the IMessageFilter interface defines a PreFilterMessage property which gets messages before its sent to a form. you can make one message filter, create events that you wish to subscribe to in your form (keeps you from having to listen for all those messages in each form), and in the constructor or form load event add the filter, and in your dispose or destructor, remove the filter.
form code:
Code:
ClassA clsA = new ClassA();
MessageFilter myListener = new MessageFilter();
myListener.Message1Recieved += new EventHandler(myHandlerFor1);
myListener.Message2Recieved += new EventHandler(myHandlerFor2);
myListener.Message3Recieved += new EventHandler(myHandlerFor3);
// ...
private void MyForm_Load(object sender, EventArgs e) {
Application.AddMessageFilter(myListener);
}
// ...
~MyForm() {
Application.RemoveMessageFilter(myListener);
}
the message filter:
Code:
namespace MessageTest {
using System;
using System.Windows.Forms;
public class MessageFilter : IMessageFilter {
public MessageFilter() {
}
public bool PreFilterMessage(ref Message m) {
// TODO: Add ClassToPost.PreFilterMessage implementation
return false;
}
}
}
ClassA
Code:
using System;
using System.Windows.Forms;
public class ClassA : NativeWindow {
public ClassA() {
WndProc(...);
WndProc(...);
WndProc(...);
WndProc(...);
WndProc(...);
WndProc(...);
WndProc(...);
}
}