鱼C论坛

 找回密码
 立即注册
查看: 2984|回复: 1

[知识点备忘] 第031讲:随机矩形

[复制链接]
发表于 2016-3-13 03:14:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
知识点回顾:

1. PeekMessage 函数

一直以来,我们都是使用 GetMessage 函数为主导的这个循环来处理程序的消息队列。但 GetMessage 函数有一个问题,就是它比较执着……因为当消息队列中如果没有消息了,它也会一直在那等待,直到获取消息才返回。本来这也没什么问题,因为 Windows 的核心理念就是“Don’t call me, I will call you.”,我们只需要写好回调函数,然后等着消息触发来调用即可。

不过在有些时候,我们倒是希望应用程序能在空闲时做一些“业余”的事情。也就是说,当消息队列为空的时候,让我们的应用程序也可以执行一些操作。由于 GetMessage 函数会一直等到获取消息才交出控制权。所以,我们应该使用另外一个函数来代替。没错,就是 PeekMessage 函数。

PeekMessage 函数的一个特点就是无论是否从消息队列中获取消息,它总是立即返回。我们通过观察它的返回值来判断是否获取得到消息:如果返回值是非 0,那么说明已经从消息队列中取得消息;如果返回值为 0,则说明此时消息队列为空。


2. 使用 PeekMessage 函数改造消息循环

  1. ……
  2.         while (TRUE)
  3.         {
  4.         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))  // 偷窥
  5.         {
  6.             if (msg.message == WM_QUIT)
  7.                 break;
  8.             TranslateMessage(&msg);
  9.             DispatchMessage(&msg);
  10.         }
  11.         else
  12.         {
  13.             // 让程序空闲时执行的代码
  14.         }
  15.         }
  16. ……
复制代码

解释一下:

首先我们构造一个条件永远为真的死循环,因为 PeekMessage 函数不会因为接收到退出消息就返回 FALSE。所以我们后边需要明确检测 WM_QUIT 消息,如果拿到的消息是 WM_QUIT,则使用break语句退出循环,否则转换并分派消息。


3. 利用 PeekMessage 函数生成随机矩形

  1. #include <windows.h>
  2. #include <stdlib.h>        

  3. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  4. void DrawRectangle (HWND) ;
  5.         
  6. int cxClient, cyClient ;
  7. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  8.                    PSTR szCmdLine, int iCmdShow)
  9. {
  10.     ……
  11.     while (TRUE)
  12.     {
  13.         if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
  14.         {
  15.             if (msg.message == WM_QUIT)
  16.                 break ;
  17.             TranslateMessage (&msg) ;
  18.             DispatchMessage (&msg) ;
  19.         }
  20.         else
  21.             DrawRectangle (hwnd) ;
  22.     }
  23.         
  24.     return msg.wParam ;
  25. }
  26.         

  27. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  28. {
  29.     switch (iMsg)
  30.     {
  31.     case WM_SIZE:
  32.         cxClient = LOWORD (lParam) ;
  33.         cyClient = HIWORD (lParam) ;
  34.         return 0 ;
  35.         
  36.         
  37.         
  38.     case WM_DESTROY:
  39.         PostQuitMessage (0) ;
  40.         return 0 ;
  41.     }
  42.         
  43.     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  44. }
  45.         
  46. void DrawRectangle (HWND hwnd)
  47. {
  48.     HBRUSH hBrush ;
  49.     HDC hdc ;
  50.     RECT rect ;
  51.         
  52.     if (cxClient == 0 || cyClient == 0)
  53.         return ;
  54.         
  55.     SetRect (&rect, rand () % cxClient, rand () % cyClient,
  56.                       rand () % cxClient, rand () % cyClient) ;
  57.         
  58.     hBrush = CreateSolidBrush (
  59.           RGB (rand () % 256, rand () % 256, rand () % 256)) ;
  60.         
  61.     hdc = GetDC (hwnd) ;
  62.     FillRect (hdc, &rect, hBrush) ;
  63.         
  64.     ReleaseDC (hwnd, hdc) ;
  65.     DeleteObject (hBrush) ;
  66. }
复制代码

33.png

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-4-9 22:39:39 | 显示全部楼层
谢谢小甲鱼
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-23 19:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表