I want to insert a 'general' message filter into a .NET application that will
intercept button presses. IMessageFilter cannot be used because it only
intercepts posted messages. So I override WndProc and filter on WM_COMMAND
messages to detect button presses in the application. However the button
presses are not being detected in my app. I have modified the app to have
just one button on it and used spy++ to see what messages the button press
generates. But nothing ! Any ideas ?

Re: Detect button presses by intercepting WM_COMMAND by Stoitcho

Stoitcho
Fri Feb 24 11:54:58 CST 2006

Message filter will work only for messages that comes through the thread
message queue. When child window sends message to its parent because they
are created by the same thread the parents wndproc is called directly and
doesn't go through the message queue.

Buttons send WM_COMMAND to their parent. If you want to intersept them you
need to override their WndProc. If button is placed on a panel you need to
derive the panel and override its WndProc. There is no way you can intersept
WM_COMMAND from all the buttons unless you don't use panels or any other
containers and place all the buttons in the same parent.


--
HTH
Stoitcho Goutsev (100)


"leightonr" <leightonr@discussions.microsoft.com> wrote in message
news:7D4A17BC-9B2A-4952-8141-DFA57EA412A5@microsoft.com...
>I want to insert a 'general' message filter into a .NET application that
>will
> intercept button presses. IMessageFilter cannot be used because it only
> intercepts posted messages. So I override WndProc and filter on
> WM_COMMAND
> messages to detect button presses in the application. However the button
> presses are not being detected in my app. I have modified the app to have
> just one button on it and used spy++ to see what messages the button press
> generates. But nothing ! Any ideas ?



Re: Detect button presses by intercepting WM_COMMAND by leightonr

leightonr
Fri Feb 24 12:04:26 CST 2006

Thanks. that is exactly what I am doing. My form has one control, which
is a Windoes.Forms.Button. In my form I override WndProc as follows :-
protected override void WndProc(ref Message m)

and in WndProc I check for a message of type WM_COMMAND. I expected that
when I clicked the button my form would get a WM_COMMAND message, but it
doesn't ?

"Stoitcho Goutsev (100)" wrote:

> Message filter will work only for messages that comes through the thread
> message queue. When child window sends message to its parent because they
> are created by the same thread the parents wndproc is called directly and
> doesn't go through the message queue.
>
> Buttons send WM_COMMAND to their parent. If you want to intersept them you
> need to override their WndProc. If button is placed on a panel you need to
> derive the panel and override its WndProc. There is no way you can intersept
> WM_COMMAND from all the buttons unless you don't use panels or any other
> containers and place all the buttons in the same parent.
>
>
> --
> HTH
> Stoitcho Goutsev (100)
>
>
> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
> news:7D4A17BC-9B2A-4952-8141-DFA57EA412A5@microsoft.com...
> >I want to insert a 'general' message filter into a .NET application that
> >will
> > intercept button presses. IMessageFilter cannot be used because it only
> > intercepts posted messages. So I override WndProc and filter on
> > WM_COMMAND
> > messages to detect button presses in the application. However the button
> > presses are not being detected in my app. I have modified the app to have
> > just one button on it and used spy++ to see what messages the button press
> > generates. But nothing ! Any ideas ?
>
>
>

Re: Detect button presses by intercepting WM_COMMAND by Stoitcho

Stoitcho
Fri Feb 24 13:38:41 CST 2006

Oh, you are right. The WindowsForms button doesn't send WM_COMMAND as native
buttons does because it is not a native button. This is not a window create
using BUTTON WNDCLASS. This is internal implementation and it simply doesn't
send this message. However using SPY++ you can see that it sends
WM_PARENTNOTIFY; try to use this.


--

Stoitcho Goutsev (100)

