现在的位置: 首页 > 综合 > 正文

windows程序设计第四章sysmets3程序详解

2018年05月07日 ⁄ 综合 ⁄ 共 2060字 ⁄ 字号 评论关闭

    程序调用BeginPaint时,Windows会适当填入PAINTSTRUCT结构的各个字段值。用户程序只使用前三个字段,其它字段由Windows内部使用。

  如果该窗口的窗口类有背景刷,BeginPaint返回前用刷子擦除无效区域的背景。在大多数情况下,fErase被标志为FALSE,这意味着Windows已经擦除了无效矩形的背景。想在窗口过程中自己定义一些背景的擦除,可以处理WM_ERASEBKGN消息。当fErase被标记为TRUEBeginPaint返回前向窗口发出WM_ERASEBKGN消息。

  如果程序通过调用InvalidateRect使客户区中的矩形失效,则该函数的最后一个参数会指定是否擦除背景。如果这个参数为FALSE,则Windows将不会擦除背景,并且在调用完BeginPaintPAINTSTRUCT结构的fErase字段将为TRUE

 

--------------------------------------------------------------------------------------------------

 

  保存si.Pos变化前的值。

 

  if(si.nPos != iVertPos)

 

  经过switch语句之后,如果si.nPos的值发生了改变,上面的if语句的条件就成了TRUE,然后执行里面的

 

  ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL);

 

  UpdateWindow(hwnd);

 

  ScrollWindow函数的功能是滚动客户区内容。假设滚动条接收到的是SB_LINEDOWNsi.nPos就会比iVertPos大,也就是说 iVertPos - si.nPos 的值是 -1,在这个时候ScrollWindow函数会把客户区的内容向上移动一行。当ScrollWindow函数的第三个参数为正数时,该函数会把客户区的内容下移。在一开始谈滚动条的时候就说过,当我们下拉滚动条的时候客户区的内容是向上移动的,一定要注意这一点。(Windows自动将显示区域中未被滚动操作覆盖的矩形设为无效,也就是将滚动所产生的空白区域设为无效。这会产生WM_PAINT消息。)

 

  UpdateWindow函数通知Windows立即刷新客户区。(水平滚动条部分也是同样道理。)

 

  case WM_VSCROLL:中的UpdateWindow函数似乎多余,根据ScrollWindow()函数的描述,滚动后,将会产生WM_PAINT消息。

 

WM_PAINTT部分

 

  把垂直滚动条和水平滚动条的当前位置分别保存到iVertPosiHorzPos中。

 

  现在假设,一共有75行信息(0行到74)需要显示,客户区能显示50(0行到49)。滚动条原来的位置是0

 

  用户把滚动条向下移动了两行,也就是说客户区的信息要向上移动两行,这个时候第0行、第1行已经看不见了,客户区顶部显示的是第2行的信息,而原来显示在客户区最后一行的第49行升到第47行了。这个时候第48行,第49行变成了空白区域。

 

  ps.rcPaint.top 是该空白区域的左上角坐标。

 

  ps.rcPaint.top / cyChar 就成了空白区域最上面一行的行数,跟据上面的假设,这是第48行。

 

  客户区内容上移了两行,所以原来48行的位置上应该显示第50行的内容。然后在第49行显示的是第51行的内容。现在客户区显示了第2 ~~~~ 51行的内容。

 

  ps.rcPaint.bottom / cyChar 是空白区域最后一行的显示位置。

 

  iPaintBeg = max (0, iVertPos + ps.rcPaint.top / cyChar);

 

  iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);

 

  为什么要在 ps.rcPaint.top / cyChar 前面加上iVertPos呢?

 

  虽然是第48行,但是要显示的内容是原来第50行的,也就是sysmetrics[50],所以要加上移动的行数iVertPos,这里iVertPos2,所以正好能在第48行显示50行的内容。iPaintBegiPaintEnd也就是数组下标的开始与结束。

 

  进入for循环。这个时候iPaintBeg的值是50iPaintEnd的值是52

 

  y = cyChar * (i - iVertPos);

 

  y的值变成48,因为第50行信息的显示位置是48,然后就是使用TextOut显示文本串了。

 

  要显示的是第i行的内容(sysmetrics[i]),也就是第50行的内容,显示坐标y是第48行的坐标,所以程序将第50行的内容显示到第48行上,以此类推。

 

  x = cxChar * (1 - iHorzPos);

 

  x坐标初始显示位置为7,与SYSMETS2不一样。

抱歉!评论已关闭.