c++ - Windows API 中的 InvalidateRect,Charles Petzold checker4.c 程序

标签 c++ c windows winapi

完整程序在这里:

http://examples.oreilly.com/9781572319950/cd_contents/Chap07/Checker4/Checker4.c

ChildWndProc 中让我感到困惑的代码:

 case WM_LBUTTONDOWN :
      SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
      SetFocus (hwnd) ;
      InvalidateRect (hwnd, NULL, FALSE) ;
      return 0 ;

           // For focus messages, invalidate the window for repaint

 case WM_SETFOCUS:
      idFocus = GetWindowLong (hwnd, GWL_ID) ;

           // Fall through

 case WM_KILLFOCUS:
      InvalidateRect (hwnd, NULL, TRUE) ;
      return 0 ;

为什么在消息 WM_LBUTTONDOWN 的情况下在 ChildWndProc 中:

返回 0 之前的最后一个语句是 InvalidateRect,因为就在它之前,程序使用 SetFocus 函数向自身发送了 WM_SETFOCUS 消息,这落到 WM_KILLFOCUS,它也有 InvalidateRect,只有最后一个参数是 TRUE,而不是 FALSE

根据我的理解,程序应该在 WM_LBUTTONDOWN 中没有 InvalidateRect 的情况下正常工作,因为它调用了 SetFocus,然后使窗口无效,但是,当我从 WM_LBUTTONDOWN 中注释掉 InvalidateRect 时,程序不会在单击鼠标或按下按钮后正确地重新绘制窗口。

为什么会这样,为什么在 WM_LBUTTONDOWN InvalidateRect 中最后一个参数是 FALSE 而在 WM_KILLFOCUS 中是

我在 Windows XP 32 位中运行 MS Visual Studio C++ 2010 Express。

最佳答案

调用 SetFocus() 不会无条件地发送 WM_SETFOCUS 消息。如果窗口在调用之前已经获得焦点,SetFocus() 将不会执行任何操作。

换句话说,WM_SETFOCUS 消息仅在焦点更改时发送。

至于TRUE/FALSE参数,就是bErase,是在重新绘制之前删除整个窗口,还是涂上已经存在的东西。在我看来,这是一种性能黑客。如果你知道你可以不删除窗口(因为你只是更新它的一小部分),你可以在这里传递 TRUE

我认为在 2015 年这种优化没有多大值(value)。如果您需要高性能显示更新,无论如何您都会使用 OpenGL 或 DirectX。

关于c++ - Windows API 中的 InvalidateRect,Charles Petzold checker4.c 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30258148/

相关文章:

c++ - "operator bool() const"是什么意思

c++ 正则表达式使用 regex_search() 提取所有子字符串

c - 在 C 中使用 strtok 将 URL 分成两部分

c++ -::FindWindow 从服务应用程序失败

asp.net - 如何清除 Windows Vista 上的 Visual Studio 缓存?

c++ - 插件 DLL 引用的 DLL 的搜索路径

sin 到 std::sin 的 C++ 别名——需要草率的快速修复

c - 如何控制 apache c 模块中的连接

c - 井字游戏 AI 错误

Windows 中的 Linux 内核检查