"leightonr" <leightonr@discussions.microsoft.com> wrote in message
news:C978B263-E177-4790-BAFE-4D8FF0E34862@microsoft.com...
> Thanks. that is exactly what I am doing. My form has one control,
> which
> is a Windoes.Forms.Button. In my form I override WndProc as follows :-
> protected override void WndProc(ref Message m)
>
> and in WndProc I check for a message of type WM_COMMAND. I expected that
> when I clicked the button my form would get a WM_COMMAND message, but it
> doesn't ?
>
> "Stoitcho Goutsev (100)" wrote:
>
>> Message filter will work only for messages that comes through the thread
>> message queue. When child window sends message to its parent because they
>> are created by the same thread the parents wndproc is called directly and
>> doesn't go through the message queue.
>>
>> Buttons send WM_COMMAND to their parent. If you want to intersept them
>> you
>> need to override their WndProc. If button is placed on a panel you need
>> to
>> derive the panel and override its WndProc. There is no way you can
>> intersept
>> WM_COMMAND from all the buttons unless you don't use panels or any other
>> containers and place all the buttons in the same parent.
>>
>>
>> --
>> HTH
>> Stoitcho Goutsev (100)
>>
>>
>> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
>> news:7D4A17BC-9B2A-4952-8141-DFA57EA412A5@microsoft.com...
>> >I want to insert a 'general' message filter into a .NET application that
>> >will
>> > intercept button presses. IMessageFilter cannot be used because it
>> > only
>> > intercepts posted messages. So I override WndProc and filter on
>> > WM_COMMAND
>> > messages to detect button presses in the application. However the
>> > button
>> > presses are not being detected in my app. I have modified the app to
>> > have
>> > just one button on it and used spy++ to see what messages the button
>> > press
>> > generates. But nothing ! Any ideas ?
>>
>>
>>



Re: Detect button presses by intercepting WM_COMMAND by leightonr

leightonr
Mon Feb 27 05:39:26 CST 2006

Thanks Stoitcho - capturing WM_PARENTNOTIFY appears to work ok. But I don't
understand the explanation of why my button on the from which is of type
Windows.Forms.Button does not cause the BN_CLICKED notification code to go to
the parent through the WM_COMMAND message. Could you elaborate on your
explanation please.

"Stoitcho Goutsev (100)" wrote:

> Oh, you are right. The WindowsForms button doesn't send WM_COMMAND as native
> buttons does because it is not a native button. This is not a window create
> using BUTTON WNDCLASS. This is internal implementation and it simply doesn't
> send this message. However using SPY++ you can see that it sends
> WM_PARENTNOTIFY; try to use this.
>
>
> --
>
> Stoitcho Goutsev (100)
>
> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
> news:C978B263-E177-4790-BAFE-4D8FF0E34862@microsoft.com...
> > Thanks. that is exactly what I am doing. My form has one control,
> > which
> > is a Windoes.Forms.Button. In my form I override WndProc as follows :-
> > protected override void WndProc(ref Message m)
> >
> > and in WndProc I check for a message of type WM_COMMAND. I expected that
> > when I clicked the button my form would get a WM_COMMAND message, but it
> > doesn't ?
> >
> > "Stoitcho Goutsev (100)" wrote:
> >
> >> Message filter will work only for messages that comes through the thread
> >> message queue. When child window sends message to its parent because they
> >> are created by the same thread the parents wndproc is called directly and
> >> doesn't go through the message queue.
> >>
> >> Buttons send WM_COMMAND to their parent. If you want to intersept them
> >> you
> >> need to override their WndProc. If button is placed on a panel you need
> >> to
> >> derive the panel and override its WndProc. There is no way you can
> >> intersept
> >> WM_COMMAND from all the buttons unless you don't use panels or any other
> >> containers and place all the buttons in the same parent.
> >>
> >>
> >> --
> >> HTH
> >> Stoitcho Goutsev (100)
> >>
> >>
> >> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
> >> news:7D4A17BC-9B2A-4952-8141-DFA57EA412A5@microsoft.com...
> >> >I want to insert a 'general' message filter into a .NET application that
> >> >will
> >> > intercept button presses. IMessageFilter cannot be used because it
> >> > only
> >> > intercepts posted messages. So I override WndProc and filter on
> >> > WM_COMMAND
> >> > messages to detect button presses in the application. However the
> >> > button
> >> > presses are not being detected in my app. I have modified the app to
> >> > have
> >> > just one button on it and used spy++ to see what messages the button
> >> > press
> >> > generates. But nothing ! Any ideas ?
> >>
> >>
> >>
>
>
>

Re: Detect button presses by intercepting WM_COMMAND by Stoitcho

Stoitcho
Mon Feb 27 08:51:52 CST 2006

leightonr,

WindowsForms control classes use native windows internally for visualizing
the UI. The Handle property that the control class exposes is the
connection between the native window and the .NET control.
Native windows controls' event system as well as the whole communication
with them is based on sending and receiving windows messages; most of them
starts WM_*. For each native control there is a stucture called WNDCLASS
which describes the common properties and functionality of all native
controls created using the class. One of the characteristics of the class is
the window procedure (winproc) that will handle the windows messages send to
all the windows in this class. The classes have name. There are predefined
classes for native windows for some of the control. One such class is the
BUTTON class. Its winproc is written in a way that it notifies its parent
with WM_COMMAND and BN_CLICKED when the button is considered to be clicked
on. In other words if one creates a native control (see CreateWindow and
CreateWindowEx API calls ) using BUTTON as the name of the class, then this
window will draw itself as a button and behaves as a button. (BTW push
buttons are only one kind of buttons that windows of this class can
represent)

