UpdateLayeredWindowIndirect failed for ptDst=(577, 205), size=(835x630), dirty=(864x630 -12, 0)

博客介绍了QT相关问题的解决办法,即把界面设置阴影效果的操作移至paintEvent中。

解决办法:

界面设置阴影效果移至paintEvent中。

Qt中使用 `UpdateLayeredWindowIndirect` 函数时遇到“参数错误”导致失败的问题,通常与窗口属性、设备上下文(DC)的配置、位图格式或函数调用参数的设置有关。此函数是Windows API的一部分,用于更新具有分层属性的窗口,常用于实现透明或半透明窗口效果。在Qt中调用它需要特别注意窗口句柄、设备上下文和更新结构体的正确设置。 ### 关键问题分析 1. **窗口样式和扩展样式配置错误** 在调用 `UpdateLayeredWindowIndirect` 之前,必须确保窗口具有 `WS_EX_LAYERED` 扩展样式。可以通过 `SetWindowLong` 或 `SetWindowLongPtr` 设置扩展样式。如果窗口未正确设置为分层窗口,调用此函数将失败[^1]。 2. **设备上下文(DC)获取错误** `UpdateLayeredWindowIndirect` 需要一个兼容的设备上下文(通常为内存DC),并且该DC必须与屏幕DC兼容。常见错误包括未正确创建兼容DC、未释放DC资源或DC的像素格式不匹配。 3. **位图格式不匹配** 用于更新的位图必须是32位ARGB格式,并且必须与内存DC兼容。如果位图格式不正确或未正确绑定到DC,函数将失败。 4. **LAYERED_WINDOW_ATTRIBUTES 结构体配置错误** `UpdateLayeredWindowIndirect` 的第二个参数是一个指向 `LAYERED_WINDOW_ATTRIBUTES` 结构体的指针。如果该结构体未正确初始化(例如未设置 `crKey` 或 `bAlpha` 值),也可能导致失败。 ### 示例代码:正确使用 `UpdateLayeredWindowIndirect` 以下是一个在Qt中正确使用 `UpdateLayeredWindowIndirect` 的示例代码片段: ```cpp #include <windows.h> #include <QWindow> #include <QScreen> #include <QPixmap> void updateLayeredWindow(HWND hwnd) { // 获取窗口DC HDC hdcScreen = GetDC(nullptr); HDC hdcMem = CreateCompatibleDC(hdcScreen); // 创建32位ARGB位图 BITMAPINFO bmi = {0}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = 800; bmi.bmiHeader.biHeight = -600; // top-down DIB bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; void* bits = nullptr; HBITMAP hBitmap = CreateDIBSection(hdcScreen, &bmi, DIB_RGB_COLORS, &bits, nullptr, 0); SelectObject(hdcMem, hBitmap); // 填充位图数据(示例:全透明) memset(bits, 0, 800 * 600 * 4); // 32位ARGB,每像素4字节 // 设置BLENDFUNCTION BLENDFUNCTION blend = {0}; blend.BlendOp = AC_SRC_OVER; blend.SourceConstantAlpha = 255; blend.AlphaFormat = AC_SRC_ALPHA; // 设置LAYERED_WINDOW_ATTRIBUTES POINT ptSrc = {0, 0}; POINT ptDest = {0, 0}; SIZE sizeWnd = {800, 600}; RECT rect; GetWindowRect(hwnd, &rect); ptDest.x = rect.left; ptDest.y = rect.top; // 调用UpdateLayeredWindowIndirect if (!UpdateLayeredWindowIndirect(hwnd, hdcMem)) { DWORD error = GetLastError(); // 处理错误 } // 清理资源 DeleteObject(hBitmap); DeleteDC(hdcMem); ReleaseDC(nullptr, hdcScreen); } ``` ### 解决方案建议 - **检查窗口句柄是否有效**:确保 `hwnd` 是有效的窗口句柄,且该窗口已设置为分层窗口。 - **验证DC创建过程**:确保 `CreateCompatibleDC` 和 `CreateDIBSection` 成功执行,且返回的DC和位图有效。 - **确认位图格式**:确保位图是32位ARGB格式,并且与内存DC兼容。 - **调试错误代码**:使用 `GetLastError()` 获取具体的错误代码,帮助定位问题根源。 - **确保窗口已显示**:根据MSDN文档,分层窗口在调用 `SetLayeredWindowAttributes` 或 `UpdateLayeredWindowIndirect` 之前不会显示[^1]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值