如何强制SetWindowPos生成WM_SIZE消息

3

我发现SetWindowPos(...hwnd...)函数如果新的大小与之前相同,则不会生成WM_SIZE消息。但有时我需要SetWindowPos即使大小没有改变也能生成WM_SIZE消息。虽然我可以在SetWindowPos之后使用SendMessage(hwnd, WM_SIZE...),但这是一个糟糕的解决方案,因为它可能会生成两次WM_SIZE。

所以,

是否有任何标志可以用于SetWindowPos或任何类似的函数,以便始终生成WM_SIZE消息?

附:

我有一个主窗口hwndMain,一个子窗口hwndChild和hwndChild2的hwndChild子窗口。当hwndMain被调整大小时,它会接收到WM_SIZE消息,并且有一个MainOnSize(...)函数来调整hwndChild的大小。同样,如果hwndChild被调整大小,它会接收到WM_SIZE消息,并且有一个ChildOnSize(...)函数来调整hwndChild2的大小。

但是有一个情况:在hwndMain和hwndChild被创建后,但hwndChild2没有被创建时,hwndMain接收到WM_SIZE消息,因此hwndMain和hwndChild被调整大小。现在,在hwndChild2被创建后,hwndMain仍然接收到WM_SIZE消息(见备注),因此它调用MainOnSize来调整hwndChild的大小。但是hwndChild的大小没有改变,因此它不会生成WM_SIZE消息,也不会调用ChildOnsize(),因此hwndChild2没有被调整大小。
备注:
hwndMain第一次接收到WM_SIZE消息是在创建时,第二次是通过使用ShowWindow(...)显示时。

5
如果您依赖于在大小未更改时调用WM_SIZE,那么您的做法是错误的...您实际上想要做什么需要这个呢? - K-ballo
我同意K-ballo所说的。看起来你依赖WM_SIZE作为捕捉所有需要重新绘制或更新其他元素的指示。了解当捕捉到WM_SIZE时你会做什么将会得到更好的答案。 - selbie
我会在帖子中解释我试图做什么。 - user565739
所以看来你想知道什么时候一个子窗口被附加到父窗口? - K-ballo
3
你真正的问题在于hwndChild2使用了错误的位置和尺寸创建。只要你在正确的位置创建一个适当尺寸的窗口,你的问题就会消失。为此,需要处理 WM_CREATE 消息并根据需要修改 CREATESTRUCT。它有一个 hwndParent 成员,因此可以访问拥有窗口并检索其大小和位置。这应该就是全部内容了。 - IInspectable
1个回答

1

您可以使用EqualRect API来确定SetWindowPos函数是否会生成WM_SIZE

bool Window::resize(int x, int y, int width, int height, bool repaint)
{
    UINT flags = SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE;

    if (!repaint)
        flags |= SWP_NOREDRAW;

    RECT requested {
       .left = x,
       .top = y,
       .right = width,
       .bottom = height
    };

    RECT actual;
    GetWindowRect(hWnd, &actual);

    const bool IsSame = EqualRect(&requested, &actual) != FALSE;
    const bool status = SetWindowPos(mhWnd, HWND_TOP, x, y, width, height, flags) != FALSE;

    if (IsSame)
       SendMessageW(hWnd, WM_SIZE, ...)
   
    return status;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接