【解決方法】私のコードでは、ちらつきを防ぐためにダブルバッファリングを使用しているのに、何も表示されずに完全に黒いウィンドウクライアント領域の色が生成されるのはなぜですか。


ちらつきを防ぐためにプログラムのメインウィンドウでダブルバッファリング方法を使用していますが、代わりにウィンドウのクライアント領域が完全に真っ黒になってしまいます。 何が問題なのでしょうか。

関連するコードを以下に示します。
WriteDatah 関​​数は実際のアプリケーションの実際の部分ではないことに注意してください。 新しいプロジェクトを作成し、問題のあるコードをそこに導入して、問題が間違っていたことを確認しました。 WriteData は Funinality における実際のコードを表します。 この新しいテスト アプリケーションでは、ダブル バッファリングが適切に行われていない、またはマッピング モードがダブル バッファリングと競合しているかのどちらかに問題を絞り込むことができました。 どう思いますか。

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;

次のコードは、ID_DRAW_DRAW_TEXT の ID を持つメニュー項目によって起動されます。 したがって、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);
    
}

私が試したこと:

一日中デバッグをしていました。 私もかなりの量のグーグルをしています。

解決策 1

最初に見ると、描画のペンとブラシの色は指定されていません。

解決策 2

私はこのクラスを使用しました: MFC でのちらつきのない描画[^] 長年にわたって、本当にうまく機能しています。 非 MFC バージョンも作成し、何度か使用しました。 コードは MFC を使用していないようですが、原理は同じです。 主にメッセージの処理がすべてです WM_PAINT。 しかし、 WM_ERASEBACKGND これも true を返すだけで処理する必要があります。 記事を注意深く読んで、間違ったことをしていないかどうかを確認することをお勧めします。

MFC 以外のバージョンを見たい場合はお知らせください。ここに投稿します。 CDC メソッドの代わりに GDI 呼び出しを使用する点を除けば、基本的に MFC バージョンと同じです。

コメント

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