Aracılığıyla paylaş


Metin Kaydırma

Bu bölümde, kullanıcının metni kaydırmasını sağlamak için uygulamanın ana pencere yordamında yapabileceğiniz değişiklikler açıklanmaktadır. Bu bölümdeki örnek, bir dizi metin dizesi oluşturup görüntüler ve kullanıcının metni hem dikey hem de yatay olarak kaydırabilmesi için WM_HSCROLL ve WM_VSCROLL kaydırma çubuğu iletilerini işler.

Bilmeniz gerekenler

Teknolojileri

Önkoşullar

  • C/C++
  • Windows Kullanıcı Arabirimi Geliştirme

Talimat

WM_CREATE İletisini İşleme

Kaydırma birimleri genellikle WM_CREATE iletisi işlenirken ayarlanır. Kaydırma birimlerini pencerenin cihaz bağlamıyla (DC) ilişkili yazı tipinin boyutlarına dayandırmak uygundur. Belirli bir DC'nin yazı tipi boyutlarını almak için GetTextMetricsişlevini kullanın.

Bu bölümdeki örnekte, bir dikey kaydırma birimi, bir karakter hücresinin yüksekliği artı dış boşluk ile eşdeğerdir. Yatay kaydırma birimi, karakter hücresinin ortalama genişliğine eşdeğerdir. Bu nedenle, ekran yazı tipi sabit genişlikli olmadığı sürece yatay kaydırma konumları gerçek karakterlere karşılık gelmez.

WM_SIZE İletisini İşleme

WM_SIZE iletisini işlerken, kaydırma aralığını ve kaydırma konumunu istemci alanının boyutlarını ve görüntülenecek metin satırlarının sayısını yansıtacak şekilde ayarlamak uygundur.

SetScrollInfo işlevi en düşük ve en yüksek konum değerlerini, sayfa boyutunu ve kaydırma çubuğunun kaydırma konumunu ayarlar.

WM_HSCROLL ve WM_VSCROLL İletilerini İşleme

Kaydırma çubuğu, kullanıcı kaydırma çubuğuna tıklayışında veya kaydırma kutusunu sürüklerken pencere yordamına WM_HSCROLL ve WM_VSCROLL iletileri gönderir. WM_VSCROLL ve WM_HSCROLL düşük sıralı sözcükleri, kaydırma eyleminin yönünü ve büyüklüğünü gösteren bir istek kodu içerir.

WM_HSCROLL ve WM_VSCROLL iletileri işlendiğinde kaydırma çubuğu istek kodu incelenir ve kaydırma artışı hesaplanır. Artış geçerli kaydırma konumuna uygulandıktan sonra, ScrollWindowEx işlevi kullanılarak pencere yeni konuma kaydırılır ve kaydırma kutusunun konumu SetScrollInfo işlevi kullanılarak ayarlanır.

Bir pencere kaydırıldıktan sonra istemci alanının bir bölümü geçersiz hale getirilir. Geçersiz bölgenin güncelleştirildiğinden emin olmak için UpdateWindow işlevi WM_PAINT iletisi oluşturmak için kullanılır.

WM_PAINT İletisini İşleme

WM_PAINT iletisini işlerken, pencerenin geçersiz bölümünde görünmesini istediğiniz metin satırlarını çizmek kullanışlıdır. Aşağıdaki örnek, geçerli kaydırma konumunu ve geçersiz bölgenin boyutlarını kullanarak, bunları görüntülemek için geçersiz bölge içindeki satır aralığını belirler.

Kaydırma Metni Örneği

Aşağıdaki örnek, istemci alanında metin görüntüleyen bir pencere için bir pencere yordamıdır. Bu örnek, metni yatay ve dikey kaydırma çubuklarından gelen girişe yanıt olarak nasıl kaydırabileceğinizi gösterir.

#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);
}

Kaydırma Çubuklarını Kullanma

Windows ortak denetimler tanıtımı (CppWindowsCommonControls)