子窗口与父窗口的消息关系网-1

windows系统下面,每一个窗口都是一个WNDCLASS的实例。而一个WNDCLASS都有一个窗口过程(WndProc)与之对应。这不管是我们自己创建的WNDCLASS窗口还是windows标准窗口,比如button,edit等。Edit控件功能强大,能够处理字符输入删除编辑等,显然是windows系统实现的。对于Edit控件的窗口过程函数,我们是无法得到的(当然排除类似hook等方法)。由此,得到一个结论:

结论1:Edit,Button等windows标准窗口控件(The standard Microsoft Windows controls :edit controls, combo boxes, list boxes, buttons, scroll bars, and static controls) 和Windows通用控件,都有自己的窗口过程函数。

另外一个很现实的问题,键盘和鼠标这两种输入设备,同一个时间点,其输入的信息,只可能是针对一个窗口而言,只能与一个窗口句柄关联。这个应该很好理解,也就是说,在windows系统中,不管屏幕上显示了多少个窗口,最终得到的键盘和鼠标的输入数据,总是具有焦点的那个窗口(这个结论我没有验证,只是推测,所以不敢肯定,不敢肯定的是没有焦点的窗口是否也可以得到输入),暂且也作为一个结论吧:

结论2:windows系统中,同一个时间点上,只有一个窗口能够得到键盘和鼠标的输入数据。

一般说来,edit,button等所谓的控件,总是放在一个窗口之上的。所以当edit得到输入焦点的时候,键盘输入数据,就关联到edit控件的句柄上,从而被消息循环派遣到了edit的窗口过程函数里了。从而得到结论3:

结论3:与该窗口句柄相关的消息被派遣到该窗口的窗口过程函数里。

为了验证上面的结论,用一个代码示例之:

step1:用VC2005创建一个win32窗口程序,就用VC系统创建的代码,不选择“空的工程”

step2:定义一个全局变量:

    HWND hEdit=NULL;

step3: 在窗口过程函数里,创建一个edit框,在窗口的WM_CREATE消息里处理:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

 ..

 case WM_CREATE:
  hEdit = CreateWindow( _T("EDIT"),      // predefined class
                              NULL,        // no window title
                              WS_CHILD | WS_VISIBLE | WS_VSCROLL |
                                    ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
                              0, 0, 400, 400,  // set size in WM_SIZE message
                              hWnd,        // parent window
                              (HMENU) ID_EDITCHILD,   // edit control ID
                              hInst,
                              NULL);       // pointer not needed

  break;

...

到此,就手工创建了一个edit编辑框放在了一个窗口上了。

接下来验证edit框获取了鼠标键盘的输入,而其父窗口在edit获得输入时却无法获得消息。

step4:还是在窗口过程中,增加键盘按下和鼠标移动消息:

 case WM_KEYDOWN:
  {
  short int key = (short int) wParam;
  TCHAR szText[256]={0};
  _stprintf( szText,_T("/n Key Down = %d") , key );
  OutputDebugString( szText );
  break;
  }
 case WM_MOUSEMOVE:
  {
   int x= LOWORD( lParam );
   int y= HIWORD( lParam );

  break;
  }

编译运行后,可以发现,在edit框之外移动鼠标,按下键盘,窗口过程截获到该消息,但是如果在edit框内按键移动鼠标,均无法得到消息。

问题来了,我们如何处理edit编辑框的WM_KEYDOWN,WM_MOUSEMOVE消息呢?

如果熟悉MFC的同学,会很快回答这个问题,写一个类继承CEdit,步骤如下:

在头文件
class Editor : public CEdit
{
   DECLARE_MESSAGE_MAP()

   afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
}
在cpp文件

BEGIN_MESSAGE_MAP(Editor, CEdit)
 //{{AFX_MSG_MAP(Editor)
 ON_WM_KEYDOWN()
....

void Editor::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
...

然后就可以接收到消息了。
可是,MFC是如何做到的呢?

 

 

 

你可能感兴趣的:(windows,button,microsoft,mfc,null,callback)