This is all related to native windows and windows API. If WindowsForms
wasn't based on native windows any of this will be valid in the context of
.NET.

The best is to forget about all the native windows stuff when programming
for .NET. All this WndProc and WM_* and alike shouldn't be used. However
apparently this is not possible.

Why System.Windows.Forms.Button class doesn't send this message? Because it
doens't create native window of class BUTTON (this is the WNDCLASS, not the
.NET class) that on the other hand means it doesn't uses native BUTTON
winproc that actually sends this WM_COMMAND. Keep in mind that .NET doesn't
need this windows messages in order to work. It uses them only to make the
link between native windows and the .NET classes. When they provide new
winproc for the button for example they don't need to send this WM_COMMAND
and BN_CLICKED because all the event system used by WindowsForms framework
is implemented in different way (not usinng windows messages).


WM_PARENTNOTIFY is a common message for all windows regardless of their
class (it is send by one winproc called default windows procedure
(DefWindowProc) that's why it still works with .NET buttons.


--
HTH
Stoitcho Goutsev (100)


"leightonr" <leightonr@discussions.microsoft.com> wrote in message
news:6926D83D-5AC5-432C-89D4-24F25A75D5D4@microsoft.com...
> Thanks Stoitcho - capturing WM_PARENTNOTIFY appears to work ok. But I
> don't
> understand the explanation of why my button on the from which is of type
> Windows.Forms.Button does not cause the BN_CLICKED notification code to go
> to
> the parent through the WM_COMMAND message. Could you elaborate on your
> explanation please.
>
> "Stoitcho Goutsev (100)" wrote:
>
>> Oh, you are right. The WindowsForms button doesn't send WM_COMMAND as
>> native
>> buttons does because it is not a native button. This is not a window
>> create
>> using BUTTON WNDCLASS. This is internal implementation and it simply
>> doesn't
>> send this message. However using SPY++ you can see that it sends
>> WM_PARENTNOTIFY; try to use this.
>>
>>
>> --
>>
>> Stoitcho Goutsev (100)
>>
>> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
>> news:C978B263-E177-4790-BAFE-4D8FF0E34862@microsoft.com...
>> > Thanks. that is exactly what I am doing. My form has one control,
>> > which
>> > is a Windoes.Forms.Button. In my form I override WndProc as follows :-
>> > protected override void WndProc(ref Message m)
>> >
>> > and in WndProc I check for a message of type WM_COMMAND. I expected
>> > that
>> > when I clicked the button my form would get a WM_COMMAND message, but
>> > it
>> > doesn't ?
>> >
>> > "Stoitcho Goutsev (100)" wrote:
>> >
>> >> Message filter will work only for messages that comes through the
>> >> thread
>> >> message queue. When child window sends message to its parent because
>> >> they
>> >> are created by the same thread the parents wndproc is called directly
>> >> and
>> >> doesn't go through the message queue.
>> >>
>> >> Buttons send WM_COMMAND to their parent. If you want to intersept them
>> >> you
>> >> need to override their WndProc. If button is placed on a panel you
>> >> need
>> >> to
>> >> derive the panel and override its WndProc. There is no way you can
>> >> intersept
>> >> WM_COMMAND from all the buttons unless you don't use panels or any
>> >> other
>> >> containers and place all the buttons in the same parent.
>> >>
>> >>
>> >> --
>> >> HTH
>> >> Stoitcho Goutsev (100)
>> >>
>> >>
>> >> "leightonr" <leightonr@discussions.microsoft.com> wrote in message
>> >> news:7D4A17BC-9B2A-4952-8141-DFA57EA412A5@microsoft.com...
>> >> >I want to insert a 'general' message filter into a .NET application
>> >> >that
>> >> >will
>> >> > intercept button presses. IMessageFilter cannot be used because it
>> >> > only
>> >> > intercepts posted messages. So I override WndProc and filter on
>> >> > WM_COMMAND
>> >> > messages to detect button presses in the application. However the
>> >> > button
>> >> > presses are not being detected in my app. I have modified the app
>> >> > to
>> >> > have
>> >> > just one button on it and used spy++ to see what messages the button
>> >> > press
>> >> > generates. But nothing ! Any ideas ?
>> >>
>> >>
>> >>
>>
>>
>>