调整窗口大小时是否可以完全消除闪烁?

2024-02-11

通常,即使使用双缓冲,在调整窗口大小时,似乎也不可避免地会发生闪烁。

第1步,原始窗口。

第2步,调整窗口大小,但多余的区域尚未绘制。

第3步,调整窗口大小,并绘制额外区域。

是否有可能以某种方式隐藏步骤 2?我可以暂停调整大小过程,直到绘画操作完成吗?

这是一个例子:

#include <Windows.h>
#include <windowsx.h>
#include <Uxtheme.h>

#pragma comment(lib, "Uxtheme.lib")

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct);
void MainWindow_OnDestroy(HWND hWnd);
void MainWindow_OnSize(HWND hWnd, UINT state, int cx, int cy);
void MainWindow_OnPaint(HWND hWnd);

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wcex = { 0 };
  HWND hWnd;
  MSG msg;
  BOOL ret;

  wcex.cbSize = sizeof(wcex);
  wcex.lpfnWndProc = WindowProc;
  wcex.hInstance = hInstance;
  wcex.hIcon = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
  wcex.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
  wcex.lpszClassName = TEXT("MainWindow");
  wcex.hIconSm = wcex.hIcon;

  if (!RegisterClassEx(&wcex))
  {
    return 1;
  }

  hWnd = CreateWindow(wcex.lpszClassName, TEXT("CWin32"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
  if (!hWnd)
  {
    return 1;
  }

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
  {
    if (ret == -1)
    {
      return 1;
    }
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)
  {
    HANDLE_MSG(hWnd, WM_CREATE, MainWindow_OnCreate);
    HANDLE_MSG(hWnd, WM_DESTROY, MainWindow_OnDestroy);
    HANDLE_MSG(hWnd, WM_SIZE, MainWindow_OnSize);
    HANDLE_MSG(hWnd, WM_PAINT, MainWindow_OnPaint);
  default:
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
  }
}

BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
  BufferedPaintInit();
  return TRUE;
}

void MainWindow_OnDestroy(HWND hWnd)
{
  BufferedPaintUnInit();
  PostQuitMessage(0);
}

void MainWindow_OnSize(HWND hWnd, UINT state, int cx, int cy)
{
  InvalidateRect(hWnd, NULL, FALSE);
}

void MainWindow_OnPaint(HWND hWnd)
{
  PAINTSTRUCT ps;
  HPAINTBUFFER hpb;
  HDC hdc;

  BeginPaint(hWnd, &ps);
  hpb = BeginBufferedPaint(ps.hdc, &ps.rcPaint, BPBF_COMPATIBLEBITMAP, NULL, &hdc);

  FillRect(hdc, &ps.rcPaint, GetStockBrush(DKGRAY_BRUSH));
  Sleep(320); // This simulates some slow drawing actions.

  EndBufferedPaint(hpb, TRUE);
  EndPaint(hWnd, &ps);
}

是否可以消除闪烁?


当窗口在拖动操作期间更新时,操作系统必须显示某物在扩展窗口区域。如果您无法提供任何内容,那么它会显示背景,直到您提供为止。由于您没有指定任何背景,因此您会得到黑色。您肯定应该指定背景画笔吗?只需将以下内容添加到您的代码中即可使行为更容易接受:

wcex.hbrBackground = GetStockBrush(DKGRAY_BRUSH);

但是,如果您需要长达 320 毫秒的时间来响应WM_PAINT那么你就破坏了用户的调整大小 UI。它变得生涩且反应迟钝。该系统的设计假设您可以足够快地绘制窗口,从而使拖动感觉平滑。解决问题的正确方法是WM_PAINT在合理的时间内运行。

