小弟是新手,搜索到的代码,关于自绘的Slider,改写了DrawThumb函数,加载了一个位图。现问题如下:
1、动态创建Slider后,托动滑块位图总是无法清除干净,而且除了在刚刚加载的位置显示整个位图外,其余位置只显示一半的位图,请问是怎么回事,如何解决。
2、OnCustomDraw函数是响应什么消息进行的,其中的Switch宏都代表什么意思?
3、动态创建,定义了控件ID后,如何设置DDX例如:
DDX_Slider(pDX, IDC_SLIDER_CONTRAST, m_contrast)这样的形势?
呵呵,问题由点多了,希望大家赐教,一定给分。
#include "stdafx.h"#include "windows.h"
#include "MySliderControl.h"
#include "HKVision.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMySliderControlCMySliderControl::CMySliderControl()
{
m_dcBk = NULL;
m_crThumbColor = NULL;
m_crThumbColorSelected = NULL;
m_bRedraw = false;
}CMySliderControl::~CMySliderControl()
{
::SelectObject(m_dcBk, m_bmpBkOld);
::DeleteObject(m_bmpBk);
::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()/////////////////////////////////////////////////////////////////////////////
// CMySliderControl message handlers
//-------------------------------------------------------------------
//
void CMySliderControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) 
//
// Description : Sent by the slider control to notify the parent window 
// about drawing operations. This notification is sent in 
// the form of a WM_NOTIFY message.
// Parameters : pNMHDR - a pointer to a NM_CUSTOMDRAW structure.
// pResult - value depends on the current drawing state.
{
LPNMCUSTOMDRAW lpcd = (LPNMCUSTOMDRAW)pNMHDR;
CDC *pDC = CDC::FromHandle(lpcd->hdc);
DWORD dwStyle = this->GetStyle();
switch(lpcd->dwDrawStage)
{
case CDDS_PREPAINT:
TRACE("!!CDDS_PREPAINT");
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
{
switch(lpcd->dwItemSpec)
{
case TBCD_TICS:
TRACE("$$TBCD_TICS");
*pResult = CDRF_DODEFAULT;
break;
case TBCD_THUMB:
TRACE("%%TBCD_THUMB");

DrawThumb(pDC, lpcd);
*pResult = CDRF_SKIPDEFAULT;
break;
case TBCD_CHANNEL:
TRACE("&&TBCD_CHANNEL");

DrawChannel(pDC, lpcd);
*pResult = CDRF_SKIPDEFAULT;
break;
}
break;
}
}
}void CMySliderControl::DrawChannel(CDC *pDC, LPNMCUSTOMDRAW lpcd)
{
CClientDC clientDC(GetParent());
CRect crect;
CRect wrect;
GetClientRect(crect);
GetWindowRect(wrect);
GetParent()->ScreenToClient(wrect);
if (m_dcBk == NULL)
{
m_dcBk = CreateCompatibleDC(clientDC.m_hDC);
m_bmpBk = CreateCompatibleBitmap(clientDC.m_hDC, crect.Width(), crect.Height());
m_bmpBkOld = (HBITMAP)::SelectObject(m_dcBk, m_bmpBk);
::BitBlt(m_dcBk, 0, 0, crect.Width(), crect.Height(), clientDC.m_hDC, wrect.left, wrect.top, SRCCOPY);
}
// //This bit does the tics s transparently.
// //create a memory dc to hold a copy of the oldbitmap data that includes the tics,
// //because when we add the background in we will lose the tic s
HDC hSaveHDC;
HBITMAP hSaveBmp;
int iWidth = crect.Width();
int iHeight = crect.Height();
hSaveHDC = ::CreateCompatibleDC(pDC->m_hDC);
hSaveBmp = ::CreateCompatibleBitmap(hSaveHDC, iWidth, iHeight);
HBITMAP hSaveCBmpOld = (HBITMAP)::SelectObject(hSaveHDC, hSaveBmp);
//set the colours for the monochrome mask bitmap
COLORREF crOldBack = ::SetBkColor(pDC->m_hDC, RGB(0,0,0));
COLORREF crOldText = ::SetTextColor(pDC->m_hDC, RGB(255,255,255));
::BitBlt(hSaveHDC, 0, 0, iWidth, iHeight, pDC->m_hDC, crect.left, crect.top, SRCCOPY);
::BitBlt(pDC->m_hDC, 0, 0, iWidth, iHeight, m_dcBk, 0, 0, SRCCOPY);
::BitBlt(pDC->m_hDC, 0, 0, iWidth, iHeight, hSaveHDC, 0, 0, SRCAND);
//restore and clean up
::SetBkColor(pDC->m_hDC, crOldBack);
::SetTextColor(pDC->m_hDC, crOldText);
::SelectObject(hSaveHDC, hSaveCBmpOld);
::DeleteObject(hSaveBmp);
::DeleteDC(hSaveHDC);
crect = lpcd->rc;
if ((crect.bottom - crect.top) > (crect.right - crect.left))
crect.InflateRect(1, 0, 1, 0);
else //is there a better way to know vert from horiz sliders??
crect.InflateRect(0, 2, 0, 2);
DrawEdge(pDC->m_hDC, &crect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
TRACE("@Ch called");
}
void CMySliderControl::DrawThumb(CDC *pDC, LPNMCUSTOMDRAW lpcd)
{
COLORREF col;
CRect crect;
GetThumbRect( crect );
CDC memdc;
CBitmap bitmap; BITMAP bm;
CRect rectThumb;
GetThumbRect( rectThumb );
memdc.CreateCompatibleDC( pDC ); 
bitmap.LoadBitmap( IDB_SLIDER );
CBitmap* pOldBtm = memdc.SelectObject( &bitmap );
bitmap.GetObject( sizeof(bm), &bm );
pDC->BitBlt( rectThumb.left, rectThumb.top, rectThumb.left+bm.bmWidth, rectThumb.top+bm.bmHeight, &memdc, 0, 0, SRCCOPY );
memdc.SelectObject( pOldBtm );
DeleteObject( bitmap );
memdc.DeleteDC();
TRACE("*TH called");}BOOL CMySliderControl::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
void CMySliderControl::SetThumbColors(COLORREF face, COLORREF highlight)
{
m_crThumbColor = face;
m_crThumbColorSelected = highlight;
}void CMySliderControl::DrawTransparent(BOOL bRepaint)
{
if (m_dcBk != NULL && m_bmpBkOld != NULL)
{
::SelectObject(m_dcBk, m_bmpBkOld);
}
::DeleteObject(m_bmpBk);
::DeleteDC(m_dcBk);
m_dcBk = NULL;
m_bmpBk = NULL;
if (bRepaint == TRUE) 
{
Invalidate();
EnableWindow(FALSE);
EnableWindow(TRUE);
}

解决方案 »

  1.   

    头文件
    #if !defined(AFX_SLIDERCONTROL_H)
    #define AFX_AFX_SLIDERCONTROL_H
    #pragma once   // speed up compiling with MSVC++, file will only be read once
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // MySliderControl.h : header file
    //
    //
    // MySliderControl.cpp : implementation file
    //
    //
    // FEATURES:
    //
    // Transparent background.
    // Custom Transparent Channel
    // Custom thumb with optional colours..
    // CStatic objects can be auto sized.
    // Derived from CSlider
    class CMySliderControl : public CSliderCtrl
    {
    HDC m_dcBk;
    HBITMAP m_bmpBk;
    HBITMAP     m_bmpBkOld;
    COLORREF m_crThumbColor;
    COLORREF m_crThumbColorSelected;// Construction
    public:
    CMySliderControl();
    bool m_bRedraw;
    // 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()
    public:
    void SetThumbColors(COLORREF face, COLORREF highlight);
    void SetllPos(LONGLONG nPos);
    void DrawTransparent(BOOL bRepaint);
    private:
    void DrawChannel(CDC *pDC, LPNMCUSTOMDRAW lpcd);
    void DrawThumb(CDC *pDC, LPNMCUSTOMDRAW lpcd);
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_SLIDERCONTROL_H)