一步步做一个自己的对话框类之一(绘图类库准备CMKDraw)

来源:互联网 发布:宇视科技java面试题 编辑:程序博客网 时间:2024/06/08 00:16

CMKDraw主要是用于位图的绘制,代码如下

1.头文件

 

///////////////////////////////////////////////////////////////////////////////
//
// Draw.h : header file
//
//////////////////////////////////////////////////////////////////////////////
/

#pragma once

///////////////////////////////////////////////////////////////////////////////
typedef DWORD HLSCOLOR;
#define HLS(h,l,s) ((HLSCOLOR)(((BYTE)(h)
|((WORD)((BYTE)(l))<<8))|(((DWORD)(BYTE)(s))<<16)))

///////////////////////////////////////////////////////////////////////////////
#define HLS_H(hls) ((BYTE)(hls))
#define HLS_L(hls) ((BYTE)(((WORD)(hls)) 
>> 8))
#define HLS_S(hls) ((BYTE)((hls)
>>16))

#define BMP_BACK     
0
#define BMP_NORMAL   
1
#define BMP_FOCUS    
2
#define BMP_DOWN     
3
#define BMP_DISABLE  
4
#define BMP_ACTIVE   
1
#define BMP_INACTIVE 
2
#define BMP_SLIDER   
3
#define BMP_CHECK    
1
#define BMP_UNCHECK  
2


//在指定的位置绘制阴影
#define SM_CXSHADOW 10

///////////////////////////////////////////////////////////////////////////////
HLSCOLOR RGB2HLS (COLORREF rgb);
COLORREF HLS2RGB (HLSCOLOR hls);

///////////////////////////////////////////////////////////////////////////////
// Performs some modifications on the specified color : luminance and saturation
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S);

///////////////////////////////////////////////////////////////////////////////
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect);

class CMKClientRect : public CRect
{
public:
    CMKClientRect (HWND hWnd)
    
{
        ::GetClientRect (hWnd, 
this);
    }
;
    CMKClientRect (
const CWnd* pWnd)
    
{
        ::GetClientRect (pWnd
->GetSafeHwnd(), this);
    }
;
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CMKWindowRect : public CRect
{
public:
    CMKWindowRect (HWND hWnd)
    
{
        ::GetWindowRect (hWnd, 
this);
    }
;
    CMKWindowRect (
const CWnd* pWnd)
    
{
        ::GetWindowRect (pWnd
->GetSafeHwnd(), this);
    }
;
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CMKWindowText : public CString
{
public:
    CMKWindowText (HWND hWnd)
    
{
        CWnd::FromHandle (hWnd)
->GetWindowText (*this);
    }
;
    CMKWindowText (
const CWnd* pWnd)
    
{
        pWnd
->GetWindowText (*this);
    }
;
}
;


class CMemDC : public CDC 
{
private:
    CBitmap
*    m_bitmap;
    CBitmap
*    m_oldBitmap;
    CDC
*        m_pDC;
    CRect        m_rcBounds;
public:
    CMemDC(CDC
* pDC, const CRect& rcBounds) : CDC()
    
{
        CreateCompatibleDC(pDC);
        m_bitmap 
= new CBitmap;
        m_bitmap
->CreateCompatibleBitmap(pDC, rcBounds.right, rcBounds.bottom);
        m_oldBitmap 
= SelectObject(m_bitmap);
        m_pDC 
= pDC;
        m_rcBounds 
= rcBounds;
    }

    
~CMemDC() 
    
{
        m_pDC
->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(), 
                    
this, m_rcBounds.left, m_rcBounds.top, SRCCOPY);
        SelectObject(m_oldBitmap);
        
if (m_bitmap != NULL) 
            delete m_bitmap;
    }

    CMemDC
* operator->() 
    
{
        
return this;
    }

}
;
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CBufferDC : public CDC
{
    HDC     m_hDestDC;
    CBitmap m_bitmap;     
// Bitmap in Memory DC
    CRect   m_rect;
    HGDIOBJ m_hOldBitmap; 
// Previous Bitmap

public:
    CBufferDC (HDC hDestDC, 
const CRect& rcPaint = CRect(0,0,0,0));
   
~CBufferDC ();
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CPenDC
{
protected:
    CPen m_pen;
    HDC m_hDC;
    HPEN m_hOldPen;

public:
    CPenDC (HDC hDC, COLORREF crColor 
= CLR_NONE);
   
~CPenDC ();

    
void Color (COLORREF crColor);
    COLORREF Color () 
const;
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CBrushDC
{
protected:
    CBrush m_brush;
    HDC m_hDC;
    HBRUSH m_hOldBrush;

public:
    CBrushDC (HDC hDC, COLORREF crColor 
= CLR_NONE);
   
~CBrushDC ();

    
void Color (COLORREF crColor);
    COLORREF Color () 
const;
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CFontDC
{
protected:
    HFONT m_hFont;
    HDC m_hDC;
    HFONT m_hDefFont;
    COLORREF m_crTextOld;

public:
    CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText 
= CLR_DEFAULT);
    CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText 
= CLR_DEFAULT);
    CFontDC (HDC hDC, HFONT hFont, COLORREF crText 
= CLR_DEFAULT);
   
~CFontDC ();

    
const CFontDC& operator = (LPCTSTR sFaceName);
    
const CFontDC& operator = (BYTE nStockFont);
    
const CFontDC& operator = (HFONT hFont);
    
const CFontDC& operator = (COLORREF crText);
    operator LPCTSTR ();
    operator COLORREF ();
}
;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
class CBoldDC
{
protected:
    CFont m_fontBold;
    HDC m_hDC;
    HFONT m_hDefFont;

public:
    CBoldDC (HDC hDC, bool bBold);
   
~CBoldDC ();
}
;

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class CMKBitmap : public CBitmap  
{
public:
    CMKBitmap();
    virtual 
~CMKBitmap();

    BOOL LoadImage(LPCTSTR szImagePath, COLORREF crBack 
= 0);
    BOOL LoadImage(UINT uIDRes, LPCTSTR szResourceType, HMODULE hInst 
= NULL, COLORREF crBack = 0); 
    BOOL LoadBitmap (UINT nIDResource)
    
{
        
return CBitmap::LoadBitmap(nIDResource);
    }


    
// helpers
    static BOOL GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void* pResource, int& nBufSize);
    
static IPicture* LoadFromBuffer(BYTE* pBuff, int nSize);


    BOOL Draw( CDC 
*pDC, LPRECT r);
    
//draw sub bmp to special point
    BOOL Draw( CDC *pDC, int x, int y, LPRECT sr );
    BOOL Draw( CDC 
*pDC, int x, int y, LPRECT sr, COLORREF colTrans, BOOL bTrans );

    BOOL StretchDraw(CDC 
*pDC, LPRECT tr, LPRECT sr );
    BOOL StretchDraw(CDC 
*pDC, LPRECT r);

    
int     Width() return GetWidth(); }
    
int     Height()return GetHeight();}
    
