图一、透明滑动条效果图
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID ); |
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) void CMySliderControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) |
在消息响应函数中,参数pResult将传递给控件的父窗口,而参数pNMHDR指针指向了一个NMCUSTOMDRAW结构,该结构定义如下:
typedef struct tagNMCUSTOMDRAWINFO { NMHDR hdr;//含有通知信息的NMHDR结构; DWORD dwDrawStage; //目前绘制的步骤; HDC hdc; //设备上下文句柄; RECT rc; //绘制的区域; DWORD dwItemSpec; //绘制项目条的说明; UINT uItemState;//当前项目条的状态 LPARAM lItemlParam;//应用程序规定的数据; } NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW; |
从上述结构我们可以得到这么一个绘制透明控件的思路,首先判断当前绘制步骤是否处于准备绘制阶段,也既是NMCUSTOMDRAW 结构对象的成员变量dwDrawStage是否等于CDDS_PREPAINT,如是,pResult的返回值将是CDRF_NOTIFYITEMDRAW,这个返回值的意思是该控件将向父窗口发送所有与绘制相关的操作;如果成员变量dwDrawStage等于CDDS_ITEMPREPAINT,也就是说当前滑动控件处于具体项目的绘制准备阶段,那么就判断当前滑动控件要绘制的是滑动控件的轨道还是滑动控件的滑标(滑动控件由三个部分组成,轨道、滑标和刻度,在实现透明的滑动控件时我们可以不用考虑其刻度问题),如果NMCUSTOMDRAW对象的成员变量dwItemSpec 等于TBCD_THUMB,那末表示将要绘制的滑动控件的项目是滑标,此时可以让pResult返回CDRF_DODEFAULT,通知其父窗口自己将绘制自己本身,此次绘制循环不再发送任何消息。如果dwItemSpec等于TBCD_CHANNEL,表示即将绘制滑动控件的轨道,此时,也就是我们大显身手实现透明的时候了,具体如何实现透明的效果,请参考《实例:透明位图的实现》,处理完透明显示效果后,不要忘记让pResult返回"0"
二、编程步骤
1、 启动Visual C++6.0,生成一个基于对话框的应用程序,将该程序命名为"TransparentSliderDemo";
2、 使用Class Wizard在程序中定义新的类CmySliderControl,其基类选择为CSliderCtrl;
3、 在程序的对话框中放置三个滑动控件,使用Class Wizar分别为其在对话框类中添加对应的CSliderCtrl类型变量m_slider1、m_slider2、m_slider3,然后将上述变量修改为 CMySliderControl类型;
4、 添加代码,编译运行程序;
三、程序代码
//////////////////////////////////////////// MySliderControl.h : header file #if !defined(AFX_MYSLIDERCONTROL_H__C76FA857_51CC_4EB6_A8E2_8323BBEF10BD__INCLUDED_) #define AFX_MYSLIDERCONTROL_H__C76FA857_51CC_4EB6_A8E2_8323BBEF10BD__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CMySliderControl : public CSliderCtrl { CDC m_dcBk; CBitmap m_bmpBk; CBitmap *m_bmpBkOld; //CBitmap* m_pbmpOldBk; CPen m_penThumb; CPen m_penThumbLight; CPen m_penThumbLighter; CPen m_penThumbDark; CPen m_penThumbDarker; COLORREF m_crThumb; COLORREF m_crThumbLight; COLORREF m_crThumbLighter; COLORREF m_crThumbDark; COLORREF m_crThumbDarker; // Construction public: CMySliderControl(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMySliderControl) //}}AFX_VIRTUAL // Implementation public: virtual ~CMySliderControl(); // Generated message map functions protected: //{{AFX_MSG(CMySliderControl) afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; #endif //////////// MySliderControl.cpp : implementation file #include "stdafx.h" #include "MySliderControl.h" #include "windows.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CMySliderControl::CMySliderControl() { m_dcBk.m_hDC = NULL; } CMySliderControl::~CMySliderControl() { DeleteObject(m_dcBk.SelectObject(&m_bmpBkOld)); DeleteDC(m_dcBk); } BEGIN_MESSAGE_MAP(CMySliderControl, CSliderCtrl) //{{AFX_MSG_MAP(CMySliderControl) ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CMySliderControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { LPNMCUSTOMDRAW lpcd = (LPNMCUSTOMDRAW)pNMHDR; CDC *pDC = CDC::FromHandle(lpcd->hdc); switch(lpcd->dwDrawStage) { case CDDS_PREPAINT: *pResult = CDRF_NOTIFYITEMDRAW ; break; //return; case CDDS_ITEMPREPAINT: if (lpcd->dwItemSpec == TBCD_THUMB) { *pResult = CDRF_DODEFAULT; break; } if (lpcd->dwItemSpec == TBCD_CHANNEL) { CClientDC clientDC(GetParent()); CRect crect; CRect wrect; GetClientRect(crect); GetWindowRect(wrect); GetParent()->ScreenToClient(wrect); if (m_dcBk.m_hDC == NULL) { m_dcBk.CreateCompatibleDC(&clientDC); m_bmpBk.CreateCompatibleBitmap(&clientDC, crect.Width(), crect.Height()); m_bmpBkOld = m_dcBk.SelectObject(&m_bmpBk); m_dcBk.BitBlt(0, 0, crect.Width(), crect.Height(), &clientDC, wrect.left, wrect.top, SRCCOPY); } //This bit does the tics marks transparently. CDC SaveCDC; CBitmap SaveCBmp, maskBitmap; //set the colours for the monochrome mask bitmap COLORREF crOldBack = pDC->SetBkColor(RGB(0,0,0)); COLORREF crOldText = pDC->SetTextColor(RGB(255,255,255)); CDC maskDC; int iWidth = crect.Width(); int iHeight = crect.Height(); SaveCDC.CreateCompatibleDC(pDC); SaveCBmp.CreateCompatibleBitmap(&SaveCDC, iWidth, iHeight); CBitmap* SaveCBmpOld = (CBitmap *)SaveCDC.SelectObject(SaveCBmp); //fill in the memory dc for the mask maskDC.CreateCompatibleDC(&SaveCDC); //create a monochrome bitmap maskBitmap.CreateBitmap(iWidth, iHeight, 1, 1, NULL); //select the mask bitmap into the dc CBitmap* OldmaskBitmap = maskDC.SelectObject(&maskBitmap); //copy the oldbitmap data into the bitmap, this includes the tics. SaveCDC.BitBlt(0, 0, iWidth, iHeight, pDC, crect.left, crect.top, SRCCOPY); //now copy the background into the slider BitBlt(lpcd->hdc, 0, 0, iWidth, iHeight, m_dcBk.m_hDC, 0, 0, SRCCOPY); // Blit the mask based on background colour maskDC.BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCCOPY); // Blit the image using the mask pDC->BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCINVERT); pDC->BitBlt(0, 0, iWidth, iHeight, &maskDC, 0, 0, SRCAND); pDC->BitBlt(0, 0, iWidth, iHeight, &SaveCDC, 0, 0, SRCINVERT); //restore and clean up pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText); DeleteObject(SelectObject(SaveCDC, SaveCBmpOld)); DeleteDC(SaveCDC); DeleteObject(maskDC.SelectObject(OldmaskBitmap)); DeleteDC(maskDC); *pResult = 0; break; } } } BOOL CMySliderControl::OnEraseBkgnd(CDC* pDC) { return FALSE; } |
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名