网上找过很多资料,左不行右不通,你抄我抄大家抄的不管了,但是某些解释的详细的资料也不行,或许还有MFC版本的原因。咬咬牙,决定自己实现一个。虽然粗枝大叶,但是网友们如果
按照这里的方法,应该能行。照着葫芦画瓢仍行不通的网友们请留言。说明一下,我用VS2010+MFC10环境。
实现步骤如下:
1、把CListCtrl子类化
2、在IDE中把CListCtrl的Transparent复选框勾上。
3、实现WM_PARENTNOTIFY,代码如下:
void CMyListCtrl::OnParentNotify(UINT message, LPARAM lParam)
{
if (message==IDC_TREE_FILE)
{
LPTSTR lp=(LPTSTR)calloc(MAX_PATH,sizeof(TCHAR));
lstrcpy(lp,(LPTSTR)lParam);
memset(m_szFileFullName,0,MAX_PATH*sizeof(TCHAR));
lstrcpy(m_szFileFullName,lp);
lstrcat(lp,L"\\*.*");
CFileFind ff;
DeleteAllItems();
GetParent()->InvalidateRect(&m_rc);
SetRedraw(FALSE);
BOOL bFind=ff.FindFile(lp);
CString szFileName=L"";
do
{
bFind=ff.FindNextFile();
if (ff.IsDots())
{
continue;
}
szFileName=ff.GetFileName();
if (szFileName.IsEmpty())
{
break;
}
if (!ff.IsDirectory())
{
InsertItem(0,szFileName.GetBuffer(szFileName.GetLength()));
}
} while (bFind);
SetRedraw(TRUE);
GetParent()->InvalidateRect(&m_rc);
delete lp;
}
else if (message==WM_USER+1&&lParam==0)
{
SetBkColor(CLR_NONE);
SetTextBkColor(CLR_NONE);
SetClassLong(GetSafeHwnd(),GCL_HBRBACKGROUND,(LONG)GetStockObject(NULL_BRUSH));
GetWindowRect(&m_rc);
GetParent()->ScreenToClient(&m_rc);
::SendMessage(GetHeaderCtrl()->GetSafeHwnd(),WM_PARENTNOTIFY,WM_USER+1,0);
}
else
{
CListCtrl::OnParentNotify(message, lParam);
}
}
4、实现LVN_ITEMCHANGED,代码如下:
void CMyListCtrl::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
//要刷新旧列表项。用一个变量把旧列表项记录下来。
GetParent()->InvalidateRect(&m_rc);
//异或用于追加,与用于判断
if (pNMLV->uNewState&LVIS_SELECTED)
{
LPTSTR lp=(LPTSTR)calloc(MAX_PATH,sizeof(TCHAR));
lstrcpy(lp,m_szFileFullName);
lstrcat(lp,L"\\");
lstrcat(lp,GetItemText(pNMLV->iItem,pNMLV->iSubItem));
GetParent()->SetDlgItemText(IDC_EDIT_FILE,lp);
delete lp;
}
*pResult = 0;
}
5、分别实现LVN_DELETEALLITEMS、LVN_DELETEITEM、WM_HSCROLL、WM_VSCROLL、WM_MOUSEWHEEL,在每个调用CListCtrl默认处理之后追加一行代码:
GetParent()->InvalidateRect(&m_rc);
*pResult = 0;
6、用类向导新建一个继承CHeaderCtrl类的新类,实现WM_PAINT,代码如下:
void CMyHeaderCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CHeaderCtrl::OnPaint()
HDC dcMem=::CreateCompatibleDC(GetParent()->GetParent()->GetDC()->GetSafeHdc());
SelectObject(dcMem,m_bmp);
BitBlt(dc.GetSafeHdc(),0,0,m_rc.right-m_rc.left,m_rc.bottom-m_rc.top,dcMem,m_rc.left,m_rc.top,SRCCOPY);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(255,0,0));
dc.SelectObject(CreatePen(PS_DOT,1,RGB(255,0,255)));
dc.SelectObject(GetStockObject(NULL_BRUSH));
dc.SelectObject(m_font);
dc.Rectangle(0,0,m_rc.right-m_rc.left,m_rc.bottom-m_rc.top);
HDITEM col;
GetItem(0,&col);
if (lstrlen(col.pszText))
{
dc.TextOut(0,3,col.pszText,lstrlen(col.pszText));
}
else
{
dc.TextOut(0,3,L"文件名",3);
}
}
7、重载PreSubclassWindow,代码如下:
void CMyListCtrl::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
CListCtrl::PreSubclassWindow();
m_headerFile.SubclassWindow(GetHeaderCtrl()->GetSafeHwnd());
}
好了,到此完成。网友们一定发现界面上的CEdit、CButton、CStatic、CTreeCtrl全是透明的。