1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "CustomColorDialog.h"
8 static std::vector
<std::unique_ptr
<CScreenWnd
>> g_screenWnds
;
9 static BOOL CALLBACK
CreateScreenWndCB(HMONITOR monitor
, HDC dc
, LPRECT rect
, LPARAM data
);
11 /////////////////////////////////////////////////////////////////////////////
14 class CScreenWnd
: public CWnd
22 virtual BOOL
Create(CMFCColorDialog
* pColorDlg
, CRect rect
);
26 virtual ~CScreenWnd();
28 // Generated message map functions
30 //{{AFX_MSG(CScreenWnd)
31 afx_msg
void OnMouseMove(UINT nFlags
, CPoint point
);
32 afx_msg
void OnLButtonDown(UINT nFlags
, CPoint point
);
33 afx_msg BOOL
OnEraseBkgnd(CDC
* pDC
);
37 CMFCColorDialog
* m_pColorDlg
;
40 /////////////////////////////////////////////////////////////////////////////
43 IMPLEMENT_DYNAMIC(CCustomColorDialog
, CMFCColorDialog
)
45 //////////////////////////////////////////////////////////////////////////
46 CCustomColorDialog::CCustomColorDialog(COLORREF clrInit
, DWORD dwFlags
, CWnd
* pParentWnd
) :
47 CMFCColorDialog(clrInit
, dwFlags
, pParentWnd
), m_callback(0), m_colorPrev(0)
51 //////////////////////////////////////////////////////////////////////////
52 BEGIN_MESSAGE_MAP(CCustomColorDialog
, CMFCColorDialog
)
54 ON_MESSAGE(WM_KICKIDLE
, OnKickIdle
)
55 ON_BN_CLICKED(IDC_AFXBARRES_COLOR_SELECT
, OnColorSelect
)
58 //////////////////////////////////////////////////////////////////////////
59 BOOL
CCustomColorDialog::OnInitDialog()
61 CMFCColorDialog::OnInitDialog();
63 m_colorPrev
= m_CurrentColor
;
64 m_pPropSheet
->SetActivePage(m_pColourSheetTwo
);
66 return TRUE
; // return TRUE unless you set the focus to a control
67 // EXCEPTION: OCX Property Pages should return FALSE
70 //////////////////////////////////////////////////////////////////////////
71 void CCustomColorDialog::OnMouseMove(UINT nFlags
, CPoint point
)
73 CMFCColorDialog::OnMouseMove(nFlags
, point
);
75 if (m_colorPrev
!= m_NewColor
)
76 OnColorChange(m_NewColor
);
79 //////////////////////////////////////////////////////////////////////////
80 LRESULT
CCustomColorDialog::OnKickIdle(WPARAM
, LPARAM lCount
)
82 if (m_colorPrev
!= m_NewColor
)
83 OnColorChange(m_NewColor
);
88 //////////////////////////////////////////////////////////////////////////
89 void CCustomColorDialog::OnColorChange(COLORREF col
)
96 //////////////////////////////////////////////////////////////////////////
97 void CCustomColorDialog::OnColorSelect()
104 CWinThread
* pCurrThread
= ::AfxGetThread();
105 if (pCurrThread
== NULL
)
112 m_bPickerMode
= TRUE
;
114 ::SetCursor(m_hcurPicker
);
116 LONG_PTR thisPtr
= reinterpret_cast<LONG_PTR
>(this);
117 ::EnumDisplayMonitors(NULL
, NULL
, CreateScreenWndCB
, thisPtr
);
119 SetForegroundWindow();
124 COLORREF colorSaved
= m_NewColor
;
126 while (m_bPickerMode
)
128 while (m_bPickerMode
&& ::PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
130 if (msg
.message
== WM_KEYDOWN
)
135 m_bPickerMode
= FALSE
;
139 SetNewColor(colorSaved
);
140 m_bPickerMode
= FALSE
;
144 else if (msg
.message
== WM_RBUTTONDOWN
|| msg
.message
== WM_MBUTTONDOWN
)
146 m_bPickerMode
= FALSE
;
150 if (!pCurrThread
->PreTranslateMessage(&msg
))
152 ::TranslateMessage(&msg
);
153 ::DispatchMessage(&msg
);
156 pCurrThread
->OnIdle(0);
164 std::for_each(g_screenWnds
.begin(), g_screenWnds
.end(), [](const std::unique_ptr
<CScreenWnd
>& pScreenWnd
)
166 pScreenWnd
->DestroyWindow();
168 g_screenWnds
.clear();
170 m_bPickerMode
= FALSE
;
173 //////////////////////////////////////////////////////////////////////////
174 BOOL CALLBACK
CreateScreenWndCB(HMONITOR monitor
, HDC dc
, LPRECT rect
, LPARAM data
)
176 MONITORINFOEX monitorInfo
;
177 monitorInfo
.cbSize
= sizeof(MONITORINFOEX
);
178 ::GetMonitorInfo(monitor
, &monitorInfo
);
180 CCustomColorDialog
* self
= reinterpret_cast<CCustomColorDialog
*>(data
);
182 std::unique_ptr
<CScreenWnd
> pScreenWnd(new CScreenWnd());
183 pScreenWnd
->Create(self
, monitorInfo
.rcMonitor
);
185 g_screenWnds
.push_back(std::move(pScreenWnd
));
190 /////////////////////////////////////////////////////////////////////////////
193 CScreenWnd::CScreenWnd()
197 CScreenWnd::~CScreenWnd()
201 BEGIN_MESSAGE_MAP(CScreenWnd
, CWnd
)
202 //{{AFX_MSG_MAP(CScreenWnd)
210 /////////////////////////////////////////////////////////////////////////////
211 // CScreenWnd message handlers
213 BOOL
CScreenWnd::Create(CMFCColorDialog
* pColorDlg
, CRect rect
)
215 m_pColorDlg
= pColorDlg
;
217 string strClassName
= ::AfxRegisterWndClass(CS_SAVEBITS
, AfxGetApp()->LoadCursor(IDC_AFXBARRES_COLOR
), (HBRUSH
)(COLOR_BTNFACE
+ 1), NULL
);
219 return CWnd::CreateEx(WS_EX_TOOLWINDOW
| WS_EX_TRANSPARENT
, strClassName
, _T(""), WS_VISIBLE
| WS_POPUP
, rect
, NULL
, 0);
222 void CScreenWnd::OnMouseMove(UINT nFlags
, CPoint point
)
224 MapWindowPoints(m_pColorDlg
, &point
, 1);
225 m_pColorDlg
->SendMessage(WM_MOUSEMOVE
, nFlags
, MAKELPARAM(point
.x
, point
.y
));
227 CWnd::OnMouseMove(nFlags
, point
);
230 void CScreenWnd::OnLButtonDown(UINT nFlags
, CPoint point
)
232 MapWindowPoints(m_pColorDlg
, &point
, 1);
233 m_pColorDlg
->SendMessage(WM_LBUTTONDOWN
, nFlags
, MAKELPARAM(point
.x
, point
.y
));
236 BOOL
CScreenWnd::OnEraseBkgnd(CDC
* /*pDC*/)
241 BOOL
CCustomColorDialog::PreTranslateMessage(MSG
* pMsg
)
244 #define AFX_TCF_TEXT CF_UNICODETEXT
246 #define AFX_TCF_TEXT CF_TEXT
249 if (m_colorPrev
!= m_NewColor
)
251 OnColorChange(m_NewColor
);
254 if (pMsg
->message
== WM_KEYDOWN
)
256 UINT nChar
= (UINT
) pMsg
->wParam
;
257 BOOL bIsCtrl
= (::GetAsyncKeyState(VK_CONTROL
) & 0x8000);
259 if (bIsCtrl
&& (nChar
== _T('C') || nChar
== VK_INSERT
))
266 strText
.Format(_T("RGB(%d, %d, %d)"), GetRValue(m_NewColor
), GetGValue(m_NewColor
), GetBValue(m_NewColor
));
268 HGLOBAL hClipbuffer
= ::GlobalAlloc(GMEM_DDESHARE
, (strText
.GetLength() + 1) * sizeof(TCHAR
));
269 LPTSTR lpszBuffer
= (LPTSTR
) GlobalLock(hClipbuffer
);
271 lstrcpy(lpszBuffer
, (LPCTSTR
) strText
);
273 ::GlobalUnlock(hClipbuffer
);
274 ::SetClipboardData(AFX_TCF_TEXT
, hClipbuffer
);
281 return CMFCColorDialog::PreTranslateMessage(pMsg
);