Example of Scrolling Text

The following example shows how to have your application scroll text in response to input from the horizontal and vertical scroll bars.

HDC hdc;

PAINTSTRUCT ps;

TEXTMETRIC tm;

SCROLLINFO si;

/* These variables are required to display text. */

static int xClient; /* width of client area */

static int yClient; /* height of client area */

static int xClientMax; /* maximum width of client area */

static int xChar; /* horizontal scrolling unit */

static int yChar; /* vertical scrolling unit */

static int xUpper; /* average width of uppercase letters */

static int xPos; /* current horizontal scrolling position */

static int yPos; /* current vertical scrolling position */

static int xMax; /* maximum horiz. scrolling position */

static int yMax; /* maximum vert. scrolling position */

int xInc; /* horizontal scrolling increment */

int yInc; /* vertical scrolling increment */

int i; /* loop counter */

int x, y; /* horiz. and vert. printing coords */

int FirstLine; /* first line in the invalidated area */

int LastLine; /* last line in the invalidated area */

/* Create an array of lines to display. */

#define LINES 27

static char *abc[] = { "anteater", "bear", "cougar", "dingo",

"elephant", "frog", "gazelle", "hyena", "iguana", "jackal",

"kangaroo", "llama", "moose", "newt", "octopus", "penguin",

"quail", "rat", "squid", "tortoise", "urus", "vole",

"walrus", "xylophone", "yak", "zebra",

"This line contains many words, but no character. Go figure." };

switch (uMsg) {

case WM_CREATE :

/* Get the handle of the client area's device context. */

hdc = GetDC (hwnd);

/* Extract font dimensions from the text metrics. */

GetTextMetrics (hdc, &tm);

xChar = tm.tmAveCharWidth;

xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;

yChar = tm.tmHeight + tm.tmExternalLeading;

/* Free the device context. */

ReleaseDC (hwnd, hdc);

/*

* Set an arbitrary maximum width for client area.

* (xClientMax is the sum of the widths of 48 average

* lowercase letters and 12 uppercase letters.)

*/

xClientMax = 48 * xChar + 12 * xUpper;

return 0;

case WM_SIZE:

/* Retrieve the dimensions of the client area. */

yClient = HIWORD (lParam);

xClient = LOWORD (lParam);

/*

* Determine the maximum vertical scrolling position.

* The two is added for extra space below the lines

* of text.

*/

yMax = max (0, LINES + 2 - yClient/yChar);

/*

* Make sure the current vertical scrolling position

* does not exceed the maximum.

*/

yPos = min (yPos, yMax);

/*

* Adjust the vertical scrolling range and scroll box

* position to reflect the new yMax and yPos values.

*/

si.cbSize = sizeof(si);

si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;

si.nMin = 0;

si.nMax = yMax;

si.nPage = yClient / yChar;

si.nPos = yPos;

SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

/*

* Determine the maximum horizontal scrolling position.

* The two is added for extra space to the right of the

* lines of text.

*/

xMax = max (0, 2 + (xClientMax - xClient)/xChar);

/*

* Make sure the current horizontal scrolling position

* does not exceed the maximum.

*/

xPos = min (xPos, xMax);

/*

* Adjust the horizontal scrolling range and scroll box

* position to reflect the new xMax and xPos values.

*/

si.cbSize = sizeof(si);

si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;

si.nMin = 0;

si.nMax = xMax;

si.nPage = xClient / xChar;

si.nPos = xPos;

SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

return 0;

case WM_PAINT:

/* Prepare the window for painting. */

hdc = BeginPaint(hwnd, &ps);

/*

* Use the current vertical scrolling position and

* coordinates of the invalid rectangle to determine

* the range of new lines that should be drawn in the

* client area.

*/

FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);

LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);

/* Display these lines. */

for (i = FirstLine;i < LastLine;i++) {

x = xChar * (1 - xPos);

y = yChar * (1 - yPos + i);

TextOut (hdc, x, y, abc[i], lstrlen(abc[i]));

}

/* Indicate that painting is finished. */

EndPaint(hwnd, &ps);

break;

case WM_HSCROLL:

switch(LOWORD (wParam)) {

/* User clicked shaft left of the scroll box. */

case SB_PAGEUP:

xInc = -8;

break;

/* User clicked shaft right of the scroll box. */

case SB_PAGEDOWN:

xInc = 8;

break;

/* User clicked the left arrow. */

case SB_LINEUP:

xInc = -1;

break;

/* User clicked the right arrow. */

case SB_LINEDOWN:

xInc = 1;

break;

/* User dragged the scroll box. */

case SB_THUMBTRACK:

xInc = HIWORD(wParam) - xPos;

break;

default:

xInc = 0;

}

/*

* If applying the horizontal scrolling increment does not

* take the scrolling position out of the scrolling range,

* increment the scrolling position, adjust the position

* of the scroll box, and update the window.

*/

if (xInc = max (-xPos, min (xInc, xMax - xPos))) {

xPos += xInc;

ScrollWindowEx (hwnd, -xChar * xInc, 0,

(CONST RECT *) NULL, (CONST RECT *) NULL,

(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);

si.cbSize = sizeof(si);

si.fMask = SIF_POS;

si.nPos = xPos;

SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

UpdateWindow (hwnd);

}

return 0;

case WM_VSCROLL:

switch(LOWORD (wParam)) {

/* User clicked the shaft above the scroll box. */

case SB_PAGEUP:

yInc = min(-1, -yClient / yChar);

break;

/* User clicked the shaft below the scroll box. */

case SB_PAGEDOWN:

yInc = max(1, yClient / yChar);

break;

/* User clicked the top arrow. */

case SB_LINEUP:

yInc = -1;

break;

/* User clicked the bottom arrow. */

case SB_LINEDOWN:

yInc = 1;

break;

/* User dragged the scroll box. */

case SB_THUMBTRACK:

yInc = HIWORD(wParam) - yPos;

break;

default:

yInc = 0;

}

/*

* If applying the vertical scrolling increment does not

* take the scrolling position out of the scrolling range,

* increment the scrolling position, adjust the position

* of the scroll box, and update the window. UpdateWindow

* sends the WM_PAINT message.

*/

if (yInc = max(-yPos, min(yInc, yMax - yPos))) {

yPos += yInc;

ScrollWindow(hwnd, 0, -yChar * yInc,

(CONST RECT *) NULL, (CONST RECT *) NULL,

(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);

si.cbSize = sizeof(si);

si.fMask = SIF_POS;

si.nPos = YPos;

SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

UpdateWindow (hwnd);

}

return 0;

Software for developers
Delphi Components
.Net Components
Software for Android Developers
More information resources
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
Databases for Amazon shops developers
Amazon Categories Database
Browse Nodes Database