Code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
TEXTMETRIC tm;
SCROLLINFO si;
static int cxChar, cyChar, cxCaps;
static int cyClient, cxClient, iMaxWidth;
int i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;
char szBuffer[10];
switch ( iMsg )
{
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 colums
iMaxWidth = 22 * cxCaps + 40 * cxChar; // In Pixels
return 0;
case WM_SIZE :
cyClient = HIWORD(lParam);
cxClient = LOWORD(lParam);
// Set vertical scroll bar range and page size
si.cbSize = sizeof(si);
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 :
// Get all the vertical scroll bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
// Save the position for comparison later
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 :
si.nPos = si.nTrackPos;
break;
default :
break;
}
// Set the position and then retrieve it
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
// If the position has changed, scroll the widow and update it
if ( si.nPos != iVertPos )
{
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL :
// Get all the horizontal bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_HORZ, &si);
// Save the position for comparinson later
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
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.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
// Get Horizontal scroll bar position
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
//-- Can't seem to get how this code below works
// 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,
strlen(sysMetrics[i].szLabel));
TextOut(hdc, x + 22 * cxCaps, y,
sysMetrics[i].szDescr,
strlen(sysMetrics[i].szDescr));
SetTextAlign(hdc, TA_TOP | TA_RIGHT);
TextOut(hdc, x + 22 * cxCaps + 40 * cxChar, y, szBuffer,
sprintf(szBuffer, "%d", GetSystemMetrics(sysMetrics[i].iIndex)));
SetTextAlign(hdc, TA_TOP | TA_LEFT);
}
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
default :
break;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
Thanks in advanced.