如何强制SetWindowPos生成WM_SIZE消息

How to force SetWindowPos to generate WM_SIZE message

本文关键字:SIZE 消息 WM 生成 何强制 SetWindowPos      更新时间:2023-10-16

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

Is any flag for SetWindowPos or any similar functions so a WM_SIZE message is always generated?

ps:

我有一个主窗口hwndMain,一个子窗口hwndChild和hwndChild的子窗口hwndChild2。当hwndMain被调整大小时,它接收WM_SIZE,并且有一个MainOnSize(…)函数来调整hwndChild的大小。类似地,如果hwndChild被调整大小,它接收WM_SIZE,并且有一个childsize(…)函数来调整hwndChild2的大小。

但它来的情况:hwndMain和hwndChild被创建后,但不hwndChild2, hwndMain收到WM_SIZE,所以hwndMain和hwndChild被调整大小。现在hwndChild2创建后,hwndMain仍然收到一个WM_SIZE(见备注),所以它调用MainOnSize来调整hwndChild的大小。但是hwndChild的大小没有改变,所以它不会生成WM_SIZE,也不会调用ChildOnsize(),因此hwndChild2不会调整大小。

备注:

hwndMain第一次接收WM_SIZE是在创建WM_SIZE的时候,第二次是在使用ShowWindow(…)显示WM_SIZE的时候。

您可以使用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;
}