gpt4 book ai didi

c++ - 什么可能导致两个相等的后续 SetWindowPos() 调用设置不同的窗口大小?

转载 作者:搜寻专家 更新时间:2023-10-31 01:31:51 25 4
gpt4 key购买 nike

作为我正在进行的项目的一部分,我想突出显示桌面区域。现在我使用一个半透明的红色顶层窗口来实现这个,即我

  1. 创建一个带有红色背景画笔的自定义窗口类。
  2. 为我的自定义类创建一个具有 WS_EX_LAYERED 样式集的窗口。
  3. 调用SetLayeredWindowAttributes使窗口 50% 半透明。

它大部分工作得很好,但我注意到我的覆盖窗口和 SetWindowPos 之间有一个相当奇怪的交互。功能:当将小于 32 的宽度或高度传递给 SetWindowPos 时。 39 像素,第一次调用 SetWindowPos 实际上会使窗口比请求的大,但后续调用按预期工作。这是一个演示该问题的小示例程序 - 它在桌面的左上角创建覆盖窗口,然后调用 SetWindowPos 两次,延迟一秒。请注意红色矩形是如何先变成正方形然后垂直缩小的。

#include <windows.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// Register custom class for overlay window, forcing red background
WNDCLASSW overlayClassDef = {
0,
DefWindowProcW,
0,
0,
hInstance,
NULL,
NULL,
::CreateSolidBrush( RGB( 255, 0, 0 ) ),
NULL,
L"Overlay_Window"
};

ATOM overlayClass = ::RegisterClassW( &overlayClassDef );

// Create overlay window using 'layered' flag to enable making it
// translucent
HWND m_overlay = ::CreateWindowExW(
WS_EX_LAYERED | WS_EX_NOACTIVATE,
(LPCWSTR)overlayClass,
NULL,
0,
0,
0,
0,
0,
NULL,
NULL,
hInstance,
NULL
);

// Strip WS_BORDER and WS_DLGFRAME styles to get perfectly flat window; these
// styles appear to get added by default for toplevel windows.
int windowStyle = ::GetWindowLongPtr( m_overlay, GWL_STYLE );
windowStyle &= ~WS_BORDER;
windowStyle &= ~WS_DLGFRAME;
::SetWindowLongPtr( m_overlay, GWL_STYLE, windowStyle );

// Show the window and make it 50% translucent
::ShowWindow( m_overlay, SW_SHOWNA );
::SetLayeredWindowAttributes( m_overlay, 0, 127, LWA_ALPHA );

// Set the position to 100/100 (50x20 pixels); the window on
// screen becomes higher than 20 pixels though!
::SetWindowPos( m_overlay, HWND_TOPMOST, 100, 100, 50, 20, SWP_NOACTIVATE);
::Sleep( 1000 );

// Set the position once more -- this time, the window shrinks
// to 20 pixels vertically.
::SetWindowPos( m_overlay, HWND_TOPMOST, 100, 100, 50, 20, SWP_NOACTIVATE);
::Sleep( 1000 );

// Releasing resources omitted for brevity
return 0;
}

关于这种行为的一些观察:

  1. 如果在窗口标志中设置了 WS_BORDERWS_DLGFRAME,则不会发生此效果;但是,我想清除这两个标志以获得完全平坦的窗口。
  2. 当使用宽度 >= 32 像素时,效果似乎不会水平出现
  3. 当使用高度 >= 39 像素时,效果似乎不会垂直出现
  4. 当不使用自定义窗口类而是实例化内置的 STATIC 类时,也可以重现这一点。

是否有接近 32 像素的神奇最小窗口大小需要特殊处理?

最佳答案

更新窗口样式后,您需要确保重新计算窗口大小和框架指标。为此,您需要在更新视觉样式后立即使用 SWP_FRAMECHANGED 标志手动调用 SetWindowPos:

::SetWindowLongPtr( m_overlay, GWL_STYLE, windowStyle );
::SetWindowPos(m_overlay, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOREDRAW);

关于c++ - 什么可能导致两个相等的后续 SetWindowPos() 调用设置不同的窗口大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44693692/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com