0

我对编辑控制窗口过程进行了子类化,然后发现它不再发送 EN_UPDATE。

我错过了什么,有人可以建议我解决这个问题吗?

LRESULT CALLBACK EditBoxProc_textbox3( HWND hwnd, UINT message , WPARAM wParam, LPARAM lParam )
{
  int previous_position = 0 ;
  WCHAR previous_text [1024];
  WCHAR current_text [1024];


  switch (message)
  {

    case WM_CREATE:
       previous_text[0] = L'\0';
       current_text[0] = L'\0';
       break;

    case EN_SETFOCUS:
      // :TODO: read the current text of the textbox3 and update textbox2 
      // text according to it.                                             //
      Edit_Enable(hwndTextBox2,FALSE);
      break;

    case EN_UPDATE:
      MessageBox(NULL,L"EN_UPDATE", lpszAppName,MB_OK);
      GetWindowText( hwndTextBox3,  current_text ,1024);
      if( is_valid_textbox3(current_text))
      {
        wcscpy(previous_text,current_text);
        previous_position = LOWORD(Edit_GetSel(hwndTextBox3));
        update_textbox2(NULL);

      }else
      {
        SetWindowText(hwndTextBox3, previous_text );
        Edit_SetSel(hwndTextBox3,previous_position, previous_position);
      }  
      break;

    case EN_KILLFOCUS:
      Edit_Enable(hwndTextBox2,TRUE);
      break;
    default:
      break;
  }
  return CallWindowProc(edit_old_wndproc_textbox3,hwnd,message,\
           wParam,lParam);
}
4

1 回答 1

4

然后发现它不再发送 EN_UPDATE

它从来没有发送过 EN_UPDATE。它是实际作为 WM_COMMAND 消息发送的通知消息。它被发送到 Edit 控件的父级,而不是控件本身。EN_SET/KILLFOCUS 也是如此。

The design philosophy here is that an Edit control can simply be put on, say, a dialog. And the custom code that makes the dialog behave in a certain way is written in the parent window's procedure with no requirement to subclass the control. Which is fine but it makes it difficult to create a customized edit control that can have its own behavior. Or in other words, it makes it hard to componentize an edit control. The EN_SET/KILLFOCUS notifications are not a problem, you can simple detect their corresponding WM_SET/KILLFOCUS messages. But you'll hit the wall on EN_UPDATE, the control doesn't send any message like that to itself. Only the parent window can detect it.

Componentizing an edit control is pretty desirable and actively pursued by object-oriented class libraries like Winforms and Qt. They have a class wrapper for the control (TextBox, QLineEdit) that has a virtual method that can be overridden (OnTextChanged, changeEvent) so that the control can be customized into a derived class with its own behavior. And generate an event (aka signal) that anybody can subscribe to, not just the parent (TextChanged, textChanged). To make that work, the parent window needs to participate. When it gets the WM_COMMAND message, it must echo the notification back to the child control. Either by sending a special message back or by calling a virtual method on the child class.

You can of course implement this yourself as well, albeit that you are liable of reinventing such a class library. Consider using an existing one instead.

于 2013-03-30T14:25:32.790 回答