现在的位置: 首页 > 综合 > 正文

VC版本改写的变色龙按钮

2013年04月08日 ⁄ 综合 ⁄ 共 43207字 ⁄ 字号 评论关闭
乌拉圭软件作者gonchuki开发的变色龙按钮非常漂亮,也非常著名。源代码公开的版本最新为2.0.6B,下载地址为:http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=37471&lngWId=1
由于该版本是VB开发的,在某些其它的IDE中有些属性不支持,比如说在VC中不支持ToolTipText。我将它改写为一个VC版本。但是该版本比2.0.6B有点删减,比如说gonchuki支持的按钮快捷键我改写的不支持。
另外,我新加了一种Graphic按钮类型,该类型按钮显示4个图片:通常状态图片、按下图片、鼠标移动在按钮上时的图片、Disable时图片,并且在这种类型下,没有按钮边框,可以让开发人员轻松灵活地制作各种按钮效果。
BLOG好像不能上传附件,我只好将接口定义文件及控件的H、CPP文件列出如下(我使用VC6创建的是MFC控件工程,工程名称是Chameleon)
(最后:重发布请注明原作者gonchuki):

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Chameleon.odl
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Chameleon.odl : type library source for ActiveX Control project.

// This file will be processed by the Make Type Library (mktyplib) tool to
// produce the type library (Chameleon.tlb) that will become a resource in
// Chameleon.ocx.

#include <olectl.h>
#include <idispids.h>

[ uuid(56102E2F-1E92-4CE0-9007-507506A21492), version(1.0),
  helpfile("Chameleon.hlp"),
  helpstring("ChameleonButton,based on gonchuki's work"),
  control ]
