YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET

 


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


VC++ Tutorial: Custom CListBox - A ListBox with Radio Box, DrawFrameControl, DrawFocusRect

 
 By Jaime Olivares. 

Introduction

Recently I had discussed in a Visual C++ forum about a member's request to implement a custom ListBox control similar to CCheckListBox, but with radio buttons. Initially it appeared to be trivial, since the ListBox control's unique selection version complies with ucancode.neter requirements, but I have concluded that this control has some advantages:

  • It is clearer, with radio buttons, that options are mutually exclusive.
  • Is a good alternative to a group of radio buttons, because you have to maintain just one control.
  • It inherits some useful features like scrolling, sort and multi-column.
  • Will be easier to change options dynamically, as shown in demo application.
  • Will be easier to manage selection events, also shown in demo application.

Using the code

To implement CRadioListBox into your project, you just need to do a few steps:

  • Include RadioListBox.cpp and RadioListBox.h in your project.
  • Insert a CRadioListBox object into your dialog class declaration (.h file).
  • Put a standard ListBox control into your dialog's template layout, "ensure that 'owner draw fixed' property is active".
  • Create or modify an OnInitDialog event, and subclass corresponding ListBox.

For example, if your dialog is named CMyDialog, the ListBox member is m_RadioListBox, and the control ID is IDC_RADIOLISTBOX, then you can subclass the control in the following way:

BOOL CMyDialog::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Some other custom source code here

    m_RadioListBox.SubclassDlgItem(IDC_RADIOLISTBOX, this);   
    
    return TRUE;  // return TRUE  unless you set the focus to a control
}

There are other ways to subclass a control in a MFC application, as explained by Eric Sanchez in his article ("Control Subclassing") but I think the above version is the shortest one.

Transparency

As you can see in the above pictures, there is a transparency feature, so the ListBox can imitate Radio Button's aspect, this can be easily done by setting the WS_EX_TRANSPARENCY attribute of the control in the Visual C++ Dialog Editor. Also it will be necessary to make WS_BORDER style "off".

CRadioListBox internals

CRadioListBox class is derived from CListBox class with just one derived method: DrawItem. The method does not highlight the selected item as in a standard ListBox control, but draws a radio button instead. It also manages focus state to draw the focus rectangle properly and the background color according to the transparency attribute. I know it could have been better, but this first version runs OK under different screen conditions. Here is the source code:

Collapse
void CRadioListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    // just draws focus rectangle when listbox is empty
    if (lpDrawItemStruct->itemID == (UINT)-1)
      {
         if (lpDrawItemStruct->itemAction & ODA_FOCUS)
         pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
         return;
      }
    else
      {
         int selChange = lpDrawItemStruct->itemAction & ODA_SELECT;
         int focusChange = lpDrawItemStruct->itemAction & ODA_FOCUS;
         int drawEntire = lpDrawItemStruct->itemAction & ODA_DRAWENTIRE;
         if (selChange || drawEntire) 
         {
               BOOL sel = lpDrawItemStruct->itemState & ODS_SELECTED;
               // Draws background rectangle, color depends on transparency
               pDC->FillSolidRect(&lpDrawItemStruct->rcItem, 
               ::GetSysColor((GetExStyle()&WS_EX_TRANSPARENT)?
                                                COLOR_BTNFACE:COLOR_WINDOW));
               // Draw radio button
               int h = 
                 lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
               CRect rect(lpDrawItemStruct->rcItem.left+2, 
                          lpDrawItemStruct->rcItem.top+2, 
                          lpDrawItemStruct->rcItem.left+h-3, 
                          lpDrawItemStruct->rcItem.top+h-3);
               pDC->DrawFrameControl(&rect, DFC_BUTTON, 
                       DFCS_BUTTONRADIO | (sel?DFCS_CHECKED:0));
               // Draws item text
               pDC->SetTextColor(COLOR_WINDOWTEXT);
               pDC->SetBkMode(TRANSPARENT);
               lpDrawItemStruct->rcItem.left += h;
               pDC->DrawText((LPCTSTR)lpDrawItemStruct->itemData, 
                            &lpDrawItemStruct->rcItem, DT_LEFT);
         }
         // draws focus rectangle
         if (focusChange || (drawEntire && 
                  (lpDrawItemStruct->itemState & ODS_FOCUS)))
             pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
     }
}

To achieve transparency feature, it will be necessary to control the background painting too, by handling the WM_CTLCOLOR message:

HBRUSH CRadioListBox::CtlColor(CDC* pDC, UINT nCtlColor) 
{
    // If transparent style selected...
    if ( (GetExStyle()&WS_EX_TRANSPARENT) && nCtlColor==CTLCOLOR_LISTBOX)
        return (HBRUSH)::GetSysColorBrush(COLOR_BTNFACE);

    return NULL;
}

 

 

Copyright ?1998-2009 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net