Windows Develop Bookmark and Share   
 index > Windows Forms General > How to extract information from System.Windows.Forms.Message
 

How to extract information from System.Windows.Forms.Message


I have an event listener to listen to application-wide mouse events using a IMessageFilter. It receives a System.Windows.Forms.Message object whenever an event occurs. I can filter them out using the Msg property, but I also want to know more information about that event such as:
  • Component that is being clicked on
  • Click coordinates (x, y position).
By looking at the call stack for a click it appears that .NET somehow get this information just from System.Windows.Forms.Message object, but I couldnt find much online about how to go about getting that information.

Any help would be much appreciated.

Thanks in advance!
Amda  Friday, November 09, 2007 3:23 AM

Hi, Amda,

Based on my understanding, you want to get 1) the Control you click and 2) the coordinates of your click from IMessageFilter, don't you?

To solve this problem, lets review Windows Messages and Message Queuesfirst.

http://msdn2.microsoft.com/en-us/library/ms644927.aspx

http://msdn2.microsoft.com/en-us/library/ms644928.aspx

As you can see, the Windows applications will receive and respond tothe Windows Messages when it is running in Windows.

And the IMessageFilter is used to "allow an application to capture a message before it is dispatched to a control or form."

http://msdn2.microsoft.com/en-us/library/system.windows.forms.imessagefilter.aspx

So you should know the WindowsMessage name before you want to get that from the Message object.

And here theWM_LBUTTONDOWN message is helpful here, because the Windows Form gets this Message when it is clicked. But it could be complex to get the Control Messages, because you will have to deal with WM_COMMAND or WM_NOTIFY seperately, I would rather do that with common WinForm functions.

http://msdn2.microsoft.com/en-us/library/bb775494.aspx

For example,

MyFilter.cs (My IMessageFilter to capture the Windows Messages)

Code Block

class MyFilter : IMessageFilter

{

public delegate void MyMouseHandler(object sender, MyArgs e);

public event MyMouseHandler MyMouseClick;

private const int WM_LBUTTONDOWN = 0x0201;

#region public bool PreFilterMessage(ref Message m)

{

switch (m.Msg)

{

case WM_LBUTTONDOWN :

Point mouse = Control.MousePosition;

OnMouseClick(new MyArgs(mouse));

break;

default:

break;

}

return false;

}

#endregion

private void OnMouseClick(MyArgs e)

{

if (MyMouseClick != null)

{

MyMouseClick(this, e);

}

}

}

public class MyArgs : EventArgs

{

private Point position;

public Point Position

{

get { return position; }

set { position = value; }

}

public MyArgs(Point _position)

{

position = _position;

}

}

Code Block

public Form1()

{

InitializeComponent();

filer = new MyFilter();

filer.MyMouseClick += new MyFilter.MyMouseHandler(filer_MyMouseClick);

Application.AddMessageFilter(filer);

}

void filer_MyMouseClick(object sender, MyArgs e)

{

Point location = PointToClient(e.Position);

label1.Text = "X="+ location.X.ToString() + " Y=" + location.Y.ToString();

foreach (Control c in this.Controls)

{

if (c.Bounds.Contains(location))

{

label1.Text += " " + c.Name + " clicked";

}

}

}

MyFilter filer;

private void Form1_Load(object sender, EventArgs e)

{

}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

Application.RemoveMessageFilter(filer);

}

Hope this helps,

Regards

Yu Guo â€?MSFT  Thursday, November 15, 2007 1:58 AM

Hi, Amda,

Based on my understanding, you want to get 1) the Control you click and 2) the coordinates of your click from IMessageFilter, don't you?

To solve this problem, lets review Windows Messages and Message Queuesfirst.

http://msdn2.microsoft.com/en-us/library/ms644927.aspx

http://msdn2.microsoft.com/en-us/library/ms644928.aspx

As you can see, the Windows applications will receive and respond tothe Windows Messages when it is running in Windows.

And the IMessageFilter is used to "allow an application to capture a message before it is dispatched to a control or form."

http://msdn2.microsoft.com/en-us/library/system.windows.forms.imessagefilter.aspx

So you should know the WindowsMessage name before you want to get that from the Message object.

And here theWM_LBUTTONDOWN message is helpful here, because the Windows Form gets this Message when it is clicked. But it could be complex to get the Control Messages, because you will have to deal with WM_COMMAND or WM_NOTIFY seperately, I would rather do that with common WinForm functions.

http://msdn2.microsoft.com/en-us/library/bb775494.aspx

For example,

MyFilter.cs (My IMessageFilter to capture the Windows Messages)

Code Block

class MyFilter : IMessageFilter

{

public delegate void MyMouseHandler(object sender, MyArgs e);

public event MyMouseHandler MyMouseClick;

private const int WM_LBUTTONDOWN = 0x0201;

#region public bool PreFilterMessage(ref Message m)

{

switch (m.Msg)

{

case WM_LBUTTONDOWN :

Point mouse = Control.MousePosition;

OnMouseClick(new MyArgs(mouse));

break;

default:

break;

}

return false;

}

#endregion

private void OnMouseClick(MyArgs e)

{

if (MyMouseClick != null)

{

MyMouseClick(this, e);

}

}

}

public class MyArgs : EventArgs

{

private Point position;

public Point Position

{

get { return position; }

set { position = value; }

}

public MyArgs(Point _position)

{

position = _position;

}

}

Code Block

public Form1()

{

InitializeComponent();

filer = new MyFilter();

filer.MyMouseClick += new MyFilter.MyMouseHandler(filer_MyMouseClick);

Application.AddMessageFilter(filer);

}

void filer_MyMouseClick(object sender, MyArgs e)

{

Point location = PointToClient(e.Position);

label1.Text = "X="+ location.X.ToString() + " Y=" + location.Y.ToString();

foreach (Control c in this.Controls)

{

if (c.Bounds.Contains(location))

{

label1.Text += " " + c.Name + " clicked";

}

}

}

MyFilter filer;

private void Form1_Load(object sender, EventArgs e)

{

}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)

{

Application.RemoveMessageFilter(filer);

}

Hope this helps,

Regards

Yu Guo â€?MSFT  Thursday, November 15, 2007 1:58 AM

You can use google to search for other answers

Custom Search

More Threads

• ListBox SelectedIndexChanged event fires even if index is not changed?
• When does DataGridView really lose focus?
• ProgressBar Beginners question
• OnPaint acts different in Vista and in Xp
• Emulating Form.ValidateChildren for a TabPage
• How to always scroll to the last line in a textBox
• ToolStripButton's ContextMenu
• CWebBrowser: how to get DomDocument in C++
• Keeping Track of Time?
• Find width and length of an image w/0 loading it