Bagikan melalui


Cara Melakukan Pengujian Hit pada Tata Letak Teks

Menyediakan tutorial singkat tentang cara menambahkan pengujian hit ke aplikasi DirectWrite yang menampilkan teks dengan menggunakan antarmuka IDWriteTextLayout.

Hasil dari tutorial ini adalah aplikasi yang menggaris bawahi karakter yang diklik oleh tombol mouse kiri, seperti yang ditunjukkan pada cuplikan layar berikut.

cuplikan layar

Ini cara berisi bagian-bagian berikut:

Langkah 1: Buat Tata Letak Teks.

Untuk memulai, Anda memerlukan aplikasi yang menggunakan objek IDWriteTextLayout . Jika Anda sudah memiliki aplikasi yang menampilkan teks dengan tata letak teks, buka Langkah 2.

Untuk menambahkan tata letak teks, Anda harus melakukan hal berikut:

  1. Deklarasikan penunjuk ke antarmuka IDWriteTextLayout sebagai anggota kelas.

    IDWriteTextLayout* pTextLayout_;
    
  2. Di akhir metode CreateDeviceIndependentResources , buat objek antarmuka IDWriteTextLayout dengan memanggil metode CreateTextLayout .

    // Create a text layout using the text format.
    if (SUCCEEDED(hr))
    {
        RECT rect;
        GetClientRect(hwnd_, &rect); 
        float width  = rect.right  / dpiScaleX_;
        float height = rect.bottom / dpiScaleY_;
    
        hr = pDWriteFactory_->CreateTextLayout(
            wszText_,      // The string to be laid out and formatted.
            cTextLength_,  // The length of the string.
            pTextFormat_,  // The text format to apply to the string (contains font information, etc).
            width,         // The width of the layout box.
            height,        // The height of the layout box.
            &pTextLayout_  // The IDWriteTextLayout interface pointer.
            );
    }
    
  3. Kemudian, Anda harus mengubah panggilan ke metode ID2D1RenderTarget::D rawText menjadi ID2D1RenderTarget::D rawTextLayout seperti yang ditunjukkan dalam kode berikut.

    pRT_->DrawTextLayout(
        origin,
        pTextLayout_,
        pBlackBrush_
        );
    

Langkah 2: Tambahkan metode OnClick.

Sekarang tambahkan metode ke kelas yang akan menggunakan fungsionalitas pengujian hit tata letak teks.

  1. Nyatakan metode OnClick dalam file header kelas.

    void OnClick(
        UINT x,
        UINT y
        );
    
  2. Tentukan metode OnClick dalam file implementasi kelas.

     void DemoApp::OnClick(UINT x, UINT y)
     {    
     }
    

Langkah 3: Lakukan Pengujian Hit.

Untuk menentukan di mana pengguna telah mengklik tata letak teks, kita akan menggunakan metode IDWriteTextLayout::HitTestPoint .

Tambahkan yang berikut ini ke metode OnClick yang Anda tentukan di Langkah 2.

  1. Deklarasikan variabel yang akan kami teruskan sebagai parameter ke metode .

    DWRITE_HIT_TEST_METRICS hitTestMetrics;
    BOOL isTrailingHit;
    BOOL isInside; 
    

    Metode HitTestPoint menghasilkan parameter berikut.

    Variabel Deskripsi
    hitTestMetrics Geometri sepenuhnya mencakup lokasi uji hit.
    isInside Menunjukkan apakah lokasi uji klik berada di dalam string teks atau tidak. Saat FALSE, posisi terdekat tepi teks dikembalikan.
    isTrailingHit Menunjukkan apakah lokasi hit-test berada di sisi depan atau di sisi berikutnya dari karakter.
  2. Panggil metode HitTestPoint dari objek IDWriteTextLayout .

    pTextLayout_->HitTestPoint(
                    (FLOAT)x, 
                    (FLOAT)y,
                    &isTrailingHit,
                    &isInside,
                    &hitTestMetrics
                    );
    

    Kode dalam contoh ini meneruskan variabel x dan y untuk posisi tanpa modifikasi apa pun. Ini dapat dilakukan dalam contoh ini karena tata letak teks berukuran sama dengan jendela dan berasal dari sudut kiri atas jendela. Jika ini tidak terjadi, Anda harus menentukan koordinat sehubungan dengan asal tata letak teks.

Langkah 4: Garis bawahi Teks yang Diklik.

Tambahkan yang berikut ini ke OnClick yang Anda tentukan di Langkah 2, setelah panggilan ke metode HitTestPoint .

if (isInside == TRUE)
{
    BOOL underline;

    pTextLayout_->GetUnderline(hitTestMetrics.textPosition, &underline);

    DWRITE_TEXT_RANGE textRange = {hitTestMetrics.textPosition, 1};

    pTextLayout_->SetUnderline(!underline, textRange);
}

Kode ini melakukan hal berikut.

  1. Memeriksa apakah titik uji klik berada di dalam teks menggunakan variabel isInside .

  2. Anggota textPosition dari struktur hitTestMetrics berisi indeks berbasis nol dari karakter yang diklik.

    Mendapatkan garis bawah untuk karakter ini dengan meneruskan nilai ini ke metode IDWriteTextLayout::GetUnderline .

  3. Mendeklarasikan variabel DWRITE_TEXT_RANGE dengan posisi mulai diatur ke hitTestMetrics.textPosition dan panjang 1.

  4. Alihkan garis bawah dengan menggunakan metode IDWriteTextLayout::SetUnderline .

Setelah mengatur garis bawah, gambar ulang teks dengan memanggil metode DrawD2DContent kelas.

DrawD2DContent();

Langkah 5: Tangani pesan WM_LBUTTONDOWN.

Terakhir, tambahkan pesan WM_LBUTTONDOWN ke handler pesan untuk aplikasi Anda dan panggil metode OnClick dari kelas .

case WM_LBUTTONDOWN:
    {
        int x = GET_X_LPARAM(lParam); 
        int y = GET_Y_LPARAM(lParam);

        pDemoApp->OnClick(x, y);
    }
    break;

GET_X_LPARAM dan makro GET_X_LPARAM dideklarasikan dalam file header windowsx.h. Mereka dengan mudah mengambil posisi x dan y dari klik mouse.