none
Something about the CScrollView update... RRS feed

  • 问题

  • Hi there!

    I want bind a color bar(bitmap) at the right of the client of a CScrollView, that is it fixed there while scrolling,

    with the following code it seems to work.

    but the color bar will appear at another position when the scroll thumb click, just a very fast  shine, and then disappered, everything is ok, and the problem will not apper while view size is changing.

    I have tried to draw all  the content in a memory dc(not shown here), then BitBit it to the client, problem goes on..

    what I have done is list here, 

    any one can help me to find out what cause the flash and how get rid of it.

    Thanks a lot!

    ////////////////////////////////////////////////////////////

    // A test view 

    class CMyScrViewTestView : public CScrollView

    {...}

    ////////////////////////////////////////////////////////////////////

    void CMyScrViewTestView::OnInitialUpdate()
    {
    CScrollView::OnInitialUpdate();

    CSize sizeTotal;
    sizeTotal.cx = sizeTotal.cy = 2048;
    SetScrollSizes(MM_TEXT, sizeTotal);
           // load and prepare the color bar on a memory DC.
    CClientDC dc(this);
    m_memDC_ClrBar.CreateCompatibleDC(&dc);
    CBitmap bmp;
    bmp.LoadBitmap(IDB_BITMAP_CLRBAR);
    m_memDC_ClrBar.SelectObject(&bmp);
    }

    /////////////////////////////////////////////////////////////////

    void CMyScrViewTestView::DocToClient(CRect& rect)
    {
    CClientDC dc(this);
    OnPrepareDC(&dc, NULL);
    dc.LPtoDP(rect);
    rect.NormalizeRect();
    }

    /////////////////////////////////////////////////////////////////

    // problem apper here!

    BOOL CMyScrViewTestView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
    {
    if (!CScrollView::OnScrollBy(sizeScroll, bDoScroll))
    return FALSE;
    if (bDoScroll)
    {
    //UpdateWindow();
    //Invalidate();
    RedrawWindow(); //????
    }
    return TRUE;
    }

    //////////////////////////////////////////////////////////////

     void CMyScrViewTestView::OnDraw(CDC*  pDC )

    {
    CMyScrViewTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc) return;
    CDC dc;
    CDC* pDrawDC = pDC;
    CBitmap bitmap;
    CBitmap* pOldBitmap = 0;

    // only paint the rect that needs repainting
    CRect client;
    pDC->GetClipBox(client);
    CRect rect = client;
    DocToClient(rect);

    // draw to offscreen bitmap for fast looking repaints
    if (dc.CreateCompatibleDC(pDC))
    {
    if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
    {
    OnPrepareDC(&dc, NULL);
    pDrawDC = &dc;
    // offset origin more because bitmap is just piece of the whole drawing
    dc.OffsetViewportOrg(-rect.left, -rect.top);
    pOldBitmap = dc.SelectObject(&bitmap);
    dc.SetBrushOrg(rect.left % 8, rect.top % 8);
    // might as well clip to the same rectangle
    dc.IntersectClipRect(client);
    }
    }
    pDrawDC->FillSolidRect(&client, 0xff00ff);
    //////////////////////////////////////////////////////////////////////////
    // For test only
    pDoc->Draw(pDrawDC);// it works correct!

    if (pDrawDC != pDC)
    {
    pDC->SetViewportOrg(0, 0);
    pDC->SetWindowOrg(0,0);
    pDC->SetMapMode(MM_TEXT);
    dc.SetViewportOrg(0, 0);
    dc.SetWindowOrg(0,0);
    dc.SetMapMode(MM_TEXT);

    pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
    &dc, 0, 0, SRCCOPY);

    dc.SelectObject(pOldBitmap);
    }
    // Show the color bar bitmap at the right in the client area.
    CRect rcWholeClient;
    GetClientRect(&rcWholeClient);
    pDC->StretchBlt(rcWholeClient.right-30,0,30,rcWholeClient.Height(),
    &m_memDC_ClrBar,
    0,0,30,256,
    SRCCOPY);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////

    BOOL CMyScrViewTestView::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: Add your message handler code here and/or call default
    return TRUE;
     }

    2013年4月13日 11:05

全部回复