int     GetWidth() 
    
{
        
if (!GetSafeHandle())
            
return 0;
        BITMAP bm;
        memset( 
&bm, 0, sizeof(bm) );
        GetBitmap(
&bm);
        
return bm.bmWidth;
    }

    
int     GetHeight()
    
{
        
if (!GetSafeHandle())
            
return 0;
        BITMAP bm;
        memset( 
&bm, 0, sizeof(bm) );
        GetBitmap(
&bm);
        
return bm.bmHeight;
    }


    BOOL Attach(HBITMAP hbmp) 
{    return CBitmap::Attach( hbmp );}
    BOOL LoadBitmap(LPCTSTR szFilename) 
    

        ASSERT(szFilename);
        DeleteObject();
        
return LoadImage( szFilename );
    }


    BOOL DrawTransparent(CDC 
* pDC, int x, int y, COLORREF crColour);    
    HRGN CreateRgnFromFile( COLORREF color );

    
static void MKTransparentBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth, 
                           
int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc,
                           COLORREF colorTransparent, HPALETTE hPal );

protected:
    BOOL Attach(IPicture
* pPicture, COLORREF crBack);

}
;


class CMKDraw
{
public:
    typedef 
enum _tagDrawMode
    
{
        DrawModeFill 
= 0,
        DrawModeWidthStretch 
= 1,
        DrawModeHeightStretch 
= 2,
        DrawModeAllStretch 
= 3,
        DrawMode3D 
= 4,
        DrawModeState 
= 5,
        DrawModeHeightCenter3D 
= 6,
        DrawModeHeightStretch3D 
= 7
    }
DrawMode;

    
static BOOL MKDrawBitmap(CDC* pDC, LPCRECT lpRect, CBitmap* pBitmap,UINT Mode = DrawModeHeightStretch);
    
static BOOL MKDrawVerticalText(CDC* pDC,LPCRECT lpRect,LPCTSTR lpText,int length,UINT format,LOGFONT *lf);
    
static HRGN BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010);
    
static BOOL MKFillGradient(CDC *pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz = TRUE ) ;
    
static void MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT& rc) ;

}
;

 2.实现文件,CPP文件如下:

 

///////////////////////////////////////////////////////////////////////////////
//
// Draw.cpp : implementation file
//
//////////////////////////////////////////////////////////////////////////////
/

#include 
"stdafx.h"
#include 
"MKDraw.h"
///////////////////////////////////////////////////////////////////////////////
HLSCOLOR RGB2HLS (COLORREF rgb)
{
    unsigned 
char minval = min(GetRValue(rgb), min(GetGValue(rgb), GetBValue(rgb)));
    unsigned 
char maxval = max(GetRValue(rgb), max(GetGValue(rgb), GetBValue(rgb)));
    
float mdiff  = float(maxval) - float(minval);
    
float msum   = float(maxval) + float(minval);
   
    
float luminance = msum / 510.0f;
    
float saturation = 0.0f;
    
float hue = 0.0f

    
if ( maxval != minval )
    

        
float rnorm = (maxval - GetRValue(rgb)  ) / mdiff;      
        
float gnorm = (maxval - GetGValue(rgb)) / mdiff;
        
float bnorm = (maxval - GetBValue(rgb) ) / mdiff;   

        saturation 
= (luminance <= 0.5f? (mdiff / msum) : (mdiff / (510.0f - msum));

        
if (GetRValue(rgb) == maxval) hue = 60.0f * (6.0f + bnorm - gnorm);
        
if (GetGValue(rgb) == maxval) hue = 60.0f * (2.0f + rnorm - bnorm);
        
if (GetBValue(rgb) == maxval) hue = 60.0f * (4.0f + gnorm - rnorm);
        
if (hue > 360.0f) hue = hue - 360.0f;
    }

    
return HLS ((hue*255)/360, luminance*255, saturation*255);
}


