Отображение изображения в методе MFC, который не ONPaint - PullRequest
0 голосов
/ 27 сентября 2011

Я пытаюсь отобразить изображение в диалоговом окне динамически, это не проблема, если я помещаю код в метод on paint и использую оттуда постоянный ток, я не могу этого сделать, хотя мне нужно отобразить после окнапоказано, код, который я использую, выглядит следующим образом, я получаю постоянный ток окна клиента, создавая растровое изображение из ресурса и «пытаюсь» отобразить его в окне, но ничего не отображается. Есть предложения, что может быть не так?*

void CProcessSteps::OnShowWindow(BOOL bShow, UINT nStatus) 
{
    CDialog::OnShowWindow(bShow, nStatus);  

    SetupInstructions();<-----------------Call To Method
}




void CProcessSteps::OnPaint() 
{   
    CPaintDC dc(this);
}

void CProcessSteps::SetupInstructions()
{
    CDC *pDC = new CDC();<------------------------------Problem starts here
    CFontUtil cfu;
    cfu.SetFont(&LineFont,30);

    CDC memDC;
    memDC.CreateCompatibleDC(pDC);

    int stepTop = 10;
    int stepEnd = 230;
    int imageLeft = 30;
    STEP_STRUCT* step;

    CBitmap iconImage;
    iconImage.LoadBitmap ( IDB_TID_CHECK );

    memDC.SelectObject(&iconImage);

    CRect iconRect;
    BITMAP bmInfo;
    iconImage.GetObject ( sizeof ( bmInfo ), &bmInfo );
    iconRect.SetRect ( imageLeft, stepTop, imageLeft+bmInfo.bmWidth, stepTop+bmInfo.bmHeight );

    pDC = this->GetDC();
    pDC->BitBlt(imageLeft, stepTop, imageLeft+bmInfo.bmWidth, stepTop+bmInfo.bmHeight, &memDC, 0, 0, SRCCOPY);

    //RedrawWindow();<-------- tried this here no luck

    int stepCount = m_pageStructure->PageSteps.GetCount();<----------------------------Bellow this works correctly

    POSITION pos = m_pageStructure->PageSteps.GetHeadPosition();
    while (pos)
    {
        step = m_pageStructure->PageSteps.GetNext(pos);

        CStatic *label = new CStatic;
        label->Create(_T( step->StepInstruction ),WS_CHILD | WS_VISIBLE, CRect(80, stepTop, 480, stepEnd), this);
        label->SetFont(&LineFont, true);


        label->GetWindowRect(rect);
        ScreenToClient(rect);

        pDC = label->GetDC();
        pDC->SelectObject(&LineFont);
        pDC->DrawText(step->StepInstruction, &rect, DT_CALCRECT|DT_WORDBREAK); 
        label->ReleaseDC(pDC);
        label->MoveWindow(rect);    

        stepTop += rect.Height();
        stepTop += 30;
        stepEnd += rect.Height();
    }
}

Ответы [ 3 ]

2 голосов
/ 27 сентября 2011

Причины, по которым вы не можете использовать OnPaint (), неясны.

Обычная стратегия, когда нужно перерисовать все или часть окна при каком-либо событии, заключается в вызове InvalidateRect () .

Windows, в свою очередь, отправит WM_PAINT (обработано вашим OnPaint() методом) вашему приложению, указав, какая часть окна должна быть перерисована.

1 голос
/ 27 сентября 2011

Я думаю, что в функции BeginPaint есть нечто большее, чем просто предоставление вам CDC. А BeginPaint можно вызывать только из OnPaint-метода.

Чтобы решить вашу проблему, используйте Invalidate-функции для принудительного перерисовки из вашего метода «SetupInstructions». Затем сделайте рисование внутри функции OnPaint.

0 голосов
/ 28 сентября 2011

Полагаю, CProcessSteps происходит от CWnd, возможно, от CDialog?

Если вы хотите нарисовать в клиентской области производного класса CWnd, вы должны получить DC, используя метод CWnd GetDC,Я не понимаю, почему вы создаете свой собственный CDC, вы должны получить CWnd DC в начале SetupInstructions и использовать этот DC везде, также для создания вашего memDC.

Также вам следуетбудьте осторожны, когда вы выделяете память (новый CStatic), если вы не вызываете delete для этих переменных, у вас будут утечки памяти.Если вам действительно нужно динамически создавать эти CStatics, вам нужно будет сохранить указатель на все из них, чтобы удалить их, прежде чем закрывать диалоговое окно / представление.

Как и предполагали люди, я не думаю, что вы следуетеправильный путь рисования с использованием OnShowWindow.Вы должны использовать OnPaint, чтобы сделать ваши вещи для рисования, если вы не хотите рисовать изображение, пока окно полностью не инициализировано, вы должны использовать переменную-член окна (например, bool), инициализированную в false в конструкторе, и установить егоистина, когда вы готовы нарисовать изображение.Затем вызов Invalidate нарисует изображение.Что-то вроде:

В .h:

class CProcessSteps : CDialog
{
   ...

private:
   bool m_bReadyToDraw;
}; 

В .cpp:

CProcessSteps::CProcessSteps() : CDialog()
{ 
   m_bReadyToDraw = false;
}

BOOL CProcessSteps::OnInitDialog() 
{
   CDialog:OnInitDialog();

   m_bReadyToDraw = true;

   return TRUE;
}
void CProcessSteps::OnPaint() 
{   
    CPaintDC dc(this);

    if(m_bReadyToDraw)
    {
       CFontUtil cfu;
       cfu.SetFont(&LineFont,30);

       CDC memDC;
       memDC.CreateCompatibleDC(&dc);        

       ...

    }
}

Надеюсь, это поможет.

Хавьер

...