You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现Windows窗口Resize与重绘同步,解决抖动问题

解决Windows窗口Resize动画时界面元素抖动的问题

方法1:使用内存DC(双缓冲)预绘制元素

在窗口调整尺寸前,先基于新的窗口宽高在内存中完成所有界面元素的绘制,等窗口大小调整完成后,一次性将内存中的绘制结果复制到窗口DC,避免分步绘制导致的抖动。

示例代码:

// 假设在窗口调整尺寸的逻辑中
int new_width = ...;
int new_height = ...;

// 创建内存DC和兼容位图
HDC hdc = GetDC(window);
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP memBitmap = CreateCompatibleBitmap(hdc, new_width, new_height);
HBITMAP oldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);

// 在内存DC中完成绘制(替换为你的实际绘制逻辑,基于new_width/new_height居中元素)
RECT memRect = {0, 0, new_width, new_height};
FillRect(memDC, &memRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
DrawCenteredPNG(memDC, new_width, new_height); // 你的居中绘制函数

// 调整窗口大小
bool success = SetWindowPos(window, NULL, xpos, ypos, new_width, new_height, SWP_NOZORDER | SWP_NOCOPYBITS);
if (!success) {
    printf("Failed resizing window. Error code: %lu\n", GetLastError());
}

// 将内存DC内容复制到窗口DC
BitBlt(hdc, 0, 0, new_width, new_height, memDC, 0, 0, SRCCOPY);

// 清理资源
SelectObject(memDC, oldBitmap);
DeleteObject(memBitmap);
DeleteDC(memDC);
ReleaseDC(window, hdc);

方法2:锁定窗口更新直到操作完成

使用LockWindowUpdate暂时禁止窗口重绘,等窗口尺寸调整完成且绘制准备好后,再解锁并强制更新,避免中间状态的显示。

示例代码:

// 锁定窗口,禁止临时重绘
LockWindowUpdate(window);

// 调整窗口大小
bool success = SetWindowPos(window, NULL, xpos, ypos, new_window_width, new_window_height, SWP_NOZORDER | SWP_NOCOPYBITS);
if (!success) {
    printf("Failed resizing window. Error code: %lu\n", GetLastError());
    LockWindowUpdate(NULL); // 失败必须解锁
    return;
}

// 触发后台重绘
RECT rect = {0, 0, new_window_width, new_window_height};
InvalidateRect(window, &rect, TRUE);
UpdateWindow(window); // 强制完成重绘流程

// 解锁窗口,显示最终结果
LockWindowUpdate(NULL);

方法3:调整SetWindowPos参数并同步重绘

给SetWindowPos添加SWP_FRAMECHANGED标志让窗口重新计算非客户区,结合RedrawWindow强制同步重绘,减少延迟:

bool success = SetWindowPos(window, NULL, xpos, ypos, new_window_width, new_window_height, 
                            SWP_NOZORDER | SWP_NOCOPYBITS | SWP_FRAMECHANGED);
if (!success) {
    printf("Failed resizing window. Error code: %lu\n", GetLastError());
}

// 同步重绘窗口及子控件
RedrawWindow(window, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);

注意事项

  • LockWindowUpdate同一时间只能锁定一个窗口,使用后必须调用LockWindowUpdate(NULL)解锁,否则会影响其他窗口绘制。
  • 内存DC方式要注意资源的正确释放,避免内存泄漏。
  • 若是逐帧扩展的动画,建议每帧都用双缓冲,同时控制帧率(比如定时器或短延时),让resize和重绘节奏匹配。

内容的提问来源于stack exchange,提问作者Andreas Sandberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 07:15:56