关于视觉C:仅接收WM_NCHITTEST的MFC VC CStatic

MFC VC++ CStatic only receiving WM_NCHITTEST

我用C语言创建了一个小型的MFC Document View App,但在从CStatic继承的类中接收消息时遇到一些麻烦。我已经成功创建了CStatic派生类,并且它在我的View上可见,但是未触发我的消息处理程序。

使用Spy时,似乎窗口仅接收WM_NCHITTEST并且返回HTTRANSPARENT,根据MSDN的意思是:

"在当前由同一线程中的另一个窗口覆盖的窗口中(消息将被发送到同一线程中的基础窗口,直到其中一个返回非HTTRANSPARENT的代码为止。)"

这是间谍的努力:

1
2
3
4
5
6
7
8
<000001> 001D1350 S WM_NCHITTEST xPos:128 yPos:167
<000002> 001D1350 R WM_NCHITTEST nHittest:HTTRANSPARENT
<000003> 001D1350 S WM_NCHITTEST xPos:128 yPos:166
<000004> 001D1350 R WM_NCHITTEST nHittest:HTTRANSPARENT
<000005> 001D1350 S WM_NCHITTEST xPos:128 yPos:165
<000006> 001D1350 R WM_NCHITTEST nHittest:HTTRANSPARENT
<000007> 001D1350 S WM_NCHITTEST xPos:128 yPos:164
<000008> 001D1350 R WM_NCHITTEST nHittest:HTTRANSPARENT

这似乎很奇怪,因为CStatic派生是我视图的唯一子窗口。我是这样创建的:

1
2
Create(pItem->Value->GetBuffer(), WS_CHILD | WS_VISIBLE | SS_CENTER, Rect, Parent);
ShowWindow(SW_SHOW);

其中Parent是指向CView的指针。

我们将不胜感激。

编辑:

Foo.h

1
2
3
4
5
6
7
8
9
10
11
12
13
class Foo: public CStatic
{
    DECLARE_DYNAMIC(Foo)
public:
    Foo();
    virtual ~Foo();
    virtual void CreateCtrl(CWnd * Parent, POINT TopLeft, SIZE sz);

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};

Foo.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Foo::CreateCtrl(CWnd * Parent, POINT TopLeft, SIZE sz)
{
    CRect Rect(TopLeft, sz);
    Create(pItem->Value->GetBuffer(), WS_CHILD | WS_VISIBLE | SS_CENTER, Rect, Parent);
    ShowWindow(SW_SHOW);
}

BEGIN_MESSAGE_MAP(Foo, CStatic)    
    ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

void Foo::OnLButtonUp(UINT nFlags, CPoint point)
{  
    AfxMessageBox("Hello World!");
    __super::OnLButtonUp(nFlags, point);
}


请参见Microsoft的文章"关于静态控件",尤其是本部分:

WM_NCHITTEST: Returns HTCLIENT if the control style is SS_NOTIFY; otherwise, returns HTTRANSPARENT.

一旦窗口从WM_NCHITTEST返回HTTRANSPARENT,所有其他鼠标消息就会以Z顺序到达其下方的窗口;在您的情况下,父视图。就鼠标处理而言,该窗口是"透明的"。


经过一些实验,看起来像Foo::CreateCtrl()中的设置和其他SS_NOTIFY样式使MFC调用Foo::OnLButtonUp()

我对这种样式设置有些困惑,尤其是在阅读了这篇SO帖子之后; SS_NOTIFY的MSDN页面仅显示"当用户单击或双击控件时,发送父窗口STN_CLICKED,STN_DBLCLK,STN_DISABLE和STN_ENABLE通知代码。"

也许没有SS_NOTIFY样式,它不必接收消息,因为它们没有中继到父级?

无论如何,添加SS_NOTIFY样式似乎可以使其正常工作!