按照网上的代码,我继承了CStatic,实现了一个可以使背景色透明的子类CTransStatic。我现在用一个timer,每0.1秒让CTransStatic换一张图片,但是我发现可以明显地看到图片刷新。请问有什么办法能让换图的过程看上去比较流畅么?PS:
显示的是bitmap图片。
没有用LoadImage来取得HBITMAP,因为发现使用LoadImage刷新的更严重,而是使用的网上一段显示jpg图片的代码。如下:
HBITMAP LoadJPG(const   char   *FileName)   
{   
    IPicture*   p=NULL;   
    IStream*   s=NULL;   
    HGLOBAL   hG;   
    void*   pp;   
    FILE*   fp;   
    
    //   Read   file   in   memory   
    fp   =   fopen(FileName,"rb");   
    if   (!fp)   
        return   NULL;   
    
    fseek(fp,0,SEEK_END);   
    int   fs   =   ftell(fp);   
    fseek(fp,0,SEEK_SET);   
    hG   =   GlobalAlloc(GPTR,fs);   
    if   (!hG)   
    {   
        fclose(fp);   
        return   NULL;   
    }   
    pp   =   (void*)hG;   
    fread(pp,1,fs,fp);   
    fclose(fp);   
    
    CreateStreamOnHGlobal(hG,false,&s);   
    if   (!s)   
    {   
        GlobalFree(hG);   
        return   NULL;   
    }   
    
    OleLoadPicture(s,0,false,IID_IPicture,(void**)&p);   
    
    if   (!p)   
    {   
        s->Release();   
        GlobalFree(hG);   
        return   NULL;   
    }   
    
    s->Release();   
    GlobalFree(hG);   
    
    HBITMAP   hB   =   0;   
    p->get_Handle((unsigned   int*)&hB);   
    
    //   Copy   the   image.   Necessary,   because   upon   p's   release,   
    //   the   handle   is   destroyed.   
    HBITMAP   hBB   =   (HBITMAP)CopyImage(   hB,IMAGE_BITMAP,0,0,LR_COPYRETURNORG   );   
    
    p->Release();   
    return   hBB;   
}

解决方案 »

  1.   

    我对界面不是很熟悉,不太明白你的意思,呵呵。我希望能够顺畅的播放n张图片,但不知道使用的方法是否得当,比如:
    是否应该使用多个图片,还是应该将多个图片拼接成一张大图
    是否应该用 CStatic控件实现这一个功能
    等等。
      

  2.   

       CMyStatic::OnPaint()     
          {
           static int i=0;    //用于控制切换位图        CPaintDC dc(this);
            CDC memoDC;
    memoDC.CreateCompatibleDC(&dc);
    CBitmap bitmap,*oldBitmap;
    oldBitmap=NULL;
    BITMAP bmp;
    bitmap.LoadBitmap(IDB_BITMAP_BKGROUND+i);  /////////////////////加载位图
    bitmap.GetObject(sizeof(BITMAP),&bmp);
    oldBitmap=memoDC.SelectObject(&bitmap);

    CRect rectClient;
    GetClientRect(&rectClient); dc.StretchBlt(0,0,rectClient.Width(),rectClient.Height(),&memoDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); memoDC.SelectObject(oldBitmap); memoDC.DeleteDC();
    bitmap.DeleteObject();
            
            i++;
         }上面的方法是先把位图绘制到内存DC中,然后再放缩到控件上。核心代码就是这样的。你只需设置在OnTimer中调用Invalidate刷新屏幕即可。bitmap.LoadBitmap(IDB_BITMAP_BKGROUND+i);每次刷新时都会加载下一副位图。  
      

  3.   

    谢谢你,你真热心。你的代码要求把bitmap导入资源吧,我这里导入的时候会提示超过256色,无法正常显示。我发现我的刷新问题好像,呵呵只是好像,是由于:
    我使用了网上的代码,CTransStatic,他重写了OnPaint函数,但是这个函数有问题,无法将上一次的bitmap清除掉,导致我必须每次换图后要手动Invalidate窗口,导致刷新问题。代码如下:
    void CTransStatic::OnPaint(){
        
        HBITMAP l_hbmpBitmap = GetBitmap() ;
        
        if( l_hbmpBitmap == NULL )
            
        {
            
            Default() ;
            
            return ;
            
        }
        
        CPaintDC l_PaintDC( this ) ;
        
        CRect l_rcClient ;
        
        GetClientRect( &l_rcClient ) ;
        
        CDC l_MaskDC ;
        
        l_MaskDC.CreateCompatibleDC( &l_PaintDC ) ;
        
        CBitmap l_MaskBitmap ;
        
        l_MaskBitmap.CreateBitmap( l_rcClient.Width(), l_rcClient.Height(),
            
            1, 1, NULL ) ;
        
        CBitmap* l_pOldMaskBitmap = l_MaskDC.SelectObject( &l_MaskBitmap ) ;
        
        CDC l_MemoryDC ;
        
        l_MemoryDC.CreateCompatibleDC( &l_PaintDC ) ;
        
        CBitmap* l_pOldMemoryBitmap =
            
            l_MemoryDC.SelectObject( CBitmap::FromHandle( l_hbmpBitmap ) ) ;
        
        COLORREF l_crOldBack =l_MemoryDC.SetBkColor( RGB( 160, 160, 64 ) ) ;//这是我定义的要滤掉的背景色。
        
        l_MaskDC.BitBlt( 0, 0, l_rcClient.Width(), l_rcClient.Height(), &l_MemoryDC,
            
            0, 0, SRCCOPY ) ;
        
        l_PaintDC.BitBlt( 0, 0, l_rcClient.Width(), l_rcClient.Height(), &l_MemoryDC,
            
            0, 0, SRCINVERT ) ;
        
        l_PaintDC.BitBlt( 0, 0, l_rcClient.Width(), l_rcClient.Height(), &l_MaskDC,
            
            0, 0, SRCAND ) ;
        
        l_PaintDC.BitBlt( 0, 0, l_rcClient.Width(), l_rcClient.Height(), &l_MemoryDC,
            
            0, 0, SRCINVERT ) ;
        
        l_MemoryDC.SelectObject( l_pOldMemoryBitmap ) ;
        
        l_MaskDC.SelectObject( l_pOldMaskBitmap ) ;
    }
    我每次换图后都要:
    // m_static是显示图片的控件。    m_static->SetBitmap(hbmp);    CRect   rect;   
        m_static->GetClientRect(&rect);   
      //InvalidateRect(&rect);从而产生了刷新问题。