您的位置:首页 > 其它

第四章 输出文字part2

2009-11-16 12:52 267 查看
4.4建立更好的滚动:

Win32 API介绍的两个滚动条函数称作SetScrollInfo和GetScrollInfo。这些函数可以完成以前函数的全部功能,并增加了两个新特性。

SetScrollInfo (hwnd, iBar, &si, bRedraw) ;
GetScrollInfo (hwnd, iBar, &si) ;

Bar参数是SB_VERT或SB_HORZ,它还可以是用于滚动条控制的SB_CTL。SB是通知码的前缀。SetScrollInfo的最后一个参数可以是TRUE或FALSE,指出了是否要Windows重新绘制计算了新信息后的滚动条。

两个函数的第三个参数是SCROLLINFO结构,定义为:
typedef struct tagSCROLLINFO
{
UINT cbSize ;// set to sizeof (SCROLLINFO)
UINT fMask ; // values to set or get
int nMin ; // minimum range value
int nMax ; // maximum range value
UINT nPage ; // page size
int nPos ; // current position
int nTrackPos ;// current tracking position
}
SCROLLINFO, * PSCROLLINFO ;
WM_VSCROLL程序拦截SB_THUMBTRACK消息并忽略SB_THUMBPOSITION。
WM_HSCROLL处理拦截SB_THUMBPOSITION通知码并忽略SB_THUMBTRACK。

#include <windows.h>
#include "sysmets.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("SysMets3");
HWND  hwnd;
MSG   msg;
WNDCLASS    wndclass;

wndclass.style        = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc  = WndProc ;
wndclass.cbClsExtra   = 0 ;
wndclass.cbWndExtra   = 0 ;
wndclass.hInstance    = hInstance ;
wndclass.hIcon        = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor      = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName= szAppName;

if (!RegisterClass (&wndclass))
{
MessageBox(NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 3"),
WS_OVERLAPPEDWINDOW  |  WS_VSCROLL  |
WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
HDC hdc;
int i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
PAINTSTRUCT ps;
SCROLLINFO  si;
TCHAR       szBuffer[10];
TEXTMETRIC  tm;

switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
cyChar = tm.tmHeight + tm.tmExternalLeading ;

ReleaseDC(hwnd, hdc);
// Save the width of the three columns
iMaxWidth = 40 * cxChar + 22 * cxCaps;
return 0;

case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);

// Set vertical scroll bar range and page size
si.cbSize          = sizeof (si);//结构的大小
//SIF_RANGE复制滚动范围到由lpsi指向的SCROLLINFO结构的nMin和nMax成员中。
//SIF_PAGE旗标能够取得页面大小
si.fMask           = SIF_RANGE | SIF_PAGE;
si.nMin            = 0 ;
si.nMax            = NUMLINES - 1;
si.nPage           = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
// Set horizontal scroll bar range and page size
si.cbSize          = sizeof (si);
si.fMask           = SIF_RANGE | SIF_PAGE;
si.nMin			   = 0;
si.nMax            = 2 + iMaxWidth / cxChar;
si.nPage           = cxClient / cxChar;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;

case WM_VSCROLL:
//取得所有的垂直滚动条信息
si.cbSize          = sizeof (si);
si.fMask           = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
// Save the position for comparison later on
iVertPos = si.nPos;
switch (LOWORD (wParam))
{
case SB_TOP:
si.nPos = si.nMin;
break;
case SB_BOTTOM:
si.nPos = si.nMax;
break;
case SB_LINEUP:
si.nPos -= 1;
break;
case SB_LINEDOWN:
si.nPos += 1;
break;
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
//SCROLLINFO结构的nTrackPos字段将指出目前的32位的卷动方块位置
si.nPos = si.nTrackPos;
break;
default:
break;
}
// Set the position and then retrieve it.   Due to adjustments
//    by Windows it may not be the same as the value set.
si.fMask = SIF_POS;//是SIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的组合。
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);

// If the position has changed, scroll the window and update it
if (si.nPos != iVertPos)
{
//在窗口的显示区域中卷动信息而不是重画它
//函数的第二个参数给出了水平卷动显示区域的数值,第三个参
//数是垂直卷动显示区域的数值,单位都是图素。
//最后两个参数设定为NULL,这指出了要卷动整个显示区域
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL);
//ScrollWindow不是GDI函数,因为它不需设备内容句柄。
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof(si);
si.fMask  = SIF_ALL;//是SIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的组合。
// Save the position for comparison later on
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
switch (LOWORD (wParam))
{
case SB_LINELEFT:
si.nPos -= 1;
break;
case SB_LINERIGHT:
si.nPos += 1;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBPOSITION:
si.nPos = si.nTrackPos;
break;
default:
break;
}
// Set the position and then retrieve it.   Due to adjustments
//      by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &si);
// If the position has changed, scroll the window
if (si.nPos != iHorzPos)
{
ScrollWindow(hwnd, cxChar * (iHorzPos - si.nPos), 0,
NULL, NULL);
}
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// Get vertical scroll bar position
si.cbSize = sizeof (si);
si.fMask  = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;

// Get horizontal scroll bar position
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
// Find painting limits
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(NUMLINES - 1,
iVertPos + ps.rcPaint.bottom / cyChar);

for (i = iPaintBeg ; i <= iPaintEnd ; i++)
{
x = cxChar * (1 - iHorzPos);
y = cyChar * (i - iVertPos);

TextOut (hdc, x, y,
sysmetrics[i].szLabel,
lstrlen (sysmetrics[i].szLabel));

TextOut (hdc, x + 22 * cxCaps, y,
sysmetrics[i].szDesc,
lstrlen (sysmetrics[i].szDesc));
SetTextAlign (hdc, TA_RIGHT | TA_TOP);
TextOut (hdc, x + 22 * cxCaps + 40 * cxChar, y, szBuffer,
wsprintf (szBuffer, TEXT ("%5d"),
GetSystemMetrics (sysmetrics[i].iIndex)));

SetTextAlign (hdc, TA_LEFT | TA_TOP);
}
EndPaint (hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: