Color Component Editor Control

Environment: VC6, NT4,98,2000,XP

 

Introduction

When one comes to editing color values, a variety of free custom controls is available on internet. Most of the time they are color pickers, list boxes, property sheets with system and HTML colors, etc. They usually work with RGB components, sometimes with the HSL model. We felt that there was a lack with edit-based color editors and we decided to mimic one of the controls Jasc Software is using in Paint Shop Pro to edit a color value, component by component in the RGB (Red, Green, Blue) and HSL (Hue, Saturation, Light) models.

You can see a screenshot of the well-known color dialog in PSP at the top of this article.

The goal is to develop a control having the same behavior and the exact same look. Why? Because we like this control and we feel it as a standard that should come naturally as an MFC class. We understand that this piece of code is not a revolution, but we are sure that some of you will find it valuable for their own project.

So let's go and first have a look at the object design of the classes we show in this article.

Design

Our framework is composed of four GUI classes and two utility classes. As usual for a custom control, we derive the main class, GWCColorComponentEditCtrl (pretty long name), from CWnd. Doing this will allow the client to integrate the control in a Cdialog at design time (since we will also define a window class) or dynamically in any window.

This main class is linked to three internal components:

" A CEdit instance: the user must be able to enter a value directly at the keyboard.
" A CspinButtonCtrl instance: it's also convenient to modify a value by clicking on these small arrows.
" A static window called GWCGradientColorWnd: this popup window makes easy to see the changes on the color by dragging the mouse from the minimum to the maximum value allowed (0 to 255).

Here is the class diagram showing the links between all these elements :



Click here for larger image

 

As you can see there is another class called GWCColorComponentSet. This is one of the utility classes we talked above. We created it for the following reason: most of the time, you won't use GWCColorComponentEditCtrl alone. Instead you will create three of them to edit the three components of a color (either RGB or HSL). As you can see on the PSP screenshot, they even show both models with six controls. GWCColorComponentSet allows to link all these components so that it keeps track of the edited color and notifies the group when one of them changes. It makes the client code and the effort to produce to use this framework minimals.

The other utility class, GWCColorFunc, is a static class providing utility functions for color conversions.

Note also the bottom colored line below the edit control. This is a convenient way to change the value with a quick drag of the mouse. There is no underlying window for this effect. Instead, the bar is drawn by GWCColorComponentEditCtrl.

Installation

We have made the code ready to be included as a library. Just install the source package in a directory. Open the workspace and compile all the desired configurations (a mix of release/debug/lib/dll/Unicode). All lib and dll files are produced in a sub-directory called bin.

In Visual C++ (tools -> options -> directories tab), add the bin directory to your list of library directories and its parent directory to the list of include directories. Either the bin directory is in your path or you copy the dlls in /windows/system32, it's up to you.

The source code is fully commented so we won't go into it. Let's just see how to use it in a dialog box. It's very simple:

In your stdafx.h file, add the following line:

#include <GWCCCEInc.h>

You don't need to insert a library file in your project because it will be done automatically with this included header file. However, you have to add a preprocessor variable in your project settings in the following cases:

  • If you want to use this control as a static library, define _GWCCCECTRL_STATIC_.
  • If you want to use this control as a DLL in one of your MFC DLL, define _GWCCCECTRL_IN_OTHER_DLL.

Of course, you must have somewhere a COLORREF variable (m_myColor) in your code to hold your color.

Creation

Create a GWCColorComponentSet instance to hold the controls we will create:

GWCColorComponentSet m_compSet;

In the dialog editor, create any number of custom controls you want and set their window class to "ColorCompEditCtrl". Their height should be the same as a standard edit control. Create the corresponding variables in the dialog header file.

GWCColorComponentEditCtrl m_myComponent;

One more step for the creation, in your dialog DoDataExchange method, add the following line for each of your controls:

DDX_Control(pDX, IDC_MYCOMPONENT, m_myComponent);

When created dynamically in a window instead of a dialog box, use the following method:

Allocate all the needed instances of GWCColorComponentEditCtrl and call their method Create. Use a height of 23 pixels for a standard look.

Initialization

Now you must initialize each control and tell him what kind of component it represents. Basically, you do this in OnInitDialog:

m_myComponent.SetType(GWCColorComponentEditCtrl::RED);

Instead of RED you have the choice of GREEN, BLUE, HUE, SAT, LIGHT.

When you are done with that, you link all your components in the GWCColorComponentSet instance and set the initial color.

m_compSet.RegisterComponentCtrl(m_myComponent);

m_compSet.SetColor(m_myColor);

Dynamics

Your window or dialog box can be notified when one of the components changes. To do this you have to write a handler for a registered message.

In the header file add this in your message map:

afx_msg LRESULT OnColorCompChanged(WPARAM wParam, 
                                        LPARAM lParam);

In the body add this:

// In your message map :
ON_REGISTERED_MESSAGE( WM_GWCCOLORCOMPEDIT_CHANGED, 
                       OnColorCompChanged)

LRESULT CMyDialog::OnColorCompChanged( WPARAM wParam, 
                                       LPARAM lParam)
{
   m_myColor = m_compSet.GetColor();
   return (LRESULT)0;
}

wParam contains the value of the component (0 to 255) and lParam contains the window identifier of the control that sent this message.

Disclaimer

This software, source code and sample, is provided "as is". Aircom software makes no representations or warranties of any kind concerning the quality, safety or suitability of the software, either expressed or implied, including without limitation any implied warranties of merchantability, fitness for a particular purpose, or non-infringement.

Downloads

Download demo project - 59 Kb
Download source - 53 Kb


Comments

  • No setup for me

    Posted by Legacy on 05/02/2002 12:00am

    Originally posted by: Philippe Lhoste

    I dislike setups most of the time, because in most cases, they are not needed, and they add often a lot of clutter to my system. Plus they are not "transparent", ie. I don't know what they will do, what files they content, etc.

    It *may* be useful for your demo, if you register keys, etc. ie. if your setup does complex things.
    But I doubt it useful for your source.

    NSIS is nice and small, but don't overuse it!

    Thank you.

    Reply
  • It is perfect. But ..

    Posted by Legacy on 04/12/2002 12:00am

    Originally posted by: Flyangel

    It is a helper. But the sample is not like the picture showing.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 11, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT One of the languages that have always been supported with the Intel® RealSense™ SDK (Software Developer Kit) is JavaScript, specifically so that web-enabled apps could be created. Come hear from Intel Expert Bob Duffy as he reviews his own little "space shooting" game where the orientation of your face controls the aiming reticle to help teach developers how to write apps and games in JavaScript that can use facial and gesture …

  • Live Event Date: May 6, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT Where are you in your plans to adopt Disaster Recovery-as-a-Service? Are you just getting started? Fighting an uphill battle with management? At Cisco, Zerto and iland, we've seen it all – from the early adopters who excitedly rushed to implement DRaaS with us nine years ago to the IT folks dragging their business leaders into the future. With our years of experience, we've learned there are six types of DRaaS leaders – but which type …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date