library CHAMELEONLib
{
    importlib(STDOLE_TLB);
    importlib(STDTYPE_TLB);

    //  Primary dispatch interface for CChameleonCtrl

    [ uuid(CBD15FBF-9BA7-46C5-B013-5F75A5750E31),
      helpstring("Dispatch interface for Chameleon Control"), hidden ]
    dispinterface _DChameleon
    {
        properties:
            // NOTE - ClassWizard will maintain property information here.
            //    Use extreme caution when editing this section.
            //{{AFX_ODL_PROP(CChameleonCtrl)
            [id(DISPID_BACKCOLOR), bindable, requestedit] OLE_COLOR BackColor;
            [id(DISPID_TEXT), bindable, requestedit] BSTR Text;
            [id(DISPID_ENABLED), bindable, requestedit] boolean Enabled;
            [id(DISPID_FONT), bindable] IFontDisp* Font;
            [id(DISPID_FORECOLOR), bindable, requestedit] OLE_COLOR ForeColor;
            [id(DISPID_HWND)] OLE_HANDLE hWnd;
            [id(1)] long MousePointer;
            [id(2)] IPictureDisp* MouseIcon;
            [id(3)] IPictureDisp* Picture;
            [id(4)] long ButtonType;
            [id(5)] long ColorScheme;
            [id(6)] boolean Press;
            [id(7)] boolean ShowFocusRect;
            [id(8)] boolean Stretch;
            [id(9)] BSTR ToolTipText;
            [id(10)] OLE_COLOR BackOverColor;
            [id(11)] OLE_COLOR ForeOverColor;
            [id(12)] long TextEffect;
            [id(13)] boolean HandPointer;
            [id(14)] IPictureDisp* DownPicture;
            [id(15)] IPictureDisp* OverPicture;
            [id(16)] IPictureDisp* DisablePicture;
            //}}AFX_ODL_PROP

        methods:
            // NOTE - ClassWizard will maintain method information here.
            //    Use extreme caution when editing this section.
            //{{AFX_ODL_METHOD(CChameleonCtrl)
            //}}AFX_ODL_METHOD

            [id(DISPID_ABOUTBOX)] void AboutBox();
    };

    //  Event dispatch interface for CChameleonCtrl

    [ uuid(E9D3BEB5-028F-4330-AF0C-D51827D2E638),
      helpstring("Event interface for Chameleon Control") ]
    dispinterface _DChameleonEvents
    {
        properties:
            //  Event interface has no properties

        methods:
            // NOTE - ClassWizard will maintain event information here.
            //    Use extreme caution when editing this section.
            //{{AFX_ODL_EVENT(CChameleonCtrl)
            [id(DISPID_CLICK)] void Click();
            [id(DISPID_MOUSEDOWN)] void MouseDown(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
            [id(DISPID_MOUSEUP)] void MouseUp(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
            [id(DISPID_MOUSEMOVE)] void MouseMove(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y);
            [id(DISPID_KEYDOWN)] void KeyDown(short* KeyCode, short Shift);
            [id(DISPID_KEYUP)] void KeyUp(short* KeyCode, short Shift);
            [id(DISPID_KEYPRESS)] void KeyPress(short* KeyAscii);
            [id(1)] void MouseOver();
            [id(2)] void MouseOut();
            //}}AFX_ODL_EVENT
    };

    //  Class information for CChameleonCtrl

    [ uuid(6AE6E06F-390B-402D-B3A1-C0FF5FB598E7),
      helpstring("Chameleon Control"), control ]
    coclass Chameleon
    {
        [default] dispinterface _DChameleon;
        [default, source] dispinterface _DChameleonEvents;
    };

    //{{AFX_APPEND_ODL}}
    //}}AFX_APPEND_ODL}}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ChameleonCtl.h
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_CHAMELEONCTL_H__2E1BDC1A_34B2_45FB_A4EA_912BCA97F3E5__INCLUDED_)
#define AFX_CHAMELEONCTL_H__2E1BDC1A_34B2_45FB_A4EA_912BCA97F3E5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// ChameleonCtl.h : Declaration of the CChameleonCtrl ActiveX Control class.

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl : See ChameleonCtl.cpp for implementation.

class CChameleonCtrl : public COleControl
{
    DECLARE_DYNCREATE(CChameleonCtrl)

// Constructor
public:
    CChameleonCtrl();

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CChameleonCtrl)
    public:
    virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
    virtual void DoPropExchange(CPropExchange* pPX);
    virtual void OnResetState();
    //}}AFX_VIRTUAL

// Implementation
protected:
    ~CChameleonCtrl();

    DECLARE_OLECREATE_EX(CChameleonCtrl)    // Class factory and guid
    DECLARE_OLETYPELIB(CChameleonCtrl)      // GetTypeInfo
    DECLARE_PROPPAGEIDS(CChameleonCtrl)     // Property page IDs
    DECLARE_OLECTLTYPE(CChameleonCtrl)        // Type name and misc status

// Message maps
    //{{AFX_MSG(CChameleonCtrl)
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg void OnSetFocus(CWnd* pOldWnd);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()

// Dispatch maps
    //{{AFX_DISPATCH(CChameleonCtrl)
    afx_msg long GetMousePointer();
    afx_msg void SetMousePointer(long nNewValue);
    afx_msg LPPICTUREDISP GetMouseIcon();
    afx_msg void SetMouseIcon(LPPICTUREDISP newValue);
    afx_msg LPPICTUREDISP GetPicture();
    afx_msg void SetPicture(LPPICTUREDISP newValue);
    afx_msg long GetButtonType();
    afx_msg void SetButtonType(long nNewValue);
    afx_msg long GetColorScheme();
    afx_msg void SetColorScheme(long nNewValue);
    afx_msg BOOL GetPress();
    afx_msg void SetPress(BOOL bNewValue);
    afx_msg BOOL GetShowFocusRect();
    afx_msg void SetShowFocusRect(BOOL bNewValue);
    afx_msg BOOL GetStretch();
    afx_msg void SetStretch(BOOL bNewValue);
    afx_msg BSTR GetToolTipText();
    afx_msg void SetToolTipText(LPCTSTR lpszNewValue);
    afx_msg OLE_COLOR GetBackOverColor();
    afx_msg void SetBackOverColor(OLE_COLOR nNewValue);
    afx_msg OLE_COLOR GetForeOverColor();
    afx_msg void SetForeOverColor(OLE_COLOR nNewValue);
    afx_msg long GetTextEffect();
    afx_msg void SetTextEffect(long nNewValue);
    afx_msg BOOL GetHandPointer();
    afx_msg void SetHandPointer(BOOL bNewValue);
    afx_msg LPPICTUREDISP GetDownPicture();
    afx_msg void SetDownPicture(LPPICTUREDISP newValue);
    afx_msg LPPICTUREDISP GetOverPicture();
    afx_msg void SetOverPicture(LPPICTUREDISP newValue);
    afx_msg LPPICTUREDISP GetDisablePicture();
    afx_msg void SetDisablePicture(LPPICTUREDISP newValue);
    //}}AFX_DISPATCH
    DECLARE_DISPATCH_MAP()

    virtual void OnBackColorChanged();
    virtual void OnForeColorChanged();
    virtual void OnTextChanged();
    virtual void OnEnabledChanged();
    virtual void OnFontChanged();

    afx_msg void AboutBox();

// Event maps
    //{{AFX_EVENT(CChameleonCtrl)
    void FireMouseOver()
        {FireEvent(eventidMouseOver,EVENT_PARAM(VTS_NONE));}
    void FireMouseOut()
        {FireEvent(eventidMouseOut,EVENT_PARAM(VTS_NONE));}
    //}}AFX_EVENT
    DECLARE_EVENT_MAP()

// Dispatch and event IDs
public:
    enum {
    //{{AFX_DISP_ID(CChameleonCtrl)
    dispidMousePointer = 1L,
    dispidMouseIcon = 2L,
    dispidPicture = 3L,
    dispidButtonType = 4L,
    dispidColorScheme = 5L,
    dispidPress = 6L,
    dispidShowFocusRect = 7L,
    dispidStretch = 8L,
    dispidToolTipText = 9L,
    dispidBackOverColor = 10L,
    dispidForeOverColor = 11L,
    dispidTextEffect = 12L,
    dispidHandPointer = 13L,
    dispidDownPicture = 14L,
    dispidOverPicture = 15L,
    dispidDisablePicture = 16L,
    eventidMouseOver = 1L,
    eventidMouseOut = 2L,
    //}}AFX_DISP_ID
    };

protected:

    /////////////////////////////////////////////////////////////////////////////
    //成员函数
    //

    //重绘函数
    int Redraw( int nStatus, bool bForce, CDC * pdcDraw = NULL);

    //检查鼠标是否在控件上
    bool CheckMouseOver();

    //创建控件区域
    int MakeRegion( CRgn & rgnCreate );

    //设置窗口颜色变量
    int SetColor();
    //增减RBG颜色值
    DWORD ShiftColor( DWORD ulColor, int nValue, bool m_bXP = false );
    //XP风格的增减RGB颜色值
    DWORD ShiftColorOXP( DWORD ulColor, int nBase = 0xB0 );

    //画文本
    int DrawCaption( HDC hdcCtrl, int nDrawType );
    //画文本的特效
    int DrawEffect( HDC hdcCtrl, CRect recDraw );

    //画长方形
    int DrawRectangle( HDC hdcCtrl, int nLeft, int nTop, int nWidth, int nHeight, DWORD ulColor, bool bBoard = false );
    //画边框
    int DrawFrame( HDC hdcCtrl, DWORD ulHigh, DWORD ulDark, DWORD ulLight, DWORD ulShadow, int nExtraOffset, bool bFlat = false );
    //画焦点框
    int DrawFocusR( HDC hdcCtrl, CRect recFocus, DWORD ulColor );
    //画线
    int DrawLine( HDC hdcCtrl, int nX1, int nY1, int nX2, int nY2, DWORD ulColor );

    //向ToolTipCtrl发送消息
    void RelayEvent(UINT message, WPARAM wParam, LPARAM lParam);

    //设置鼠标
    int SetMoveCursor( long lMousePointer );
    //恢复鼠标
    int RestoreCursor();

    //获得图片高宽
    int GetPictureSize( int nType, int &nWidth, int &nHeight );

    /////////////////////////////////////////////////////////////////////////////
    //属性变量
    //

    //鼠标类型(未使用)
    long m_lMousePointer;
    //m_lMousePointer为99(自定义)时的鼠标(未使用)
    CPictureHolder m_phdMouseIcon;
    //当按钮类型为Graphic时,正常状态图片
    CPictureHolder m_phdPicture;
    //按钮类型
    //Windows16 = 1,
    //Windows32 = 2,
    //WindowsXP = 3,
    //Mac = 4,
    //Java = 5,
    //Netscape6 = 6,
    //SimpleFlat = 7,
    //FlatHight= 8,
    //OfficeXP= 9,
    //Transparent= 10,
    //Hover= 11,
    //KDE2= 12,
    //Graphic = 13
    long m_lButtonType;
    //按钮颜色方案
    //UseWindows = 1,
    //Custom = 2,
    //ForceStandard = 3,
    //UseContainer = 4
    long m_lColorScheme;
    //是否为CheckBox行为风格按扭
    BOOL m_bPress;
    //是否显示焦点框
    BOOL m_bShowFocusRect;
    //是否扩充图片至按钮当前大小
    BOOL m_bStretch;
    //工具提示文本
    CString m_strTipText;
    //鼠标移动在按钮上时的背景颜色
    long m_lBackOverColor;
    //鼠标移动在按钮上时的前景颜色
    long m_lForeOverColor;
    //按钮文字效果
    //None = 0,
    //Embossed = 1,
    //Engraved = 2,
    //Shadowed = 3
    long m_lTextEffect;
    //鼠标移动在按钮上时,是否将光标改为一只手
    BOOL m_bHandPointer;
    //当按钮类型为Graphic时,按下状态图片
    CPictureHolder m_phdDownPicture;
    //当按钮类型为Graphic时,鼠标移动状态图片
    CPictureHolder m_phdOverPicture;
    //当按钮类型为Graphic时,不可用状态图片
    CPictureHolder m_phdDisablePicture;

    /////////////////////////////////////////////////////////////////////////////
    //状态变量
    //

    //快捷键(未使用)
    BYTE m_ucAccessKey;

    //鼠标移动在控件上面的标志
    bool m_bMouseOver;
    //当前鼠标类型
    long m_lCursorType;
    //移动在按钮上面之前的鼠标
    HCURSOR m_hPrevCursor;

    //键盘按下的键
    int m_nLastKey;

    //如果Press属性为true,当前是否处于Press状态
    bool m_bPressState;

    //当前焦点状态
    bool m_bFocus;

    //当前按钮状态:0,正常;1,按下
    int m_nStatus;
    //当前显示的文字
    CString m_strText;
    //当前文字的显示位置和大小
    CRect m_recText;
   
    //按钮的高度和宽度
    int m_nWidth;
    int m_nHeight;

    //焦点框
    CRect m_recFocusRect;
    //窗口区域
    CRgn m_rgnControl;

    //各种颜色
    DWORD m_ulFace;
    DWORD m_ulFaceO;
    DWORD m_ulText;
    DWORD m_ulTextO;
    DWORD m_ulShadow;
    DWORD m_ulLight;
    DWORD m_ulHighLight;
    DWORD m_ulDarkShadow;
    DWORD m_ulXPFace;
    DWORD m_ulOfficeXPB;
    DWORD m_ulOfficeXPF;

    //工具提示功能对象
    CToolTipCtrl m_ttpMes;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CHAMELEONCTL_H__2E1BDC1A_34B2_45FB_A4EA_912BCA97F3E5__INCLUDED)

/*
    /////////////////////////////////////////////////////////////////////////////
    //未使用的属性枚举变量
    //

    typedef [uuid(55A57721-6744-49d2-A711-01E12E6CC023), version(1.0)]
    enum ButtonTypes{
        Windows16 = 1,
        Windows32 = 2,
        WindowsXP = 3,
        Mac = 4,
        Java = 5,
        Netscape6 = 6,
        SimpleFlat = 7,
        FlatHight= 8,
        OfficeXP= 9,
        Transparent= 10,
        Hover= 11,
        KDE2= 12,
        Graphic = 13
    } ButtonTypes;
   
    typedef [uuid(7D7C39D1-5479-4650-937A-768645B2634A), version(1.0)]
    enum ColorTypes{
        UseWindows = 1,
        Custom = 2,
        ForceStandard = 3,
        UseContainer = 4
    } ColorTypes;
   
    typedef [uuid(9CE8E7E4-134F-4950-819B-2208193A3F8B), version(1.0)]
    enum EffectTypes{
        None = 0,
        Embossed = 1,
        Engraved = 2,
        Shadowed = 3
    } EffectTypes;

    MousePointer:
    Default        0        (默认值)由对象决定的形状。
    Arrow        1        箭头。
    Cross        2        十字(十字型指针)
    IBeam        3        I 型标。
    Icon        4        图标(在方块中的小方块)。
    Size        5        大小(四向箭头指向上下左右)。
    SizeNESW    6        右上 - 左下大小(双向箭头分别指向右上和左下)。
    SizeNS        7        垂直大小(双向箭头分别指向上和下)。
    SizeNWSE    8        左上 - 右下大小。
    SizeEW        9        水平大小(双向箭头分别指向左和右)。
    UpArrow        10        向上箭头键。
    Hourglass    11        沙漏(等待)。
    NoDrop        12        不允许放下。
    ArrowHourglass    13    箭头和沙漏。
    ArrowQuestion    14    箭头和问号。
    SizeAll            15    四向箭头。
    Custom            99    由 MouseIcon 属性指定的自定义图标。
*/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ChameleonCtl.cpp
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ChameleonCtl.cpp : Implementation of the CChameleonCtrl ActiveX Control class.

#include "stdafx.h"
#include "Chameleon.h"
#include "ChameleonCtl.h"
#include "ChameleonPpg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CChameleonApp NEAR theApp;

IMPLEMENT_DYNCREATE(CChameleonCtrl, COleControl)

/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CChameleonCtrl, COleControl)
    //{{AFX_MSG_MAP(CChameleonCtrl)
    ON_WM_TIMER()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_KEYDOWN()
    ON_WM_KEYUP()
    ON_WM_KILLFOCUS()
    ON_WM_SETFOCUS()
    ON_WM_MOUSEMOVE()
    ON_WM_SIZE()
    ON_WM_CREATE()
    ON_WM_RBUTTONUP()
    ON_WM_RBUTTONDOWN()
    ON_WM_MBUTTONUP()
    ON_WM_MBUTTONDOWN()
    //}}AFX_MSG_MAP
    ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CChameleonCtrl, COleControl)
    //{{AFX_DISPATCH_MAP(CChameleonCtrl)
    DISP_PROPERTY_EX(CChameleonCtrl, "MousePointer", GetMousePointer, SetMousePointer, VT_I4)
    DISP_PROPERTY_EX(CChameleonCtrl, "MouseIcon", GetMouseIcon, SetMouseIcon, VT_PICTURE)
    DISP_PROPERTY_EX(CChameleonCtrl, "Picture", GetPicture, SetPicture, VT_PICTURE)
    DISP_PROPERTY_EX(CChameleonCtrl, "ButtonType", GetButtonType, SetButtonType, VT_I4)
    DISP_PROPERTY_EX(CChameleonCtrl, "ColorScheme", GetColorScheme, SetColorScheme, VT_I4)
    DISP_PROPERTY_EX(CChameleonCtrl, "Press", GetPress, SetPress, VT_BOOL)
    DISP_PROPERTY_EX(CChameleonCtrl, "ShowFocusRect", GetShowFocusRect, SetShowFocusRect, VT_BOOL)
    DISP_PROPERTY_EX(CChameleonCtrl, "Stretch", GetStretch, SetStretch, VT_BOOL)
    DISP_PROPERTY_EX(CChameleonCtrl, "ToolTipText", GetToolTipText, SetToolTipText, VT_BSTR)
    DISP_PROPERTY_EX(CChameleonCtrl, "BackOverColor", GetBackOverColor, SetBackOverColor, VT_COLOR)
    DISP_PROPERTY_EX(CChameleonCtrl, "ForeOverColor", GetForeOverColor, SetForeOverColor, VT_COLOR)
    DISP_PROPERTY_EX(CChameleonCtrl, "TextEffect", GetTextEffect, SetTextEffect, VT_I4)
    DISP_PROPERTY_EX(CChameleonCtrl, "HandPointer", GetHandPointer, SetHandPointer, VT_BOOL)
    DISP_PROPERTY_EX(CChameleonCtrl, "DownPicture", GetDownPicture, SetDownPicture, VT_PICTURE)
    DISP_PROPERTY_EX(CChameleonCtrl, "OverPicture", GetOverPicture, SetOverPicture, VT_PICTURE)
    DISP_PROPERTY_EX(CChameleonCtrl, "DisablePicture", GetDisablePicture, SetDisablePicture, VT_PICTURE)
    DISP_STOCKPROP_BACKCOLOR()
    DISP_STOCKPROP_TEXT()
    DISP_STOCKPROP_ENABLED()
    DISP_STOCKPROP_FONT()
    DISP_STOCKPROP_FORECOLOR()
    DISP_STOCKPROP_HWND()
    //}}AFX_DISPATCH_MAP
    DISP_FUNCTION_ID(CChameleonCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()

/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CChameleonCtrl, COleControl)
    //{{AFX_EVENT_MAP(CChameleonCtrl)
    EVENT_CUSTOM("MouseOver", FireMouseOver, VTS_NONE)
    EVENT_CUSTOM("MouseOut", FireMouseOut, VTS_NONE)
    EVENT_STOCK_CLICK()
    EVENT_STOCK_MOUSEDOWN()
    EVENT_STOCK_MOUSEUP()
    EVENT_STOCK_MOUSEMOVE()
    EVENT_STOCK_KEYDOWN()
    EVENT_STOCK_KEYUP()
    EVENT_STOCK_KEYPRESS()
    //}}AFX_EVENT_MAP