如果您确实无法实现足够快的绘画以实现平滑拖动,那么我建议采用以下几种替代方案:

  1. 拖动期间禁用窗口更新。我确信这可以针对单个窗口完成,但我不记得如何做到这一点。
  2. 在调整大小/拖动处于活动状态时绘制一些假的东西,并推迟真实的绘制,直到调整大小/拖动完成。聆听WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE是这一切的关键。这个 Microsoft 示例程序说明了如何做到这一点:https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/winui/fulldrag/ https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/winui/fulldrag/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调整窗口大小时是否可以完全消除闪烁? 的相关文章

  • 代码块调试问题

    我正在尝试在代码块中运行一个简单的链表程序 但我无法运行该程序并且收到以下错误 Active debugger config GDB CDB debugger Default Building to ensure sources are u
  • 任务计划程序控制台输出在哪里? (C# 控制台应用程序)

    我正在运行 C Windows 控制台应用程序 并通过任务计划程序传递几个参数 它全天运行 将其他应用程序创建的平面文件数据加载到 SQL Server 中 该程序间歇性失败 并且我有 Try Catch 逻辑 该逻辑使用 Console
  • 递归显式模板实例化以导出库的符号

    在我之前的问题中我问过递归显式模板实例化是否可能 https stackoverflow com questions 7395113 is recursive explicit template instantiation possible
  • 递归显式模板实例化可能吗?

    给定一个类似的模板 template
  • 查找周边上的点来表示边界/形状

    我有一个简单的二维网格 其格式为myGrid x y 我正在尝试找到一种方法来找到所选网格周围的周长 这样我就有了所选网格的形状 这是我的意思的一个例子 这里的想法是找到所有相关的 角点 也就是图像周边的红点 放入一个列表中 这样我就可以从
  • 管理多个解决方案中存在的 C# 项目的 Nuget 包

    我现在正处于这样的阶段重构疯狂一个有很多的大项目遗留和不稳定的模块 我决定拆分解决方案目前 所有项目 大约有 20 个 而且由于下个月肯定会出现单元测试项目 还会有更多 链接在一起 使其更加独立和细化 通过这种方法 有一些模块 例如需要在多
  • iPhone 编程游戏

    使用 Objective C 还是 C 为 iPhone 编写游戏最好 像 Flight Control 这样的游戏会用什么语言编写 图形应采用什么格式才能在 iPhone 上正确显示并快速加载 像 Flight Control 这样的游戏
  • 本机 C++ 通过代理 C++ 托管 dll 使用 C# dll

    这相当复杂 所以请耐心听我说 我有一个用本机 仅限 Win32 C 编码的第 3 方程序 目标 作为目标设计的一部分 它实现了一个 dll 插件系统 本机 DLL 当放置在程序的 ext 目录中时 由目标加载 然后 目标根据需要调用每个 D
  • 如何使用 Regsvr32 注册 .NET COM DLL?

    我有一个使用 COM DLL 的 VB6 应用程序 该DLL是用C 编写的 在 C 项目属性中 我检查了 Register for COM interop 选项 VB6 应用程序在我的开发机器上运行良好 C 代码完全遵循以下格式 CodeP
  • 驱蚊程序?

    不 我认真的 最近 我读到 当电脑的压电蜂鸣器以一定频率振动时 声音可以驱赶蚊子 真的吗 如何以编程方式访问 PC 蜂鸣器 而不是扬声器 最好使用 C 我不知道有没有蚊子 但我的头疼得要命 啊啊 using System Runtime I
  • System.NotSupportedException:“集合是只读的。”从 iList 中删除对象时抛出

    运行下面的代码片段时抛出异常 我有一个 iListof webelements 如果该元素包含字符串 WSC 我想将其从 iList 中删除 谁能帮我吗 代码如下 IList
  • 从动态服务器中抓取 html 列表数据

    哈喽大家好 抱歉提出转储问题 这是我最后的手段 我发誓我尝试了无数其他 Stackoverflow 问题 不同的框架等 但这些似乎没有帮助 我有以下问题 一个网站显示一个数据列表 前面有大量的 div li span 等标签 它是一个很大的
  • 使用 openssl 库获取 x509 证书哈希

    我目前正在开发一个应用程序 它使用 openssl 库 libcrypto 来生成证书 现在我必须获取现有证书的哈希值 当我使用终端时 我可以使用以下命令生成哈希值 openssl x509 hash in cert pem noout 输
  • 如何在 ASP.NET MVC 中获取参数数组作为 GET / POST?

    如何最好地获取数组 item gt value 对作为 GET POST 参数 在 PHP 中 我可以这样做 网址 这得到的参数为 Array a gt Array one gt 100 two gt 200 有什么方法可以在 ASP NE
  • 创建 PING 程序时限制 ICMP 回显答复

    我正在编写一个多线程 ping 程序 我在每个线程 针对每个 IP 上创建了原始套接字 并使用 sendto 向每个线程发送了 ICMP Echo 请求 然后在每个线程中执行了 receivevfrom 我正在从各种套接字中的 IP 获取消
  • ASP.NET Core中间件如何进行DI?

    我正在尝试将依赖项注入到我的中间件构造函数中 如下所示 public class CreateCompanyMiddleware private readonly RequestDelegate next private readonly
  • 为什么 istream/ostream 慢

    于 50 40http channel9 msdn com Events GoingNative 2013 Writing Quick Code in Cpp Quickly http channel9 msdn com Events Go
  • 发送和接收 Windows 消息

    Windows 消息似乎是通知 Windows 操作系统上的应用程序的好方法 它实际上运作良好 但我想到了几个问题 How to指定结构化数据lparamSendMessage 例程 就像许多消息代码一样 我的意思是 参数当然是一个指针 但
  • 为 winforms ComboBox 中的单个项目着色?

    我遇到了一个困境 我有一个表单 其中包含许多组合框 其中包含在某些情况下可能无效 过时的信息 选项 项目 我不能简单地从项目中删除过时的信息 但我确实想在选项无效时为用户提供视觉线索 我正在考虑对项目进行着色 可能是红色 来指示它们是否无效
  • 警告从 lambda 返回捕获的引用

    我尝试使用 lambda 有条件地将引用绑定到两个变量之一 int foo bar int choice gt int if true some condition return foo else return bar 这会在 clang

随机推荐

  • spring 作用域代理 bean

    谁能解释一下弹簧的用途 ScopedProxy注解 我thought它与会话范围的 bean 有关 但我不太确定是什么 在我对范围的使用中 我使用了会话范围的 bean 但没有使用 ScopedProxy注释 或没有 aop 作用域代理 所
  • CSS 在某个点改变背景颜色

    我希望当某个元素进入视图时整个网站的背景从白色变为黑色 因此 当您滚动元素时 背景会变为黑色 当您向后滚动时 我希望页面的背景颜色变回白色 谢谢你 HTML div class colorChange div
  • Google Places API - getQueryPredictions 受国家/城市/州限制吗?

    下面是 google 给出的 getQueryPredictions 示例 service getQueryPredictions input pizza near callback 有没有办法限制特定国家 城市 州的结果 其他功能 组件有
  • .NET 写入 PCAP 文件

    All 我花了一天的大部分时间查看各种 PCAP 库 在我承诺编写 PCAP 编写器之前 我想描述一下我的场景并征求意见 我有一个客户要求我提供一项服务来读取 pcap 文件并将数据包写入他们选择的数据库中 然后 客户端可以查询数据库 日期
  • 从多选ListView返回值

    编辑 好的 我找到了解决方案 不知道这是正确的解决方案 但它确实可以正常工作 添加到下面的代码中 我试图允许用户从清单中选择多个目录 并在单击 提交 按钮后返回它们 这是我的代码片段 它使用 sdcard 上的所有目录填充 ListView
  • 通过特定属性的值在数组中搜索对象的最有效方法

    实现搜索方法的最快 最有效的方法是什么 该方法将返回具有限定条件的对象id 示例对象数组 array object id gt one color gt white object id gt two color gt red object
  • 在字符串中每两个字符后插入冒号(:) 的方法是什么?

    我试图弄清楚 INPUT String data 506313B5EA3E OUTPUT String data 50 63 13 B5 EA 3E 我尝试使用 java util Arrays toString data split lt
  • 无法打开文件(在项目“Pods”的目标“React”中)(在目标“React”中)

    我有一个reactNative项目 我正在尝试在最新的xcode 10 1中运行 但是在我构建时它抛出了两个错误 error Users ios Pods Target Support Files React React xcconfig
  • 在 Eclipse 中调试 JavaScript

    如何在 Eclipse 中调试 JavaScript 我使用的是 Eclipse 3 2 1 每次我单击侧面时 它都会提供添加书签的选项 但没有断点 有人可以帮助我吗 2015年 在Eclipse中调试JavaScript至少有六种选择 自
  • Apache Kafka 和 Avro:org.apache.avro.generic.GenericData$Record 无法转换为 com.harmeetsingh13.java.Customer

    每当我尝试从 kafka 队列读取消息时 我都会收到以下异常 error run main 0 java lang ClassCastException org apache avro generic GenericData Record
  • if else 不检查 Python 中的两个条件

    我希望根据特定条件创建新列 pred n 条件如下 如果年份小于或等于当前年份且月份小于当前月份 则 pred n 应等于 yhatpct 否则应为yhatpct ft 尝试以下语法 if dfyz year x lt datetime n
  • FCM 服务不可用 nack

    我有一个 python3 程序 可以成功连接到 FCM XMPP 测试服务器 但是 发送 JSON 后 它返回给我一个SERVICE UNAVAILABLE每次nack消息 上周的同一段代码运行得非常好 The 文档 https fireb
  • Django 模型管理器.py 和 models.py

    鉴于以下情况 模型 py from managers import PersonManager from django db import models class Person models Model first name models
  • 电对模式和 Python 三引号

    有没有办法在电对模式下启用自动配对Python三引号 这可以在自动配对模式下使用进行配置autopair python triple quote action 是否有类似的方法可以在电对模式下启用此功能 您可以执行以下操作 defun py
  • Rails 在开发模式下不会记录模板错误

    我的 Rails 3 2 9 app 没有向我显示任何有关错误的具体错误信息在模板中 无论我使用 haml 还是 erb 我总是会得到 我们很抱歉 但有些不对劲 事实上 韦布里克is in 发展模式 如果我的模型或控制器出现错误 我会看到完
  • 如何在 GDAL ruby​​ 绑定中显式关闭数据集?

    我在用GDAL https gdal org 1 7 1 从ruby1 9生成GeoTIFF文件 在里面tutorial https gdal org tutorials raster api tut html他们建议使用 GDALClos
  • Ubuntu 11.10链接perftools库

    我无法让 Ubuntu 11 10 中的 gcc 正确链接到 google perftools lprofiler 问题似乎是链接器丢弃了程序中未直接使用的库 一个例子会有所帮助 我们称之为 main cpp include
  • Xamarin iOS UIButton 如何以编程方式单击按钮?

    我试图通过在 ViewWillAppear 函数中以编程方式调用按钮来伪造单击按钮的行为 onclick 函数是在我的 ViewDidLoad 中定义的 您可以看到我正在尝试使用执行选择器来手动调用按钮 该按钮似乎没有运行 有任何想法吗 p
  • WebRTC:对多个对等连接使用相同的 SDP?

    是否可以在多个对等连接中使用相同的 SDP 我正在使用 WebRTC 构建视频会议 这个想法是 呼叫者使用某种信令机制 使用其 SDP 每个用户相同的 SDP 向所有其他用户发送广播消息 然后用户将使用其 SDP 进行响应 当用户收到某人的
  • 调整窗口大小时是否可以完全消除闪烁?

    通常 即使使用双缓冲 在调整窗口大小时 似乎也不可避免地会发生闪烁 第1步 原始窗口 第2步 调整窗口大小 但多余的区域尚未绘制 第3步 调整窗口大小 并绘制额外区域 是否有可能以某种方式隐藏步骤 2 我可以暂停调整大小过程 直到绘画操作完