Mengapa kode saya menghasilkan warna area klien jendela yang sepenuhnya hitam tanpa tampilan apa pun menggunakan buffering ganda untuk mencegah kedipan.

pemrograman


Saya menggunakan metode buffering ganda di jendela utama program saya untuk mencegah kedipan, tetapi saya malah mendapatkan area klien jendela yang sepenuhnya hitam. Apa masalahnya.

Kode yang relevan ditunjukkan di bawah ini:
Harap dicatat bahwa Fungsi WriteDatah bukan merupakan bagian sebenarnya dari aplikasi sebenarnya. Saya membuat proyek baru dan membawa kode yang bermasalah ke dalamnya untuk mengetahui apakah ada yang salah. WriteData mewakili kode aktual dalam funinalitas. Dengan aplikasi pengujian baru ini, saya dapat mempersempit masalahnya menjadi buffering ganda yang tidak dilakukan dengan benar atau mode pemetaan bertentangan dengannya. Bagaimana menurutmu.

C++
case WM_CREATE:
    {
        HDC hdc = GetDC(hWnd);

        std::tuple<double, double, int, int> Tuple = GetAppDocumentSize(hWnd, hdc, iPageWidth, iPageHeight);
        iOneMMX = static_cast<int>(Approximate(get<0>(Tuple), 0));
        iOneMMY = static_cast<int>(Approximate(get<1>(Tuple), 0));
        int iWidth = GetSystemMetrics(SM_CXSCREEN);
        int iHeight = GetSystemMetrics(SM_CYSCREEN);
        hMemDC = CreateCompatibleDC(hdc);
        hBitmap = CreateCompatibleBitmap(hdc, iWidth, iHeight);
        hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
        HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
        hOldBrush = (HBRUSH)SelectObject(hMemDC, hBrush);

        ReleaseDC(hWnd,hdc);


        break;
    }
C++
case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            std::tuple<double,double,int,int> Tuple = GetAppDocumentSize(hWnd, hdc, iPageWidth, iPageHeight);
          
            BitBlt(hdc, 0, 0, iPageWidth, iPageHeight, hMemDC, 0, 0, SRCCOPY);

            EndPaint(hWnd, &ps);
        }
        break;

Kode berikut ini dimasukkan ke dalam item menu dengan ID ID_DRAW_DRAW_TEXT. Jadi, ditangani oleh WM_COMMAND.

C++
case ID_DRAW_DRAWTEXT:
            {
                Rectangle(hMemDC, 0, 0, iPageWidth, iPageHeight);
                WriteDatah(hMemDC,iOneMMX,iOneMMY,iPageWidth,iPageHeight);

                InvalidateRect(hWnd, NULL, FALSE);

                break;
            }

C++
HFONT CreateAppFont(int cHeight, int cWeight, DWORD bItalic, int cEscapement, DWORD bUnderline, LPCWSTR pszFaceName)
{
    return CreateFont(cHeight, 0, cEscapement, cEscapement, cWeight, bItalic, bUnderline, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
        CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, pszFaceName);


}
C++
double Approximate(double dNumber, int iDecimalPlaces)
{
    int iMultipier = static_cast<int>(pow(10, iDecimalPlaces));
    dNumber *= iMultipier;

    double dInteger = 0.0;
    double dDecimal = modf(dNumber, &dInteger);

    int Integer = static_cast<int>(dInteger);

    if (dDecimal >= 0.5)
    {
        Integer++;
    }

    double dResult = Integer / iMultipier;

    return dResult;
}
C++
void WriteDatah(HDC hdc,int iOneMMX,int iOneMMY,int iPageWidth,int iPageHeight)
{
    UNREFERENCED_PARAMETER(iPageHeight);

    std::wstring wstData = L"Jesus is Lord of the Nations";
    
    int iOneINCHY = GetDeviceCaps(hdc, LOGPIXELSY);
    double dOneFontPOINT = (double)iOneINCHY / 72.0;
    int iOneFontPOINT = static_cast<int>(Approximate(dOneFontPOINT, 0));

    int iFontSize = 10 * iOneFontPOINT;

    HFONT hFont = CreateAppFont(iFontSize, FW_BOLD);
    HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);

    int iLeft = 10 * iOneMMX;
    int iTop = 10 * iOneMMY;

    SIZE size;
    GetTextExtentPoint32(hdc, wstData.c_str(), lstrlen(wstData.c_str()), &size);
    TEXTMETRIC tm;
    GetTextMetrics(hdc, &tm);

    for (int i = 0; i < 100; i++)
    {
        TextOut(hdc, iLeft, iTop, wstData.c_str(), lstrlen(wstData.c_str()));

        iTop += tm.tmHeight + tm.tmExternalLeading;

    }
      
       


    SelectObject(hdc, hOldFont);
    
}

Apa yang saya coba:

Saya telah melakukan debug sepanjang hari. Saya juga punya cukup banyak googling.

Solusi 1

Dari tampilan pertama: Anda tidak menentukan warna pena dan kuas untuk gambar.

Solusi 2

Saya telah menggunakan kelas ini: Gambar Bebas Flicker Di MFC[^] selama bertahun-tahun dan itu bekerja dengan sangat baik. Saya juga menulis versi non-MFC yang telah saya gunakan beberapa kali. Kode Anda tampaknya tidak menggunakan MFC tetapi prinsipnya sama. Ini semua tentang penanganan pesan, terutama WM_PAINT. Namun, WM_ERASEBACKGND juga perlu ditangani dengan hanya mengembalikan true. Saya menyarankan Anda membaca artikel tersebut dengan cermat untuk mengetahui apakah Anda melakukan kesalahan.

Beri tahu saya jika Anda ingin melihat versi non-MFC dan saya akan mempostingnya di sini. Ini pada dasarnya sama dengan versi MFC kecuali menggunakan panggilan GDI dan bukan metode CDC.

コメント

タイトルとURLをコピーしました