【问题标题】:Is there something special about the wndProc messages for a RichEdit20WPT window?RichEdit20WPT 窗口的 wndProc 消息有什么特别之处吗?
【发布时间】:2016-12-08 12:51:24
【问题描述】:

我目前正在尝试对编辑控件进行子类化,尤其是 Outlook 客户端中的电子邮件主题。此控件属于 RichEdit20WPT 类。

我通过使用以下 WINAPI 方法获得了一个 wndProc。

<DllImport("ComCtl32.dll", CharSet:=CharSet.Auto)> _
    Public Shared Function SetWindowSubclass(hWnd As IntPtr, newProc As Win32SubClassProc, uIdSubclass As IntPtr, dwRefData As IntPtr) As Integer
    End Function

 <DllImport("comctl32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Public Shared Function DefSubclassProc(ByVal hWnd As IntPtr, ByVal uMsg As IntPtr, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
    End Function

    Public Delegate Function Win32SubClassProc(hWnd As IntPtr, Msg As IntPtr, wParam As IntPtr, lParam As IntPtr, uIdSubclass As IntPtr, dwRefData As IntPtr) As Integer

然后会有一个这样的 wndProc;

Private WM_CONTEXTMENU As IntPtr = &H7B

Private Function SubClassProc(hWnd As IntPtr, Msg As IntPtr, wParam As IntPtr, lParam As IntPtr, uIdSubclass As IntPtr, dwRefData As IntPtr) As Integer

        Select Case Msg

            Case WM_DESTROY                   

            Case WM_NCDESTROY

            Case WM_LBUTTONDOWN

            Case WM_CONTEXTMENU   'NEVER HAPPENS

            Case WM_RBUTTONDOWN

        End Select

        Return DefSubclassProc(hWnd, Msg, wParam, lParam)
    End Function

我收到了 L 和 R 按钮的向下和向上消息,但没有 WM_CONTEXTMENU。我目前的意图是在上下文菜单中添加一个菜单项,以便我使用 WM_RBUTTONDOWN 消息作为替代方案。

此控件是否特殊且已知不显示 WM_CONTEXTMENU 消息?

在上下文菜单中选择某些内容后,我也很难找到出现的消息。我的理解是在上下文菜单中单击的菜单项的消息被提供给父级,在这种情况下是这个 RichEdit20WPT 窗口。它是否正确?请注意,我没有制作自己的上下文菜单,而是将其附加到现有菜单中,因此我不会更改上下文菜单的所有者或类似的内容。

【问题讨论】:

  • 你敢打赌它有什么特别之处!这不是标准的 Windows 控件。标准富文本框控件的类名称为RichEdit20WPT 后缀是 Outlook 团队添加的,用于表示他们的自定义实现。
  • 我的假设是在鼠标右键单击消息后会出现一个上下文菜单。除了它不是 WM_CONTEXTMENU 消息这一事实之外,这个假设对我来说似乎没问题。
  • 您的代码是否在创建窗口的进程中执行。
  • WM_CONTEXTMENU 是向后兼容的窗口消息之一,它不是标准窗口生命周期的一部分,而是由DefWindowProc() 生成的,如果你给它某些消息。在这种情况下,WM_CONTEXTMENU 仅在将 WM_RBUTTONDOWN 提供给 DefWindowProc() 时才会生成,并且 Outlook 作者很可能从未将其传递给 DefWindowProc(),而是在 WM_RBUTTONDOWN 中自己处理上下文菜单逻辑。
  • "我的理解是,在上下文菜单中单击的菜单项的消息被提供给父级,在这种情况下是这个 RichEdit20WPT 窗口。这是正确的吗?" - 当应用程序显示弹出菜单时,它指定HWND 来接收菜单消息。这不需要是 RichEdit 本身。例如,一些第 3 方框架使用专用的消息窗口。我们不知道 Outlook 使用什么。了解 RichEdit 是否接收到菜单消息的最简单方法是检查您的子类是否正在接收它们。如果没有,你可能不得不直接挂钩TrackPopupMenu/Ex()

标签: vb.net winapi outlook-addin


【解决方案1】:

感谢所有帮助我至少继续寻找答案或在这种情况下为消息的 cmets。对于任何来到这里并希望添加到 Outlook 菜单的上下文菜单的人。

首先这里有两个很好的链接,它们通常解释了要做什么。 How to disable copy/paste commands in the Windows edit control context menu? Modify right-click context menu in standard controls 任何阅读它们的人都可以假设标准的编辑控件(例如 Windows 窗体应用程序上的文本框)将发送消息。

对于 Outlook(至少 2007 / 2010),这是我发现的;

  1. 您需要为 Explorer 和 Inspector 找到的文本框是 RichEdit20WPT
  2. 但是,此窗口没有获得所需的两条关键消息。 (a) 在显示上下文菜单之前它不会让 WM_INITMENUPOPUP 知道,其次 (b) 当您在上下文菜单中选择某些内容时,它不会收到消息,在这种情况下是 WM_COMMAND。
  3. 为了修改上下文菜单,您需要将主题文本框的父级子类化,该父级是类 #32770 的窗口。
  4. 由于父类是子类,因此存在一些挑战。要知道我们的目标文本框何时从 #32770 窗口右键单击,您需要查找 WM_SETCURSOR。

类似这样的东西,其中 wParam 将是文本框的 Hwnd,而 HiWord 将是鼠标消息;

Case NativeMethodsEX.WM_SETCURSOR
    If wParam = subjectHwnd Then
        Dim pMap As New NativeMethodsEX.LParamMap(lParam)
    If pMap.hiword = NativeMethodsEX.WM_RBUTTONUP Then
        rightClickOnSubject = True
    Else
        rightClickOnSubject = False
    End If
    End If

然后不久就会有这个消息

Case NativeMethodsEX.WM_INITMENUPOPUP
    If rightClickOnSubject Then
        'check here if you want to display something.
    End If

一旦您知道这一点,您就可以实施其他论坛答案中的想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多