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.