| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913 |
- // ColourPopup.cpp : implementation file
- //
- // Written by Chris Maunder ([email protected])
- // Extended by Alexander Bischofberger ([email protected])
- // 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, DWORD hTask)
- {
- CWnd::OnActivateApp(bActive, hTask);
- // If Deactivating App, cancel this selection
- if (!bActive)
- EndSelection(CPN_SELENDCANCEL);
- }
|