///////////////////////////////////////////////////////////////////////////////
static BYTE _ToRGB (float rm1, float rm2, float rh)
{
  
if      (rh > 360.0f) rh -= 360.0f;
  
else if (rh <   0.0f) rh += 360.0f;
 
  
if      (rh <  60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;   
  
else if (rh < 180.0f) rm1 = rm2;
  
else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;      
                   
  
return (BYTE)(rm1 * 255);
}


///////////////////////////////////////////////////////////////////////////////
COLORREF HLS2RGB (HLSCOLOR hls)
{
    
float hue        = ((int)HLS_H(hls)*360)/255.0f;
    
float luminance  = HLS_L(hls)/255.0f;
    
float saturation = HLS_S(hls)/255.0f;

    
if ( saturation == 0.0f )
    
{
        
return RGB (HLS_L(hls), HLS_L(hls), HLS_L(hls));
    }

    
float rm1, rm2;
     
    
if ( luminance <= 0.5f ) rm2 = luminance + luminance * saturation;  
    
else                     rm2 = luminance + saturation - luminance * saturation;
    rm1 
= 2.0f * luminance - rm2;   
    BYTE red   
= _ToRGB (rm1, rm2, hue + 120.0f);   
    BYTE green 
= _ToRGB (rm1, rm2, hue);
    BYTE blue  
= _ToRGB (rm1, rm2, hue - 120.0f);

    
return RGB (red, green, blue);
}


///////////////////////////////////////////////////////////////////////////////
COLORREF HLS_TRANSFORM (COLORREF rgb, int percent_L, int percent_S)
{
    HLSCOLOR hls 
= RGB2HLS (rgb);
    BYTE h 
= HLS_H(hls);
    BYTE l 
= HLS_L(hls);
    BYTE s 
= HLS_S(hls);

    
if ( percent_L > 0 )
    
{
        l 
= BYTE(l + ((255 - l) * percent_L) / 100);
    }

    
else if ( percent_L < 0 )
    
{
        l 
= BYTE((l * (100+percent_L)) / 100);
    }

    
if ( percent_S > 0 )
    
{
        s 
= BYTE(s + ((255 - s) * percent_S) / 100);
    }

    
else if ( percent_S < 0 )
    
{
        s 
= BYTE((s * (100+percent_S)) / 100);
    }

    
return HLS2RGB (HLS(h, l, s));
}


/////////////////////////////////////////////////////////////////////////////
HBITMAP WINAPI GetScreenBitmap (LPCRECT pRect)
{
    HDC     hDC;
    HDC     hMemDC;
    HBITMAP hNewBitmap 
= NULL;

    
if ( (hDC = ::GetDC (NULL)) != NULL )
    
{
        
if ( (hMemDC = ::CreateCompatibleDC (hDC)) != NULL )
        
{
            
if ( (hNewBitmap = ::CreateCompatibleBitmap (hDC, pRect->right - pRect->left, pRect->bottom - pRect->top)) != NULL )
            
{
                HBITMAP hOldBitmap 
= (HBITMAP)::SelectObject(hMemDC, hNewBitmap);
                ::BitBlt (hMemDC, 
00, pRect->right - pRect->left, pRect->bottom - pRect->top,
                          hDC, pRect
->left, pRect->top, SRCCOPY);
                ::SelectObject (hMemDC, (HGDIOBJ) hOldBitmap);
            }

            ::DeleteDC (hMemDC);
        }

        ::ReleaseDC (NULL, hDC);
    }

    
return hNewBitmap;
}



///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
CBufferDC::CBufferDC (HDC hDestDC, const CRect& rcPaint) : m_hDestDC (hDestDC)
{
    
if ( rcPaint.IsRectEmpty() )
    
{
        ::GetClipBox (m_hDestDC, m_rect);
    }

    
else
    
{
        m_rect 
= rcPaint;
    }

    VERIFY(Attach (::CreateCompatibleDC (m_hDestDC)));
    m_bitmap.Attach (::CreateCompatibleBitmap (m_hDestDC, m_rect.right, m_rect.bottom));
    m_hOldBitmap 
= ::SelectObject (m_hDC, m_bitmap);

    
if ( m_rect.top > 0 )
    
{
        ExcludeClipRect (
00, m_rect.right, m_rect.top);
    }

    
if ( m_rect.left > 0 )
    
{
        ExcludeClipRect (
0, m_rect.top, m_rect.left, m_rect.bottom);
    }

}


///////////////////////////////////////////////////////////////////////////////
CBufferDC::~CBufferDC ()
{
    VERIFY(::BitBlt (m_hDestDC, m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), m_hDC, m_rect.left, m_rect.top, SRCCOPY));
    ::SelectObject (m_hDC, m_hOldBitmap);
}



///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
CPenDC::CPenDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
{
    VERIFY(m_pen.CreatePen (PS_SOLID, 
1, crColor));
    m_hOldPen 
= (HPEN)::SelectObject (m_hDC, m_pen);
}


///////////////////////////////////////////////////////////////////////////////
CPenDC::~CPenDC ()
{
    ::SelectObject (m_hDC, m_hOldPen);
}


///////////////////////////////////////////////////////////////////////////////
void CPenDC::Color (COLORREF crColor)
{
    ::SelectObject (m_hDC, m_hOldPen);
    VERIFY(m_pen.DeleteObject());
    VERIFY(m_pen.CreatePen (PS_SOLID, 
1, crColor));
    m_hOldPen 
= (HPEN)::SelectObject (m_hDC, m_pen);
}


