/** * @file XTPColorPopup.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #include "Common/XTPTypeId.h" #include "Common/XTPFramework.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPSynchro.h" #include "Common/XTPApplication.h" #include "Common/XTPSingleton.h" #include "Common/XTPGdiObjects.h" #include "Common/XTPDrawHelpers.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPHookManager.h" #include "Controls/Util/XTPControlTheme.h" #include "Controls/Defines.h" #include "Controls/Popup/XTPColorSelectorCtrl.h" #include "Controls/Popup/XTPColorPopup.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CXTPColorPopup CXTPColorPopup::CXTPColorPopup(BOOL bAutoDelete /*= FALSE*/, LPARAM callerParam /*= 0*/) : m_callerParam(callerParam) { m_bAutoDelete = bAutoDelete; m_bDisplayShadow = TRUE; m_bEndSelection = FALSE; m_pShadowManager = new CXTPShadowManager(); } CXTPColorPopup::~CXTPColorPopup() { CMDTARGET_RELEASE(m_pShadowManager); } #include "Common/Base/Diagnostic/XTPBeginAfxMap.h" BEGIN_MESSAGE_MAP(CXTPColorPopup, CXTPColorSelectorCtrl) //{{AFX_MSG_MAP(CXTPColorPopup) ON_WM_ACTIVATE() ON_WM_DESTROY() ON_WM_CREATE() ON_WM_KILLFOCUS() ON_WM_LBUTTONDOWN() ON_WM_NCPAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() #include "Common/Base/Diagnostic/XTPEndAfxMap.h" ///////////////////////////////////////////////////////////////////////////// // CXTPColorPopup message handlers BOOL CXTPColorPopup::Create(CRect& rect, CWnd* pParentWnd, DWORD dwPopup, COLORREF clrColor, COLORREF clrDefault /*= CLR_DEFAULT*/) { if (m_pTheme->GetThemeStyle() != xtpControlThemeDefault) { SetBorders(XTP_DPI_X(4), XTP_DPI_Y(4), XTP_DPI_X(6), XTP_DPI_Y(6)); } else { SetBorders(XTP_DPI_X(4), XTP_DPI_Y(4), XTP_DPI_X(10), XTP_DPI_Y(10)); } m_rcExclude = rect; if (!CXTPColorSelectorCtrl::Create(rect, pParentWnd, dwPopup | WS_POPUP, clrColor, clrDefault)) return FALSE; SetFont(pParentWnd->GetFont()); return TRUE; } void CXTPColorPopup::PostNcDestroy() { CXTPMouseMonitor::SetupHook(NULL); if (m_bAutoDelete) { delete this; } } void CXTPColorPopup::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CWnd::OnActivate(nState, pWndOther, bMinimized); // If we lose activation (other than to the color dialog) post // a close message... if (nState == WA_INACTIVE && !IsColorDlgVisible()) { PostMessage(WM_CLOSE); } } void CXTPColorPopup::OnDestroy() { CWnd::OnDestroy(); // Inform the parent that we are closing up. m_pParentWnd->SendMessage(CPN_XTP_CLOSEUP, (WPARAM)m_clrColor, m_callerParam); } int CXTPColorPopup::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CXTPColorSelectorCtrl::OnCreate(lpCreateStruct) == -1) return -1; BOOL bThinBorder = GetTheme()->m_bThinBorder; if (bThinBorder) { ModifyStyle(WS_DLGFRAME | WS_THICKFRAME | WS_BORDER, 0, 0); ModifyStyleEx(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME, WS_EX_STATICEDGE, SWP_FRAMECHANGED); } else { ModifyStyle(0, WS_DLGFRAME, SWP_FRAMECHANGED); } CRect rcWork = XTPMultiMonitor()->GetWorkArea(m_rcWnd); CSize size = m_rcWnd.Size(); // move right if (m_rcWnd.left < rcWork.left) { m_rcWnd.left = rcWork.left; m_rcWnd.right = m_rcWnd.left + size.cx; } // move left else if (m_rcWnd.right > rcWork.right) { m_rcWnd.right = rcWork.right; m_rcWnd.left = m_rcWnd.right - size.cx; } // move up if (m_rcWnd.bottom > rcWork.bottom) { if (m_rcExclude.IsRectEmpty()) m_rcWnd.bottom = rcWork.top; else m_rcWnd.bottom = m_rcExclude.top; m_rcWnd.top = m_rcWnd.bottom - size.cy; } HWND hWnd = m_hWnd; SetFocus(); if (!IsWindow(hWnd)) return -1; SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0); ModifyStyle(WS_CHILD, WS_POPUP); SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)m_pParentWnd->m_hWnd); CWnd* pTopParent = m_pParentWnd->GetParentOwner(); SetWindowPos(pTopParent->GetExStyle() & WS_EX_TOPMOST ? &CWnd::wndTopMost : &CWnd::wndTop, m_rcWnd.left, m_rcWnd.top, m_rcWnd.Width(), m_rcWnd.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (bThinBorder && m_bDisplayShadow) { m_pShadowManager->SetShadowOptions(xtpShadowOfficeAlpha); m_pShadowManager->SetShadow(this); } CXTPMouseMonitor::SetupHook(this); m_bEndSelection = FALSE; m_pParentWnd->SendMessage(CPN_XTP_DROPDOWN, (WPARAM)m_clrColor, m_callerParam); return 0; } // Adds a window to send color picker notifications to. void CXTPColorPopup::AddListener(HWND hwndListener) { m_listeners.Add(hwndListener); } void CXTPColorPopup::EndSelection(int nCurSel) { m_bEndSelection = TRUE; CXTPMouseMonitor::SetupHook(NULL); OnEndSelection(nCurSel, m_callerParam); DestroyWindow(); } void CXTPColorPopup::OnKillFocus(CWnd* pNewWnd) { CWnd::OnKillFocus(pNewWnd); if (!m_pColorDlg && !m_bEndSelection) { EndSelection(-1); } } void CXTPColorPopup::OnLButtonDown(UINT nFlags, CPoint point) { CRect rc; GetClientRect(&rc); if (!rc.PtInRect(point) && !IsColorDlgVisible()) { EndSelection(-1); return; } CXTPColorSelectorCtrl::OnLButtonDown(nFlags, point); } void CXTPColorPopup::OnNcPaint() { if (GetTheme()->m_bThinBorder) { CWindowDC dc(this); CXTPWindowRect rc(this); rc.OffsetRect(-rc.TopLeft()); dc.Draw3dRect(0, 0, rc.Width(), rc.Height(), GetTheme()->m_crPopupBorder, GetTheme()->m_crPopupBorder); } else { Default(); } }