首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过Win32消息处理未处理的到Sublcassed控件的OCM_消息反射

如何通过Win32消息处理未处理的到Sublcassed控件的OCM_消息反射
EN

Stack Overflow用户
提问于 2019-06-26 20:15:04
回答 1查看 199关注 0票数 2

我在CodeProject上发现了以下内容。这是有意义的,除非子类控件不处理OCM_消息,这意味着原始消息的默认处理永远不会发生。是否有一个优雅的解决方案,而不是总是同步这个函数发送的消息与子类窗口过程?

代码语言:javascript
复制
LRESULT DefParentProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
  switch (umsg) {
    case WM_NOTIFY:
    {
      NMHDR* nmhdr = (NMHDR*)lparam;
      if (nmhdr->hwndFrom != NULL)
        return SendMessage(nmhdr->hwndFrom, umsg + OCM__BASE, wparam, lparam);
      break;
    }

    // All of these provide the control's HHWND in LPARAM
    case WM_COMMAND:
    case WM_CTLCOLORBTN:
    case WM_CTLCOLOREDIT:
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORLISTBOX:
    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLORSCROLLBAR:
    case WM_CTLCOLORSTATIC:
    case WM_VKEYTOITEM:
    case WM_CHARTOITEM:
      if (lparam != 0)
        return SendMessage((HWND)lparam, umsg + OCM__BASE, wparam, lparam);
      break;

  // All of these provide ID of the control in WPARAM:
    case WM_DRAWITEM:
    case WM_MEASUREITEM:
    case WM_DELETEITEM:
    case WM_COMPAREITEM:
      if (wparam != 0) {
        HWND hwndControl = GetDlgItem(hwnd, wparam);
        if (hwndControl)
          return SendMessage(hwndControl, umsg + OCM__BASE, wparam, lparam);
      }
      break;

    // Note we do not reflect WM_PARENTNOTIFY -> OCM_PARENTNOTIFY as that 
    // usually does not make much sense.
  }

  return DefWindowProc(hwnd, umsg, wparam, lparam);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-26 22:24:46

这里没有真正干净的解决办法。

您可以确保在为未处理的OCM__BASE消息调用DefWindowProc()时,所有子控件都会减去OCM_...

代码语言:javascript
复制
LRESULT WINAPI DefChildProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
  switch (umsg) {
    ...
  }

  if ((umsg >= OCM__BASE) && (umsg <= OCM__MAX)) {
    umsg -= OCM__BASE;
  }

  return DefWindowProc(hwnd, umsg, wparam, lparam);
}

否则,可以让每个OCM_...消息在其WPARAMLPARAM中携带指向结构的指针,其中结构包含真正的WPARAM/LPARAM和输出LRESULT,然后如果处理给定的OCM_...消息,每个子控件都可以返回TRUE。如果DefWindowProc()返回FALSE,则父程序可以使用原始的WM_...消息调用SendMessage(OCM_...)

代码语言:javascript
复制
struct OCMInfo
{
  LPARAM lParam;
  LRESULT lResult;
};

LRESULT WINAPI DefParentProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
  switch (umsg) {
    case WM_NOTIFY:
    {
      NMHDR* nmhdr = (NMHDR*)lparam;
      if (nmhdr->hwndFrom != NULL)
      {
        OCMInfo info;
        info.lParam = lParam;
        info.lResult = 0;
        if (SendMessage(nmhdr->hwndFrom, umsg + OCM__BASE, wparam, (LPARAM)&info))
          return info.lResult;
      }
      break;
    }

    // All of these provide the control's HHWND in LPARAM
    case WM_COMMAND:
    case WM_CTLCOLORBTN:
    case WM_CTLCOLOREDIT:
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORLISTBOX:
    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLORSCROLLBAR:
    case WM_CTLCOLORSTATIC:
    case WM_VKEYTOITEM:
    case WM_CHARTOITEM:
      if (lparam != 0)
      {
        OCMInfo info;
        info.lParam = lParam;
        info.lResult = 0;
        if (SendMessage((HWND)lparam, umsg + OCM__BASE, wparam, (LPARAM)&info))
          return info.lResult;
      }
      break;

  // All of these provide ID of the control in WPARAM:
    case WM_DRAWITEM:
    case WM_MEASUREITEM:
    case WM_DELETEITEM:
    case WM_COMPAREITEM:
      if (wparam != 0) {
        HWND hwndControl = GetDlgItem(hwnd, wparam);
        if (hwndControl)
        {
          OCMInfo info;
          info.lParam = lParam;
          info.lResult = 0;
          if (SendMessage(hwndControl, umsg + OCM__BASE, wparam, (LPARAM)&info))
            return info.lResult;
        }
      }
      break;

    // Note we do not reflect WM_PARENTNOTIFY -> OCM_PARENTNOTIFY as that 
    // usually does not make much sense.
  }

  return DefWindowProc(hwnd, umsg, wparam, lparam);
}

LRESULT WINAPI DefChildProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
  switch (umsg) {
    case OCM__NOTIFY:
    {
      OCMInfo* info = (OCMInfo*)lparam;
      NMHDR* nmhdr = (NMHDR*)(info->lparam);
      if (...) {
        ...
        info->lResult = ...;
        return TRUE;
      }
      break;
    }

    case OCM__COMMAND:
    {
      OCMInfo* info = (OCMInfo*)lparam;
      if (...) {
        ...
        info->lResult = ...;
        return TRUE;
      }
      break;
    }

    ...
  }

  return DefWindowProc(hwnd, umsg, wparam, lparam);
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56780239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档