Winapi 当事件涉及到子窗口时,如何启动用户鼠标驱动的移动或调整无边框窗口上的自定义窗口边框的大小?

Winapi 当事件涉及到子窗口时,如何启动用户鼠标驱动的移动或调整无边框窗口上的自定义窗口边框的大小?,winapi,events,user32,Winapi,Events,User32,我有一个无边界窗口,它的唯一子窗口(总是窗口大小)是第三方组件。该组件希望能够在其自行决定的某些区域发生WM_MOUSEDOWN时通知我移动或调整窗口大小(好像它不是无边界的)。它还想决定要使用的事件 因为窗口是无边界的,并且子窗口已经收到了鼠标消息,我认为我无法覆盖WM\u NCHITTEST,是吗?(或者换句话说,父窗口是否总是在我的孩子获得WM\u LBUTTONDOWN之前获得WM\u NCHITTEST?或者仅在第一次激活时/在捕获过程中获得?) GTK+用于调用DefWindowPr

我有一个无边界窗口,它的唯一子窗口(总是窗口大小)是第三方组件。该组件希望能够在其自行决定的某些区域发生
WM_MOUSEDOWN
时通知我移动或调整窗口大小(好像它不是无边界的)。它还想决定要使用的事件

因为窗口是无边界的,并且子窗口已经收到了鼠标消息,我认为我无法覆盖
WM\u NCHITTEST
,是吗?(或者换句话说,父窗口是否总是在我的孩子获得
WM\u LBUTTONDOWN
之前获得
WM\u NCHITTEST
?或者仅在第一次激活时/在捕获过程中获得?)

GTK+用于调用
DefWindowProc()
WM\u nclubuttondown
手动触发该模式事件循环。这样做吗

WM\u SYSCOMMAND
中的
SC\u MOVE
怎么样?这是否仅适用于键盘驱动的窗口移动和大小调整,而不是鼠标驱动的窗口移动和大小调整

还是我必须手动完成?我知道这是一个模式循环,它使用了一个消息过滤器常量,我知道Aero Snap至少需要手动完成

我需要在Windows Vista或更高版本上执行此操作


谢谢。

由于父窗口无边框且完全被子窗口覆盖,因此默认情况下,父窗口将不会收到
WM\u nchitest
。所有
WM\u NCHITTEST
消息将首先由孩子接收

但是,您仍然可以允许用户通过一些额外的编码来正常调整父窗口的大小。有几种不同的方法可以处理此问题:

  • 子类化子窗口以截获
    WM\n chittest
    消息。收到消息后,首先将消息传递给子窗口的默认消息处理程序,如果它返回
    HTCLIENT
    ,并且
    lParam
    中提供的屏幕坐标位于要用于调整大小的父窗口区域内,则返回
    HTTRANSPARENT
    。这将导致下一步将
    WM_NCHITTEST
    发送到父窗口,然后父窗口可以处理
    WM_NCHITTEST
    ,并根据需要的调整大小类型返回以下值之一:

    HTBOTTOM
    HTBOTTOMLEFT
    HTBOTTOMRIGHT
    HTLEFT
    HTRIGHT
    HTTOP
    HTTOPLEFT
    HTTOPRIGHT
    
  • 在子窗口的mousedown事件中,将提供的鼠标客户端坐标转换为屏幕坐标,然后调用
    ReleaseCapture()
    并向父窗口发送
    WM\u nclubuttondown
    消息,将
    wParam
    设置为上述值之一,和
    lParam
    到屏幕坐标

  • 在子窗口的mousedown事件中,调用
    ReleaseCapture()
    并向父窗口发送
    WM\u SYSCOMMAND
    消息,将
    wParam
    设置为
    SC\u SIZE
    加上下面所需的值,将
    lParam
    设置为0:

     SC_SIZE_HTLEFT = 1
     SC_SIZE_HTRIGHT = 2
     SC_SIZE_HTTOP = 3
     SC_SIZE_HTTOPLEFT = 4
     SC_SIZE_HTTOPRIGHT = 5
     SC_SIZE_HTBOTTOM = 6
     SC_SIZE_HTBOTTOMLEFT = 7
     SC_SIZE_HTBOTTOMRIGHT = 8
    
  • 任何一种方式都允许父窗口正常调整大小,以及所有涉及的内容(鼠标跟踪、捕捉等),除了一件事#1诱使操作系统认为用户已将鼠标直接移到父窗口上,因此它允许操作系统提供有关正在使用哪个“大小边界”的视觉反馈#2和#3不会提供任何视觉反馈,因此如果需要,您必须通过
    SetCursor()
    手动处理

    如果要允许用户在不调整父窗口大小的情况下拖动父窗口,可以:

  • 子类化子类
    WM\u NCHITTEST
    消息以返回相应区域中的
    HTTRANSPARENT
    ,然后让父窗口进程
    WM\u NCHITTEST
    返回
    HTCAPTION

  • 在子窗口的mousedown事件中,调用
    ReleaseCapture()
    并向父窗口发送
    WM\u SYSCOMMAND
    消息,将
    wParam
    设置为
    SC\u DRAGMOVE
    (未记录,但其值为
    $F012
    ,也称为
    SC\u MOVE+2
    ),并将
    lParam
    设置为0


  • 所以我唯一的选择就是使用
    WM\u nchitest
    ?我之所以这么问,是因为现在拖动resize的信号被记录在
    WM_LBUTTONDOWN
    处理程序中发送;我可以改变API,但没问题。低位技巧是否也适用于
    SC_SIZE
    wmnchitteest
    不是您唯一的选择。是的,
    SC_SIZE
    也有类似的低位技巧。我已经更新了我的答案。很酷,谢谢。仅仅为了标准方法的完整性,是否会出现子类化孩子的
    WM\u-NCHITTEST
    不够的情况?子类化
    WM\u-NCHITTEST
    足够轻松地处理这两种情况,但使用
    SendMessage()
    在孩子的mousedown事件中,编写代码可能会更快。