Pourquoi mon code produit-il une couleur de zone client de fenêtre entièrement noire sans aucun affichage sur l’utilisation d’une double mise en mémoire tampon pour éviter le scintillement.

la programmation


J’utilise la méthode de double mise en mémoire tampon dans la fenêtre principale de mon programme pour éviter le scintillement, mais j’obtiens à la place une zone client de fenêtre entièrement noire. Quel pourrait être le problème.

Les codes pertinents sont indiqués ci-dessous :
Veuillez noter que la fonction WriteDatah ne fait pas réellement partie de l’application réelle. J’ai créé un nouveau projet et y ai apporté le code problématique afin de comprendre que c’était faux. Les WriteData représentent le code réel en termes de fonctionnalité. Avec cette nouvelle application de test, j’ai pu affiner le problème : soit le double tampon n’est pas correctement effectué, soit le mode de mappage entre en conflit avec celui-ci. Qu’en penses-tu.

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;

Ce code suivant est lancé par l’élément de menu avec l’ID ID_DRAW_DRAW_TEXT. Ainsi, il est géré par 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);
    
}

Ce que j’ai essayé :

J’ai débogué toute la journée. J’ai aussi beaucoup de recherches sur Google.

Solution 1

Dès le premier regard : vous ne précisez pas les couleurs du stylo et du pinceau pour le dessin.

Solution 2

J’ai utilisé cette classe : Dessin sans scintillement dans MFC[^] depuis de nombreuses années et ça marche vraiment bien. J’en ai également écrit une version non-MFC que j’ai utilisée plusieurs fois. Votre code ne semble pas utiliser MFC mais les principes sont les mêmes. Il s’agit avant tout de gérer les messages WM_PAINT. Cependant, WM_ERASEBACKGND doit également être géré en renvoyant simplement true. Je vous recommande de lire attentivement l’article pour voir si vous faites quelque chose de mal.

Faites-moi savoir si vous souhaitez voir la version non-MFC et je la publierai ici. C’est essentiellement la même chose que la version MFC, sauf qu’elle utilise des appels GDI au lieu des méthodes CDC.

コメント

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