学习中,关于又一按钮自绘有关问题,向立天的源代码

学习中,关于又一按钮自绘问题,向立天的源代码
C/C++ code

void CWEBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    //解析lpDrawItemStruct结构,获取控件的相关信息
    CRect    rect    = lpDrawItemStruct->rcItem;
    UINT    state    = lpDrawItemStruct->itemState;
    CDC        *pDC    = CDC::FromHandle(lpDrawItemStruct->hDC);
    int        nOldDC    = pDC->SaveDC();

    if(state & ODS_DISABLED)
        m_nButtonState = DISABLE;

    //双缓存绘图
    CRect        rectButton;
    CBitmap        bitmapTemp, *pOldBitmap;
    CDC*        pMemDC=new CDC;

    //获取窗口大小, 创建位图内存
    GetWindowRect(rectButton);
    bitmapTemp.CreateCompatibleBitmap(pDC, rectButton.Width(), rectButton.Height());
    pMemDC->CreateCompatibleDC(pDC);
    pOldBitmap=pMemDC->SelectObject(&bitmapTemp);

    //获取背景
    this->GetParent()->ScreenToClient(rectButton);
    pMemDC->BitBlt(0, 0, rectButton.Width(), rectButton.Height(), this->GetParent()->GetDC(), rectButton.left, rectButton.top, SRCCOPY);

    //绘制按钮状态 
    DrawPicture(pMemDC, m_nButtonState, rect);

    //显示按钮的文本
    DrawButtonText(pMemDC, rect, state);

    //绘制到前景
    pDC->BitBlt(0, 0, rectButton.Width(), rectButton.Height(), pMemDC, 0, 0, SRCCOPY);
    //恢复DC
    pDC->RestoreDC(nOldDC);

    //释放内存
    pMemDC->SelectObject(pOldBitmap);
    ReleaseDC(pMemDC);
    delete    pMemDC;
}

void CWEBmpButton::DrawPicture(CDC* pDC, int nState, CRect rect)
{
    CBitmap        *pOldBitmap;
    CDC*        pMemDC = new CDC;

    //读位图到内存
    pMemDC->CreateCompatibleDC(pDC);
    pOldBitmap = pMemDC->SelectObject(&m_bmpBtnState);
    pDC->TransparentBlt(rect.left, rect.top, rect.Width(), rect.Height(), pMemDC, m_sizeButton.cx*nState, 0, m_sizeButton.cx, m_sizeButton.cy, 

m_clrColorKey);
    pMemDC->SelectObject(pOldBitmap);

    //释放内存
    ReleaseDC(pMemDC);
    delete    pMemDC;
}

这段代码是向立天很久之前的,从博客中下载的,在学习中。

因为刚开始学自绘,总有些问题:
1.什么双缓存绘图?
2.this->GetParent()->ScreenToClient(rectButton);
pMemDC->BitBlt(0, 0, rectButton.Width(), rectButton.Height(), this->GetParent()->GetDC(), rectButton.left, rectButton.top, SRCCOPY); 这行代码,我学习时,CDC

指针和它刚好相反,this->GetParent()->GetDC()->BitBlt(0, 0, rectButton.Width(), rectButton.Height(), pMemDC, rectButton.left, rectButton.top, SRCCOPY);理解是

这样,pMemDC是内存设备环境,里面有位图,是把位图画到this->GetParent()->GetDC(),而上面this->GetParent()->GetDC()中根本就没位图?难道源和目标设备环境可以互换

?这难道就是双缓存绘图?也许是我一直没搞清楚是怎么一回事?

//绘制到前景
pDC->BitBlt(0, 0, rectButton.Width(), rectButton.Height(), pMemDC, 0, 0, SRCCOPY);  这一行就是我理解的,是从pMemDC到pDC。

3.DrawPicture中第一个参数怎么会传内存设备指针,而且在此基础上又创建了个内存设备指针,迷惑?





------解决方案--------------------
就是memDC创建一个临时的DC(画布),将要画的东西画在布上,然后整个一起在画到屏幕上。
其实在实际硬用中更微妙。只要最上层的是CWnd窗口即可,里面的元素的PaintM全是由最上层的CWnd窗口中的memDC传进去,然后全画在这个CDC上,这样就不会有闪屏的感觉了
------解决方案--------------------
先绘制到内存上然后一起显示出来