我做了一个对话框应用程序,我使用OnTimer()函数设置计时器,并有SetTimer(1,750,NULL);但是为什么运行程序时,对话框会偶尔的跳动几下(有点频繁),看起来很不稳定。还有使用了OnTimer()后,我在对话框中添加了一个List Control也不能正常运行,当所加载的Item的行数超过List Control框的上端到下端的长度是就会,整个对话框就会跳个不停!List Control几乎就无法显示,只剩下两个滚动条在不停的闪!下面是我对上面两个函数的应用,可以看一下!!!!!int ChildDialog1::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
SetTimer(1, 750, NULL);
return 0;
}
void ChildDialog1::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
cir=(cir+1)%16;
Invalidate();
CDialog::OnTimer(nIDEvent);
}

解决方案 »

  1.   

    Ontimer里面不要调用Invalidate去刷新。
    没调用一次Invalidate,画面控件都会重画的
      

  2.   

    开个线程吧全局变量定义:
    UINT ThreadProc(LPVOID pParam);
    BOOL ThreadFlag = FALSE;
    CWinThread *g_pThread = NULL;启动线程:
    ThreadFlag = TRUE;
    g_pThread = AfxBeginThread(ThreadProc,NULL);
    g_pThread ->m_bAutoDelete = TRUE;线程函数:
    UINT ThreadProc(LPVOID pParam)
    { while (TRUE == ThreadFlag)
    {
    //你的代码
    } return 0;
    }退出线程:
    ThreadRecvFromACUFlag = FALSE;
    if (NULL != g_pThread)
    {
    WaitForSingleObject(g_pThread->m_hThread,INFINITE);
    g_pThread = NULL;}
      

  3.   

    退出线程的:
    ThreadRecvFromACUFlag = FALSE; 
    改为
    ThreadFlag = FALSE;
      

  4.   

    Invalidate(); 
    换成InvalidateRect试
      

  5.   

    Invalidate()之后:(MFC的,顺便了)
    OnPaint()->OnPrepareDC()->OnDraw()
    所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以不管Invalidate放哪里,都是最后的。InvalidateRect(hWnd,&rect,TRUE);向hWnd窗体发出WM_PAINT的消息,强制客户区域重绘制,
    rect是你指定要刷新的区域,此区域外的客户区域不被重绘,这样防止客户区域的一个局部的改动,而导致整个客户区域重绘而导致闪烁,如果最后的参数为TRUE,则还向窗体发送WM_ERASEBKGND消息,使背景重绘,当然在客户区域重绘之前。
    UpdateWindow()只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow,如果客户区的任一部分无效,则UpdateWindow将导致Windows用WM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow调用之后的语句。
      

  6.   

    1.你刷新的频率太高了,
    2.贴你的绘图相关的代码,OnPaint中的代码
      

  7.   

    不停调用Invalidate()当然会闪烁了,整个对话框持续刷新,由于时间间隔太短,根本来不及显示就又刷新了,所以显示不出来是很正常的.不知道你的程序是干什么用的,可以改变程序显示方式,不如局部覆盖,或者用内存DC画图显示等方法.
      

  8.   

    你不是问过这个问题吗?单文档、要在视图上移动一个BMP的图片?不是用BitBlt 解决了吗?
    不要用 Invalidate();贴下代码!
    void CView::OnTimer(UINT nIDEvent) 
    {
    cir+=1; 
    CDC *pDC = GetDC(); 
    CDC& dc = *pDC; 
    CDC memDc; 
    memDc.CreateCompatibleDC(&dc); 
    CBitmap* pOld=(CBitmap*)memDc.SelectObject(&ball); 
    dc.BitBlt(cx,cy,24,24,&memDc,0,0,SRCCOPY); 
    memDc.SelectObject(pOld); 
    memDc.DeleteDC();
    ReleaseDC(pDC);

    CView::OnTimer(nIDEvent);
    }ball为全局变量
    CBitmap ball; 
    ball.LoadBitmap(IDB_BITMAP1)
      

  9.   

    完善下,擦除影子//擦除
    RECT ret;
    ret.left=cx;
    ret.top=cy;
    ret.right=cx+1;
    ret.bottom=cy+24;
    InvalidateRect(&ret); cx+=1; 
    CDC *pDC = GetDC(); 
    CDC& dc = *pDC; 
    CDC memDc; 
    memDc.CreateCompatibleDC(&dc); 
    CBitmap* pOld=(CBitmap*)memDc.SelectObject(&ball); 
    dc.BitBlt(cx,cy,24,24,&memDc,0,0,SRCCOPY); 
    memDc.SelectObject(pOld); 
    memDc.DeleteDC();
    ReleaseDC(pDC);
      

  10.   

    Invalidate(); 
    改成
    Invalidate(FALSE); // 重绘时不擦除背景
    就不闪了
      

  11.   

    OnTimer里面不断Invalidate(); 当然要闪。用UpdateData(FALSE)就不闪了。