SHARE
Facebook X Pinterest WhatsApp

Advanced ActiveX Buttons

kSet Button ActiveX The kSet Button control is designed for developers who want an alternative to the standard Windows command button. It offers everything that the standard button offers plus a whole lot more. For creation of control the library ATL 3.0 and VC++ 6.0 (SP 3.0) was used. Control can be in several states: […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Dec 27, 1999
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

kSet Button ActiveX

The kSet Button control is designed for developers who want an alternative to the
standard Windows command button. It offers everything that the standard button offers plus
a whole lot more.

For creation of control the library ATL 3.0 and VC++ 6.0 (SP 3.0) was
used.
Control can be in several states: static, hover, push, disabled and to contain the image
and text, allows flexibly changing appearance.
kSet Button control don’t subclass an existing window.

Properties
Enabled: sets a value that determines if the control can receive user
input.
HoverEnabled: permit a hover state
AppearanceStatic: sets a appearance of control for a static state
AppearanceHover: sets a appearance of control for a hover state
AppearancePush: sets a appearance of control for a push state

ShowFocus: manner of display of focus (draws a rectangle, transition in a
hover state, nothing)
ShowStateAsFlat: display a condition through change of backcolor if
appearance equal flat or border
BorderColor: the border color of the button.
HighlightColor: the color used to display portions of the button that are
highlighted
ShadowColor: the color used to display portions of the button that
require shadow effects
TextPushColor: foreground color used to display text of the button at a
push state
TextHoverColor: foreground color used to display text of the button at a
hover state
TextStaticColor: foreground color used to display text of the button at a
static state
PictureAlignment: a value that determines the placement of the picture in
relation to the caption.
PictureSpacing: a value that determines the spacing to be used between
the picture and the caption.
PicturePush: the picture to be displayed on the button at a push state.
PictureHover: the picture to be displayed on the button at a hover state.
PictureStatic: the picture to be displayed on the button at a static
state.
PictureDisabled: When the control is disabled, the STATIC picture
displayed will automatically be changed to a disabled look. The disabled state can be
overridden by setting the PictureDisabled property.
TextPush: a value that determines the text displayed in the button at a
push state
TextStatic: a value that determines the text displayed in the button at a
static state
TextHover: a value that determines the text displayed in the button at a
hover state
FontHover: the font used for the text at a hover state.
FontStatic: the font used for the text at a hover state.
FontPush: the font used for the text at a hover state.

Methods
DoClick: feign pressing the button
AboutBox: displays the about dialog containing the product name and
version.

Event
Click: Occurs when the user presses and releases the mouse button.

Implementation
As the control don’t subclass an existing window was already mentioned earlier.
All code engaged by display of the button is concentrated in a class _ Render < >
which is mixed class. We use at drawing the button simple wrapper classes for GDI handles
such as HFONT, HPEN, etc. Directly draws the button an array of functions, the pointers on
which are stored in a static array.

[renderbutton.h]
template <class T>
class _Render
{
...
typedef void
(_Render::*PTR_FDRAW)(_kDrawDC& dc, RECT& rc);
static PTR_FDRAW& f_table (int appearance,
int status)
{
  static PTR_FDRAW&
f_table (int appearance, int status)
  {
 
//appearance, status
 
static PTR_FDRAW table[8][4] = {...};
 
...
 
return table[appearance][status];
  }
}
...
};

template <class T>
void _Render<T>::DrawIt(HDC hdc, int state, RECT& rc)
{
PTR_FDRAW ff;

// We choose function depending on a state and
appearance of the button
switch (state)
{
case 0:
  ff =
f_table(pT->m_AppearanceStatic, state);
      ...
        }
           
        //draws a button   
(this->*ff)(_kDrawDC(hdc), rc);
...
//display the text
DrawState(...);

...
//draws focus rectangle if need
DrawFocusRect(hdc, &rc_focus);
...
//display an image through method IPicture
interface
pPic->Render(...);
...
}

We imported function "TrackMouseEvent" from user32.lib for tracking of mouse
pointer.

[kbutton.cpp]
void _kButton::DetectTrackMouse()
{
m_pfTrackMouseEvent =
(PTRF_TrackMouseEvent)GetProcAddress

(GetModuleHandle(_T("user32")),_T("TrackMouseEvent"));

}

Or at absence (in Windows 95) is traced moving the mouse from second thread through a
class _kMouseMoveImpl.

The class _kMouseMoveImpl inherits logic of work with threads from class
_ApartmentThread<> and realizes tear-off interface IMouseMove.

[mousemove.h]
class ATL_NO_VTABLE _kMouseMoveImpl :
public _IMouseMove,
public CComTearOffObjectBase<_kButton>,
public _ApartmentThread<_kMouseMoveImpl,
_IMouseMove, &IID__IMouseMove>
{
...
}

[kbutton.h]
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(IID__IMouseMove, _kMouseMoveImpl,
m_pUnkMouseMove.p)

[kbutton.cpp]
void _kButton::TrackMouse()
{
if (m_pfTrackMouseEvent)
{
...
}
else
{

CComQIPtr<_IMouseMove> pI(GetControllingUnknown());

pI->_StartThread(100);
}
}

Use of a class as tear-off interface allows saving memory, as the necessity in
kMouseMoveImpl arises only at work under Win95. The similar circuit is applied and at
animation of pressing the button (for example by a call a method DoClick)

[kButton.cpp]
STDMETHODIMP _kButton::DoClick(VARIANT_BOOL bAnimate)
{
...
CComQIPtr<_IAnimationClick>
pI(GetControllingUnknown());
pI->_StartThread(100);
...
}

The class _ApartmentThread encapsulating a work with STA – creation threads, marshals an
interface pointer, etc.

[apartmentthread.h]
template <class Derived, class T, const IID* piid>
class _ApartmentThread
{
...
HRESULT _StartThread(int nTimeOut)
{
...
if
(SUCCEEDED(CoMarshalInterThreadInterfaceInStream(*piid, (T*)pDerived, &m_pStream)))

m_hThread = CreateThread(0, 0, &Apartment, (void*)this, 0,
&dw);
...

}
...
}

The properties of control are realized with the help of the macros IMPLEMENT_XXX taken
from a file atlctr.h
For properties FontXXX h PictureXXX were written macros: IMPLEMENT_PICTURE_PROPERTY h
IMPLEMENT_FONT_PROPERTY and mixed classes _HelperPictureProperty<> and
_HelperFontProperty<>

The events are realized through dispinterface IkButtonEvents and custom interface
IkButtonEvents for C++ containers.

I used for calculation of ShadowColor and HighlightColor the HSL color model realized in a
class HSLModel.

[kbutton.h]
void _kButton::Get3DColors (COLORREF clr, COLORREF& clrShadow,
COLORREF& clrHighlight)
{
_HSLModel hsl(clr);
_HSLModel _hs1 = hsl;
BYTE lum = hsl.luminance();
hsl.luminance (lum / 3 * 2);
_hs1.luminance (lum + ((240 - lum) / 2));
clrShadow = hsl.rgb();

clrHighlight = _hs1.rgb();
}

For Visual Basic IDE realized ICategorizeProperties interface in a class _
kICategorizeProperiesImpl.

[categorizeproperties.h]
template <class T>
class ATL_NO_VTABLE _kICategorizeProperiesImpl :
public ICategorizeProperties
{
STDMETHOD(MapPropertyToCategory)(DISPID dispid,
PROPCAT* ppropcat )
...
STDMETHOD(GetCategoryName)(PROPCAT propcat,
LCID lcid, BSTR* pbstrName)
...
}

[kbutton.h]
class ATL_NO_VTABLE _kButton :
...
public
_kICategorizeProperiesImpl<_kButton>,
...
{
...
BEGIN_CATEGORY_PROP_NAME_MAP(_kButton)
CATEGORY_PROP_NAME(1, _T("Picture"))
CATEGORY_PROP_NAME(2, _T("Color"))
END_CATEGORY_PROP_NAME_MAP()

BEGIN_PROPERTY_TO_CATEGORY_NAME_MAP (_kButton)
PROPERTY_TO_CATEGORY(dispidTextPush,
PROPCAT_Text)
PROPERTY_TO_CATEGORY(dispidPictureDisabled, 1)
...
END_PROPERTY_TO_CATEGORY_MAP()
...
}

Downloads

Download demo project – 45 Kb
Download source – 204 Kb

Recommended for you...

Video Game Careers Overview
CodeGuru Staff
Sep 18, 2022
Dealing with non-CLS Exceptions in .NET
Hannes DuPreez
Aug 5, 2022
Online Courses to Learn Video Game Development
Ronnie Payne
Jul 8, 2022
Best Online Courses to Learn C++
CodeGuru Staff
Jun 25, 2022
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.