///////////////////////////////////////////////////////////////////////////////
COLORREF CPenDC::Color () const
{
    LOGPEN logPen;

    ((CPenDC
*)this)->m_pen.GetLogPen (&logPen);

    
return logPen.lopnColor;
}



///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/
CBrushDC::CBrushDC (HDC hDC, COLORREF crColor) : m_hDC (hDC)
{
    
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
    
else                       VERIFY(m_brush.CreateSolidBrush (crColor));
    m_hOldBrush 
= (HBRUSH)::SelectObject (m_hDC, m_brush);
}


///////////////////////////////////////////////////////////////////////////////
CBrushDC::~CBrushDC ()
{
    ::SelectObject (m_hDC, m_hOldBrush);
}


///////////////////////////////////////////////////////////////////////////////
void CBrushDC::Color (COLORREF crColor)
{
    ::SelectObject (m_hDC, m_hOldBrush);
    VERIFY(m_brush.DeleteObject());
    
if ( crColor == CLR_NONE ) VERIFY(m_brush.CreateStockObject (NULL_BRUSH));
    
else                       VERIFY(m_brush.CreateSolidBrush (crColor));
    m_hOldBrush 
= (HBRUSH)::SelectObject (m_hDC, m_brush);
}


///////////////////////////////////////////////////////////////////////////////
COLORREF CBrushDC::Color () const
{
    LOGBRUSH logBrush;

    ((CBrushDC
*)this)->m_brush.GetLogBrush (&logBrush);

    
return logBrush.lbColor;
}



/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/
CFontDC::CFontDC (HDC hDC, LPCTSTR sFaceName, COLORREF crText)
        : m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
    
*this = sFaceName;

    
if ( crText != CLR_DEFAULT )
    
{
        
*this = crText;
    }

}


/////////////////////////////////////////////////////////////////////////////
CFontDC::CFontDC (HDC hDC, BYTE nStockFont, COLORREF crText)
        : m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
    
*this = nStockFont;

    
if ( crText != CLR_DEFAULT )
    
{
        
*this = crText;
    }

}


/////////////////////////////////////////////////////////////////////////////
CFontDC::CFontDC (HDC hDC, HFONT hFont, COLORREF crText)
        : m_hDC (hDC), m_hFont (NULL), m_hDefFont (NULL), m_crTextOld (CLR_NONE)
{
    
*this = hFont;

    
if ( crText != CLR_DEFAULT )
    
{
        
*this = crText;
    }

}


/////////////////////////////////////////////////////////////////////////////
CFontDC::~CFontDC ()
{
    
if ( m_hDefFont != NULL )
    
{
        ::SelectObject (m_hDC, m_hDefFont);
        DeleteObject (m_hFont);
    }

    
if ( m_crTextOld != CLR_NONE )
    
{
        ::SetTextColor (m_hDC, m_crTextOld);
    }

}


/////////////////////////////////////////////////////////////////////////////
const CFontDC& CFontDC::operator = (LPCTSTR sFaceName)
{
    LOGFONT lf;

    ::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), 
&lf);

    
if ( _tcsicmp (sFaceName, lf.lfFaceName) )
    
{
        
if ( m_hDefFont != NULL )
        
{
            ::SelectObject (m_hDC, m_hDefFont);
            DeleteObject (m_hFont);
        }

        _tcscpy (lf.lfFaceName, sFaceName);
        m_hFont 
= ::CreateFontIndirect (&lf);
        m_hDefFont 
= (HFONT)::SelectObject (m_hDC, m_hFont);
    }

    
return *this;
}


/////////////////////////////////////////////////////////////////////////////
const CFontDC& CFontDC::operator = (BYTE nStockFont)
{
    
if ( m_hDefFont != NULL )
    
{
        ::SelectObject (m_hDC, m_hDefFont);
        DeleteObject (m_hFont);
    }

    m_hFont 
= (HFONT)::GetStockObject (nStockFont);
    m_hDefFont 
= (HFONT)::SelectObject (m_hDC, m_hFont);

    
return *this;
}


/////////////////////////////////////////////////////////////////////////////
const CFontDC& CFontDC::operator = (HFONT hFont)
{
    
if ( m_hDefFont != NULL )
    
{
        ::SelectObject (m_hDC, m_hDefFont);
        DeleteObject (m_hFont);
    }

    m_hFont 
= hFont;
    m_hDefFont 
= (HFONT)::SelectObject (m_hDC, m_hFont);

    
return *this;
}


/////////////////////////////////////////////////////////////////////////////
const CFontDC& CFontDC::operator = (COLORREF crText)
{
    
if ( m_crTextOld == CLR_NONE )
    
{
        m_crTextOld 
= ::GetTextColor (m_hDC);
    }

    ::SetTextColor (m_hDC, crText);

    
return *this;
}


/////////////////////////////////////////////////////////////////////////////
CFontDC::operator LPCTSTR ()
{
    LOGFONT lf;

    ::GetObject (::GetCurrentObject (m_hDC, OBJ_FONT), sizeof(LOGFONT), 
&lf);

    
return lf.lfFaceName;
}


/////////////////////////////////////////////////////////////////////////////
CFontDC::operator COLORREF ()
{
    
return ::GetTextColor (m_hDC);
}



