ColourPopup.cpp
上传用户:zhoushen
上传日期:2022-06-15
资源大小:84k
文件大小:30k
- // ColourPopup.cpp : implementation file
- //
- // Written by Chris Maunder (chrismaunder@codeguru.com)
- // Extended by Alexander Bischofberger (bischofb@informatik.tu-muenchen.de)
- // Copyright (c) 1998.
- //
- // Updated 30 May 1998 to allow any number of colours, and to
- // make the appearance closer to Office 97.
- // Also added "Default" text area. (CJM)
- //
- // 13 June 1998 Fixed change of focus bug (CJM)
- // 30 June 1998 Fixed bug caused by focus bug fix (D'oh!!)
- // Solution suggested by Paul Wilkerson.
- //
- // ColourPopup is a helper class for the colour picker control
- // CColourPicker. Check out the header file or the accompanying
- // HTML doc file for details.
- //
- // This code may be used in compiled form in any way you desire. This
- // file may be redistributed unmodified by any means PROVIDING it is
- // not sold for profit without the authors written consent, and
- // providing that this notice and the authors name is included.
- //
- // This file is provided "as is" with no expressed or implied warranty.
- // The author accepts no liability if it causes any damage to you or your
- // computer whatsoever. It's free, so don't hassle me about it.
- //
- // Expect bugs.
- //
- // Please use and enjoy. Please let me know of any bugs/mods/improvements
- // that you have found/implemented and I will fix/incorporate them into this
- // file.
- #include "stdafx.h"
- #include <math.h>
- #include "ColourPicker.h"
- #include "ColourPopup.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define DEFAULT_BOX_VALUE -3
- #define CUSTOM_BOX_VALUE -2
- #define INVALID_COLOUR -1
- #define MAX_COLOURS 100
- ColourTableEntry CColourPopup::m_crColours[] =
- {
- { RGB(0x00, 0x00, 0x00), _T("Black") },
- { RGB(0xA5, 0x2A, 0x00), _T("Brown") },
- { RGB(0x00, 0x40, 0x40), _T("Dark Olive Green") },
- { RGB(0x00, 0x55, 0x00), _T("Dark Green") },
- { RGB(0x00, 0x00, 0x5E), _T("Dark Teal") },
- { RGB(0x00, 0x00, 0x8B), _T("Dark blue") },
- { RGB(0x4B, 0x00, 0x82), _T("Indigo") },
- { RGB(0x28, 0x28, 0x28), _T("Dark grey") },
- { RGB(0x8B, 0x00, 0x00), _T("Dark red") },
- { RGB(0xFF, 0x68, 0x20), _T("Orange") },
- { RGB(0x8B, 0x8B, 0x00), _T("Dark yellow") },
- { RGB(0x00, 0x93, 0x00), _T("Green") },
- { RGB(0x38, 0x8E, 0x8E), _T("Teal") },
- { RGB(0x00, 0x00, 0xFF), _T("Blue") },
- { RGB(0x7B, 0x7B, 0xC0), _T("Blue-grey") },
- { RGB(0x66, 0x66, 0x66), _T("Grey - 40") },
- { RGB(0xFF, 0x00, 0x00), _T("Red") },
- { RGB(0xFF, 0xAD, 0x5B), _T("Light orange") },
- { RGB(0x32, 0xCD, 0x32), _T("Lime") },
- { RGB(0x3C, 0xB3, 0x71), _T("Sea green") },
- { RGB(0x7F, 0xFF, 0xD4), _T("Aqua") },
- { RGB(0x7D, 0x9E, 0xC0), _T("Light blue") },
- { RGB(0x80, 0x00, 0x80), _T("Violet") },
- { RGB(0x7F, 0x7F, 0x7F), _T("Grey - 50") },
- { RGB(0xFF, 0xC0, 0xCB), _T("Pink") },
- { RGB(0xFF, 0xD7, 0x00), _T("Gold") },
- { RGB(0xFF, 0xFF, 0x00), _T("Yellow") },
- { RGB(0x00, 0xFF, 0x00), _T("Bright green") },
- { RGB(0x40, 0xE0, 0xD0), _T("Turquoise") },
- { RGB(0xC0, 0xFF, 0xFF), _T("Skyblue") },
- { RGB(0x48, 0x00, 0x48), _T("Plum") },
- { RGB(0xC0, 0xC0, 0xC0), _T("Light grey") },
- { RGB(0xFF, 0xE4, 0xE1), _T("Rose") },
- { RGB(0xD2, 0xB4, 0x8C), _T("Tan") },
- { RGB(0xFF, 0xFF, 0xE0), _T("Light yellow") },
- { RGB(0x98, 0xFB, 0x98), _T("Pale green ") },
- { RGB(0xAF, 0xEE, 0xEE), _T("Pale turquoise") },
- { RGB(0x68, 0x83, 0x8B), _T("Pale blue") },
- { RGB(0xE6, 0xE6, 0xFA), _T("Lavender") },
- { RGB(0xFF, 0xFF, 0xFF), _T("White") }
- };
- /////////////////////////////////////////////////////////////////////////////
- // CColourPopup
- CColourPopup::CColourPopup()
- {
- Initialise();
- }
- CColourPopup::CColourPopup(CPoint p, COLORREF crColour, CWnd* pParentWnd,
- LPCTSTR szDefaultText /* = NULL */,
- LPCTSTR szCustomText /* = NULL */)
- {
- Initialise();
- m_crColour = m_crInitialColour = crColour;
- m_pParent = pParentWnd;
- m_strDefaultText = (szDefaultText)? szDefaultText : _T("");
- m_strCustomText = (szCustomText)? szCustomText : _T("");
- CColourPopup::Create(p, crColour, pParentWnd, szDefaultText, szCustomText);
- }
- void CColourPopup::Initialise()
- {
- m_nNumColours = sizeof(m_crColours)/sizeof(ColourTableEntry);
- ASSERT(m_nNumColours <= MAX_COLOURS);
- if (m_nNumColours > MAX_COLOURS)
- m_nNumColours = MAX_COLOURS;
- m_nNumColumns = 0;
- m_nNumRows = 0;
- m_nBoxSize = 18;
- m_nMargin = ::GetSystemMetrics(SM_CXEDGE);
- m_nCurrentSel = INVALID_COLOUR;
- m_nChosenColourSel = INVALID_COLOUR;
- m_pParent = NULL;
- m_crColour = m_crInitialColour = RGB(0,0,0);
- m_bChildWindowVisible = FALSE;
- // Idiot check: Make sure the colour square is at least 5 x 5;
- if (m_nBoxSize - 2*m_nMargin - 2 < 5) m_nBoxSize = 5 + 2*m_nMargin + 2;
- // Create the font
- NONCLIENTMETRICS ncm;
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
- m_Font.CreateFontIndirect(&(ncm.lfMessageFont));
- // Create the palette
- struct {
- LOGPALETTE LogPalette;
- PALETTEENTRY PalEntry[MAX_COLOURS];
- } pal;
- LOGPALETTE* pLogPalette = (LOGPALETTE*) &pal;
- pLogPalette->palVersion = 0x300;
- pLogPalette->palNumEntries = (WORD) m_nNumColours;
- for (int i = 0; i < m_nNumColours; i++)
- {
- pLogPalette->palPalEntry[i].peRed = GetRValue(m_crColours[i].crColour);
- pLogPalette->palPalEntry[i].peGreen = GetGValue(m_crColours[i].crColour);
- pLogPalette->palPalEntry[i].peBlue = GetBValue(m_crColours[i].crColour);
- pLogPalette->palPalEntry[i].peFlags = 0;
- }
- m_Palette.CreatePalette(pLogPalette);
- }
- CColourPopup::~CColourPopup()
- {
- m_Font.DeleteObject();
- m_Palette.DeleteObject();
- }
- BOOL CColourPopup::Create(CPoint p, COLORREF crColour, CWnd* pParentWnd,
- LPCTSTR szDefaultText /* = NULL */,
- LPCTSTR szCustomText /* = NULL */)
- {
- ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
- ASSERT(pParentWnd->IsKindOf(RUNTIME_CLASS(CColourPicker)));
- m_pParent = pParentWnd;
- m_crColour = m_crInitialColour = crColour;
- // Get the class name and create the window
- CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,
- 0,
- (HBRUSH) (COLOR_BTNFACE+1),
- 0);
- if (!CWnd::CreateEx(0, szClassName, _T(""), WS_VISIBLE|WS_POPUP,
- p.x, p.y, 100, 100, // size updated soon
- pParentWnd->GetSafeHwnd(), 0, NULL))
- return FALSE;
- // Store the Custom text
- if (szCustomText != NULL)
- m_strCustomText = szCustomText;
- // Store the Default Area text
- if (szDefaultText != NULL)
- m_strDefaultText = szDefaultText;
-
- // Set the window size
- SetWindowSize();
- // Create the tooltips
- CreateToolTips();
- // Find which cell (if any) corresponds to the initial colour
- FindCellFromColour(crColour);
- // Capture all mouse events for the life of this window
- SetCapture();
- return TRUE;
- }
- BEGIN_MESSAGE_MAP(CColourPopup, CWnd)
- //{{AFX_MSG_MAP(CColourPopup)
- ON_WM_NCDESTROY()
- ON_WM_LBUTTONUP()
- ON_WM_PAINT()
- ON_WM_MOUSEMOVE()
- ON_WM_KEYDOWN()
- ON_WM_QUERYNEWPALETTE()
- ON_WM_PALETTECHANGED()
- ON_WM_KILLFOCUS()
- ON_WM_ACTIVATEAPP()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CColourPopup message handlers
- // For tooltips
- BOOL CColourPopup::PreTranslateMessage(MSG* pMsg)
- {
- m_ToolTip.RelayEvent(pMsg);
- // Fix (Adrian Roman): Sometimes if the picker loses focus it is never destroyed
- if (GetCapture()->GetSafeHwnd() != m_hWnd)
- SetCapture();
- return CWnd::PreTranslateMessage(pMsg);
- }
- // If an arrow key is pressed, then move the selection
- void CColourPopup::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- int row = GetRow(m_nCurrentSel),
- col = GetColumn(m_nCurrentSel);
- if (nChar == VK_DOWN)
- {
- if (row == DEFAULT_BOX_VALUE)
- row = col = 0;
- else if (row == CUSTOM_BOX_VALUE)
- {
- if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else
- row = col = 0;
- }
- else
- {
- row++;
- if (GetIndex(row,col) < 0)
- {
- if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else
- row = col = 0;
- }
- }
- ChangeSelection(GetIndex(row, col));
- }
- if (nChar == VK_UP)
- {
- if (row == DEFAULT_BOX_VALUE)
- {
- if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- }
- else if (row == CUSTOM_BOX_VALUE)
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- else if (row > 0) row--;
- else /* row == 0 */
- {
- if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- }
- ChangeSelection(GetIndex(row, col));
- }
- if (nChar == VK_RIGHT)
- {
- if (row == DEFAULT_BOX_VALUE)
- row = col = 0;
- else if (row == CUSTOM_BOX_VALUE)
- {
- if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else
- row = col = 0;
- }
- else if (col < m_nNumColumns-1)
- col++;
- else
- {
- col = 0; row++;
- }
- if (GetIndex(row,col) == INVALID_COLOUR)
- {
- if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else
- row = col = 0;
- }
- ChangeSelection(GetIndex(row, col));
- }
- if (nChar == VK_LEFT)
- {
- if (row == DEFAULT_BOX_VALUE)
- {
- if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- }
- else if (row == CUSTOM_BOX_VALUE)
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- else if (col > 0) col--;
- else /* col == 0 */
- {
- if (row > 0) { row--; col = m_nNumColumns-1; }
- else
- {
- if (m_strDefaultText.GetLength())
- row = col = DEFAULT_BOX_VALUE;
- else if (m_strCustomText.GetLength())
- row = col = CUSTOM_BOX_VALUE;
- else
- {
- row = GetRow(m_nNumColours-1);
- col = GetColumn(m_nNumColours-1);
- }
- }
- }
- ChangeSelection(GetIndex(row, col));
- }
- if (nChar == VK_ESCAPE)
- {
- m_crColour = m_crInitialColour;
- EndSelection(CPN_SELENDCANCEL);
- return;
- }
- if (nChar == VK_RETURN || nChar == VK_SPACE)
- {
- EndSelection(CPN_SELENDOK);
- return;
- }
- CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- // auto-deletion
- void CColourPopup::OnNcDestroy()
- {
- CWnd::OnNcDestroy();
- delete this;
- }
- void CColourPopup::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- // Draw the Default Area text
- if (m_strDefaultText.GetLength())
- DrawCell(&dc, DEFAULT_BOX_VALUE);
-
- // Draw colour cells
- for (int i = 0; i < m_nNumColours; i++)
- DrawCell(&dc, i);
-
- // Draw custom text
- if (m_strCustomText.GetLength())
- DrawCell(&dc, CUSTOM_BOX_VALUE);
- // Draw raised window edge (ex-window style WS_EX_WINDOWEDGE is sposed to do this,
- // but for some reason isn't
- CRect rect;
- GetClientRect(rect);
- dc.DrawEdge(rect, EDGE_RAISED, BF_RECT);
- }
- void CColourPopup::OnMouseMove(UINT nFlags, CPoint point)
- {
- int nNewSelection = INVALID_COLOUR;
- // Translate points to be relative raised window edge
- point.x -= m_nMargin;
- point.y -= m_nMargin;
- // First check we aren't in text box
- if (m_strCustomText.GetLength() && m_CustomTextRect.PtInRect(point))
- nNewSelection = CUSTOM_BOX_VALUE;
- else if (m_strDefaultText.GetLength() && m_DefaultTextRect.PtInRect(point))
- nNewSelection = DEFAULT_BOX_VALUE;
- else
- {
- // Take into account text box
- if (m_strDefaultText.GetLength())
- point.y -= m_DefaultTextRect.Height();
- // Get the row and column
- nNewSelection = GetIndex(point.y / m_nBoxSize, point.x / m_nBoxSize);
- // In range? If not, default and exit
- if (nNewSelection < 0 || nNewSelection >= m_nNumColours)
- {
- CWnd::OnMouseMove(nFlags, point);
- return;
- }
- }
- // OK - we have the row and column of the current selection (may be CUSTOM_BOX_VALUE)
- // Has the row/col selection changed? If yes, then redraw old and new cells.
- if (nNewSelection != m_nCurrentSel)
- ChangeSelection(nNewSelection);
- CWnd::OnMouseMove(nFlags, point);
- }
- // End selection on LButtonUp
- void CColourPopup::OnLButtonUp(UINT nFlags, CPoint point)
- {
- CWnd::OnLButtonUp(nFlags, point);
- DWORD pos = GetMessagePos();
- point = CPoint(LOWORD(pos), HIWORD(pos));
- if (m_WindowRect.PtInRect(point))
- EndSelection(CPN_SELENDOK);
- else
- EndSelection(CPN_SELENDCANCEL);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CColourPopup implementation
- int CColourPopup::GetIndex(int row, int col) const
- {
- if ((row == CUSTOM_BOX_VALUE || col == CUSTOM_BOX_VALUE) && m_strCustomText.GetLength())
- return CUSTOM_BOX_VALUE;
- else if ((row == DEFAULT_BOX_VALUE || col == DEFAULT_BOX_VALUE) && m_strDefaultText.GetLength())
- return DEFAULT_BOX_VALUE;
- else if (row < 0 || col < 0 || row >= m_nNumRows || col >= m_nNumColumns)
- return INVALID_COLOUR;
- else
- {
- if (row*m_nNumColumns + col >= m_nNumColours)
- return INVALID_COLOUR;
- else
- return row*m_nNumColumns + col;
- }
- }
- int CColourPopup::GetRow(int nIndex) const
- {
- if (nIndex == CUSTOM_BOX_VALUE && m_strCustomText.GetLength())
- return CUSTOM_BOX_VALUE;
- else if (nIndex == DEFAULT_BOX_VALUE && m_strDefaultText.GetLength())
- return DEFAULT_BOX_VALUE;
- else if (nIndex < 0 || nIndex >= m_nNumColours)
- return INVALID_COLOUR;
- else
- return nIndex / m_nNumColumns;
- }
- int CColourPopup::GetColumn(int nIndex) const
- {
- if (nIndex == CUSTOM_BOX_VALUE && m_strCustomText.GetLength())
- return CUSTOM_BOX_VALUE;
- else if (nIndex == DEFAULT_BOX_VALUE && m_strDefaultText.GetLength())
- return DEFAULT_BOX_VALUE;
- else if (nIndex < 0 || nIndex >= m_nNumColours)
- return INVALID_COLOUR;
- else
- return nIndex % m_nNumColumns;
- }
- void CColourPopup::FindCellFromColour(COLORREF crColour)
- {
- if (crColour == CLR_DEFAULT && m_strDefaultText.GetLength())
- {
- m_nChosenColourSel = DEFAULT_BOX_VALUE;
- return;
- }
- for (int i = 0; i < m_nNumColours; i++)
- {
- if (GetColour(i) == crColour)
- {
- m_nChosenColourSel = i;
- return;
- }
- }
- if (m_strCustomText.GetLength())
- m_nChosenColourSel = CUSTOM_BOX_VALUE;
- else
- m_nChosenColourSel = INVALID_COLOUR;
- }
- // Gets the dimensions of the colour cell given by (row,col)
- BOOL CColourPopup::GetCellRect(int nIndex, const LPRECT& rect)
- {
- if (nIndex == CUSTOM_BOX_VALUE)
- {
- ::SetRect(rect,
- m_CustomTextRect.left, m_CustomTextRect.top,
- m_CustomTextRect.right, m_CustomTextRect.bottom);
- return TRUE;
- }
- else if (nIndex == DEFAULT_BOX_VALUE)
- {
- ::SetRect(rect,
- m_DefaultTextRect.left, m_DefaultTextRect.top,
- m_DefaultTextRect.right, m_DefaultTextRect.bottom);
- return TRUE;
- }
- if (nIndex < 0 || nIndex >= m_nNumColours)
- return FALSE;
- rect->left = GetColumn(nIndex) * m_nBoxSize + m_nMargin;
- rect->top = GetRow(nIndex) * m_nBoxSize + m_nMargin;
- // Move everything down if we are displaying a default text area
- if (m_strDefaultText.GetLength())
- rect->top += (m_nMargin + m_DefaultTextRect.Height());
- rect->right = rect->left + m_nBoxSize;
- rect->bottom = rect->top + m_nBoxSize;
- return TRUE;
- }
- // Works out an appropriate size and position of this window
- void CColourPopup::SetWindowSize()
- {
- CSize TextSize;
- // If we are showing a custom or default text area, get the font and text size.
- if (m_strCustomText.GetLength() || m_strDefaultText.GetLength())
- {
- CClientDC dc(this);
- CFont* pOldFont = (CFont*) dc.SelectObject(&m_Font);
- // Get the size of the custom text (if there IS custom text)
- TextSize = CSize(0,0);
- if (m_strCustomText.GetLength())
- TextSize = dc.GetTextExtent(m_strCustomText);
- // Get the size of the default text (if there IS default text)
- if (m_strDefaultText.GetLength())
- {
- CSize DefaultSize = dc.GetTextExtent(m_strDefaultText);
- if (DefaultSize.cx > TextSize.cx) TextSize.cx = DefaultSize.cx;
- if (DefaultSize.cy > TextSize.cy) TextSize.cy = DefaultSize.cy;
- }
- dc.SelectObject(pOldFont);
- TextSize += CSize(2*m_nMargin,2*m_nMargin);
- // Add even more space to draw the horizontal line
- TextSize.cy += 2*m_nMargin + 2;
- }
- // Get the number of columns and rows
- //m_nNumColumns = (int) sqrt((double)m_nNumColours); // for a square window (yuk)
- m_nNumColumns = 8;
- m_nNumRows = m_nNumColours / m_nNumColumns;
- if (m_nNumColours % m_nNumColumns) m_nNumRows++;
- // Get the current window position, and set the new size
- CRect rect;
- GetWindowRect(rect);
- m_WindowRect.SetRect(rect.left, rect.top,
- rect.left + m_nNumColumns*m_nBoxSize + 2*m_nMargin,
- rect.top + m_nNumRows*m_nBoxSize + 2*m_nMargin);
- // if custom text, then expand window if necessary, and set text width as
- // window width
- if (m_strDefaultText.GetLength())
- {
- if (TextSize.cx > m_WindowRect.Width())
- m_WindowRect.right = m_WindowRect.left + TextSize.cx;
- TextSize.cx = m_WindowRect.Width()-2*m_nMargin;
- // Work out the text area
- m_DefaultTextRect.SetRect(m_nMargin, m_nMargin,
- m_nMargin+TextSize.cx, 2*m_nMargin+TextSize.cy);
- m_WindowRect.bottom += m_DefaultTextRect.Height() + 2*m_nMargin;
- }
- // if custom text, then expand window if necessary, and set text width as
- // window width
- if (m_strCustomText.GetLength())
- {
- if (TextSize.cx > m_WindowRect.Width())
- m_WindowRect.right = m_WindowRect.left + TextSize.cx;
- TextSize.cx = m_WindowRect.Width()-2*m_nMargin;
- // Work out the text area
- m_CustomTextRect.SetRect(m_nMargin, m_WindowRect.Height(),
- m_nMargin+TextSize.cx,
- m_WindowRect.Height()+m_nMargin+TextSize.cy);
- m_WindowRect.bottom += m_CustomTextRect.Height() + 2*m_nMargin;
- }
- // Need to check it'll fit on screen: Too far right?
- CSize ScreenSize(::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
- if (m_WindowRect.right > ScreenSize.cx)
- m_WindowRect.OffsetRect(-(m_WindowRect.right - ScreenSize.cx), 0);
- // Too far left?
- if (m_WindowRect.left < 0)
- m_WindowRect.OffsetRect( -m_WindowRect.left, 0);
- // Bottom falling out of screen?
- if (m_WindowRect.bottom > ScreenSize.cy)
- {
- CRect ParentRect;
- m_pParent->GetWindowRect(ParentRect);
- m_WindowRect.OffsetRect(0, -(ParentRect.Height() + m_WindowRect.Height()));
- }
- // Set the window size and position
- MoveWindow(m_WindowRect, TRUE);
- }
- void CColourPopup::CreateToolTips()
- {
- // Create the tool tip
- if (!m_ToolTip.Create(this)) return;
- // Add a tool for each cell
- for (int i = 0; i < m_nNumColours; i++)
- {
- CRect rect;
- if (!GetCellRect(i, rect)) continue;
- m_ToolTip.AddTool(this, GetColourName(i), rect, 1);
- }
- }
- void CColourPopup::ChangeSelection(int nIndex)
- {
- CClientDC dc(this); // device context for drawing
- if (nIndex > m_nNumColours)
- nIndex = CUSTOM_BOX_VALUE;
- if ((m_nCurrentSel >= 0 && m_nCurrentSel < m_nNumColours) ||
- m_nCurrentSel == CUSTOM_BOX_VALUE || m_nCurrentSel == DEFAULT_BOX_VALUE)
- {
- // Set Current selection as invalid and redraw old selection (this way
- // the old selection will be drawn unselected)
- int OldSel = m_nCurrentSel;
- m_nCurrentSel = INVALID_COLOUR;
- DrawCell(&dc, OldSel);
- }
- // Set the current selection as row/col and draw (it will be drawn selected)
- m_nCurrentSel = nIndex;
- DrawCell(&dc, m_nCurrentSel);
- // Store the current colour
- if (m_nCurrentSel == CUSTOM_BOX_VALUE)
- m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) m_crInitialColour, 0);
- else if (m_nCurrentSel == DEFAULT_BOX_VALUE)
- {
- m_crColour = CLR_DEFAULT;
- m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) CLR_DEFAULT, 0);
- }
- else
- {
- m_crColour = GetColour(m_nCurrentSel);
- m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) m_crColour, 0);
- }
- }
- void CColourPopup::EndSelection(int nMessage)
- {
- ReleaseCapture();
- // If custom text selected, perform a custom colour selection
- if (nMessage != CPN_SELENDCANCEL && m_nCurrentSel == CUSTOM_BOX_VALUE)
- {
- m_bChildWindowVisible = TRUE;
- CColorDialog dlg(m_crInitialColour, CC_FULLOPEN | CC_ANYCOLOR, this);
- if (dlg.DoModal() == IDOK)
- m_crColour = dlg.GetColor();
- else
- nMessage = CPN_SELENDCANCEL;
- m_bChildWindowVisible = FALSE;
- }
- if (nMessage == CPN_SELENDCANCEL)
- m_crColour = m_crInitialColour;
- m_pParent->SendMessage(nMessage, (WPARAM) m_crColour, 0);
-
- // Kill focus bug fixed by Martin Wawrusch
- if (!m_bChildWindowVisible)
- DestroyWindow();
- }
- void CColourPopup::DrawCell(CDC* pDC, int nIndex)
- {
- // For the Custom Text area
- if (m_strCustomText.GetLength() && nIndex == CUSTOM_BOX_VALUE)
- {
- // The extent of the actual text button
- CRect TextButtonRect = m_CustomTextRect;
- TextButtonRect.top += 2*m_nMargin;
- // Fill background
- pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));
- // Draw horizontal line
- pDC->FillSolidRect(m_CustomTextRect.left+2*m_nMargin, m_CustomTextRect.top,
- m_CustomTextRect.Width()-4*m_nMargin, 1, ::GetSysColor(COLOR_3DSHADOW));
- pDC->FillSolidRect(m_CustomTextRect.left+2*m_nMargin, m_CustomTextRect.top+1,
- m_CustomTextRect.Width()-4*m_nMargin, 1, ::GetSysColor(COLOR_3DHILIGHT));
- TextButtonRect.DeflateRect(1,1);
- // fill background
- if (m_nChosenColourSel == nIndex && m_nCurrentSel != nIndex)
- pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DLIGHT));
- else
- pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));
- // Draw button
- if (m_nCurrentSel == nIndex)
- pDC->DrawEdge(TextButtonRect, BDR_RAISEDINNER, BF_RECT);
- else if (m_nChosenColourSel == nIndex)
- pDC->DrawEdge(TextButtonRect, BDR_SUNKENOUTER, BF_RECT);
- // Draw custom text
- CFont *pOldFont = (CFont*) pDC->SelectObject(&m_Font);
- pDC->SetBkMode(TRANSPARENT);
- pDC->DrawText(m_strCustomText, TextButtonRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- pDC->SelectObject(pOldFont);
- return;
- }
- // For the Default Text area
- if (m_strDefaultText.GetLength() && nIndex == DEFAULT_BOX_VALUE)
- {
- // Fill background
- pDC->FillSolidRect(m_DefaultTextRect, ::GetSysColor(COLOR_3DFACE));
- // The extent of the actual text button
- CRect TextButtonRect = m_DefaultTextRect;
- TextButtonRect.DeflateRect(1,1);
- // fill background
- if (m_nChosenColourSel == nIndex && m_nCurrentSel != nIndex)
- pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DLIGHT));
- else
- pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));
- // Draw thin line around text
- CRect LineRect = TextButtonRect;
- LineRect.DeflateRect(2*m_nMargin,2*m_nMargin);
- CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
- CPen* pOldPen = pDC->SelectObject(&pen);
- pDC->SelectStockObject(NULL_BRUSH);
- pDC->Rectangle(LineRect);
- pDC->SelectObject(pOldPen);
- // Draw button
- if (m_nCurrentSel == nIndex)
- pDC->DrawEdge(TextButtonRect, BDR_RAISEDINNER, BF_RECT);
- else if (m_nChosenColourSel == nIndex)
- pDC->DrawEdge(TextButtonRect, BDR_SUNKENOUTER, BF_RECT);
- // Draw custom text
- CFont *pOldFont = (CFont*) pDC->SelectObject(&m_Font);
- pDC->SetBkMode(TRANSPARENT);
- pDC->DrawText(m_strDefaultText, TextButtonRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- pDC->SelectObject(pOldFont);
- return;
- }
- CRect rect;
- if (!GetCellRect(nIndex, rect)) return;
- // Select and realize the palette
- CPalette* pOldPalette = NULL;
- if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
- {
- pOldPalette = pDC->SelectPalette(&m_Palette, FALSE);
- pDC->RealizePalette();
- }
- // fill background
- if (m_nChosenColourSel == nIndex && m_nCurrentSel != nIndex)
- pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DHILIGHT));
- else
- pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
- // Draw button
- if (m_nCurrentSel == nIndex)
- pDC->DrawEdge(rect, BDR_RAISEDINNER, BF_RECT);
- else if (m_nChosenColourSel == nIndex)
- pDC->DrawEdge(rect, BDR_SUNKENOUTER, BF_RECT);
- CBrush brush(PALETTERGB(GetRValue(GetColour(nIndex)),
- GetGValue(GetColour(nIndex)),
- GetBValue(GetColour(nIndex)) ));
- CPen pen;
- pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
- CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
- CPen* pOldPen = (CPen*) pDC->SelectObject(&pen);
- // Draw the cell colour
- rect.DeflateRect(m_nMargin+1, m_nMargin+1);
- pDC->Rectangle(rect);
- // restore DC and cleanup
- pDC->SelectObject(pOldBrush);
- pDC->SelectObject(pOldPen);
- brush.DeleteObject();
- pen.DeleteObject();
- if (pOldPalette && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
- pDC->SelectPalette(pOldPalette, FALSE);
- }
- BOOL CColourPopup::OnQueryNewPalette()
- {
- Invalidate();
- return CWnd::OnQueryNewPalette();
- }
- void CColourPopup::OnPaletteChanged(CWnd* pFocusWnd)
- {
- CWnd::OnPaletteChanged(pFocusWnd);
- if (pFocusWnd->GetSafeHwnd() != GetSafeHwnd())
- Invalidate();
- }
- void CColourPopup::OnKillFocus(CWnd* pNewWnd)
- {
- CWnd::OnKillFocus(pNewWnd);
- ReleaseCapture();
- //DestroyWindow(); - causes crash when Custom colour dialog appears.
- }
- // KillFocus problem fix suggested by Paul Wilkerson.
- void CColourPopup::OnActivateApp(BOOL bActive, HTASK hTask)
- {
- CWnd::OnActivateApp(bActive, hTask);
- // If Deactivating App, cancel this selection
- if (!bActive)
- EndSelection(CPN_SELENDCANCEL);
- }