小甲鱼 发表于 2016-3-13 03:14:28

第031讲:随机矩形

知识点回顾:

1. PeekMessage 函数

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

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

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


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

……
        while (TRUE)
        {
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))// 偷窥
      {
            if (msg.message == WM_QUIT)
                break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
      }
      else
      {
            // 让程序空闲时执行的代码
      }
        }
……
解释一下:

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


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

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

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
void DrawRectangle (HWND) ;
      
int cxClient, cyClient ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    ……
    while (TRUE)
    {
      if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
      {
            if (msg.message == WM_QUIT)
                break ;
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
      }
      else
            DrawRectangle (hwnd) ;
    }
      
    return msg.wParam ;
}
      

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    switch (iMsg)
    {
    case WM_SIZE:
      cxClient = LOWORD (lParam) ;
      cyClient = HIWORD (lParam) ;
      return 0 ;
      
      
      
    case WM_DESTROY:
      PostQuitMessage (0) ;
      return 0 ;
    }
      
    return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
      
void DrawRectangle (HWND hwnd)
{
    HBRUSH hBrush ;
    HDC hdc ;
    RECT rect ;
      
    if (cxClient == 0 || cyClient == 0)
      return ;
      
    SetRect (&rect, rand () % cxClient, rand () % cyClient,
                      rand () % cxClient, rand () % cyClient) ;
      
    hBrush = CreateSolidBrush (
          RGB (rand () % 256, rand () % 256, rand () % 256)) ;
      
    hdc = GetDC (hwnd) ;
    FillRect (hdc, &rect, hBrush) ;
      
    ReleaseDC (hwnd, hdc) ;
    DeleteObject (hBrush) ;
}


羽枫 发表于 2017-4-9 22:39:39

谢谢小甲鱼
页: [1]
查看完整版本: 第031讲:随机矩形