END_EVENT_MAP()

/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CChameleonCtrl, 4)
    PROPPAGEID(CChameleonPropPage::guid)
    PROPPAGEID( CLSID_CFontPropPage )
    PROPPAGEID( CLSID_CColorPropPage )
    PROPPAGEID( CLSID_CPicturePropPage )
END_PROPPAGEIDS(CChameleonCtrl)

/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CChameleonCtrl, "CHAMELEON.ChameleonCtrl.1",
    0x6ae6e06f, 0x390b, 0x402d, 0xb3, 0xa1, 0xc0, 0xff, 0x5f, 0xb5, 0x98, 0xe7)

/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CChameleonCtrl, _tlid, _wVerMajor, _wVerMinor)

/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DChameleon =
        { 0xcbd15fbf, 0x9ba7, 0x46c5, { 0xb0, 0x13, 0x5f, 0x75, 0xa5, 0x75, 0xe, 0x31 } };
const IID BASED_CODE IID_DChameleonEvents =
        { 0xe9d3beb5, 0x28f, 0x4330, { 0xaf, 0xc, 0xd5, 0x18, 0x27, 0xd2, 0xe6, 0x38 } };

/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwChameleonOleMisc =
    OLEMISC_ACTIVATEWHENVISIBLE |
    OLEMISC_SETCLIENTSITEFIRST |
    OLEMISC_INSIDEOUT |
    OLEMISC_CANTLINKINSIDE |
    OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CChameleonCtrl, IDS_CHAMELEON, _dwChameleonOleMisc)

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::CChameleonCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CChameleonCtrl

