184 lines
4.8 KiB
C++
184 lines
4.8 KiB
C++
// custlist.cpp : custom listbox
|
|
//
|
|
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1998 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
#include "ctrltest.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Custom Listbox - containing colors
|
|
|
|
class CColorListBox : public CListBox
|
|
{
|
|
public:
|
|
// Operations
|
|
void AddColorItem(COLORREF color);
|
|
|
|
// Implementation
|
|
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
|
|
virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
|
|
virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCIS);
|
|
};
|
|
|
|
void CColorListBox::AddColorItem(COLORREF color)
|
|
{
|
|
// add a listbox item
|
|
AddString((LPCTSTR) color);
|
|
// Listbox does not have the LBS_HASSTRINGS style, so the
|
|
// normal listbox string is used to store an RGB color
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define COLOR_ITEM_HEIGHT 20
|
|
|
|
void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
|
|
{
|
|
// all items are of fixed size
|
|
// must use LBS_OWNERDRAWVARIABLE for this to work
|
|
lpMIS->itemHeight = COLOR_ITEM_HEIGHT;
|
|
}
|
|
|
|
void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
|
|
{
|
|
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
|
|
COLORREF cr = (COLORREF)lpDIS->itemData; // RGB in item data
|
|
|
|
if (lpDIS->itemAction & ODA_DRAWENTIRE)
|
|
{
|
|
// Paint the color item in the color requested
|
|
CBrush br(cr);
|
|
pDC->FillRect(&lpDIS->rcItem, &br);
|
|
}
|
|
|
|
if ((lpDIS->itemState & ODS_SELECTED) &&
|
|
(lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
|
|
{
|
|
// item has been selected - hilite frame
|
|
COLORREF crHilite = RGB(255-GetRValue(cr),
|
|
255-GetGValue(cr), 255-GetBValue(cr));
|
|
CBrush br(crHilite);
|
|
pDC->FrameRect(&lpDIS->rcItem, &br);
|
|
}
|
|
|
|
if (!(lpDIS->itemState & ODS_SELECTED) &&
|
|
(lpDIS->itemAction & ODA_SELECT))
|
|
{
|
|
// Item has been de-selected -- remove frame
|
|
CBrush br(cr);
|
|
pDC->FrameRect(&lpDIS->rcItem, &br);
|
|
}
|
|
}
|
|
|
|
int CColorListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCIS)
|
|
{
|
|
COLORREF cr1 = (COLORREF)lpCIS->itemData1;
|
|
COLORREF cr2 = (COLORREF)lpCIS->itemData2;
|
|
if (cr1 == cr2)
|
|
return 0; // exact match
|
|
|
|
// first do an intensity sort, lower intensities go first
|
|
int intensity1 = GetRValue(cr1) + GetGValue(cr1) + GetBValue(cr1);
|
|
int intensity2 = GetRValue(cr2) + GetGValue(cr2) + GetBValue(cr2);
|
|
if (intensity1 < intensity2)
|
|
return -1; // lower intensity goes first
|
|
else if (intensity1 > intensity2)
|
|
return 1; // higher intensity goes second
|
|
|
|
// if same intensity, sort by color (blues first, reds last)
|
|
if (GetBValue(cr1) > GetBValue(cr2))
|
|
return -1;
|
|
else if (GetGValue(cr1) > GetGValue(cr2))
|
|
return -1;
|
|
else if (GetRValue(cr1) > GetRValue(cr2))
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Dialog class
|
|
|
|
class CCustListDlg : public CDialog
|
|
{
|
|
protected:
|
|
CColorListBox m_colors;
|
|
public:
|
|
//{{AFX_DATA(CCustListDlg)
|
|
enum { IDD = IDD_CUSTOM_LIST };
|
|
//}}AFX_DATA
|
|
CCustListDlg()
|
|
: CDialog(CCustListDlg::IDD)
|
|
{ }
|
|
|
|
// access to controls is through inline helpers
|
|
BOOL OnInitDialog();
|
|
|
|
//{{AFX_MSG(CCustListDlg)
|
|
virtual void OnOK();
|
|
//}}AFX_MSG
|
|
DECLARE_MESSAGE_MAP();
|
|
};
|
|
|
|
BEGIN_MESSAGE_MAP(CCustListDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CCustListDlg)
|
|
ON_LBN_DBLCLK(IDC_LISTBOX1, OnOK) // double click for OK
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
BOOL CCustListDlg::OnInitDialog()
|
|
{
|
|
// subclass the control
|
|
VERIFY(m_colors.SubclassDlgItem(IDC_LISTBOX1, this));
|
|
|
|
// add 8 colors to the listbox (primary + secondary color only)
|
|
for (int red = 0; red <= 255; red += 255)
|
|
for (int green = 0; green <= 255; green += 255)
|
|
for (int blue = 0; blue <= 255; blue += 255)
|
|
m_colors.AddColorItem(RGB(red, green, blue));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CCustListDlg::OnOK()
|
|
{
|
|
// get the final color
|
|
int nIndex = m_colors.GetCurSel();
|
|
if (nIndex == -1)
|
|
{
|
|
CString str;
|
|
str.LoadString(IDS_PLEASE_SELECT_COLOR);
|
|
MessageBox(str);
|
|
m_colors.SetFocus();
|
|
return;
|
|
}
|
|
DWORD color = m_colors.GetItemData(nIndex);
|
|
|
|
#ifdef _DEBUG
|
|
// normally do something with it...
|
|
TRACE1("final color RGB = 0x%06lX\n", color);
|
|
#endif
|
|
|
|
EndDialog(IDOK);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Run the test
|
|
|
|
void CTestWindow::OnTestCustomList()
|
|
{
|
|
TRACE0("running dialog with custom listbox (owner draw)\n");
|
|
CCustListDlg dlg;
|
|
dlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|