📄 sccolorbox.cpp
字号:
/*
* This file is part of the EMFexplorer projet.
* Copyright (C) 2004 Smith Charles.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* Extension: for commercial use, apply the Equity Public License, which
* adds to the normal terms of the GLPL a condition of donation to the author.
* If you are interested in support for this source code,
* contact Smith Charles <smith.charles@free.fr> for more information.
*/
#include "stdafx.h"
#include "SCColorBox.h"
#include <afxdlgs.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSCColorBox
CSCColorBox::CSCColorBox():
m_pLogPalette(NULL),
m_bCustomAllowed(TRUE),
m_bDlgOpened(FALSE),
m_crSelColor(RGB(255, 255, 255))
{
}
void CSCColorBox::SCReset()
{
m_crSelColor = RGB(255, 255, 255);
SetCurSel(-1);
}
CSCColorBox::~CSCColorBox()
{
if (m_pLogPalette)
delete m_pLogPalette;
}
BEGIN_MESSAGE_MAP(CSCColorBox, CComboBox)
//{{AFX_MSG_MAP(CSCColorBox)
ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendok)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelendok)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSCColorBox utilities
/////////////////////////////////////////////////////////////////////////////
// (c) Microsoft, 1993 - 1998 / MSDN / OWNCOMBO.C
// (c) Microsoft (adapted)
void CSCColorBox::DrawItem(LPDRAWITEMSTRUCT lpdis)
{
if (lpdis->itemID == -1)
{
/* We have a request to draw an item in the list box, yet there
* are no list box items. This is sent when the user TABS into
* an empty list box or an empty list box gets the focus. We
* have to indicate (somehow) that this owner-draw list box has
* the focus. We do it in response to this message. Note that
* lpdis->itemData field would be invalid in this instance so
* we can't allow it to fall into our standard routines.
*/
HandleFocusState(lpdis, -(int)(SC_COLORITM_INFLATE));
}
else
{
switch (lpdis->itemAction)
{
case ODA_DRAWENTIRE:
DrawEntireItem(lpdis, -(int)(SC_COLORITM_INFLATE));
break;
case ODA_SELECT:
HandleSelectionState(lpdis, -((int)(SC_COLORITM_INFLATE) - 2));
break;
case ODA_FOCUS:
HandleFocusState(lpdis, -(int)(SC_COLORITM_INFLATE));
break;
}
}
}
// (c) Microsoft
/****************************************************************************
* *
* FUNCTION : HandleSelectionState(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Handles a change in an item selection state. If an item is *
* selected, a black rectangular frame is drawn around that *
* item; if an item is de-selected, the frame is removed. *
* *
* COMMENT : The black selection frame is slightly larger than the gray *
* focus frame so they won't paint over each other. *
* *
****************************************************************************/
void CSCColorBox::HandleSelectionState(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;
/* Resize rectangle to place selection frame outside of the focus
* frame and the item.
*/
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);
if (lpdis->itemState & ODS_SELECTED)
{
/* selecting item -- paint a black frame */
hbr = (HBRUSH)GetStockObject(BLACK_BRUSH);
}
else
{
/* de-selecting item -- remove frame */
hbr = (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_WINDOW));
}
FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
}
// (c) Microsoft
/****************************************************************************
* *
* FUNCTION : HandleFocusState(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Handle a change in item focus state. If an item gains the *
* input focus, a gray rectangular frame is drawn around that *
* item; if an item loses the input focus, the gray frame is *
* removed. *
* *
* COMMENT : The gray focus frame is slightly smaller than the black *
* selection frame so they won't paint over each other. *
* *
****************************************************************************/
void CSCColorBox::HandleFocusState(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;
/* Resize rectangle to place focus frame between the selection
* frame and the item.
*/
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);
if (lpdis->itemState & ODS_FOCUS)
{
/* gaining input focus -- paint a gray frame */
hbr = (HBRUSH)GetStockObject(GRAY_BRUSH);
}
else
{
/* losing input focus -- remove (paint over) frame */
hbr = (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_WINDOW));
}
FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
}
// (c) Microsoft (adapted)
/****************************************************************************
* *
* FUNCTION : DrawEntireItem(LPDRAWITEMSTRUCT, int) *
* *
* PURPOSE : Draws an item and frames it with a selection frame and/or *
* a focus frame when appropriate. *
* *
****************************************************************************/
void CSCColorBox::DrawEntireItem(
LPDRAWITEMSTRUCT lpdis,
INT inflate)
{
RECT rc;
HBRUSH hbr;
if (!lpdis || !m_pLogPalette)
return;
/* Resize rectangle to leave space for frames */
CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
InflateRect ((LPRECT)&rc, inflate, inflate);
// according to the item index, create the corresponding brush
// to draw one palette entry
// get the entry palette corresponding to the index item
int itemIdx = lpdis->itemData;
if ((itemIdx>=0) && (itemIdx<m_pLogPalette->palNumEntries))
{
COLORREF color = RGB(m_pLogPalette->palPalEntry[itemIdx].peRed,
m_pLogPalette->palPalEntry[itemIdx].peGreen,
m_pLogPalette->palPalEntry[itemIdx].peBlue);
// create brush and fill the rectangle
hbr = (HBRUSH)CreateSolidBrush(color);
FillRect(lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
/* Draw or erase appropriate frames */
HandleSelectionState(lpdis, inflate + 4);
HandleFocusState(lpdis, inflate + 2);
if(lpdis->itemState & ODS_COMBOBOXEDIT)
{
m_crSelColor = color;
}
return;
}
if (m_bCustomAllowed && itemIdx == m_pLogPalette->palNumEntries)
{
if(!(lpdis->itemState & ODS_COMBOBOXEDIT))
{
::SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
::SetBkMode(lpdis->hDC, OPAQUE);
::SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
::OffsetRect(&rc, 0, -1); // TODO: remove font's internal leading instead
::DrawText(lpdis->hDC, _T("Colors..."), 9, (LPRECT)&rc, DT_CENTER|DT_TOP);
}
else
{
// a sys color can be here
COLORREF color = m_crSelColor;
if (0x80000000 & color)
color = GetSysColor(0x000000FF & color);
// create brush and fill the rectangle
hbr = (HBRUSH)CreateSolidBrush(color);
FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
DeleteObject (hbr);
/* Draw or erase appropriate frames */
HandleSelectionState(lpdis, inflate + 4);
HandleFocusState(lpdis, inflate + 2);
}
}
}
// End of (c) 1993 - 1998 Microsoft Corp / MSDN / OWNCOMBO.C
/////////////////////////////////////////////////////////////////////////////
int CSCColorBox::CompareItem(LPCOMPAREITEMSTRUCT lpcis)
{
// TODO: Add your message handler code here and/or call default
return 0;
}
// Warning: must use CBS_OWNERDRAWVARIABLE for this to work
void CSCColorBox::MeasureItem(LPMEASUREITEMSTRUCT lpmis)
{
// Code to determine the size of specified item
int iHeight = SC_COLORITM_INFLATE + SCComputeFontHeight() + SC_COLORITM_INFLATE;
if (iHeight<SC_COLORITM_HEIGHT_RGB)
lpmis->itemHeight = SC_COLORITM_HEIGHT_RGB;
else
lpmis->itemHeight = iHeight;
}
int CSCColorBox::SCComputeFontHeight()
{
CDC* pDC = GetDC();
if (!pDC)
return -1;
CFont* pFont = GetFont();
if (pFont)
pFont = (CFont*)pDC->SelectObject(pFont);
else
pFont = (CFont*)pDC->SelectStockObject(DEFAULT_GUI_FONT);
CSize szSize = pDC->GetTextExtent(_T("M"), 1);
pDC->SelectObject(pFont);
ReleaseDC(pDC);
return szSize.cy;
}
////////////////////////////////////////////////
// Bad, bad, bad land! (though the code is good)
//
// Warning: it may not be called, so apply settings in dialog template or
// in the call to CreateEx
BOOL CSCColorBox::PreCreateWindow(CREATESTRUCT& cs)
{
// Add your specialized code here and/or call the base class
if (!CComboBox::PreCreateWindow(cs))
return FALSE;
cs.style &= ~(CBS_OWNERDRAWFIXED | CBS_SORT);
cs.style |= CBS_OWNERDRAWVARIABLE;
return TRUE;
}
// Warning: A problem in dialog template created classes (CListBox, CEdit, and so on
// created by AppStudio) is that OnCreate is not called.
// int CSCColorBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
// {
// if (CComboBox::OnCreate(lpCreateStruct) == -1)
// return -1;
//
// InitColorsComboBox(m_crSelColor);
// return 0;
// }
////////////////////////////////////////////////
// This must be called after combo creation in the parent's
// creation/initialization function
void CSCColorBox::InitColorsComboBox(COLORREF crDefaultColor)
{
m_crSelColor = crDefaultColor;
if (m_pLogPalette)
return;
m_pLogPalette = SCCreatePalette();
ASSERT(m_pLogPalette);
// CBS_HASSTRINGS is implied if one of the CBS_OWNERDRAWs is not specified
BOOL bHasString = (0!=(GetStyle() & CBS_HASSTRINGS));
ASSERT(!bHasString);
if (bHasString)
return; // ModifyStyle won't succeed
int iNbrOfitems = m_pLogPalette->palNumEntries;
for (int i=0; (i<iNbrOfitems); i++)
{
AddString((LPCTSTR)i);
// WARNING: Combo does not have the CBS_HASSTRINGS style, so the
// normal listbox string is used to store an index to the palette entry
}
if (m_bCustomAllowed)
{ // For custom color
AddString((LPCTSTR)iNbrOfitems);
SetCurSel(iNbrOfitems); // Select custom color
} else
SetCurSel(CB_ERR);
}
//
// Select the lColor in the combo box
// the return value is the selected color if it succeeds,
// -1 if it fails
//
COLORREF CSCColorBox::SCSetCurSelColor(COLORREF crColor)
{
// get the corresponding color
if (!m_pLogPalette)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -