现在的位置: 首页 > 综合 > 正文

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

2014年01月08日 ⁄ 综合 ⁄ 共 6245字 ⁄ 字号 评论关闭

下面是得自MSDN中关于Common Controls的说明,具体路径为:ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/shellcc/platform/commctls/common/common.htm#Using_Common_Control

可以发消息给通用控件来通知控件做某事或者向控件要某事。

当控件发生某事件,比如用户输入,会向父窗口发WM_NOTIFY消息。请自行查阅WM_NOTIFY和NMHDR。

只是可惜的是,EDIT等标准控件,却不发送这个消息:

Note   Not all controls will send WM_NOTIFY messages. In particular, the standard Windows controls (edit controls, combo boxes, list boxes, buttons, scroll bars, and static controls) do not send WM_NOTIFY messages. Consult the documentation for the control to determine if it will send any WM_NOTIFY messages and, if it does, which notification codes it will send.
 
关于EDIT Control,msdn有Edit Control Text Operations文章:
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/shellcc/platform/commctls/editcontrols/editcontroltextoperations.htm
详细列举了如何控制edit控件的方法。
 
在Edit Controls文章:ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.WIN32COM.v10.en/shellcc/platform/commctls/editcontrols/editcontrols.htm
列举了Edit向父窗口发送的通知消息,如下,懒得翻译了:

Notifications

EN_ALIGN_LTR_EC

The EN_ALIGN_LTR_EC notification message is sent when the user has changed the edit control direction to left-to-right. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_ALIGN_RTL_EC

The EN_ALIGN_RTL_EC notification message is sent when the user has changed the edit control direction to right-to-left. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_CHANGE

The EN_CHANGE notification message is sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification message, this notification message is sent after the system updates the screen. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_ERRSPACE

The EN_ERRSPACE notification message is sent when an edit control cannot allocate enough memory to meet a specific request. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_HSCROLL

The EN_HSCROLL notification message is sent when the user clicks an edit control's horizontal scroll bar. The parent window of the edit control receives this notification message through a WM_COMMAND message. The parent window is notified before the screen is updated.

EN_KILLFOCUS

The EN_KILLFOCUS notification message is sent when an edit control loses the keyboard focus. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_MAXTEXT

The EN_MAXTEXT notification message is sent when the current text insertion has exceeded the specified number of characters for the edit control. The text insertion has been truncated.

This message is also sent when an edit control does not have the ES_AUTOHSCROLL style and the number of characters to be inserted would exceed the width of the edit control.

This message is also sent when an edit control does not have the ES_AUTOVSCROLL style and the total number of lines resulting from a text insertion would exceed the height of the edit control.

The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_SETFOCUS

The EN_SETFOCUS notification message is sent when an edit control receives the keyboard focus. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_UPDATE

The EN_UPDATE notification message is sent when an edit control is about to redraw itself. This notification message is sent after the control has formatted the text, but before it displays the text. This makes it possible to resize the edit control window, if necessary. The parent window of the edit control receives this notification message through a WM_COMMAND message.

EN_VSCROLL

The EN_VSCROLL notification message is sent when the user clicks an edit control's vertical scroll bar or when the user scrolls the mouse wheel over the edit control. The parent window of the edit control receives this notification message through a WM_COMMAND message. The parent window is notified before the screen is updated.

WM_CTLCOLOREDIT

An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the edit control.

基本上,还是没有办法去自己处理edit的原始消息了。至此,基本上没什么好进展了。

想了想,我有一个疑问,一般来说,消息循环只写了一次而已,就是

 // Main message loop:
 while (GetMessage(&msg, NULL, 0, 0))
 {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }

这个消息循环,管的是我们自己创建的那个WNDCLASS的窗口消息循环呢?还是管的整个程序的消息循环?如果说管的是我们自己的消息循环,是否意味着Edit控件也有自己的消息循环处理?如果Edit有自己的消息循环处理,那是在哪里运行着呢?

因为我们创建Edit只是用了一个函数CreateWindow就可以了,显然这个函数里面不会调用消息循环的。这么看来,消息循环,应该管的是整个程序的。

MSDN GetMessage:

The GetMessage function retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.

Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning.

这段话,意义如下:

函数得到一个消息MSG

从调用者线程的消息队列

该函数直到得到一个消息后才返回。PeekMessage并不是这样,而是立即返回。

看看其参数

lpMsg
[out] Pointer to an MSG structure that receives message information from the thread's message queue.
hWnd
[in] Handle to the window whose messages are to be retrieved. The window must belong to the calling thread. The NULL value has a special meaning:
NULL
GetMessage retrieves messages for any window that belongs to the calling thread and thread messages posted to the calling thread using the PostThreadMessage function.
wMsgFilterMin
[in] Specifies the integer value of the lowest message value to be retrieved. Use WM_KEYFIRST to specify the first keyboard message or WM_MOUSEFIRST to specify the first mouse message.

Windows XP: Use WM_INPUT here and in wMsgFilterMax to specify only the WM_INPUT messages.

If wMsgFilterMin and wMsgFilterMax are both zero, GetMessage returns all available messages (that is, no range filtering is performed).

wMsgFilterMax
[in] Specifies the integer value of the highest message value to be retrieved. Use WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to specify the last mouse message.

Windows XP: Use WM_INPUT here and in wMsgFilterMin to specify only the WM_INPUT messages.

If wMsgFilterMin and wMsgFilterMax are both zero, GetMessage returns all available messages (that is, no range filtering is performed).

hWnd如果为NULL,得到的将是整个线程的窗口的相关消息。踏破铁鞋无觅处,得来全不费工夫!消息泵消息泵,原来是只要是一个线程里的窗口的消息,都在一个消息队列里,都在这里得到了。那就好办了。

修改消息循环为:

 // Main message loop:
 while (GetMessage(&msg, NULL, 0, 0))
 {

  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   TranslateMessage(&msg);
   if( msg.hwnd == hEdit )
   {
    switch( msg.message )
    {
    case WM_KEYDOWN:
     OutputDebugString(_T("Yes.") );
     break;
    case WM_MOUSEMOVE:
     OutputDebugString(_T("Yes2.") );
     break;
    }
   }
   DispatchMessage(&msg);
  }
 }

相对于我们自己去Dispatch Message了。这下满意了,就凭这一招,通杀所有窗口消息处理了。

 

抱歉!评论已关闭.