Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I det här avsnittet beskrivs de ändringar du kan göra i programmets huvudfönsterprocedur för att göra det möjligt för en användare att bläddra i text. Exemplet i det här avsnittet skapar och visar en matris med textsträngar och processer WM_HSCROLL och WM_VSCROLL rullningslistmeddelanden så att användaren kan rulla text både lodrätt och vågrätt.
Vad du behöver veta
Teknologier
Förutsättningar
- C/C++
- Programmering av Windows-användargränssnitt
Instruktioner
Bearbeta WM_CREATE-meddelandet
Rullningsenheter anges vanligtvis när WM_CREATE-meddelandet bearbetas. Det är praktiskt att basera rullningsenheterna på dimensionerna för teckensnittet som är associerat med fönstrets enhetskontext (DC). Om du vill hämta teckensnittsdimensionerna för en specifik DC använder du funktionen GetTextMetrics.
I det här avsnittet motsvarar en lodrät rullningsenhet höjden på en teckencell, plus externa marginaler. En vågrät rullningsenhet motsvarar den genomsnittliga bredden för en teckencell. De vågräta rullningspositionerna motsvarar därför inte faktiska tecken, såvida inte skärmteckensnittet har fastbredd.
Bearbeta WM_SIZE-meddelandet
När du bearbetar WM_SIZE meddelande är det praktiskt att justera rullningsintervallet och rullningspositionen för att återspegla dimensionerna i klientområdet samt antalet textrader som ska visas.
Funktionen SetScrollInfo anger lägsta och högsta position, sidstorleken och rullningspositionen för en rullningslist.
Bearbeta WM_HSCROLL- och WM_VSCROLL-meddelanden
Rullningslisten skickar WM_HSCROLL och WM_VSCROLL meddelanden till fönsterproceduren när användaren klickar på rullningslisten eller drar rullningsrutan. Lågordningsorden i WM_VSCROLL och WM_HSCROLL innehåller var och en en kod för begäran som anger riktningen och storleken på rullningsåtgärden.
När WM_HSCROLL och WM_VSCROLL meddelanden bearbetas granskas koden för rullningslistbegäran och rullningssteget beräknas. När inkrementet har tillämpats på den aktuella rullningspositionen rullas fönstret till den nya positionen med hjälp av funktionen ScrollWindowEx och rullningsrutans position justeras med hjälp av funktionen SetScrollInfo.
När ett fönster har rullats blir en del av klientområdet ogiltigt. För att säkerställa att den ogiltiga regionen uppdateras används funktionen UpdateWindow för att generera ett WM_PAINT meddelande.
Bearbeta WM_PAINT-meddelandet
När du bearbetar WM_PAINT meddelande är det praktiskt att rita de textrader som du vill ska visas i den ogiltiga delen av fönstret. I följande exempel används den aktuella rullningspositionen och dimensionerna för den ogiltiga regionen för att fastställa radintervallet i den ogiltiga regionen för att visa dem.
Exempel på rullningstext
Följande exempel är en fönsterprocedur för ett fönster som visar text i klientområdet. Exemplet visar hur du rullar texten som svar på indata från de vågräta och lodräta rullningslisterna.
#include "strsafe.h"
LRESULT CALLBACK MyTextWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
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
int i; // loop counter
int x, y; // horizontal and vertical coordinates
int FirstLine; // first line in the invalidated area
int LastLine; // last line in the invalidated area
HRESULT hr;
size_t abcLength; // length of an abc[] item
// Create an array of lines to display.
#define LINES 28
static TCHAR *abc[] = {
TEXT("anteater"), TEXT("bear"), TEXT("cougar"),
TEXT("dingo"), TEXT("elephant"), TEXT("falcon"),
TEXT("gazelle"), TEXT("hyena"), TEXT("iguana"),
TEXT("jackal"), TEXT("kangaroo"), TEXT("llama"),
TEXT("moose"), TEXT("newt"), TEXT("octopus"),
TEXT("penguin"), TEXT("quail"), TEXT("rat"),
TEXT("squid"), TEXT("tortoise"), TEXT("urus"),
TEXT("vole"), TEXT("walrus"), TEXT("xylophone"),
TEXT("yak"), TEXT("zebra"),
TEXT("This line contains words, but no character. Go figure."),
TEXT("")
};
switch (uMsg)
{
case WM_CREATE :
// Get the handle to 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);
// Set the vertical scrolling range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = LINES - 1;
si.nPage = yClient / yChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
// Set the horizontal scrolling range and page size.
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + xClientMax / xChar;
si.nPage = xClient / xChar;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;
case WM_HSCROLL:
// Get all the vertial scroll bar information.
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
// Save the position for comparison later on.
GetScrollInfo (hwnd, SB_HORZ, &si);
xPos = si.nPos;
switch (LOWORD (wParam))
{
// User clicked the left arrow.
case SB_LINELEFT:
si.nPos -= 1;
break;
// User clicked the right arrow.
case SB_LINERIGHT:
si.nPos += 1;
break;
// User clicked the scroll bar shaft left of the scroll box.
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
// User clicked the scroll bar shaft right of the scroll box.
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
// User dragged the scroll box.
case SB_THUMBTRACK:
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 != xPos)
{
ScrollWindow(hwnd, xChar * (xPos - si.nPos), 0, NULL, NULL);
}
return 0;
case WM_VSCROLL:
// Get all the vertial scroll bar information.
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hwnd, SB_VERT, &si);
// Save the position for comparison later on.
yPos = si.nPos;
switch (LOWORD (wParam))
{
// User clicked the HOME keyboard key.
case SB_TOP:
si.nPos = si.nMin;
break;
// User clicked the END keyboard key.
case SB_BOTTOM:
si.nPos = si.nMax;
break;
// User clicked the top arrow.
case SB_LINEUP:
si.nPos -= 1;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
si.nPos += 1;
break;
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// User dragged the scroll box.
case SB_THUMBTRACK:
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_VERT, &si, TRUE);
GetScrollInfo (hwnd, SB_VERT, &si);
// If the position has changed, scroll window and update it.
if (si.nPos != yPos)
{
ScrollWindow(hwnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hwnd);
}
return 0;
case WM_PAINT :
// Prepare the window for painting.
hdc = BeginPaint (hwnd, &ps);
// Get vertical scroll bar position.
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo (hwnd, SB_VERT, &si);
yPos = si.nPos;
// Get horizontal scroll bar position.
GetScrollInfo (hwnd, SB_HORZ, &si);
xPos = si.nPos;
// Find painting limits.
FirstLine = max (0, yPos + ps.rcPaint.top / yChar);
LastLine = min (LINES - 1, yPos + ps.rcPaint.bottom / yChar);
for (i = FirstLine; i <= LastLine; i++)
{
x = xChar * (1 - xPos);
y = yChar * (i - yPos);
// Note that "55" in the following depends on the
// maximum size of an abc[] item. Also, you must include
// strsafe.h to use the StringCchLength function.
hr = StringCchLength(abc[i], 55, &abcLength);
if ((FAILED(hr))|(abcLength == NULL))
{
//
// TODO: write error handler
//
}
// Write a line of text to the client area.
TextOut(hdc, x, y, abc[i], abcLength);
}
// Indicate that painting is finished.
EndPaint (hwnd, &ps);
return 0;
case WM_DESTROY :
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, uMsg, wParam, lParam);
}
Relaterade ämnen