/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/
CBoldDC::CBoldDC (HDC hDC, bool bBold) : m_hDC (hDC), m_hDefFont (NULL)
{
    LOGFONT lf;

    CFont::FromHandle((HFONT)::GetCurrentObject(m_hDC, OBJ_FONT))
->GetLogFont (&lf);

    
if ( ( bBold && lf.lfWeight != FW_BOLD) ||
         (
!bBold && lf.lfWeight == FW_BOLD) )
    
{
        lf.lfWeight 
= bBold ? FW_BOLD : FW_NORMAL;

        m_fontBold.CreateFontIndirect (
&lf);
        m_hDefFont 
= (HFONT)::SelectObject (m_hDC, m_fontBold);
    }

}


/////////////////////////////////////////////////////////////////////////////
CBoldDC::~CBoldDC ()
{
    
if ( m_hDefFont != NULL )
    
{
        ::SelectObject (m_hDC, m_hDefFont);
    }

}



/////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/
#define DB_GETTYPE(Style)       ((Style)&0x00FF)
#define DB_ISENABLED(Style)     (
!((Style)&DB_DISABLED))
#define DB_ISBORDER(Style)      (((Style)
&DB_BORDER)==DB_BORDER)
#define DB_ISWINDOWDC(Style)    (((Style)
&DB_WINDOWDC)==DB_WINDOWDC)
#define DB_ISFLAT(Style)        (((Style)
&DB_FLAT)==DB_FLAT)
#define DB_ISPRESSED(Style)     (((Style)
&(DB_PRESSED|DB_PRESSED2))!=0)
#define DB_ISPRESSED1(Style)    (((Style)
&DB_PRESSED)==DB_PRESSED)
#define DB_ISPRESSED2(Style)    (((Style)
&DB_PRESSED2)==DB_PRESSED2)
#define DB_ISOVER(Style)        (((Style)
&DB_OVER)==DB_OVER)
#define DB_ISTRANSPARENT(Style) (((Style)
&DB_TRANSPARENT)==DB_TRANSPARENT)

/////////////////////////////////////////////////////////////////////////////
static void _DrawTriangle (CDC* pDC, int x, int y, int nSize, bool bDown)
{
    
for ( int i = 0; i < nSize; i++ )
    
{
        pDC
->MoveTo (x-i, bDown ? y-i : y+i);
        pDC
->LineTo (x+i+1, bDown ? y-i : y+i);
    }

}

BOOL CMKDraw::MKDrawVerticalText(CDC
* pDC,LPCRECT lpRect,LPCTSTR lpText,int length,UINT format,LOGFONT *lf)
{
    
char *ptr = (char *)lpText;
    
char *start = (char *)lpText;
    
char *end = (char *)(lpText + length - 1);
    
char temp = NULL;

    BOOL IsUnicode 
= FALSE;
    
while(ptr <= end)
    
{
        
if(*ptr & 0x80)
        
{
            IsUnicode 
= TRUE;
            
break;
        }

    }

    ptr 
= (char *)lpText;
    CRect rtText;
    CSize sz;
    
int top = lpRect->top;
    
if(!IsUnicode)
    
{
        lf
->lfEscapement = 900;
        lf
->lfOrientation = 900;
        CFont font;
        font.CreateFontIndirect(lf);
        pDC
->SelectObject(&font);
        sz 
= pDC->GetTextExtent(start,(int)(end - start));
        rtText.left 
= lpRect->left + (lpRect->right - lpRect->left - sz.cy)/2;
        rtText.top 
= top;
        rtText.bottom 
= rtText.top + sz.cx;
        rtText.right 
= lpRect->right;
        pDC
->TextOut(rtText.left,rtText.bottom,start,(int)(end - start));
        
return TRUE;
    }


    lf
->lfEscapement = 0;
    lf
->lfOrientation = 0;
    CFont font;
    font.CreateFontIndirect(lf);
    pDC
->SelectObject(&font);
    
while(ptr <= end)
    
{
        
        
//UNICODE 
        if(*ptr & 0x80)
        
{
            
if(ptr + 1 > end)break;
            start 
= ptr;
            ptr 
+= 2;
            sz 
= pDC->GetTextExtent(start,(int)(ptr - start));
            CRect rtText;
            rtText.SetRect(lpRect
->left + (lpRect->right - lpRect->left - sz.cx)/2,
                top,lpRect
->right,lpRect->bottom);
            pDC
->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
            top 
+= sz.cy;
        }

        
else
        
{
            start 
= ptr;
            ptr 
+= 1;
            sz 
= pDC->GetTextExtent(start,(int)(ptr - start));
            CRect rtText;
            rtText.SetRect(lpRect
->left + (lpRect->right - lpRect->left - sz.cx)/2,
                top,lpRect
->right,lpRect->bottom);
            pDC
->TextOut(rtText.left,rtText.top, start,(int)(ptr - start));
            top 
+= sz.cy;
        }

    }

    
return TRUE;
}


