我对无窗口复选框使用 SetCapture() 有正确的想法吗?

Do I have the right idea with using SetCapture() for a windowless checkbox?

我的 Table 控件使用无窗口复选框(因为这里可以有任意数量的复选框)。现在,我使用 TrackMouseEvent(TME_LEAVE) 并在 WM_LBUTTONUP 期间手动检查鼠标是否位于复选框中。我在我的代码中针对这导致的边缘情况标记了 TODO,例如当鼠标离开客户区时缺少 WM_LBUTTONUP

现在我注意到 today's The Old New Thing 说按钮使用鼠标捕获。这引起了我的思考,在研究之后,鼠标捕获更适合我的需要; 如果我的假设是正确的,它将处理我上面提到的各种极端情况,并且总体上更正确。

特别是,我做出的假设是:即使满足所有其他条件,我也应该放弃对 WM_CAPTURECHANGED 的任何捕获相关操作。我会在 ReleaseCapture() 之后得到 WM_CAPTURECHANGED。在 SetCapture() 之后,我将始终以 WM_LBUTTONUPWM_CAPTURECHANGED 结束,以先到者为准。

我已经阅读了 MSDN 和通过谷歌搜索找到的几篇文章 "setcapture correct use";我只是想确保我有正确的想法并将正确地实施它。我呢?

on WM_LBUTTONDOWN
    if the button is in a checkbox
        SetCapture()
        mark that we're in checkbox clicking mode
on WM_MOUSEMOVE
    if we are in checkbox clicking mode
        draw the checkbox in the pressed state
on WM_LBUTTONUP
    if we are in checkbox clicking mode
        leave checkbox clicking mode
        THEN call ReleaseCapture(), so we can ignore its WM_CAPTURECHANGED
        if the mouse was released in the same checkbox
            toggle it
on WM_CAPTURECHANGED
    if we are in checkbox clicking mode
        abandon checkbox clicking mode and leave the checkbox untoggled, even if the mouse is hovering over the checkbox

我的想法对吗?特别是,我对 WM_LBUTTONDOWN 的操作顺序是否正确?谢谢。

你说的基本上是正确的,虽然一个真正的复选框在 "clicking mode" 中跟踪 WM_MOUSEMOVE 并且如果鼠标移开它会显示原始状态的复选框。所以要模拟你应该有:

on WM_MOUSEMOVE
    if we are in checkbox clicking mode
        if mouse is over the checkbox
            draw the checkbox in the pressed (toggled) state
        else
            draw the checkbox in the original state