在MFC方法中显示非ONPaint的图像

时间:2011-09-27 11:45:02

标签: c++ image mfc device

我正在尝试动态显示对话框中的图像,如果我将代码放在on paint方法并使用dc那里,它就没有问题,我不能这样做虽然我需要在窗口后显示显示,我正在使用的代码如下,我得到客户端窗口的DC从资源创建位图并“尝试”在窗口中显示它但没有任何显示,任何建议可能是什么错误?

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 个答案:

答案 0 :(得分:2)

无法使用OnPaint()的原因尚不清楚。

当需要在某些事件上重绘全部或部分窗口时,通常的策略是调用InvalidateRect()

Windows会依次将WM_PAINT(由您的OnPaint()方法处理)发送到您的应用,指定应该重绘窗口的哪一部分。

答案 1 :(得分:1)

我认为BeginPaint功能还有更多功能,而不仅仅是给你CDC。并且只能从OnPaint方法调用BeginPaint。

要解决您的问题,请使用Invalidate-functions强制从“SetupInstructions”方法重新绘制。然后在OnPaint函数中进行绘制。

答案 2 :(得分:0)

我想CProcessSteps来自CWnd,也许是CDialog?

如果要在CWnd派生类的客户区域中绘图,则必须使用CWnd GetDC方法获取DC。我不明白你为什么要创建自己的CDC,你应该在SetupInstructions的开头获得CWnd DC并在任何地方使用此DC,也可以创建你的memDC

另外,在分配内存(新CStatic)时应该小心,如果不为此变量调用delete,则会出现内存泄漏。如果你真的需要动态创建这个CStatics,你必须保留一个指向所有这些CStatics的指针,以便在关闭对话框/视图之前删除它们。

正如人们所建议的那样,我不认为你是通过使用OnShowWindow绘制正确的方法。您应该使用OnPaint来制作绘图内容,如果您不想在窗口完全初始化之前绘制图像,则应使用窗口的成员变量(例如bool)在构造函数中初始化为false并设置它准备好绘制图像时为true。然后调用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);        

       ...

    }
}

希望它有所帮助。

哈维尔