//BITMAP Width and height > 9
BOOL CMKDraw::MKDrawBitmap(CDC* pDC, LPCRECT lpRect, CBitmap* pBitmap,UINT Mode)
{
    
if(pDC == NULL)return FALSE;
    
if(pBitmap == NULL)return FALSE;

    BITMAP bitmap;
    pBitmap
->GetBitmap(&bitmap);
    
if(bitmap.bmWidth < 9)return FALSE;
    
if(bitmap.bmHeight < 9)return FALSE;

    CDC srcDC;
    srcDC.CreateCompatibleDC(pDC);
    CBitmap 
*pOldBitmap = srcDC.SelectObject(pBitmap);

    
if(Mode == DrawModeState)
    
{
        pDC
->StretchBlt(lpRect->left,lpRect->top,bitmap.bmWidth,bitmap.bmHeight,
            
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
        
return TRUE;
    }


    
if((DrawMode)Mode == DrawModeAllStretch)
    
{
        pDC
->StretchBlt(lpRect->left,lpRect->top,lpRect->right - lpRect->left,
            lpRect
->bottom - lpRect->top,&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
        srcDC.SelectObject(pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }


    
int height;
    
int width;

    
if((DrawMode)Mode == DrawModeFill)
    
{
        
int left = lpRect->left;
        
int top = lpRect->top;
        
while(left < lpRect->right)
        
{
            
if(lpRect->right - left <= bitmap.bmWidth)
            
{
                width 
= lpRect->right - left;
                
if(lpRect->bottom - top <= bitmap.bmHeight)
                
{
                    height 
= lpRect->bottom - top;
                    pDC
->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
                    
break;
                }

                
else
                
{
                    height 
= bitmap.bmHeight;
                    pDC
->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
                    top 
+= height;
                    left 
= lpRect->left;
                }

            }

            
else
            
{
                width 
= bitmap.bmWidth;
                
if(lpRect->bottom - top <= bitmap.bmHeight)
                
{
                    height 
= lpRect->bottom - top;
                    pDC
->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
                }

                
else
                
{
                    height 
= bitmap.bmHeight;
                    pDC
->BitBlt(left,top,width,height,&srcDC,0,0,SRCCOPY);
                }

                left 
+= width;
            }

        }

        srcDC.SelectObject(pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }


    
if(Mode == DrawModeHeightStretch)
    
{
        height 
= lpRect->bottom - lpRect->top;
        
int top = lpRect->top;
        
int left = lpRect->left;
        
int right = lpRect->right;

        
while((right - left) >= bitmap.bmWidth)
        
{
            pDC
->StretchBlt(left,top,bitmap.bmWidth,height,
                
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
            left 
+= bitmap.bmWidth;
        }

        width 
= right - left;
        pDC
->StretchBlt(left,top,width,height,
                
&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);

        srcDC.SelectObject(
&pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }


    
if(Mode == DrawModeWidthStretch)
    
{
        height 
= lpRect->bottom - lpRect->top;
        
int top = lpRect->top;
        width 
= lpRect->right - lpRect->left;
        
int left = lpRect->left;
        
int bottom = lpRect->bottom;

        
while((bottom - top) >= bitmap.bmHeight)
        
{
            pDC
->StretchBlt(left,top,width,bitmap.bmHeight,
                
&srcDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
            top 
+= bitmap.bmHeight;
        }

        height 
= bottom - top;
        pDC
->StretchBlt(left,top,width,height,
            
&srcDC,4,0,bitmap.bmWidth,height,SRCCOPY);

        srcDC.SelectObject(
&pOldBitmap);
        srcDC.DeleteDC();
    }


    
if(Mode == DrawMode3D)
    
{
        
int width = bitmap.bmWidth/3;
        
int height = bitmap.bmHeight/3;

        
int x = lpRect->left + width;
        
int y = lpRect->top + height;

        
//fill center
        while( x + width < lpRect->right)
        
{
            
while(y + height < lpRect->bottom)
            
{
                pDC
->BitBlt(x,y,width,height,&srcDC,width,height,SRCCOPY);
                y 
+= height;
            }

            y 
= lpRect->top + height;
            x 
+= width;
        }

        
//draw top border
        x = lpRect->left + width;
        y 
= lpRect->top;
        pDC
->BitBlt(lpRect->left,y,width,height,&srcDC,0,0,SRCCOPY);
        
while( x + width < lpRect->right)
        
{
            pDC
->BitBlt(x,y,width,height,&srcDC,width,0,SRCCOPY);
            x 
+= width;
        }

        pDC
->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,0,SRCCOPY);
        
        
//draw left border
        x = lpRect->left;
        y 
= lpRect->top + height;
        
while( y + height < lpRect->bottom)
        
{
            pDC
->BitBlt(x,y,width,height,&srcDC,0,height,SRCCOPY);
            y 
+= height;
        }


        
//draw right border
        x = lpRect->right - width;
        y 
= lpRect->top + height;
        
while( y + height < lpRect->bottom)
        
{
            pDC
->BitBlt(x,y,width,height,&srcDC,width + width,height,SRCCOPY);
            y 
+= height;
        }

            
        
//draw bottom border
        x = lpRect->left + width;
        y 
= lpRect->bottom - height;
        pDC
->BitBlt(lpRect->left,y,width,height,&srcDC,0,height + height,SRCCOPY);
        
while( x + width < lpRect->right)
        
{
            pDC
->BitBlt(x,y,width,height,&srcDC,width,height + height,SRCCOPY);
            x 
+= width;
        }

        pDC
->BitBlt(lpRect->right - width,y,width,height,&srcDC,width + width,height + height,SRCCOPY);
    
        srcDC.SelectObject(
&pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }

    
if(Mode == DrawModeHeightStretch3D)
    
{
        
int width = bitmap.bmWidth / 3;
        
int height = lpRect->bottom - lpRect->top;
        
int x = lpRect->left;
        
int y = lpRect->top;
        
int right = lpRect->right;

        pDC
->StretchBlt(x,y,width,height,&srcDC,0,0,width,bitmap.bmHeight,SRCCOPY);
        
while((x + width) < right)
        
{
            pDC
->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
            x 
+= width;
        }

        pDC
->StretchBlt(right - width,y,width,height,&srcDC,width + width,0,width,bitmap.bmHeight,SRCCOPY);

        srcDC.SelectObject(
&pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }


    
if(Mode == DrawModeHeightCenter3D)
    
{
        
int width = bitmap.bmWidth / 3;
        
int height = lpRect->bottom - lpRect->top;
        
int x = lpRect->left;
        
int y = lpRect->top;
        
int right = lpRect->right;
        
while((x + width) < right)
        
{
            pDC
->StretchBlt(x,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);
            x 
+= width;
        }

        pDC
->StretchBlt(right - width,y,width,height,&srcDC,width,0,width,bitmap.bmHeight,SRCCOPY);

        srcDC.SelectObject(
&pOldBitmap);
        srcDC.DeleteDC();
        
return TRUE;
    }


    srcDC.SelectObject(
&pOldBitmap);
    srcDC.DeleteDC();
    
return TRUE;
}


HRGN CMKDraw::BitmapToRegion (HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
{
    HRGN hRgn 
= NULL;

    
if (hBmp)
    
{
        
// Create a memory DC inside which we will scan the bitmap content
        HDC hMemDC = CreateCompatibleDC(NULL);
        
if (hMemDC)
        
{
            
// Get bitmap size
            BITMAP bm;
            GetObject(hBmp, sizeof(bm), 
&bm);

            
// Create a 32 bits depth bitmap and select it into the memory DC 
            BITMAPINFOHEADER RGB32BITSBITMAPINFO = {    
                    sizeof(BITMAPINFOHEADER),    
// biSize 
                    bm.bmWidth,                    // biWidth; 
                    bm.bmHeight,                // biHeight; 
                    1,                            // biPlanes; 
                    32,                            // biBitCount 
                    BI_RGB,                        // biCompression; 
                    0,                            // biSizeImage; 
                    0,                            // biXPelsPerMeter; 
                    0,                            // biYPelsPerMeter; 
                    0,                            // biClrUsed; 
                    0                            // biClrImportant; 
            }
;
            VOID 
* pbits32; 
            HBITMAP hbm32 
= CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
            
if (hbm32)
            
{
                HBITMAP holdBmp 
= (HBITMAP)SelectObject(hMemDC, hbm32);

                
// Create a DC just to copy the bitmap into the memory DC
                HDC hDC = CreateCompatibleDC(hMemDC);
                
if (hDC)
                
{
                    
// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
                    BITMAP bm32;
                    GetObject(hbm32, sizeof(bm32), 
&bm32);
                    
while (bm32.bmWidthBytes % 4)
                        bm32.bmWidthBytes
++;

                    
// Copy the bitmap into the memory DC
                    HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
                    BitBlt(hMemDC, 
00, bm.bmWidth, bm.bmHeight, hDC, 00, SRCCOPY);

                    
// For better performances, we will use the ExtCreateRegion() function to create the
                    
// region. This function take a RGNDATA structure on entry. We will add rectangles by
                    
// amount of ALLOC_UNIT number in this structure.
                    #define ALLOC_UNIT    100
                    DWORD maxRects 
= ALLOC_UNIT;
                    HANDLE hData 
= GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
                    RGNDATA 
*pData = (RGNDATA *)GlobalLock(hData);
                    pData
->rdh.dwSize = sizeof(RGNDATAHEADER);
                    pData
->rdh.iType = RDH_RECTANGLES;
                    pData
->rdh.nCount = pData->rdh.nRgnSize = 0;
                    SetRect(
&pData->rdh.rcBound, MAXLONG, MAXLONG, 00);

                    
// Keep on hand highest and lowest values for the "transparent" pixels
                    BYTE lr = GetRValue(cTransparentColor);
                    BYTE lg 
= GetGValue(cTransparentColor);
                    BYTE lb 
= GetBValue(cTransparentColor);
                    BYTE hr 
= min(0xff, lr + GetRValue(cTolerance));
                    BYTE hg 
= min(0xff, lg + GetGValue(cTolerance));
                    BYTE hb 
= min(0xff, lb + GetBValue(cTolerance));

                    
// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
                    BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1* bm32.bmWidthBytes;
                    
for (int y = 0; y < bm.bmHeight; y++)
                    
{
                        TRACE(
" ");
                        
// Scan each bitmap pixel from left to right
                        for (int x = 0; x < bm.bmWidth; x++)
                        
{
                            
// Search for a continuous range of "non transparent pixels"
                            int x0 = x;
                            LONG 
*= (LONG *)p32 + x;
                            
while (x < bm.bmWidth)
                            
{
                                TRACE(
"1");
                                BYTE b 
= GetRValue(*p);
                                
if (b >= lr && b <= hr)
                                
{
                                    b 
= GetGValue(*p);
                                    
if (b >= lg && b <= hg)
                                    
{
                                        b 
= GetBValue(*p);
                                        
if (b >= lb && b <= hb)
                                        
{
                                            TRACE(
"0");
                                            
// This pixel is "transparent"
                                            break;
                                        }

                                    }

                                }

                                p
++;
                                x
++;
                            }


                            
if (x > x0)
                            
{
                                
// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
                                if (pData->rdh.nCount >= maxRects)
                                
{
                                    GlobalUnlock(hData);
                                    maxRects 
+= ALLOC_UNIT;
                                    hData 
= GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
                                    pData 
= (RGNDATA *)GlobalLock(hData);
                                }

                                RECT 
*pr = (RECT *)&pData->Buffer;
                                SetRect(
&pr[pData->rdh.nCount], x0, y, x, y+1);
                                
if (x0 < pData->rdh.rcBound.left)
                                    pData
->rdh.rcBound.left = x0;
                                
if (y < pData->rdh.rcBound.top)
                                    pData
->rdh.rcBound.top = y;
                                
if (x > pData->rdh.rcBound.right)
                                    pData
->rdh.rcBound.right = x;
                                
if (y+1 > pData->rdh.rcBound.bottom)
                                    pData
->rdh.rcBound.bottom = y+1;
                                pData
->rdh.nCount++;

                                
// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
                                
// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
                                if (pData->rdh.nCount == 2000)
                                
{
                                    HRGN h 
= ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
                                    
if (hRgn)
                                    
{
                                        CombineRgn(hRgn, hRgn, h, RGN_OR);
                                        DeleteObject(h);
                                    }

                                    
else
                                        hRgn 
= h;
                                    pData
->rdh.nCount = 0;
                                    SetRect(
&pData->rdh.rcBound, MAXLONG, MAXLONG, 00);
                                }

                            }

                        }


                        
// Go to next row (remember, the bitmap is inverted vertically)
                        p32 -= bm32.bmWidthBytes;
                    }


                    
// Create or extend the region with the remaining rectangles
                    HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
                    
if (hRgn)
                    
{
                        CombineRgn(hRgn, hRgn, h, RGN_OR);
                        DeleteObject(h);
                    }

                    
else
                        hRgn 
= h;

                    
// Clean up
                    GlobalFree(hData);
                    SelectObject(hDC, holdBmp);
                    DeleteDC(hDC);
                }


                DeleteObject(SelectObject(hMemDC, holdBmp));
            }


            DeleteDC(hMemDC);
        }
    
    }


    
return hRgn;
}
 


BOOL CMKDraw::MKFillGradient(CDC 
*pDC, CRect rect, COLORREF colorStart, COLORREF colorFinish, BOOL bHorz /*= TRUE*/ )
{
    
int nShift = 6;
    
int nSteps = 1 << nShift;

    
for (int i = 0; i < nSteps; i++)
    
{
        BYTE bR 
= (BYTE) ((GetRValue(colorStart) * (nSteps - i) +
                   GetRValue(colorFinish) 
* i) >> nShift);
        BYTE bG 
= (BYTE) ((GetGValue(colorStart) * (nSteps - i) +
                   GetGValue(colorFinish) 
* i) >> nShift);
        BYTE bB 
= (BYTE) ((GetBValue(colorStart) * (nSteps - i) +
                   GetBValue(colorFinish) 
* i) >> nShift);
        CBrush br (RGB(bR, bG, bB));
        CRect r2 
= rect;
        
if (bHorz)
        
{
            r2.bottom 
= rect.bottom - 
                ((i 
* rect.Height()) >> nShift);
            r2.top 
= rect.bottom - 
                (((i 
+ 1* rect.Height()) >> nShift );
            
if (r2.Height() > 0)
                pDC
->FillRect(r2, &br);
        }

        
else
        
{
            r2.left 
= rect.left + 
                ((i 
* rect.Width()) >> nShift);
            r2.right 
= rect.left + 
                (((i 
+ 1* rect.Width()) >> nShift);
            
if (r2.Width() > 0)
                pDC
->FillRect(r2, &br);
        }

    }


    
return TRUE ;
}


void CMKDraw::MKDrawShadow(HDC hDCIn, HDC hDCOut, RECT& rc)
{
    
for ( int x = 0; x < rc.right-1; x++ )
    
{
        
int nEnd = ( x > rc.right-SM_CXSHADOW*2 ) ? rc.right-SM_CXSHADOW-x : SM_CXSHADOW;

        
for ( int y = ( x < 2 ) ? 2-x : x > rc.right-SM_CXSHADOW-3 ? x-rc.right+SM_CXSHADOW+3 : 0; y < nEnd; y++ )
        
{
            
int nMakeSpec = 78+(3-(x==0?0:(x==1?(y<2?0:1):(x==2?(y<2?y:2):y))))*5;
            COLORREF cr 
= GetPixel (hDCIn, x+SM_CXSHADOW, rc.bottom-y-1);
            COLORREF cr2 
= RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
                               ((nMakeSpec 
* int(GetGValue(cr))) / 100),
                               ((nMakeSpec 
* int(GetBValue(cr))) / 100));
            SetPixel (hDCOut, x
+SM_CXSHADOW, rc.bottom-y-1, cr2);
        }

    }

    
    
for ( x = 0; x < SM_CXSHADOW; x++ )
    
{
        
for ( int y = rc.top ; y < rc.bottom-x-SM_CXSHADOW-((x>0)?1:2); y++ )
        
{
            
int nMakeSpec = 78+(3-(y==0?0:(y==1?(x<2?0:1):(y==2?(x<2?x:2):x))))*5;
            COLORREF cr 
= GetPixel (hDCIn, rc.right-x-1, y+SM_CXSHADOW);
            COLORREF cr2 
= RGB(((nMakeSpec * int(GetRValue(cr))) / 100),
                               ((nMakeSpec 
* int(GetGValue(cr))) / 100),
                               ((nMakeSpec 
* int(GetBValue(cr))) / 100));
            SetPixel (hDCOut, rc.right
-x-1, y+SM_CXSHADOW, cr2);
        }

    }

}

 

下一步介绍如何用这个绘制对话框.

原创粉丝点击