Visual c++ 写入memDC中的内存位图不会在bitblt、MFC对话框程序后显示

Visual c++ 写入memDC中的内存位图不会在bitblt、MFC对话框程序后显示,visual-c++,mfc,bitblt,Visual C++,Mfc,Bitblt,在我的MFC对话框程序中,我想每2秒更新对话框窗口中的位图。我使用内存位图缓冲区进行绘制,MFC计时器每隔2秒调用一次OnTimer(),并调用UpdateRateGraphics(),后者绘制内存中的位图。 函数的作用是:在必要时使用bitblt()将内存位图复制到屏幕窗口。 初始化在OnInitDialog()中完成。 只要我直接在bitblt之前从OnPaint()中调用绘图函数UpdateRateGraphics(),绘图就可以工作。 当我从timer函数调用drawing函数时(这是我

在我的MFC对话框程序中,我想每2秒更新对话框窗口中的位图。我使用内存位图缓冲区进行绘制,MFC计时器每隔2秒调用一次OnTimer(),并调用UpdateRateGraphics(),后者绘制内存中的位图。 函数的作用是:在必要时使用bitblt()将内存位图复制到屏幕窗口。 初始化在OnInitDialog()中完成。 只要我直接在bitblt之前从OnPaint()中调用绘图函数UpdateRateGraphics(),绘图就可以工作。 当我从timer函数调用drawing函数时(这是我想要的),屏幕上只显示一个来自bitblt的黑色方块,但是位图内容,目前只有一个稍微移动的绿色方块,丢失了。 为什么呢

GlobVars.h:
EXTERN HDC          memDC;                      // Device Context of a memory 
EXTERN HBITMAP      memBitmap;                  // A bitmap to draw onto, will be placed in the memory device context
EXTERN HBITMAP      *memBitmapOld;              // A bitmap to draw onto, will be placed in the memory device context
EXTERN HBRUSH       brush;                      // A GDI brush to define fill color etc.
EXTERN HBRUSH       brushOld;                   //


// Initialization, at the end of OnInitDialog():
CPaintDC    dc(this);
memDC = CreateCompatibleDC(dc.m_hDC);
memBitmap = CreateCompatibleBitmap(dc.m_hDC, 200, 200);
// Select it. An application cannot select a single bitmap into more than one DC at a time.
SelectObject(memDC, memBitmap);



void CmfritzmonDlg::UpdateRateGraphics()
{
    // Setup a GDIO brush object with fill color
    brush = CreateSolidBrush(RGB(0, 0xff, 0));
    // Select it
    brushOld = (HBRUSH) SelectObject(memDC, brush);
    // draw a rectangle using brush and memDC as destination
    Rectangle(memDC, 10, 10, 200, 200);
    SelectObject(memDC, brushOld);
    DeleteObject(brush);

    Invalidate();   // NEW, after adding this, it is working!
}



void CmfritzmonDlg::OnTimer(UINT_PTR nIDEvent)
{
    // cyclically called from SetTimer()
    UpdateRateGraphics();       // when called here, not ok !!!
    CDialogEx::OnTimer(nIDEvent);
}


void CmfritzmonDlg::OnPaint()
{
    if (IsIconic()) {
    } else {
        UpdateRateGraphics();       // When called here, OK !!!
        CPaintDC dc(this);
        BitBlt(dc.m_hDC, 0, 0, 200, 200, memDC, 0, 0, SRCCOPY);
    //  CDialogEx::OnPaint();
    }
}


void CmfritzmonDlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    // Delete Objects for bitmap drawing
    SelectObject(memDC, memBitmapOld);
    DeleteObject(memBitmap);
    DeleteDC(memDC);
}

没有任何代码可以查看。我首先看一下如何在OnTimer()处理程序中获得HDC,但由于没有什么可看的,所以也无话可说。在修改
OnTimer()中的位图后是否需要触发重新绘制<代码>无效安装()
。渲染代码不考虑时间,因此渲染图像不会随时间而更改。即使它被渲染,您也不会注意到任何差异。您需要触发重新绘制,因此确保系统通过调用(或相关成员函数)生成
WM_PAINT
消息;作为UpdateGraphics()的最后一行。感谢您提供的解决方案:)虽然可以在
UpdateRateGraphics()
中调用
Invalidate()
(意思是:我的数据已经更新,现在也更新显示),但我不明白您为什么需要在
OnPaint()
中调用
UpdateRateGraphics()
。绘制请求(
WM_Paint
/
OnPaint()
)可能是由于调整部分(或整个)窗口的大小/移动/取消隐藏等而发生的,并且此类事件也不保证重新计算数据(例如,想象一下,必须从数据库中检索这些数据,这将导致依赖于窗口绘图的访问,当然这不是OK)。请考虑删除此调用。