给你tree的代码:BOOL cTree::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); CDC MemDC; MemDC.CreateCompatibleDC(pDC); HBITMAP hBmp=(HBITMAP)MemDC.SelectObject(m_bitmap.m_hObject); pDC->StretchBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,320,240,SRCCOPY); // set back (HBITMAP)MemDC.SelectObject(hBmp); // free DeleteObject(MemDC); // return TRUE; } // void cTree::OnPaint() { CPaintDC dc(this); // get size CRect rc; GetClientRect(&rc); // Create a compatible memory DC CDC memDC; memDC.CreateCompatibleDC(&dc); // Select a compatible bitmap into the memory DC CBitmap bitmap; bitmap.CreateCompatibleBitmap( &dc, rc.Width(), rc.Height()); HBITMAP oldBmp=(HBITMAP)memDC.SelectObject(&bitmap); // Let the control draws the tree. DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); // 'and' to the background dc.BitBlt(0,0,rc.Width(),rc.Height(),&memDC,0,0,SRCAND); // set back memDC.SelectObject(oldBmp); // free DeleteObject(bitmap.m_hObject); DeleteObject(memDC); }
对话框,控件等,全部从内存DC中拷贝指定区域的图片做背景。
BitBlt 就可以实现了。
http://www.vckbase.com/index.php/wv/206.html
用OnEraseBkgnd返回true,可以看到对话框的背景,这个方法不行吗?
{
CListCtrl::OnPaint();
CDC* cdc=GetDC();
CRect rect;
GetClientRect(&rect);
int Width=rect.Width();
int Height=rect.Height();
CDC MemDC;
MemDC.CreateCompatibleDC(cdc);//创建一个与指定设备兼容的内存设备上下文环境(DC) CBitmap memBmp;
memBmp.CreateCompatibleBitmap(cdc,Width,Height);//创建与指定的设备环境相关的设备兼容的位图
//成功返回位图句柄
CBitmap* pOldMemBmp=MemDC.SelectObject(&memBmp);
//m_savebmp=MemDC.SelectObject(&memBmp);
//画背景图片到内存中
CBitmap* pnewbmp=cdc->SelectObject(&m_Bmp);
MemDC.BitBlt(0,0,Width,Height,cdc,0,0,SRCCOPY);//保存图片
cdc->SelectObject(pnewbmp);//选择一对象到指定的设备上下文环境中
rect.top=0;
rect.left=0;
rect.right=Width;
rect.bottom=rect.top+Height;
int size=GetHeaderCtrl()->GetItemCount();
for(int i=0;i<size&&rect.top<Height;i++)
{
rect.OffsetRect(0,20);
}
cdc->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);//绘图
}
绘制CListCtrl控件背景图片怎么没用啊
问题在于CListCtrl Paint时会改变背景。
void CListCtrlCl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
int total=GetItemCount();//设置复选框的状态,界面未刷新
if(m_Header.bFlag==false)
{
for(int i=0;i<total;i++)
{
m_bItemCheckState[i] = !m_bItemCheckState[i];
InvalidateRect(NULL,true);
}
}
m_Header.bFlag=true;
if (lpDrawItemStruct->CtlType != ODT_LISTVIEW)
return;
RECT rectiSubItem = {0};
RECT rectCheckBox = {0};
CDC* pDC;
pDC = CDC::FromHandle(lpDrawItemStruct->hDC); WCHAR szBuffer[256] = {0};
int nTotalColumn = 0; CHeaderCtrl* pListHeader = NULL;
LV_ITEM lvi; pListHeader = (CHeaderCtrl*)GetDlgItem(0);
nTotalColumn = pListHeader->GetItemCount(); //第一列是要显示复选框的一列
pListHeader->GetItemRect(0,&rectCheckBox);
//循环地绘制列表控件各个子项
LV_COLUMN lvc;//, lvcprev ;
::ZeroMemory(&lvc, sizeof(lvc));
lvc.mask = LVCF_WIDTH | LVCF_FMT;
//for (int iColumn = 0;iColumn<nTotalColumn;++iColumn)
for(int iColumn=0;GetColumn(iColumn,&lvc);iColumn++)
{
CDC* pDC;
pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rtClient;
GetClientRect(&rtClient);
//for ( int nCol=0; GetColumn(nCol, &lvc); nCol++)
//{
if ( iColumn >0 )
{
// Get Previous Column Width in order to move the next display item
GetColumn(iColumn-1, &lvc) ;//GetColumn(iColumn-1, &lvcprev) ;
lpDrawItemStruct->rcItem.left+= lvc.cx;//lvcprev.cx ;
lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left;
}
CRect rcItem;
if (!GetSubItemRect(lpDrawItemStruct->itemID,iColumn,LVIR_LABEL,rcItem))
continue; ::ZeroMemory(&lvi, sizeof(lvi));
lvi.iItem = lpDrawItemStruct->itemID;
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iSubItem = iColumn;//0;
lvi.pszText = szBuffer;
lvi.cchTextMax = sizeof(szBuffer);
VERIFY(GetItem(&lvi)); CRect rcTemp;
rcTemp = rcItem;
if ( lpDrawItemStruct->itemState&ODS_SELECTED)
{
pDC->FillSolidRect(&rcItem, GetSysColor(COLOR_HIGHLIGHT)) ;//记录选中后设置字体背景色
}else
{
COLORREF color;
color = GetBkColor();
CBrush hbrush;
pDC->FillSolidRect(rcTemp,color);//加了这一句,添加的记录文本都会有背景色,如果删除文本背景透明,但是如果前一列的文本长度大于单元格的长度,文本会继续显示在后一列中,请问这个问题怎么解决啊???
}
//pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT));
if (iColumn == 0)
{
rectCheckBox.top = lpDrawItemStruct->rcItem.top;
rectCheckBox.bottom = lpDrawItemStruct->rcItem.bottom;
m_nRowHeight=lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top;
DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_CHECKED);
//绘制复选框
if (m_bItemCheckState[lpDrawItemStruct->itemID])
{
m_bItemCheckState[lpDrawItemStruct->itemID]=true;
DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_CHECKED);//已选中
}else
{
m_bItemCheckState[lpDrawItemStruct->itemID]=false;
DrawFrameControl(lpDrawItemStruct->hDC,&rectCheckBox,DFC_BUTTON,DFCS_BUTTONCHECK);//未选中
}
}else
{
int len=_tcslen(szBuffer);
CRect tRect;
GetItemRect(0,&tRect,iColumn);
pDC->DrawText(szBuffer,len,&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字
pDC->DrawEdge(&lpDrawItemStruct->rcItem,EDGE_RAISED,BF_BOTTOM);//下划线
}
UINT uFormat=DT_CENTER ;
if (m_Header.m_Format[iColumn]=='0')
{
uFormat = DT_LEFT;
}else if (m_Header.m_Format[iColumn]=='1')
{
uFormat = DT_CENTER;
}else if (m_Header.m_Format[iColumn]=='2')
{
uFormat = DT_RIGHT;
}
}
}
画文字时
int len=_tcslen(szBuffer);
CRect tRect;
GetItemRect(0,&tRect,iColumn);
pDC->DrawText(szBuffer,len,&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字
要查文字可能的pixel程度,超过要截尾:
CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
即:
CSize pixLen=pDC->GetTextExtent(szBuffer,len);
if(pixLen.x < 该列宽度) pDC->DrawText()
int len=_tcslen(szBuffer);
CRect tRect;
GetSubItemRect(lpDrawItemStruct->itemID,iColumn,LVIR_BOUNDS,tRect);
CSize pixLen=pDC->GetTextExtent(szBuffer,len);
if(pixLen.cx<tRect.Width())
pDC->DrawText(szBuffer,len,&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字
else
pDC->DrawText(szBuffer,tRect.Width(),&lpDrawItemStruct->rcItem,DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS|DT_LEFT);//画文字 pDC->DrawEdge(&lpDrawItemStruct->rcItem,EDGE_RAISED,BF_BOTTOM);//下划线
为什么没用啊?
上面这个解决了,是你说的那样,我自己搞错了,呵呵,谢谢!能不能告诉我怎么画CListCtrl、CTreeCtrl、CTabctrl的背景啊
如果背景是单一颜色,可以在CustomDraw中对每个item设置BkColor。
如果背景是图就麻烦了。这时要用‘透明窗口’的绘制方法。
就是把控件的图和背景图混合。
用EraseBkGrnd是不行的,因为控件绘制时会把背景全覆盖掉。
我还是看看这个网址吧:http://www.vckbase.com/index.php/wv/206.html
void CTreeControl::OnPaint()
{
// create a compatible memory dc
//绘制背景图片
CTreeCtrl::OnPaint();
}
我将OnPaint函数改成上面这样,然后注释SetBKImage函数,背景确实是透明,但是节点的背景为白色,并且点击节点展开和收拢都没有刷新界面!该怎么解决啊
void CTreeControl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
//Invalidate();
CRect rc;
GetClientRect(&rc);
InvalidateRect(rc);
SetRedraw(TRUE);//TRUE,则重画标志被设置
*pResult = 0;
}void CTreeControl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
CRect rc;
GetClientRect(&rc);
InvalidateRect(rc);
//SetRedraw(FALSE);//标志被清除
SetRedraw(false);
*pResult = 0;
}
我上面调用的系统刷新函数为什么没用呢?将对应控件背景的区域绘制下来,刷新控件的区域,难道不是吗?
那我要设置CTreeCtrl背景图和对话框背景图混合怎么做呢?
可以实现,前提是我要从对话框背景图片上截取一张图片CTreeCtrl控件大小的图片,然后将图片保存为.bmp格式,但是我不知道怎么截取怎么保存?
在Paint中:
1.产生memDC,
2.把memDC交给DefWindowProc(WM_PAINT,memDC.m_hDC,0);
让父类把窗口绘在memDC上;
3.再把背景绘到memDC上 (SRCAND)
4,绘到dc上。
CPaintDC dc(this); // device context for painting
CRect rcclient;
GetClientRect(&rcclient);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
memdc.SelectObject( &bitmap ); CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0); CDC maskdc;
maskdc.CreateCompatibleDC(&dc);
CBitmap maskbitmap;
maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
maskdc.SelectObject( &maskbitmap );
maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,rcclient.left, rcclient.top, SRCCOPY); CBrush brush;
brush.CreatePatternBrush(&m_bitmap);
dc.FillRect(rcclient, &brush);
memdc.SetBkColor(RGB(0,0,0));
memdc.SetTextColor(RGB(255,255,255));
memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND); dc.SetBkColor(RGB(255,255,255));
dc.SetTextColor(RGB(0,0,0));
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc,rcclient.left, rcclient.top,SRCPAINT);
brush.DeleteObject();你说的是这个吧
brush.CreatePatternBrush(&m_bitmap);
dc.FillRect(rcclient, &brush); 好像有问题
1.在EraseBackGround中仍按绘背景处理。
这时DC中已有背景。
2在Paint用memDC把控件绘制的取出后,
dc.bitblt(0,0,wid,hei,&memdc,0,0,SRCAND);
就可以了。
{
CWnd* pParent = GetParent();
ASSERT_VALID(pParent);
CPoint pt(0, 0);
MapWindowPoints(pParent, &pt, 1);
pt = pDC->OffsetWindowOrg(pt.x, pt.y);
LRESULT lResult = pParent->SendMessage(WM_ERASEBKGND,(WPARAM)pDC->m_hDC, 0L);
pDC->SetWindowOrg(pt.x, pt.y);
return lResult;
}
本来我OnEraseBkgnd里面return true,把他改成你这样,就是原来的那个背景了,没有图片
可以参考#36的代码啊,只不过将那个DC换成内存DC,图片用CreateCompatibleBitmap创建,选入内存DC,给父对话框发WM_ERASEBKGND或WM_PAINT消息后,内存DC中的位图就保存了对应的对话框背景了用BitBlt来截屏也可以,但不靠谱的,万一被别的窗口挡住,截到的图片就不对了
至于发WM_ERASEBKGND消息还是WM_PAINT消息取决于你的对话框背景是在WM_ERASEBKGND还是WM_PAINT画上去的
我刚刚在看MapWindowPoints的相关信息,谢谢,我试试看!
{
//MessageBox(_T("paint"));
CListCtrl::OnPaint();//否则不能进入drawitem函数
CPaintDC dc(this);
CBitmap bitmap;
CRect rect;
GetClientRect(&rect);
bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(bitmap);
CWnd* pParent = GetParent();
//ASSERT_VALID(pParent);
CPoint pt(0, 0);
MapWindowPoints(pParent,&pt,2);
//pt =memDC.OffsetWindowOrg(pt.x,pt.y);//->OffsetWindowOrg(pt.x, pt.y);
memDC.OffsetWindowOrg(pt.x,pt.y);
LRESULT lResult = pParent->SendMessage(WM_ERASEBKGND,(WPARAM)memDC.m_hDC, 0L);//pDC->m_hDC
memDC.SetWindowOrg(pt.x, pt.y);}
我在OnPaint中这样写的,怎么报错呢???
Run-Time Check Failure #2 - Stack around the variable 'pt' was Run-Time Check Failure #2 - Stack around the variable 'pt' was corrupted..
{
CRect rc;
GetClientRect(&rc);
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
HBITMAP hBmp=(HBITMAP)MemDC.SelectObject(m_bitmap.m_hObject);
pDC->StretchBlt(0,0,rc.Width(),rc.Height(),&MemDC,0,0,320,240,SRCCOPY);
// set back
(HBITMAP)MemDC.SelectObject(hBmp);
// free
DeleteObject(MemDC);
//
return TRUE;
}
//
void cTree::OnPaint()
{
CPaintDC dc(this);
// get size
CRect rc;
GetClientRect(&rc);
// Create a compatible memory DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);
// Select a compatible bitmap into the memory DC
CBitmap bitmap;
bitmap.CreateCompatibleBitmap( &dc, rc.Width(), rc.Height());
HBITMAP oldBmp=(HBITMAP)memDC.SelectObject(&bitmap);
// Let the control draws the tree.
DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
// 'and' to the background
dc.BitBlt(0,0,rc.Width(),rc.Height(),&memDC,0,0,SRCAND);
// set back
memDC.SelectObject(oldBmp);
// free
DeleteObject(bitmap.m_hObject);
DeleteObject(memDC);
}
BOOL CListCtrlCl::OnEraseBkgnd(CDC* pDC)//背景透明,首先擦除背景
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//CPaintDC dc(this);
CBitmap bitmap;
CRect rect;
GetClientRect(&rect);
bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(bitmap);
CWnd* pParent = GetParent();
//ASSERT_VALID(pParent);
CPoint pt(0, 0);
//MapWindowPoints(pParent,&pt,2);
MapWindowPoints(pParent,&pt,1);
//pt =memDC.OffsetWindowOrg(pt.x,pt.y);//->OffsetWindowOrg(pt.x, pt.y);
memDC.OffsetWindowOrg(pt.x,pt.y);
LRESULT lResult = pParent->SendMessage(WM_ERASEBKGND,(WPARAM)memDC.m_hDC, 0L);//pDC->m_hDC
memDC.SetWindowOrg(pt.x, pt.y); return false;
}
我在头文件中声明为CBitmap m_bitmap,在.cpp中没有给其赋值,这样好像不对吧?
我要手动给m_bitmap赋值吗
{
CListCtrl::OnPaint();//否则不能进入drawitem函数
CPaintDC dc(this);
CBitmap bitmap;
CRect rect;
GetClientRect(&rect);
bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(bitmap);
CWnd* pParent = GetParent();
//ASSERT_VALID(pParent);
CPoint pt(0, 0);
MapWindowPoints(pParent, &pt, 1);
pt =memDC.OffsetWindowOrg(pt.x,pt.y);
pParent->SendMessage(WM_ERASEBKGND,(WPARAM)memDC.m_hDC, 0L);
pParent->SendMessage(WM_PAINT,(WPARAM)memDC.m_hDC, 0L);
memDC.SetWindowOrg(pt.x, pt.y);
//至此memDC上已经保存了父窗口的背景内容
//用户可以调用BitBlt(...)等函数拷贝memDC的内容到子窗口,这样就达到了透明效果;
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC , 0);
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
//如果不行就用这里的方法:http://www.vckbase.com/index.php/wv/206.html
}BOOL CListCtrlCl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
这样对话框必须有自己的背景图。
对话框的擦背景中就是把这个背景图绘到对话框上,同时你要把ListCtrl所占的那块保留下来。作为他的背景这样list就看上去是透明的了。
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap bmpbkgnd;
bmpbkgnd.LoadBitmapW(IDB_BITMAPBK);
BITMAP bkbmp;
bmpbkgnd.GetBitmap(&bkbmp);
CBitmap* pbmp=memDC.SelectObject(&bmpbkgnd);
dc.StretchBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,bkbmp.bmWidth,bkbmp.bmHeight,SRCCOPY);
但是这里
BOOL CTreeControl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CRect treeRect;
GetClientRect(&treeRect);
CDC memdc;
memdc.CreateCompatibleDC(pDC);
HBITMAP hbmp=(HBITMAP)memdc.SelectObject(m_bitmap.m_hObject);
pDC->StretchBlt(0,0,treeRect.Width(),treeRect.Height(),&memdc,0,0,treeRect.Width(),treeRect.Height(),SRCCOPY);
(HBITMAP)memdc.SelectObject(hbmp);
DeleteObject(memdc);
return TRUE;
}
void CTreeControl::OnPaint()
{
CPaintDC dc(this);
CRect rc;//获得大小
GetClientRect(&rc); CDC memdc;//创建一个兼容的内存DC
memdc.CreateCompatibleDC(&dc); CBitmap bitmap;//将一张兼容的bitmap放入内存DC中
bitmap.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height());
HBITMAP oldBmp=(HBITMAP)memdc.SelectObject(&bitmap); DefWindowProc(WM_PAINT,(WPARAM)memdc.m_hDC,0);//响应函数画树 dc.BitBlt(0,0,rc.Width(),rc.Height(),&memdc,0,0,SRCAND);//背景图片,and
memdc.SelectObject(oldBmp);//设置背景图片
DeleteObject(bitmap.m_hObject);//释放资源
DeleteObject(memdc);
}
这里好像并没有给m_bitmap赋值,从哪里可以看出,我是从对话框背景相对应的位置画出的CTreeCtrl的背景图片呢?
我将dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
改为dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 400, 400, SRCCOPY);
在坐标为(400,400)并没有画出图片,CListCtrl可以看到对话框的背景图片,我想应该是调用这个函数的原因吧
BOOL CListCtrlCl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
从哪里可以看出“ListCtrl所占的那块保留下来”???
不是的,BitBlt才开始画,改了坐标,如果图片宽度或高度小于400,就什么都没画出来了
dc.StretchBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,bkbmp.bmWidth,bkbmp.bmHeight,SRCCOPY);
但是这里
"
到这里ClistCtrl的背景并没有保存下来,
BOOL CTreeControl::OnEraseBkgnd(CDC* pDC)时。
对话框已经被他覆盖取不到背景的!
那怎么办呢?我以为上面添加了控件,对话框的背景不会不覆盖,但是用OnEraseBkgnd不是可以擦除控件的背景而看到对话框的背景吗?既然可以看到为什么不可以保存呢?
itemexpending 时要Invalidate()
在对话框背景中,(可以先隐藏控件)画完背景后,截取控件大小的位图,(其实应该做成Brush CreatePattenBrush)。这个Brush放对话框中。
在控件背景时,GetParent-》取这个Brush,就可以画了。
和文件无关。
我用了,没用
void CTreeControl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
Invalidate();
//CRect rc;
//GetClientRect(&rc);
//InvalidateRect(rc);
//SetRedraw(TRUE);//TRUE,则重画标志被设置
SetRedraw(true);
*pResult = 0;
}void CTreeControl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
Invalidate();
//CRect rc;
//GetClientRect(&rc);
//InvalidateRect(rc);
//SetRedraw(FALSE);//标志被清除
//SetRedraw(false);
*pResult = 0;
}
我的VC6可以没问题(没ScrollBar)
还是一样的,是不是不用重写OnItemexpanded函数啊?
m_MyList.ShowWindow(SW_HIDE)
http://115.com/file/e7jp2fvb
OnPaint函数中CListCtrl::OnPaint();写在前面的代码好像都不执行的?我本来想在CListCtrl绘制之前绘制图片放在CListCtrl::OnPaint();的前面好像行不通
BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
}
我不知道你的编译器是不是vs2008,我的运行结果就是我想问你们那个问题
http://my.csdn.net/my/album/detail/1184040
void CMyTreeCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting CRect rcclient;
GetClientRect(&rcclient); // create a compatible memory dc
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
CBitmap *oldbitmap = memdc.SelectObject( &bitmap );
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0); CWnd* pParent = GetParent();
CPoint pt(0, 0);
MapWindowPoints(pParent, &pt, 1);
pt = dc.SetWindowOrg(pt.x, pt.y);
pParent->SendMessage(WM_ERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0L);
dc.SetWindowOrg(pt.x, pt.y); ::TransparentBlt(dc.GetSafeHdc(), 0, 0, rcclient.Width(), rcclient.Height(), memdc.GetSafeHdc(), 0, 0, rcclient.Width(), rcclient.Height(), RGB(255,255,255)); memdc.SelectObject(oldbitmap);
bitmap.DeleteObject();
}BOOL CTreeDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
CDC memdc;
memdc.CreateCompatibleDC(pDC);
memdc.SelectObject( &m_bitmap );
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
return TRUE;
}
我之前设置CTreeCtrl背景透明可以看到对话框的背景,现在是想设置CTreeCtrl和对话框的背景一致,但是按你的方法,文字确实不重叠了,滚动条移动也没问题,就是背景变成 了没有加图片时的样子
//{{AFX_MSG_MAP(CTreeDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
我猜是不是这个函数MapWindowPoints(pParent, &pt, 1);在执行OnPaint函数的时候对话框的背景图就没了,然后MapWindowPoints取的背景图片就是错的啊
{
// TODO: Add your message handler code here and/or call default
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);//DeleteDC needed
CBitmap* pOldBitmap = dcMem.SelectObject(&m_bitmap);
// Retrieve the size of our bitmap...
BITMAP bmp;
m_bitmap.GetObject(sizeof(bmp),&bmp);
// and the size of our window's client area
CRect rect;
GetClientRect(&rect);
// Create Edit background brush; only once !
if(!m_blInitEditBr)
{// add edit rect
CRgn prgnClip;
CRect selEditRc;
m_SelEdit.GetWindowRect(selEditRc);
prgnClip.CreateRectRgnIndirect(selEditRc);//DeleteObject needed
CDC* pDCex=GetDCEx(&prgnClip,DCX_PARENTCLIP);//ReleaseDC needed
// Fill the client area of dlg,include SelEdit with our bitmap
pDCex->StretchBlt(rect.left, rect.top,rect.Width(), rect.Height(),
&dcMem,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
//we create the background brush of SelEdit
CDC dcMemEd;
dcMemEd.CreateCompatibleDC(pDCex);//DeleteDC needed
CBitmap EditBmp;//DeleteObject needed
EditBmp.CreateCompatibleBitmap(pDCex,selEditRc.Width(),selEditRc.Height());
pOldBitmap = dcMemEd.SelectObject(&EditBmp);
ScreenToClient(&selEditRc);
MapWindowPoints(this,selEditRc);
dcMemEd.BitBlt(0,0,selEditRc.Width(),selEditRc.Height(),
pDCex,selEditRc.left, selEditRc.top, SRCCOPY);
CBitmap *nowBMP=dcMemEd.SelectObject(pOldBitmap);
// copy to CB for checking
#ifdef TEST
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,nowBMP->GetSafeHandle());
CloseClipboard();
#endif
m_pbrEd=new CBrush;
m_pbrEd->CreatePatternBrush(nowBMP);
m_blInitEditBr=TRUE;
//
DeleteObject(prgnClip);
DeleteObject(EditBmp);
ReleaseDC(pDCex);
dcMemEd.DeleteDC();
}
else
{// MORMAL
pDC->StretchBlt(rect.left, rect.top,rect.Width(), rect.Height(),
&dcMem,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
}
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();
//
return TRUE;
// return CDialog::OnEraseBkgnd(pDC);
}
下面是在派生EDit中的调用:
BOOL CSelEdit::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CDrawEditDlg *pdlg=(CDrawEditDlg*)GetParent();
CRect rc;
GetWindowRect(&rc);
ScreenToClient(&rc);
// afxDump << rc << "\n";
pDC->FillRect(rc,pdlg->m_pbrEd);//PatternBrush
return TRUE;
// return CEdit::OnEraseBkgnd(pDC);
}
//
注意:
m_pbrEd=new CBrush;
m_pbrEd->CreatePatternBrush(nowBMP);
m_blInitEditBr=TRUE;
3句产生一个位图画刷。
我绘制CListCtrl背景图片好像成功了,是这样的我的CHeaderCtrl也实现了一个继承类,我在列头添加了一个复选框,让点击复选框下面的实现反选,为什么只有我点击列名头复选框时,图片才进行绘制呢?好奇怪,我的绘制函数是写在CListCtrl继承类中啊
用来绘制CListCtrl的背景图片,我该为
CMy3dvstarDlg* starDlg=(CMy3dvstarDlg*)GetParent();
CRect rc;
GetWindowRect(&rc);
rc.left+=100;
rc.top+=100;
pDC->FillRect(rc,starDlg->m_pbrEd);
图片并没有在我指定的位置进行重绘,是不是根本就没有成功啊!为什么在CListCtrl的(100,100)没有绘制图片呢???
把对话框改成‘window’(class info)就有了。不要手动的
#ifdef TEST
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,nowBMP->GetSafeHandle());
CloseClipboard();
#endif
#ifdef 1 // TEST
打开画板程序,paste进来看看。
CListCtrl本身有个SetBkImage函数,不过没用过。
我刚刚试了一下,任何控件,只要在
BOOL CListCtrlCl::OnEraseBkgnd(CDC* pDC)//背景透明,首先擦除背景
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CBrush brush;
CBitmap bit;
bit.LoadBitmapW(IDB_BITMAPBK);
CRect rect;
GetClientRect(&rect);
brush.CreatePatternBrush(&bit);
pDC->FillRect(&rect,&brush);
return TRUE;
}
加载的图片都不会有刷新的问题,现在我知道的是
用你说的
BOOL CDrawEditDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);//DeleteDC needed
CBitmap* pOldBitmap = dcMem.SelectObject(&m_bitmap);
// Retrieve the size of our bitmap...
BITMAP bmp;
m_bitmap.GetObject(sizeof(bmp),&bmp);
// and the size of our window's client area
CRect rect;
GetClientRect(&rect);
// Create Edit background brush; only once !
if(!m_blInitEditBr)
{// add edit rect
CRgn prgnClip;
CRect selEditRc;
m_SelEdit.GetWindowRect(selEditRc);
prgnClip.CreateRectRgnIndirect(selEditRc);//DeleteObject needed
CDC* pDCex=GetDCEx(&prgnClip,DCX_PARENTCLIP);//ReleaseDC needed
// Fill the client area of dlg,include SelEdit with our bitmap
pDCex->StretchBlt(rect.left, rect.top,rect.Width(), rect.Height(),
&dcMem,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
//we create the background brush of SelEdit
CDC dcMemEd;
dcMemEd.CreateCompatibleDC(pDCex);//DeleteDC needed
CBitmap EditBmp;//DeleteObject needed
EditBmp.CreateCompatibleBitmap(pDCex,selEditRc.Width(),selEditRc.Height());
pOldBitmap = dcMemEd.SelectObject(&EditBmp);
ScreenToClient(&selEditRc);
MapWindowPoints(this,selEditRc);
dcMemEd.BitBlt(0,0,selEditRc.Width(),selEditRc.Height(),
pDCex,selEditRc.left, selEditRc.top, SRCCOPY);
CBitmap *nowBMP=dcMemEd.SelectObject(pOldBitmap);
// copy to CB for checking
#ifdef TEST
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,nowBMP->GetSafeHandle());
CloseClipboard();
#endif
m_pbrEd=new CBrush;
m_pbrEd->CreatePatternBrush(nowBMP);
m_blInitEditBr=TRUE;
//
DeleteObject(prgnClip);
DeleteObject(EditBmp);
ReleaseDC(pDCex);
dcMemEd.DeleteDC();
}
else
{// MORMAL
pDC->StretchBlt(rect.left, rect.top,rect.Width(), rect.Height(),
&dcMem,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
}
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();
//
return TRUE;
// return CDialog::OnEraseBkgnd(pDC);
}是不是相当于自己创建了一张CBitmap图片,这个与我OnEraseBkgnd中添加的图片,除了一个是工程手动添加的资源,一个是自己创建的资源外,还有什么本质区别没???
或者说我上面的理解错误?
这个已经是画刷,不是bitmap !
EditBmp.CreateCompatibleBitmap(pDCex,selEditRc.Width(),selEditRc.Height());
pOldBitmap = dcMemEd.SelectObject(&EditBmp);
这句话就相当于把图片保存在了EditBmp中吗???
这句是空的bmp
pOldBitmap = dcMemEd.SelectObject(&EditBmp);
准备绘制
dcMemEd.BitBlt(0,0,selEditRc.Width(),selEditRc.Height(),
pDCex,selEditRc.left, selEditRc.top, SRCCOPY);
这句是绘制
CBitmap *nowBMP=dcMemEd.SelectObject(pOldBitmap);
这句是取出绘制完的bmp。
没有这句bmp还被selected,在 dcMemEd 内。
dcMemEd.CreateCompatibleDC(pDCex);//兼容的内存设备上下文环境
CBitmap EditBmp;//DeleteObject needed
EditBmp.CreateCompatibleBitmap(pDCex,selEditRc.Width(),selEditRc.Height());//指定的设备环境相关的设备兼容的位图
pOldBitmap = dcMemEd.SelectObject(&EditBmp);//对象替换先前的相同类型的对象,是将dcMemEd替换EditBmp,还是将EditBmp替换dcMemEd
ScreenToClient(&selEditRc);
MapWindowPoints(this,selEditRc);
dcMemEd.BitBlt(0,0,selEditRc.Width(),selEditRc.Height(),
pDCex,selEditRc.left, selEditRc.top, SRCCOPY);//应该是保存图片吧
CBitmap *nowBMP=dcMemEd.SelectObject(pOldBitmap); // m_pbrEd->CreatePatternBrush(nowBMP);//用 m_pbrEd->CreatePatternBrush(&pOldBitmap)应该与上面是等价的吧ScreenToClient(&selEditRc);
MapWindowPoints(this,selEditRc);这两句好像似乎没影响
不懂,求解释???
MapWindowPoints(this,selEditRc);这两句好像似乎没影响
”
是 确定Edit在对话框中位置,
m_SelEdit.GetWindowRect(selEditRc);
要的是整个窗口。
ScreenToClient(&selEditRc);
变客户区,
MapWindowPoints(this,selEditRc);
变换到对话框中坐标。