WainZhang
人生总有许多巧合,两条平行线也可能会有交汇的一天。 人生总有许多意外,握在手里面的风筝也会突然断了线。 在这个熟悉又陌生的城市中,无助地寻找一个陌生又熟悉的身影。

Painting the Window 绘制窗口

你已经创建了你的窗口。现在你想在里面展示一些东西。在Windows术语中,这被称为painting the window。为了混合隐喻,窗口是一块空白的画布,等待你去填充它。

有时你的程序会启动绘画来更新窗口的外观。其他时候,操作系统会通知你必须重新绘制窗口的一部分。当发生这种情况时,操作系统会向窗口发送一个WM_PAINT的消息。必须绘制的窗口部分称为update region。

首次显示窗口时,必须绘制窗口的整个客户端区域(client area)。因此,你将始终接收到至少一个WM_PAINT消息。

 

 

你只负责绘制客户端区域。周围的框架,包括标题栏,由操作系统自动绘制。在完成客户端区域的绘制之后,你将清除update region,这会告诉操作系统在发生更改之前,不需要再发送一个WM_PAINT消息。

现在假设用户移动了另外一个窗口,使它遮盖了本窗口的一部分。当被遮盖的部分再次可见时,该部分被添加到update region,本窗口将接收到另一个 WM_PAINT消息。

 

 

The update region also changes if the user stretches the window. In the following diagram, the user stretches the window to the right. The newly exposed area on the right side of the window is added to the update region: 如果用户拉伸窗口(stretches the window),更新区域(update region)也会被改变。下图中,用户将窗口拉伸到右边。窗口右侧新暴露的区域被添加到更新区域。

 

 

In our first example program, the painting routine is very simple. It just fills the entire client area with a solid color. Still, this example is enough to demonstrate some of the important concepts. 在我们的第一个示例程序中,绘图的例行步骤非常简单。它只是用纯色(solid color)填充整个客户区域。不过,这个例子足以说明一些重要的概念。

C++

switch (uMsg){

   case WM_PAINT:

   {

        PAINTSTRUCT ps;

        HDC hdc = BeginPaint(hwnd, &ps);                

        // All painting occurs here, between BeginPaint and EndPaint.

        FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

        EndPaint(hwnd, &ps);

    }

    return 0;

}

 

通过调用 BeginPaint函数启动绘画操作。这个函数填充了PAINTSTRUCT结构体,并提供了重新绘制请求的信息。当前更新区域是在PAINTSTRUCTrcPaint成员中给出的。此更新区域是相对于客户端区域定义的。

 

 

在你的绘画代码中,你有两个基本的选择:

  • 绘制整个客户端区域,无视更新区域的大小。在更新区域之外的任何东西都被截断(clipped)。也就是说,操作系统会忽略它。
  • 通过只绘制更新区域内窗口的一部分来优化。

如果你总是绘制整个客户端区域,代码会很简单。如果你有复杂的绘图逻辑,那么跳过更新区域之外的区域会更有效。紧接着的代码使用单一的系统定义的窗口背景色(COLOR_WINDOW)填充了更新区域。COLOR_WINDOW所指示的实际颜色取决于用户当前的配色方案(color scheme.)。

C++

            FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));

 

FillRect的细节在该例子中并不重要,但是第二个参数给出要填充的矩形的坐标。在本例中,我们传入整个更新区域(ps.rcPaint)。在第一个WM_PAINT 消息中,需要绘制整个客户端区域,因此rcPaint将包含整个客户端区域。在随后的WM_PAINT消息中,rcPaint可能包含一个较小的矩形。

FillRect 函数是图形设备接口(GDI)的一部分,它为Windows图形提供了很长时间的动力。在Windows7中,微软推出了一款名为Direct2D的新图形引擎,该引擎支持高性能的图形操作,比如硬件加速。Direct2D可通过Platform Update for Windows Vista获得Windows Vista,也可通过Platform Update for Windows Server 2008获得Windows Server 2008。(GDI仍然得到充分支持)

完成绘制之后,调用 EndPaint函数。此函数会清除更新区域,并向Windows发出窗口已完成绘制的信号。

posted on 2018-07-26 14:15  WainZhang  阅读(431)  评论(0编辑  收藏  举报