• CListCtrl透明完美实现


    转载请注明来源:http://www.cnblogs.com/xuesongshu/

      网上找过很多资料,左不行右不通,你抄我抄大家抄的不管了,但是某些解释的详细的资料也不行,或许还有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全是透明的。下一篇博客我将介绍我是怎么做到CTreeCtrl透明的。

  • 相关阅读:
    解决 未能为数据库 '数据库用户名' 中的对象 '表名' 分配空间,因为文件组 'PRIMARY' 已满
    获取一个目录下文件扩展名为txt或htm或html的文件的几种方法
    由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
    图解C#创建SqlServer MD5 加密函数
    SqlServer 日期转换 所有格式
    使用SoapHeader对WebService进行身份验证
    禁用文本框粘贴功能
    去除 以下文件中的行尾不一致,要将行尾标准化吗 的提示
    程序锁定windows系统以及调用其它系统对话框,如控制面板,重启系统
    yakuake shell
  • 原文地址:https://www.cnblogs.com/xuesongshu/p/2959104.html
Copyright © 2020-2023  润新知