在处理鼠标事件的时候,我捕获的都是WM_NCLBUTTON***的消息。。
代码大致如下:
switch(message)
{
case WM_NCLBUTTONDOWN:
     ...Do some event handling work...
     return ::DefWindowProc(...);
case WM_NCLBUTTONUP:
     ...Do some event handling work...
     return ::DefWindowProc(...);
case WM_NCLBUTTONDBLCLK:
     ...Do some event handling work...
     return ::DefWindowProc(...);
case WM_NCHITTEST:
     int code = DefWindowProc();
     return (code == HTCLIENT?HTCAPTION:code);
}
Problem1 :为什么我没法响应WM_NCLBUTTONUP消息,在我去掉各个return ::DefWindowProc()之后就能捕捉到消息了。我想问一下为什么会这样??
Problem2: 在能响应WM_NCLBUTTONUP消息后,如何不去响应鼠标双击事件,而是每次都是单击事件(就是说双击被当成2次单击)PS:我在WM_NCHITTEST消息处理中将HTCLIENT转换为HTCAPTION了,使得整个客户区域成为caption了,这样子上面的WM_NCLBUTTON***事件便能够被响应了。。

解决方案 »

  1.   

    Problem1 :为什么我没法响应WM_NCLBUTTONUP消息,在我去掉各个return ::DefWindowProc()之后就能捕捉到消息了。我想问一下为什么会这样??
        那你单击时进入哪个case了?
    Problem2: 在能响应WM_NCLBUTTONUP消息后,如何不去响应鼠标双击事件,而是每次都是单击事件(就是说双击被当成2次单击)
        处理双击事件,比如在双击事件里SendMessage
      

  2.   

    Problem1:单击的时候没有进入任何case啊,在按下button的时候能够收到WM_NCLBUTTONDOWN的消息,但是release button的时候无法捕获到WM_NCLBUTTONUP消息。但是如果我响应WM_NCLBUTTONDBLCLK的时候,在双击结束的时候能够相应到WM_NCLBUTTONUP消息,我用dialog-based的一个简单测试程序也产生相应的结果。。哪位大虾解释一下啊?急!
    第二个问题,我也尝试过处理双击事件,但结果肯定不对了,因为你本来就是在响应双击事件,实质上根本不起任何作用。。
      

  3.   

    Problem1:因为系统对 WM_NCLBUTTONDOWN 的默认处理中进行了 SetCaptrue() 操作,鼠标被捕获后,窗口将只能收到以客户区形式表达的鼠标消息,直到 ReleaseCaptrue() 被调用。所以你无法响应WM_NCLBUTTONUP事件。而去掉::DefWindowProc()之后,当然就可以接收到WM_NCLBUTTONUP事件了。
      

  4.   

    补:在最大化的时候不用去掉::DefWindowProc()也可以接收到WM_NCLBUTTONUP消息的
      

  5.   

    To zxk105(银翼&天羽): 谢谢回复
    那么系统在什么时候去ReleaseCapture呢?应该不是我们自己去显示的调用吧。
    还有一点我弄不明白的就是,如果我不case WM_NCLBUTTONDBLCLK的话,那么在双击的时候
    却能够捕获到WM_NCLBUTTONUP的消息,当然如果我case WM_NCLBUTTONDBLCLK的时候就只能
    捕获到WM_NCLBUTTONDBLCLK的消息了。。
      

  6.   

    如果是你SetCapture的话也应由你来ReleaseCapture
    MSDN如是说:
    When the window no longer requires all mouse input, the thread that created the window should call the ReleaseCapture function to release the mouse. 
      

  7.   

    嗯,谢谢。
    zxk105(银翼&天羽)说的是在DefWindowProc的时候系统自动调用SetCapture.我看了一下源代码,的确如此,但是我想知道系统是在什么时候去调用ReleaseCapture呢?显然系统Set的,那么Release操作也应该由系统来做。
      

  8.   

    我们先来看看,他们的一些特性:
    WM_NCLBUTTONDOWN,WM_NCLBUTTONUP,WM_NCLBUTTONDBLCLK,WM_NCHITTEST
    他们对应的处理函数都有一些相同的参数:UINT nHitTest, CPoint point 
    nHitTest
    Specifies the hit-test code. A hit test is a test that determines the location of the cursor.
    指定了击中测试代码。击中测试用于确定光标的位置。 
    point
    Specifies a CPoint object that contains the x and y screen coordinates of the cursor position. These coordinates are always relative to the upper-left corner of the screen.
    指定了一个CPoint对象,其中包含了光标位置的x轴和y轴屏幕坐标。这些坐标总是相对于屏幕的左上角的// 当用户在CWnd的非客户区内放开鼠标左键(或右键)时,框架调用这个成员函数。如果合适的话,将发出WM_SYSCOMMAND消息.
    //注意 框架调用这个成员函数以允许你的应用程序处理一个Windows消息。传递给你的成员函数的参数反映了接收到消息时框架接收到的参数。如果你调用了这个函数的基类实现,则该实现将使用最初传递给消息的参数(而不是你提供给这个函数的参数)。
    =============================================================================
    Problem1 :为什么我没法响应WM_NCLBUTTONUP消息,在我去掉各个return ::DefWindowProc()之后就能捕捉到消息了。我想问一下为什么会这样??
    Problem2: 在能响应WM_NCLBUTTONUP消息后,如何不去响应鼠标双击事件,而是每次都是单击事件(就是说双击被当成2次单击)
    ==============================================================================
    在WM_NCHITTEST消息处理中将HTCLIENT转换为HTCAPTION了,使得整个客户区域成为caption了,这样子上面的WM_NCLBUTTON***事件便能够被响应了。。
    ==============================================================================
    CWnd::OnNcHitTest  
    afx_msg UINT OnNcHitTest( CPoint point );
    Return Value
    One of the mouse hit-test enumerated values listed below. 
    下面列出的鼠标击中测试枚举值之一。 
    Parameters
    point
    Contains the x- and y-coordinates of the cursor. These coordinates are always screen coordinates.
    包含了光标的x轴和y轴坐标。这些坐标总是用屏幕坐标给出的。 
    Res
    The framework calls this member function for the CWnd object that contains the cursor (or the CWnd object that used the SetCapture member function to capture the mouse input) every time the mouse is moved.
    每当鼠标移动时,框架就为包含光标(或者是用SetCapture成员函数捕获了鼠标输入的CWnd对象)的CWnd对象调用这个成员函数。 
    Note   This member function is called by the framework to allow your application to handle a Windows message. The parameters passed to your function reflect the parameters received by the framework when the message was received. If you call the base-class implementation of this function, that implementation will use the parameters originally passed with the message and not the parameters you supply to the function.
    注意 框架调用这个成员函数以允许你的应用程序处理一个Windows消息。传递给你的成员函数的参数反映了接收到消息时框架接收到的参数。如果你调用了这个函数的基类实现,则该实现将使用最初传递给消息的参数(而不是你提供给这个函数的参数)。 
    CWnd Overview |  Class Members |  Hierarchy Chart
    See Also   CWnd::GetCapture,WM_NCHITTEST
    Mouse Enumerated Values
    HTBORDER   In the border of a window that does not have a sizing border.
    HTBORDER 在不具有可变大小边框的窗口的边框上。 
    HTBOTTOM   In the lower horizontal border of the window.
    HTBOTTOM 在窗口的水平边框的底部。 
    HTBOTTOMLEFT   In the lower-left corner of the window border.
    HTBOTTOMLEFT 在窗口边框的左下角。 
    HTBOTTOMRIGHT   In the lower-right corner of the window border.
    HTBOTTOMRIGHT 在窗口边框的右下角 
    HTCAPTION   In a title-bar area.
    HTCAPTION 在标题条中。 
    HTCLIENT   In a client area.
    HTCLIENT 在客户区中。 
    HTERROR   On the screen background or on a dividing line between windows (same as HTNOWHERE except that the DefWndProc Windows function produces a system beep to indicate an error).
    HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。 
    HTGROWBOX   In a size box.
    HTGROWBOX 在尺寸框中。 
    HTHSCROLL   In the horizontal scroll bar.
    HTHSCROLL 在水平滚动条上。 
    HTLEFT   In the left border of the window.
    HTLEFT 在窗口的左边框上。 
    HTMAXBUTTON   In a Maximize button.
    HTMAXBUTTON 在最大化按钮上。 
    HTMENU   In a menu area.
    HTMENU 在菜单区域。 
    HTMINBUTTON   In a Minimize button.
    HTMINBUTTON 在最小化按钮上。 
    HTNOWHERE   On the screen background or on a dividing line between windows.
    HTNOWHERE 在屏幕背景或窗口之间的分隔线上。 
    HTREDUCE   In a Minimize button.
    HTREDUCE 在最小化按钮上。 
    HTRIGHT   In the right border of the window.
    HTRIGHT 在窗口的右边框上。 
    HTSIZE   In a size box (same as HTGROWBOX).
    HTSIZE 在尺寸框中。(与HTGROWBOX相同) 
    HTSYSMENU   In a Control menu or in a Close button in a child window.
    HTSYSMENU 在控制菜单或子窗口的关闭按钮上。 
    HTTOP   In the upper horizontal border of the window.
    HTTOP 在窗口水平边框的上方。 
    HTTOPLEFT   In the upper-left corner of the window border.
    HTTOPLEFT 在窗口边框的左上角。 
    HTTOPRIGHT   In the upper-right corner of the window border.
    HTTOPRIGHT 在窗口边框的右上角。 
    HTTRANSPARENT   In a window currently covered by another window.
    HTTRANSPARENT 在一个被其它窗口覆盖的窗口中。 
    HTVSCROLL   In the vertical scroll bar.
    HTVSCROLL 在垂直滚动条中。 
    HTZOOM   In a Maximize button.
    HTZOOM 在最大化按钮上。