程序调用BeginPaint时,Windows会适当填入PAINTSTRUCT结构的各个字段值。用户程序只使用前三个字段,其它字段由Windows内部使用。
如果该窗口的窗口类有背景刷,BeginPaint返回前用刷子擦除无效区域的背景。在大多数情况下,fErase被标志为FALSE,这意味着Windows已经擦除了无效矩形的背景。想在窗口过程中自己定义一些背景的擦除,可以处理WM_ERASEBKGN消息。当fErase被标记为TRUE时BeginPaint返回前向窗口发出WM_ERASEBKGN消息。
如果程序通过调用InvalidateRect使客户区中的矩形失效,则该函数的最后一个参数会指定是否擦除背景。如果这个参数为FALSE,则Windows将不会擦除背景,并且在调用完BeginPaint后PAINTSTRUCT结构的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_LINEDOWN,si.nPos就会比iVertPos大,也就是说 iVertPos - si.nPos 的值是 -1,在这个时候ScrollWindow函数会把客户区的内容向上移动一行。当ScrollWindow函数的第三个参数为正数时,该函数会把客户区的内容下移。在一开始谈滚动条的时候就说过,当我们下拉滚动条的时候客户区的内容是向上移动的,一定要注意这一点。(Windows自动将显示区域中未被滚动操作覆盖的矩形设为无效,也就是将滚动所产生的空白区域设为无效。这会产生WM_PAINT消息。)
UpdateWindow函数通知Windows立即刷新客户区。(水平滚动条部分也是同样道理。)
case WM_VSCROLL:中的UpdateWindow函数似乎多余,根据ScrollWindow()函数的描述,滚动后,将会产生WM_PAINT消息。
WM_PAINTT部分
把垂直滚动条和水平滚动条的当前位置分别保存到iVertPos和iHorzPos中。
现在假设,一共有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,这里iVertPos是2,所以正好能在第48行显示50行的内容。iPaintBeg与iPaintEnd也就是数组下标的开始与结束。
进入for循环。这个时候iPaintBeg的值是50,iPaintEnd的值是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不一样。