Value of Life

codeproject round button 본문

IT/MFC

codeproject round button

앵글메이커 2008. 8. 10. 22:14
반응형

Sample Image

Introduction

I wanted a button that looked exactly like normal buttons, but instead I wanted them circular. This class can be used like any other owner drawn control - simply include the header file, and declare your button controls as CRoundButton instead of CButton

First of all I make sure the buttons are circles (and not ellipses) and store the centre and radius of the button. Next I simply make the button owner drawn and draw it like every other owner drwn button, but instead of being able to use nice routines like Draw3dRect, I had to roll my own circle drawing routine which would draw each pixel with the correct colour dependant on the point on the circle I was drawing.

I will not include the full source in this page - it is available for download here. The owner draw part is simple and follows along the lines of any other owner drawn button. The circle drawing routine is a standard algorithm, with the only modification in calculating the pixel colour. Given two colours crBright and crDark, and an angle relative to the x-axis, the colour for a pixel can be calculated using the following.

COLORREF GetColour(double dAngle, COLORREF crBright, COLORREF crDark)
{
#define Rad2Deg            180.0/3.1415 
#define LIGHT_SOURCE_ANGLE  -2.356    // -2.356 radians = -135 degrees, 
                                      // i.e. From the top left of the screen

    ASSERT(dAngle > -3.1416 && dAngle < 3.1416);
    double dAngleDifference = LIGHT_SOURCE_ANGLE - dAngle;

    if (dAngleDifference < -3.1415) 
        dAngleDifference = 6.293 + dAngleDifference;
    else if (dAngleDifference > 3.1415) 
        dAngleDifference = 6.293 - dAngleDifference;

    double Weight = 0.5*(cos(dAngleDifference)+1.0);

    BYTE Red   = (BYTE) (Weight*GetRValue(crBright) + 
                        (1.0-Weight)*GetRValue(crDark));
    BYTE Green = (BYTE) (Weight*GetGValue(crBright) + 
                        (1.0-Weight)*GetGValue(crDark));
    BYTE Blue  = (BYTE) (Weight*GetBValue(crBright) + 
                        (1.0-Weight)*GetBValue(crDark));

    return RGB(Red, Green, Blue);
}

This is a simple linear interpolation between the two colours based on the cosine of the angle between the light source and the point. Angles are measured from the +ve x-axis (i.e. (1,0) = 0 degrees, (0,1) = 90 degrees ), but remember: positive y points down!

Update

  • Download demo project - 24 Kb
  • Download source files - 5 Kb

    Sample Image

    This class is based on Chris Maunder's Round Buttons. However, instead of forcing all buttons to be round, this class allows buttons to be elliptical, with the major and minor axes based on the bounds of the rectangle passed to the buttons' creation function (Either through CEllipticalButton::Create or via the DevStudio resource editor).

    This class can be used like any other owner drawn control - simply include the header file, and declare your button controls as CEllipticalButton instead of CButton

  • License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    반응형

    'IT > MFC' 카테고리의 다른 글

    AquaButton: A sample custom button control with a Mac OS X look  (0) 2008.08.12
    CxSkinbutton  (0) 2008.08.11
    codeprject round slider control  (0) 2008.08.10
    Round Button Control - mfc 아님  (0) 2008.08.10
    MFC 버튼에 BMP넣는 두가지 방법  (1) 2008.08.10