Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Глюк прорисовки текста в первый раз


Автор: ANTON_AL 12.2.2008, 16:14
Доброго дня!


Проблема такая: есть диалог, который выводит картинку. Когда приложение стартует, на диалоге появляется текст "No Frame", который говорит о том, что картинка не загружена.

Этот диалог немодальный и принадлежит главному окну приложения.
Когда главное окно создаётся, в обработчике OnCreate( ) создаётся также этот диалог, и после создания вызывается метод RedrawWindow( ), чтобы его обновить.

Результат первого обновления - вместо текста - белый прямоугольник. Когда происходит второе обновление, например, если изменить размер окна, то текст нормально рисуется.


Что это такое, даже не знаю, как это исправлять ??

Автор: dizzy1984 13.2.2008, 06:31
код OnPaint?

Автор: ANTON_AL 14.2.2008, 16:08
Код

afx_msg void
FrameDialog::OnPaint( )
{    
    //Handle frame resizing. If main window was resized, back buffer will
    //also be resized
    {
        RECT rect;
        this->GetWindowRect( &rect );

        //If sizes of window was changed, recreate back buffer
        if (    rect.right - rect.left != m_BackBuffer.Width() || 
                rect.bottom - rect.top != m_BackBuffer.Height()        )
        {
            m_BackBuffer.Destroy( );
            m_BackBuffer.Create( rect.right - rect.left, rect.bottom - rect.top );
        }
    }

    
    bool bDone = m_BackBuffer.BeginUsing( );
    if ( bDone )
    {
        CPaintDC dc( this );

        
        //If no frame to draw, print "No Frame" to back buffer
        if ( m_pImg == NULL || m_pImg->IsNull() )
        {
            RECT rect;
            this->GetWindowRect( &rect );
            ::OffsetRect( &rect, -rect.left, -rect.top );

            CString strMsg = _T("No Frame");
            COLORREF colorOld = m_BackBuffer.DC()->SetTextColor( RGB(255, 255, 200) );
            m_BackBuffer.DC()->DrawText( strMsg, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER );
            //restore previous color
            m_BackBuffer.DC()->SetTextColor( colorOld );
        }
        else
            this->DrawFrameToBackBuffer( );

        

        RECT rect;
        this->GetWindowRect( &rect );
        
        
        //Present back buffer to front buffer (screen)
        dc.BitBlt(    0, 0, rect.right - rect.left, rect.bottom - rect.top,
                        m_BackBuffer.DC(),
                        0, 0, SRCCOPY );

        
        //Clean back buffer
        m_BackBuffer.Clean( RGB(0, 0, 0) );
    }
    //Release device context of back buffer.
    m_BackBuffer.EndUsing( );
}


m_BackBuffer - это обвёртка вокруг класса CImage, представляет задний буффер. Device Context получается из объекта CImage, который находится внутри объекта m_BackBuffer методом BackBuffer::BeginUsing( );
Код

bool
BackBuffer::BeginUsing( )
{
    //m_Buffer - is CImage class object
    if ( m_Buffer.IsNull() )
        return false;

    //m_pCDC - is a pointer to object of class CDC
    m_pCDC = CDC::FromHandle( m_Buffer.GetDC() );
    return true;
}



m_pImg - это указатель на картинку, которая должна прорисовываться в диалоге, если он нулевой, то рисуем текст "No Frame" ( С которым и есть проблема )

В конце обработчика OnPaint уничтожаем полученный Device Context методом BackBuffer::EndUsing( )
Код

void
BackBuffer::EndUsing( )
{
    if ( m_Buffer.IsNull() )
        return;

    m_Buffer.ReleaseDC( );
    m_pCDC = NULL;
}




Автор: dizzy1984 15.2.2008, 06:54
Код нормальный, только одно предположение - не создается битмап для отрисовки текста "No Frame".  Например, метод create вызывается только из OnPaint, но изменения размеров окна не происходит и соответственно битмап не создается. Так что не помешало бы привести код создания битмапа. 
Замечания по коду:
 afx_msg обычно ставится только в объявлении.
 
Цитата(ANTON_AL @  14.2.2008,  18:08 Найти цитируемый пост)
this->GetWindowRect( &rect );

В моем доме попрошу не выражаться.

//Handle frame resizing. If main window was resized, back buffer will    
//also be resized
Лучше поместить в OnSize, скобочки там не нужны.

Автор: ANTON_AL 15.2.2008, 12:20
Разобрался. Оказывается, что текст прорисовывался, но он был белым на белом фоне текста. Надо было явно установить цвет фона теста методом CDC::SetBkColor(...)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)