Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze sectie worden de wijzigingen beschreven die u kunt aanbrengen in de hoofdvensterprocedure van een toepassing, zodat een gebruiker door tekst kan schuiven. In het voorbeeld in deze sectie wordt een matrix met tekenreeksen gemaakt en weergegeven, en worden WM_HSCROLL en WM_VSCROLL schuifbalkberichten verwerkt, zodat de gebruiker zowel verticaal als horizontaal kan schuiven.
Wat u moet weten
Technologieën
Voorwaarden
- C/C++
- Programmeren van Windows-gebruikersinterface
Aanwijzingen
Het WM_CREATE-bericht verwerken
Scrollunits worden doorgaans ingesteld tijdens het verwerken van het WM_CREATE bericht. Het is handig om de schuifeenheden te baseren op de afmetingen van het lettertype dat is gekoppeld aan de apparaatcontext van het venster (DC). Als u de lettertypeafmetingen voor een specifieke Device Context wilt ophalen, gebruikt u de functie GetTextMetrics.
In het voorbeeld in deze sectie is één verticale schuifeenheid gelijk aan de hoogte van een tekencel, plus externe voorloop. Eén horizontale schuifeenheid is gelijk aan de gemiddelde breedte van een tekencel. De horizontale schuifposities komen daarom niet overeen met werkelijke tekens, tenzij het schermlettertype een vaste breedte heeft.
Het WM_SIZE-bericht verwerken
Bij het verwerken van het WM_SIZE bericht is het handig om het schuifbereik en de schuifpositie aan te passen om de afmetingen van het clientgebied weer te geven, evenals het aantal regels tekst dat wordt weergegeven.
Met de functie SetScrollInfo worden de minimum- en maximumpositiewaarden, het paginaformaat en de schuifpositie voor een schuifbalk ingesteld.
De WM_HSCROLL- en WM_VSCROLL-berichten verwerken
De schuifbalk verzendt WM_HSCROLL en WM_VSCROLL berichten naar de vensterprocedure wanneer de gebruiker op de schuifbalk klikt of het schuifvak sleept. De woorden in lage volgorde van WM_VSCROLL en WM_HSCROLL bevatten elk een aanvraagcode die de richting en grootte van de schuifactie aangeeft.
Wanneer de WM_HSCROLL en WM_VSCROLL berichten worden verwerkt, wordt de aanvraagcode voor de schuifbalk onderzocht en wordt de schuifverhoging berekend. Nadat de increment is toegepast op de huidige schuifpositie, wordt het venster naar de nieuwe positie geschoven met behulp van de functie ScrollWindowEx en wordt de positie van het schuifvak aangepast met behulp van de functie SetScrollInfo.
Nadat een venster is geschoven, wordt een deel van het clientgebied ongeldig gemaakt. Om ervoor te zorgen dat de ongeldige regio wordt bijgewerkt, wordt de functie UpdateWindow- gebruikt om een WM_PAINT bericht te genereren.
Het verwerken van het WM_PAINT-bericht
Wanneer u het WM_PAINT bericht verwerkt, kunt u de tekstregels tekenen die u wilt weergeven in het ongeldige gedeelte van het venster. In het volgende voorbeeld worden de huidige schuifpositie en de afmetingen van de ongeldige regio gebruikt om het bereik van lijnen binnen deze regio te bepalen en weer te geven.
Voorbeeld van het schuiven van tekst
Het volgende voorbeeld is een vensterprocedure voor een venster waarin tekst in het clientgebied wordt weergegeven. In het voorbeeld ziet u hoe u de tekst kunt schuiven als reactie op invoer van de horizontale en verticale schuifbalken.
#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);
}
Verwante onderwerpen