2

我真的对此感到困惑。我有一个CRichEditCtrl派生类,它在我的 CDialog 中也被子类化为子控件。(Win32窗口本身的窗口类rich-edit是较新的RICHEDIT50W。)

我正在尝试调查在用户点击 ENTER 以使该控件显示垂直滚动条之前光标位于窗口底部的那一刻广播的消息:

在此处输入图像描述

当我使用 Spy++ 检查该窗口的消息时,它表明我收到了一系列WS_STYLECHANGING/WS_STYLECHANGED消息。但是当我试图将它们困在我的子类 WndProc 中时,什么也没有发生。

所以我决定设置一个测试(在Debug构建中)。这是我为子类修改的 WndProc,在br0和上有两个断点br1

LRESULT CMyRichEdit::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    // TODO: Add your specialized code here and/or call the base class
    LRESULT lRes;

    static BOOL bDoLogging = 0;
    if(message == WM_NCCALCSIZE)
    {
        int br0 = 0;       //Breakpoint here
    }
    if(bDoLogging)
    {
        TRACE(L"msg=0x%X\n", message);
    }

    if(message == WM_STYLECHANGED)      //0x007D
    {
        int br1 = 0;       //Breakpoint here
    }

    //Then its regular processing
    // ....


    return CRichEditCtrl::WindowProc(message, wParam, lParam);
}

所以我设置了 Spy++ 来监视我的窗口的消息,然后在它的垂直滚动条即将显示时到达控件本身的点(上面的屏幕截图),然后点击Enter. 在这一点上br0被击中的WM_NCCALCSIZE消息。然后我手动设置bDoLogging为1,删除所有断点,让它运行。

这是 Spy++ 的输出:

在此处输入图像描述

这是我的日志副本:

atlTraceGeneral - msg=0x83  WM_NCCALCSIZE
atlTraceGeneral - msg=0x47  WM_WINDOWPOSCHANGED
atlTraceGeneral - msg=0x5   WM_SIZE
atlTraceGeneral - msg=0xF   WM_PAINT
atlTraceGeneral - msg=0x85  WM_NCPAINT
atlTraceGeneral - msg=0x14  WM_ERASEBKGND
atlTraceGeneral - msg=0xF   WM_PAINT       <<-- missing after this one
atlTraceGeneral - msg=0x87  WM_GETDLGCODE
atlTraceGeneral - msg=0x102 WM_CHAR
atlTraceGeneral - msg=0x87  WM_GETDLGCODE
atlTraceGeneral - msg=0x8   WM_KILLFOCUS
atlTraceGeneral - msg=0x281 WM_IME_SETCONTEXT
atlTraceGeneral - msg=0x282 WM_IME_NOTIFY

看到我的日志中缺少WS_STYLECHANGING/消息。WS_STYLECHANGED以下是 Spy++ 中的属性:

000619 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4

000621 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4

000623 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4

000625 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4

000627 -- WS_STYLECHANGING:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4

000629 -- WS_STYLECHANGED:
styleOld: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4
styleNew: WS_CHILDWINDOW | WS_VISIBLE | WS_VSCROLL | WS_MAXIMIZEBOX | 00D4

此外,下次我运行应用程序时,我也会这样做,但现在在根 MFC 窗口过程中设置一个特定的断点AfxWndProc

在此处输入图像描述

作为条件:

在此处输入图像描述

看看WS_STYLECHANGED消息是否在我的子类收到之前在 MFC 的某个地方被吃掉了。虽然该断点在应用程序启动时命中了几次,但当 Spy++ 显示它时它永远不会被命中。

那么给出了什么:它是 MFC 吗?我的代码?还是 Spy++ 中的错误?

PS。我正在使用 Spy++ x64 版本 15.00.27729

4

1 回答 1

2

我检查 - 控制真的没有得到WM_STYLECHANGINGWM_STYLECHANGED。但是当我设置SetWindowsHookExW(WH_CALLWNDPROC, ..)自线程时-我查看WM_STYLECHANGINGWM_STYLECHANGEDhere。Spy++ 也使用WH_CALLWNDPROC- 因为它并记录此消息。那么为什么控制窗口程序不接收呢?我在调试器下查看 - 窗口过程是从调用的UserCallWinProcCheckWow,但对于某些 Windows 消息 -ThemePreWndProc首先调用,如果它返回 true - 未为此消息调用原始窗口过程。所以以防万一WM_STYLECHANGINGWM_STYLECHANGED被“吞噬”了ThemePreWndProc

所以这不是您的代码或 MFC 中的错误,也不是 Spy++ 中的错误。简单的窗口“功能”

于 2019-04-05T08:26:54.437 回答