BOOL CChameleonCtrl::CChameleonCtrlFactory::UpdateRegistry(BOOL bRegister)
{
    // TODO: Verify that your control follows apartment-model threading rules.
    // Refer to MFC TechNote 64 for more information.
    // If your control does not conform to the apartment-model rules, then
    // you must modify the code below, changing the 6th parameter from
    // afxRegApartmentThreading to 0.

    if (bRegister)
        return AfxOleRegisterControlClass(
            AfxGetInstanceHandle(),
            m_clsid,
            m_lpszProgID,
            IDS_CHAMELEON,
            IDB_CHAMELEON,
            afxRegApartmentThreading,
            _dwChameleonOleMisc,
            _tlid,
            _wVerMajor,
            _wVerMinor);
    else
        return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::CChameleonCtrl - Constructor

CChameleonCtrl::CChameleonCtrl()
{
    InitializeIIDs(&IID_DChameleon, &IID_DChameleonEvents);

    //属性变量初始化
    m_lMousePointer = 0;
    m_phdMouseIcon.CreateEmpty();
    m_phdPicture.CreateEmpty();
    m_lButtonType = 3;
    m_lColorScheme = 1;
    m_bPress = FALSE;
    m_bShowFocusRect = TRUE;
    m_bStretch = TRUE;
    m_strTipText.Empty();
    m_lBackOverColor = GetSysColor(COLOR_BTNFACE);
    m_lForeOverColor = GetSysColor(COLOR_WINDOWTEXT);
    m_lTextEffect = 0;
    m_bHandPointer = FALSE;
    m_phdDownPicture.CreateEmpty();
    m_phdOverPicture.CreateEmpty();
    m_phdDisablePicture.CreateEmpty();
   
    //状态变量初始化
    m_ucAccessKey = 0;
    m_bMouseOver = false;
    m_lCursorType = -1;
    m_hPrevCursor = NULL;
    m_nLastKey = 0;
    m_bPressState = false;
    m_bFocus = false;
    m_nStatus = 0;
    m_nWidth = 0;
    m_nHeight = 0;
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::~CChameleonCtrl - Destructor

CChameleonCtrl::~CChameleonCtrl()
{
    // TODO: Cleanup your control's instance data here.
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::OnDraw - Drawing function

void CChameleonCtrl::OnDraw(
            CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
    //强制使用传入的pdc重画,pdc可能为控件DC,也可能为容器DC(设计状态)
    Redraw( m_nStatus, true, pdc );
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::DoPropExchange - Persistence support

void CChameleonCtrl::DoPropExchange(CPropExchange* pPX)
{
    ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
    COleControl::DoPropExchange(pPX);

    // TODO: Call PX_ functions for each persistent custom property.
    //属性序列化
    PX_Long(pPX, "MousePointer", m_lMousePointer, 0);
    PX_Picture(pPX, "MouseIcon",m_phdMouseIcon);
    PX_Picture(pPX, "Picture",m_phdPicture);
    PX_Long(pPX, "ButtonType", m_lButtonType, 3);
    PX_Long(pPX, "ColorScheme", m_lColorScheme, 1);
    PX_Bool(pPX, "Press", m_bPress, FALSE);
    PX_Bool(pPX, "ShowFocusRect", m_bShowFocusRect, TRUE);
    PX_Bool(pPX, "Stretch", m_bStretch, TRUE);
    PX_String(pPX, "ToolTipText", m_strTipText);
    PX_Long(pPX, "BackOverColor", m_lBackOverColor, GetSysColor(COLOR_BTNFACE));
    PX_Long(pPX, "ForeOverColor", m_lForeOverColor, GetSysColor(COLOR_WINDOWTEXT));
    PX_Long(pPX, "TextEffect", m_lTextEffect, 0);
    PX_Bool(pPX, "HandPointer", m_bHandPointer, FALSE);
    PX_Picture(pPX, "DownPicture",m_phdDownPicture);
    PX_Picture(pPX, "OverPicture",m_phdOverPicture);
    PX_Picture(pPX, "DisablePicture",m_phdDisablePicture);
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::OnResetState - Reset control to default state

void CChameleonCtrl::OnResetState()
{
    COleControl::OnResetState();  // Resets defaults found in DoPropExchange

    //重置各属性变量
    m_lMousePointer = 0;
    m_phdMouseIcon.CreateEmpty();
    m_phdPicture.CreateEmpty();
    m_lButtonType = 3;
    m_lColorScheme = 1;
    m_bPress = FALSE;
    m_bShowFocusRect = TRUE;
    m_bStretch = TRUE;
    m_strTipText.Empty();
    m_lBackOverColor = GetSysColor(COLOR_BTNFACE);
    m_lForeOverColor = GetSysColor(COLOR_WINDOWTEXT);
    m_lTextEffect = 0;
    m_bHandPointer = FALSE;
    m_phdDownPicture.CreateEmpty();
    m_phdOverPicture.CreateEmpty();
    m_phdDisablePicture.CreateEmpty();
}

int CChameleonCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (COleControl::OnCreate(lpCreateStruct) == -1)
        return -1;

    //创建控件时,创建工具提示功能对象
    if( m_ttpMes.Create( this, TTS_ALWAYSTIP ) )
    {
        m_ttpMes.AddTool( this );
        if( AmbientUserMode() && m_ttpMes.m_hWnd != NULL )
        {
            if( m_strTipText.GetLength() > 0 )
            {
                m_ttpMes.Activate( true );
                m_ttpMes.UpdateTipText( m_strTipText, this );
            }
            else
            {
                m_ttpMes.Activate( false );
            }
        }
    }

    return 0;
}

void CChameleonCtrl::OnTimer(UINT nIDEvent)
{
    if( nIDEvent == 1 )
    {
        //检查鼠标是否在控件上,不是则激发MouseOut事件
        if( !CheckMouseOver() )
        {
            KillTimer( 1 );
            m_bMouseOver = false;
            if( m_bPressState )
            {
                Redraw( 1, true );
            }
            else
            {
                Redraw( 0, true );
            }

            FireMouseOut();
        }
    }
}

void CChameleonCtrl::OnKillFocus(CWnd* pNewWnd)
{
    COleControl::OnKillFocus(pNewWnd);
   
    //获得/丢失焦点时,将结果记录于m_bFocus
    if( m_bEnabled )
    {
        m_bFocus = false;
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnSetFocus(CWnd* pOldWnd)
{
    COleControl::OnSetFocus(pOldWnd);
   
    //获得/丢失焦点时,将结果记录于m_bFocus
    if( m_bEnabled )
    {
        m_bFocus = true;
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
    if( m_bEnabled )
    {
        short sButton = 0;
        short sShift = 0;

        //按下鼠标左键时重绘控件
        Redraw( 1, false );
   
        //激发MouseDown事件
        if( nFlags & MK_LBUTTON )
        {
            sButton += 1;
        }
        if( nFlags & MK_SHIFT )
        {
            sShift += 1;
        }
        if( nFlags & MK_CONTROL )
        {
            sShift += 2;
        }
        FireMouseDown( sButton, sShift, point.x, point.y );
    }
   
    //激发工具提示对象事件
    RelayEvent( WM_LBUTTONDOWN, (WPARAM)nFlags,
        MAKELPARAM(LOWORD(point.x), LOWORD(point.y)) );

    COleControl::OnLButtonDown(nFlags, point);
}

void CChameleonCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
    if( m_bEnabled )
    {
        short sButton = 0;
        short sShift = 0;

        //根据Press属性及当前鼠标的按下状态重画控件
        if( m_bPress )
        {
            m_bPressState = !m_bPressState;
        }
        if( m_bPressState )
        {
            Redraw( 1, true );
        }
        else
        {
            Redraw( 0, true );
        }

        //激发MouseUp、Click事件
        if( nFlags & MK_LBUTTON )
        {
            sButton += 1;
        }
        if( nFlags & MK_SHIFT )
        {
            sShift += 1;
        }
        if( nFlags & MK_CONTROL )
        {
            sShift += 2;
        }
        FireMouseUp( sButton, sShift, point.x, point.y );
        FireClick();
    }

    //激发工具提示对象事件
    RelayEvent( WM_LBUTTONUP, (WPARAM)nFlags,
        MAKELPARAM(LOWORD(point.x), LOWORD(point.y)) );

    COleControl::OnLButtonUp(nFlags, point);
}

void CChameleonCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
    if( m_bEnabled )
    {
        short sButton = 0;
        short sShift = 0;

        //当鼠标左键按下或者无键按下,并且移动在控件上时
        if( nFlags <= MK_LBUTTON )
        {
            if( CheckMouseOver() )
            {
                if( nFlags == 0 && !m_bMouseOver )
                {
                    SetTimer( 1, 100, NULL );
                    m_bMouseOver = true;
                    Redraw( 0, true );

                    FireMouseOver();
                }
                else if( nFlags == MK_LBUTTON )
                {
                    SetTimer( 1, 100, NULL );
                    m_bMouseOver = true;
                    Redraw( 1, false );
                    m_bMouseOver = false;
                }
            }
        }

        //激发MouseMove事件
        if( nFlags & MK_LBUTTON )
        {
            sButton += 1;
        }
        if( nFlags & MK_RBUTTON )
        {
            sButton += 2;
        }
        if( nFlags & MK_MBUTTON )
        {
            sButton += 4;
        }
        if( nFlags & MK_SHIFT )
        {
            sShift += 1;
        }
        if( nFlags & MK_CONTROL )
        {
            sShift += 2;
        }
        FireMouseMove( sButton, sShift, point.x, point.y );
    }

    //激发工具提示对象事件
    RelayEvent( WM_MOUSEMOVE, (WPARAM)nFlags,
        MAKELPARAM(LOWORD(point.x), LOWORD(point.y)) );

    COleControl::OnMouseMove(nFlags, point);
}

void CChameleonCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    if( m_bEnabled )
    {
        USHORT usKey = nChar;
        short sShift = 0;

        m_nLastKey = nChar;

        if( m_nLastKey == 32 )
        {
            //响应空格键
            Redraw( 1, false );
        }
        else if( m_nLastKey == 39 || m_nLastKey == 40 )
        {
            //right and down arrows
            //When use in VC and VB,don't need to handle this
        }
        else if( m_nLastKey == 37 || m_nLastKey == 38 )
        {
            //left and up arrows
            //When use in VC and VB,don't need to handle this
        }

        FireKeyDown( &usKey, sShift );
    }

    COleControl::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CChameleonCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    if( m_bEnabled )
    {
        USHORT usKey = nChar;
        short sShift = 0;
   
        if( m_nLastKey == 32 && usKey == 32 )
        {
            //响应空格键
            if( m_bPress )
            {
                m_bPressState = !m_bPressState;
            }
            if( m_bPressState )
            {
                Redraw( 1, true );
            }
            else
            {
                Redraw( 0, true );
            }
            FireClick();
        }

        FireKeyUp( &usKey, sShift );
        FireKeyPress( &usKey );
    }

    COleControl::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CChameleonCtrl::OnSize(UINT nType, int cx, int cy)
{
    if( !m_bStretch && m_lButtonType == 13 )
    {
        //在Stretch为false,且按钮类型为图片的时候,
        //将按钮设为图片的大小
        int nWidth;
        int nHeight;
        GetPictureSize( 1, nWidth, nHeight );
        if( nWidth == 0 || nHeight == 0 )
        {
            SetControlSize( 32, 32 );
        }
        else
        {
            SetControlSize( nWidth, nHeight );
        }
    }
    else
    {
        COleControl::OnSize(nType, cx, cy);
    }

    //保存按钮的大小
    GetClientRect( m_recFocusRect );
    m_nWidth = m_recFocusRect.Width();
    m_nHeight = m_recFocusRect.Height();

    //计算焦点框的大小
    if( m_lButtonType == 7 )
    {
        InflateRect( m_recFocusRect, -3, -3 );
    }
    else if( m_lButtonType == 12 )
    {
        InflateRect( m_recFocusRect, -5, -5 );
        OffsetRect( m_recFocusRect, 1, 1 );
    }
    else
    {
        InflateRect( m_recFocusRect, -4, -4 );
    }

    //根据按钮类型创建按钮绘画区域
    MakeRegion( m_rgnControl );
    SetWindowRgn( m_rgnControl, true );
}

void CChameleonCtrl::OnRButtonUp(UINT nFlags, CPoint point)
{
    //丢弃鼠标右键和中键的响应
    //COleControl::OnRButtonUp(nFlags, point);
}

void CChameleonCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
    //丢弃鼠标右键和中键的响应
    //COleControl::OnRButtonDown(nFlags, point);
}

void CChameleonCtrl::OnMButtonUp(UINT nFlags, CPoint point)
{
    //丢弃鼠标右键和中键的响应
    //COleControl::OnMButtonUp(nFlags, point);
}

void CChameleonCtrl::OnMButtonDown(UINT nFlags, CPoint point)
{
    //丢弃鼠标右键和中键的响应
    //COleControl::OnMButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl::AboutBox - Display an "About" box to the user

void CChameleonCtrl::AboutBox()
{
    CDialog dlgAbout(IDD_ABOUTBOX_CHAMELEON);
    dlgAbout.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CChameleonCtrl message handlers

void CChameleonCtrl::OnBackColorChanged()
{
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnForeColorChanged()
{
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnTextChanged()
{
    CString strCaption = InternalGetText();
    int nFind = strCaption.Find( "&" );
    if( nFind != -1 )
    {
        if( strCaption.GetLength() > nFind + 1 )
        {
            m_ucAccessKey = (BYTE)strCaption.GetAt( nFind + 1 );
        }
        else
        {
            m_ucAccessKey = 0;
        }
    }
    else
    {
        m_ucAccessKey = 0;
    }

    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnEnabledChanged()
{
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }
}

void CChameleonCtrl::OnFontChanged()
{
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }
}

long CChameleonCtrl::GetMousePointer()
{
    return m_lMousePointer;
}

void CChameleonCtrl::SetMousePointer(long nNewValue)
{
    m_lMousePointer = nNewValue;
    if( ( m_lMousePointer < 0 || m_lMousePointer > 15 )
        && m_lMousePointer != 99 )
    {
        m_lMousePointer = 0;
    }

    SetModifiedFlag();
}

LPPICTUREDISP CChameleonCtrl::GetMouseIcon()
{
    return m_phdMouseIcon.GetPictureDispatch();
}

void CChameleonCtrl::SetMouseIcon(LPPICTUREDISP newValue)
{
    m_phdMouseIcon.SetPictureDispatch(newValue);

    SetModifiedFlag();
}

LPPICTUREDISP CChameleonCtrl::GetPicture()
{
    return m_phdPicture.GetPictureDispatch();
}

void CChameleonCtrl::SetPicture(LPPICTUREDISP newValue)
{
    m_phdPicture.SetPictureDispatch(newValue);
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

long CChameleonCtrl::GetButtonType()
{
    return m_lButtonType;
}

void CChameleonCtrl::SetButtonType(long newValue)
{
    m_lButtonType = newValue;
    if( m_lButtonType < 1 || m_lButtonType > 13 )
    {
        m_lButtonType = 3;
    }

    if( IsWindow( m_hWnd ) )
    {
        MakeRegion( m_rgnControl );
        SetWindowRgn( m_rgnControl, true );

        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

long CChameleonCtrl::GetColorScheme()
{
    return m_lColorScheme;
}

void CChameleonCtrl::SetColorScheme(long nNewValue)
{
    m_lColorScheme = nNewValue;
    if( m_lButtonType < 1 || m_lButtonType > 4 )
    {
        m_lButtonType = 1;
    }

    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

BOOL CChameleonCtrl::GetPress()
{
    return m_bPress;
}

void CChameleonCtrl::SetPress(BOOL bNewValue)
{
    m_bPress = bNewValue;
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

BOOL CChameleonCtrl::GetShowFocusRect()
{
    return m_bShowFocusRect;
}

void CChameleonCtrl::SetShowFocusRect(BOOL bNewValue)
{
    m_bShowFocusRect = bNewValue;
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

BOOL CChameleonCtrl::GetStretch()
{
    return m_bStretch;
}

void CChameleonCtrl::SetStretch(BOOL bNewValue)
{
    CRect recClient;

    m_bStretch = bNewValue;
    if( IsWindow( m_hWnd ) )
    {
        GetClientRect( recClient );
        OnSize( 0, recClient.Width(), recClient.Height() );

        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

BSTR CChameleonCtrl::GetToolTipText()
{
    return m_strTipText.AllocSysString();
}

void CChameleonCtrl::SetToolTipText(LPCTSTR lpszNewValue)
{
    m_strTipText = lpszNewValue;

    if( AmbientUserMode() && m_ttpMes.m_hWnd != NULL )
    {
        if( m_strTipText.GetLength() > 0 )
        {
            m_ttpMes.Activate( true );
            m_ttpMes.UpdateTipText( m_strTipText, this );
        }
        else
        {
            m_ttpMes.Activate( false );
        }
    }

    SetModifiedFlag();
}

OLE_COLOR CChameleonCtrl::GetBackOverColor()
{
    return m_lBackOverColor;
}

void CChameleonCtrl::SetBackOverColor(OLE_COLOR nNewValue)
{
    m_lBackOverColor = nNewValue;
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

OLE_COLOR CChameleonCtrl::GetForeOverColor()
{
    return m_lForeOverColor;
}

void CChameleonCtrl::SetForeOverColor(OLE_COLOR nNewValue)
{
    m_lForeOverColor = nNewValue;
    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

long CChameleonCtrl::GetTextEffect()
{
    return m_lTextEffect;
}

void CChameleonCtrl::SetTextEffect(long nNewValue)
{
    m_lTextEffect = nNewValue;
    if( m_lTextEffect < 0 || m_lTextEffect > 3 )
    {
        m_lTextEffect = 0;
    }

    if( IsWindow( m_hWnd ) )
    {
        Redraw( m_nStatus, true );
    }

    SetModifiedFlag();
}

BOOL CChameleonCtrl::GetHandPointer()
{
    return m_bHandPointer;
}

void CChameleonCtrl::SetHandPointer(BOOL bNewValue)
{
    m_bHandPointer = bNewValue;

    SetModifiedFlag();
}

LPPICTUREDISP CChameleonCtrl::GetDownPicture()
{
    return m_phdDownPicture.GetPictureDispatch();
}

void CChameleonCtrl::SetDownPicture(LPPICTUREDISP newValue)
{
    m_phdDownPicture.SetPictureDispatch(newValue);

    SetModifiedFlag();
}

LPPICTUREDISP CChameleonCtrl::GetOverPicture()
{
    return m_phdOverPicture.GetPictureDispatch();

    return NULL;
}

void CChameleonCtrl::SetOverPicture(LPPICTUREDISP newValue)
{
    m_phdOverPicture.SetPictureDispatch(newValue);

    SetModifiedFlag();
}

LPPICTUREDISP CChameleonCtrl::GetDisablePicture()
{
    return m_phdDisablePicture.GetPictureDispatch();

    return NULL;
}

void CChameleonCtrl::SetDisablePicture(LPPICTUREDISP newValue)
{
    m_phdDisablePicture.SetPictureDispatch(newValue);

    SetModifiedFlag();
}

/////////////////////////////////////////////////////////////////////////////
//
// 重绘函数
// 参数:    pdcDraw        绘图场景
//            nStatus        按钮状态,0,正常;1,按下
//            bForce        是否强制重画
// 返回值:    0            正确
//
/////////////////////////////////////////////////////////////////////////////
int CChameleonCtrl::Redraw( int nStatus, bool bForce, CDC * pdcDraw )
{
    BOOL bDefault;
    bool bReleaseDC = false;

    CString strCaption = InternalGetText();
    CFont * pfntOld;

    if( !bForce )
    {
        //如果当前按钮状态未变化,文字也未变化,则取消不必要的重画
        if( m_nStatus == nStatus && m_strText == strCaption )
        {
            return 0;
        }
    }

    //按钮区域为空则退出
    if( m_nHeight == 0 || m_nWidth == 0 )
    {
        return 0;
    }

    //保存按钮状态、文字
    m_nStatus = nStatus;
    m_strText = strCaption;

    //获取按钮是否为Default按钮
    GetAmbientProperty( DISPID_AMBIENT_DISPLAYASDEFAULT, VT_BOOL, &bDefault );

    //如果未传入DC,则获取控件DC
    if( pdcDraw == NULL )
    {
        pdcDraw = GetDC();
        bReleaseDC = true;
    }

    //选入STOCK FONT
    pfntOld = SelectStockFont( pdcDraw );

    //设置绘画所需的各种表面颜色
    SetColor();

    DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth, m_nHeight, m_ulFace );

    if( m_bEnabled )
    {
        if( m_nStatus == 0 )
        {
            //正常状态
            if( m_lButtonType == 1 )
            {
                //Windows16
                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
                DrawFrame( pdcDraw->m_hDC, m_ulHighLight, m_ulShadow,
                    m_ulHighLight, m_ulShadow, -1 );
                DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth, m_nHeight,
                    m_ulDarkShadow, true );
                DrawFocusR( pdcDraw->m_hDC, m_recFocusRect, m_ulText );
            }
            else if( m_lButtonType == 2 )
            {
                //Windows32
                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
               
                if( bDefault && m_bShowFocusRect )
                {
                    DrawFrame( pdcDraw->m_hDC, m_ulHighLight, m_ulDarkShadow,
                        m_ulLight, m_ulShadow, -1 );
                    DrawFocusR( pdcDraw->m_hDC, m_recFocusRect, m_ulText );
                    DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth, m_nHeight,
                        m_ulDarkShadow, true );
                }
                else
                {
                    DrawFrame( pdcDraw->m_hDC, m_ulHighLight, m_ulDarkShadow,
                        m_ulLight, m_ulShadow, 0 );
                }
            }
            else if( m_lButtonType == 3 )
            {
                //WindowsXP
                float fStep;

                fStep = 25 / (float)m_nHeight;
                for( int nCount = 1; nCount <= m_nHeight; nCount++ )
                {
                    DrawLine( pdcDraw->m_hDC, 0, nCount, m_nWidth,
                        nCount, ShiftColor( m_ulXPFace, (int)(-fStep * nCount), true ) );
                }

                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
                DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth, m_nHeight, 0x733C00, true );
                SetPixel( pdcDraw->m_hDC, 1, 1, 0x7B4D10 );
                SetPixel( pdcDraw->m_hDC, 1, m_nHeight - 2, 0x7B4D10 );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 2, 1, 0x7B4D10 );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 2, m_nHeight - 2, 0x7B4D10 );

                if( m_bMouseOver )
                {
                    DrawRectangle( pdcDraw->m_hDC, 1, 2,
                        m_nWidth - 2, m_nHeight - 4, 0x31B2FF, true );
                    DrawLine( pdcDraw->m_hDC, 2, m_nHeight - 2,
                        m_nWidth - 2, m_nHeight - 2, 0x96E7 );
                    DrawLine( pdcDraw->m_hDC, 2, 1, m_nWidth - 2, 1, 0xCEF3FF );
                    DrawLine( pdcDraw->m_hDC, 1, 2, m_nWidth - 1, 2, 0x8CDBFF );
                    DrawLine( pdcDraw->m_hDC, 2, 3, 2, m_nHeight - 3, 0x6BCBFF );
                    DrawLine( pdcDraw->m_hDC, m_nWidth - 3,
                        3, m_nWidth - 3, m_nHeight - 3, 0x6BCBFF );
                }
                else if( ( m_bFocus || bDefault ) && m_bShowFocusRect )
                {
                    DrawRectangle( pdcDraw->m_hDC, 1, 2,
                        m_nWidth - 2, m_nHeight - 4, 0xE7AE8C, true );
                    DrawLine( pdcDraw->m_hDC, 2, m_nHeight - 2,
                        m_nWidth - 2, m_nHeight - 2, 0xEF826B );
                    DrawLine( pdcDraw->m_hDC, 2, 1, m_nWidth - 2, 1, 0xFFE7CE );
                    DrawLine( pdcDraw->m_hDC, 1, 2, m_nWidth - 1, 2, 0xF7D7BD );
                    DrawLine( pdcDraw->m_hDC, 2, 3, 2, m_nHeight - 3, 0xF0D1B5 );
                    DrawLine( pdcDraw->m_hDC, m_nWidth - 3, 3,
                        m_nWidth - 3, m_nHeight - 3, 0xF0D1B5 );
                }
                else
                {
                    DrawLine( pdcDraw->m_hDC, 2, m_nHeight - 2,
                        m_nWidth - 2, m_nHeight - 2, ShiftColor( m_ulXPFace, -0x30, true ) );
                    DrawLine( pdcDraw->m_hDC, 1, m_nHeight - 3,
                        m_nWidth - 2, m_nHeight - 3, ShiftColor( m_ulXPFace, -0x20, true ) );
                    DrawLine( pdcDraw->m_hDC, m_nWidth - 2, 2,
                        m_nWidth - 2, m_nHeight - 2, ShiftColor( m_ulXPFace, -0x24, true ) );
                    DrawLine( pdcDraw->m_hDC, m_nWidth - 3, 3,
                        m_nWidth - 3, m_nHeight - 3, ShiftColor( m_ulXPFace, -0x18, true ) );
                    DrawLine( pdcDraw->m_hDC, 2, 1,
                        m_nWidth - 2, 1, ShiftColor( m_ulXPFace, 0x10, true ) );
                    DrawLine( pdcDraw->m_hDC, 1, 2,
                        m_nWidth - 2, 2, ShiftColor( m_ulXPFace, 0x0A, true ) );
                    DrawLine( pdcDraw->m_hDC, 1, 2, 1, m_nHeight - 2,
                        ShiftColor( m_ulXPFace, -0x05, true ) );
                    DrawLine( pdcDraw->m_hDC, 2, 3, 2, m_nHeight - 3,
                        ShiftColor( m_ulXPFace, -0x0A, true ) );
                }
            }
            else if( m_lButtonType == 4 )
            {
                //Mac
                DrawRectangle( pdcDraw->m_hDC, 1, 1,
                    m_nWidth - 2, m_nHeight - 2, m_ulLight );
                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
                DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth, m_nHeight,
                    m_ulDarkShadow, true );
                SetPixel( pdcDraw->m_hDC, 1, 1, m_ulDarkShadow );
                SetPixel( pdcDraw->m_hDC, 1, m_nHeight - 2, m_ulDarkShadow );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 2, 1, m_ulDarkShadow );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 2, m_nHeight - 2, m_ulDarkShadow );
                DrawLine( pdcDraw->m_hDC, 1, 2, 2, 0, m_ulFace );
                DrawLine( pdcDraw->m_hDC, 3, 2, m_nWidth - 3, 2, m_ulHighLight );
                DrawLine( pdcDraw->m_hDC, 2, 2, 2, m_nHeight - 3, m_ulHighLight );
                SetPixel( pdcDraw->m_hDC, 3, 3, m_ulHighLight );
                DrawLine( pdcDraw->m_hDC, m_nWidth - 3, 1,
                    m_nWidth - 3, m_nHeight - 3, m_ulFace );
                DrawLine( pdcDraw->m_hDC, 1, m_nHeight - 3,
                    m_nWidth - 3, m_nHeight - 3, m_ulFace );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 4, m_nHeight - 4, m_ulFace );
                DrawLine( pdcDraw->m_hDC, m_nWidth - 2, 2,
                    m_nWidth - 2, m_nHeight - 2, m_ulShadow );
                DrawLine( pdcDraw->m_hDC, 2, m_nHeight - 2,
                    m_nWidth - 2, m_nHeight - 2, m_ulShadow );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 3, m_nHeight - 3, m_ulShadow );
            }
            else if( m_lButtonType == 5 )
            {
                //Java
                DrawRectangle( pdcDraw->m_hDC, 1, 1, m_nWidth - 1, m_nHeight - 1,
                    ShiftColor( m_ulFace, 0x0C ) );
                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
                DrawRectangle( pdcDraw->m_hDC, 1, 1, m_nWidth - 1, m_nHeight - 1,
                    m_ulHighLight, true );
                DrawRectangle( pdcDraw->m_hDC, 0, 0, m_nWidth - 1, m_nHeight - 1,
                    ShiftColor( m_ulShadow, -0x1A ), true );
                SetPixel( pdcDraw->m_hDC, 1, m_nHeight - 2,
                    ShiftColor( m_ulShadow, 0x1A ) );
                SetPixel( pdcDraw->m_hDC, m_nWidth - 2, 1,
                    ShiftColor( m_ulShadow, 0x1A ) );
                if( m_bFocus && m_bShowFocusRect )
                {
                    DrawRectangle( pdcDraw->m_hDC, m_recText.left - 2, m_recText.top -1,
                        m_recText.Width() + 4, m_recText.Height() + 2, 0xCC9999, true );
                }
            }
            else if( m_lButtonType == 6 )
            {
                //Netscape6
                if( m_bMouseOver )
                {
                    DrawCaption( pdcDraw->m_hDC, 1 );
                }
                else
                {
                    DrawCaption( pdcDraw->m_hDC, 0 );
                }
                DrawFrame( pdcDraw->m_hDC, ShiftColor( m_ulLight, 0x08 ),
                    m_ulShadow, ShiftColor( m_ulLight, 0x08 ), m_ulShadow, 0 );
               
                DrawFocusR( pdcDraw->m_hDC, m_recFocusRect, m_ulText );
            }
            else if( m_lButtonType == 7 )
            {
                //SimpleFlat
     

抱歉!评论已关闭.