ReactOS 0.4.15-dev-7906-g1b85a5f
cicuif.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Cicero
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Cicero UIF Library
5 * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include "precomp.h"
9#include "cicuif.h"
10
12// static members
13
31
33
36
38
40{
44
45 HIGHCONTRAST HighContrast = { sizeof(HighContrast) };
46 ::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HighContrast), &HighContrast, 0);
47 m_bHighContrast1 = !!(HighContrast.dwFlags & HCF_HIGHCONTRASTON);
50 const COLORREF black = RGB(0, 0, 0), white = RGB(255, 255, 255);
52 (rgbBtnText == black && rgbBtnFace == white) ||
53 (rgbBtnText == white && rgbBtnFace == black));
54}
55
57{
59 ::GetVersionEx(this);
61}
62
64// CUIFTheme
65
67{
68 if (!hWnd || !m_pszClassList)
69 return E_FAIL;
70
71 if (!cicGetFN(s_hUXTHEME, s_fnOpenThemeData, TEXT("uxtheme.dll"), "OpenThemeData"))
72 return E_FAIL;
74 return (m_hTheme ? S_OK : E_FAIL);
75}
76
78{
79 if (m_hTheme)
80 return S_OK;
82}
83
85{
86 if (!m_hTheme)
87 return S_OK;
88
89 if (!cicGetFN(s_hUXTHEME, s_fnCloseThemeData, TEXT("uxtheme.dll"), "CloseThemeData"))
90 return E_FAIL;
91
93 m_hTheme = NULL;
94 return hr;
95}
96
98CUIFTheme::DrawThemeBackground(HDC hDC, int iStateId, LPCRECT pRect, LPCRECT pClipRect)
99{
100 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeBackground, TEXT("uxtheme.dll"), "DrawThemeBackground"))
101 return E_FAIL;
102 return s_fnDrawThemeBackground(m_hTheme, hDC, m_iPartId, iStateId, pRect, pClipRect);
103}
104
107{
108 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeParentBackground, TEXT("uxtheme.dll"), "DrawThemeParentBackground"))
109 return E_FAIL;
111}
112
114CUIFTheme::DrawThemeText(HDC hDC, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect)
115{
116 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeText, TEXT("uxtheme.dll"), "DrawThemeText"))
117 return E_FAIL;
118 return s_fnDrawThemeText(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchText, dwTextFlags, dwTextFlags2, pRect);
119}
120
122CUIFTheme::DrawThemeIcon(HDC hDC, int iStateId, LPCRECT pRect, HIMAGELIST himl, int iImageIndex)
123{
124 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeIcon, TEXT("uxtheme.dll"), "DrawThemeIcon"))
125 return E_FAIL;
126 return s_fnDrawThemeIcon(m_hTheme, hDC, m_iPartId, iStateId, pRect, himl, iImageIndex);
127}
128
130CUIFTheme::GetThemeBackgroundExtent(HDC hDC, int iStateId, LPCRECT pContentRect, LPRECT pExtentRect)
131{
132 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundExtent, TEXT("uxtheme.dll"), "GetThemeBackgroundExtent"))
133 return E_FAIL;
134 return s_fnGetThemeBackgroundExtent(m_hTheme, hDC, m_iPartId, iStateId, pContentRect, pExtentRect);
135}
136
138CUIFTheme::GetThemeBackgroundContentRect(HDC hDC, int iStateId, LPCRECT pBoundingRect, LPRECT pContentRect)
139{
140 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeBackgroundContentRect, TEXT("uxtheme.dll"), "GetThemeBackgroundContentRect"))
141 return E_FAIL;
142 return s_fnGetThemeBackgroundContentRect(m_hTheme, hDC, m_iPartId, iStateId, pBoundingRect, pContentRect);
143}
144
146CUIFTheme::GetThemeTextExtent(HDC hDC, int iStateId, LPCWSTR pszText, int cchCharCount, DWORD dwTextFlags, LPCRECT pBoundingRect, LPRECT pExtentRect)
147{
148 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeTextExtent, TEXT("uxtheme.dll"), "GetThemeTextExtent"))
149 return E_FAIL;
150 return s_fnGetThemeTextExtent(m_hTheme, hDC, m_iPartId, iStateId, pszText, cchCharCount, dwTextFlags, pBoundingRect, pExtentRect);
151}
152
154CUIFTheme::GetThemePartSize(HDC hDC, int iStateId, LPRECT prc, THEMESIZE eSize, SIZE *psz)
155{
156 if (!cicGetFN(s_hUXTHEME, s_fnGetThemePartSize, TEXT("uxtheme.dll"), "GetThemePartSize"))
157 return E_FAIL;
158 return s_fnGetThemePartSize(m_hTheme, hDC, m_iPartId, iStateId, prc, eSize, psz);
159}
160
162CUIFTheme::DrawThemeEdge(HDC hDC, int iStateId, LPCRECT pDestRect, UINT uEdge, UINT uFlags, LPRECT pContentRect)
163{
164 if (!cicGetFN(s_hUXTHEME, s_fnDrawThemeEdge, TEXT("uxtheme.dll"), "DrawThemeEdge"))
165 return E_FAIL;
166 return s_fnDrawThemeEdge(m_hTheme, hDC, m_iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect);
167}
168
170CUIFTheme::GetThemeColor(int iStateId, int iPropId, COLORREF *pColor)
171{
172 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeColor, TEXT("uxtheme.dll"), "GetThemeColor"))
173 return E_FAIL;
174 return s_fnGetThemeColor(m_hTheme, m_iPartId, iStateId, iPropId, pColor);
175}
176
178CUIFTheme::GetThemeMargins(HDC hDC, int iStateId, int iPropId, LPRECT prc, MARGINS *pMargins)
179{
180 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeMargins, TEXT("uxtheme.dll"), "GetThemeMargins"))
181 return E_FAIL;
182 return s_fnGetThemeMargins(m_hTheme, hDC, m_iPartId, iStateId, iPropId, prc, pMargins);
183}
184
186CUIFTheme::GetThemeFont(HDC hDC, int iStateId, int iPropId, LOGFONTW *pFont)
187{
188 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeFont, TEXT("uxtheme.dll"), "GetThemeFont"))
189 return E_FAIL;
190 return s_fnGetThemeFont(m_hTheme, hDC, m_iPartId, iStateId, iPropId, pFont);
191}
192
194CUIFTheme::GetThemeSysColor(INT iColorId)
195{
196 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysColor, TEXT("uxtheme.dll"), "GetThemeSysColor"))
197 return RGB(0, 0, 0);
198 return s_fnGetThemeSysColor(m_hTheme, iColorId);
199}
200
201STDMETHODIMP_(int)
202CUIFTheme::GetThemeSysSize(int iSizeId)
203{
204 if (!cicGetFN(s_hUXTHEME, s_fnGetThemeSysSize, TEXT("uxtheme.dll"), "GetThemeSysSize"))
205 return 0;
206 return s_fnGetThemeSysSize(m_hTheme, iSizeId);
207}
208
209STDMETHODIMP_(void)
210CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId)
211{
214 m_pszClassList = pszClassList;
215}
216
218// CUIFObject
219
222{
224 m_hTheme = NULL;
226 m_nObjectID = nObjectID;
227 m_style = style;
228
229 if (prc)
230 m_rc = *prc;
231 else
232 m_rc = { 0, 0, 0, 0 };
233
234 if (m_pParent)
235 {
238 }
239 else
240 {
241 m_pWindow = NULL;
242 m_pScheme = NULL;
243 }
244
246
249
251
252 m_dwUnknown4[0] = -1; //FIXME: name
253 m_dwUnknown4[1] = -1; //FIXME: name
254}
255
257{
258 if (m_pWindow)
259 {
260 CUIFToolTip *pToolTip = m_pWindow->m_pToolTip;
261 if (pToolTip && pToolTip->m_pToolTipTarget == this)
262 pToolTip->m_pToolTipTarget = NULL;
263 }
264
265 if (m_pszToolTip)
266 {
267 delete[] m_pszToolTip;
269 }
270
271 for (size_t iObj = m_ObjectArray.size(); iObj > 0; )
272 {
273 --iObj;
274 delete m_ObjectArray[iObj];
275 }
277
278 if (m_pWindow)
279 m_pWindow->RemoveUIObj(this);
280
282}
283
284STDMETHODIMP_(void) CUIFObject::OnPaint(HDC hDC)
285{
286 if (!(m_pWindow->m_style & UIF_WINDOW_ENABLETHEMED) || !OnPaintTheme(hDC))
287 OnPaintNoTheme(hDC);
288}
289
290STDMETHODIMP_(BOOL) CUIFObject::OnSetCursor(UINT uMsg, LONG x, LONG y)
291{
292 return FALSE;
293}
294
295STDMETHODIMP_(void) CUIFObject::GetRect(LPRECT prc)
296{
297 *prc = m_rc;
298}
299
300STDMETHODIMP_(BOOL) CUIFObject::PtInObject(POINT pt)
301{
302 return m_bVisible && ::PtInRect(&m_rc, pt);
303}
304
305STDMETHODIMP_(void) CUIFObject::PaintObject(HDC hDC, LPCRECT prc)
306{
307 if (!m_bVisible)
308 return;
309
310 if (!prc)
311 prc = &m_rc;
312
313 OnPaint(hDC);
314
315 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
316 {
318 RECT rc;
319 if (::IntersectRect(&rc, prc, &pObject->m_rc))
320 pObject->PaintObject(hDC, &rc);
321 }
322}
323
324STDMETHODIMP_(void) CUIFObject::CallOnPaint()
325{
326 if (m_pWindow)
327 m_pWindow->UpdateUI(&m_rc);
328}
329
330STDMETHODIMP_(void) CUIFObject::Enable(BOOL bEnable)
331{
332 if (m_bEnable == bEnable)
333 return;
334
336 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
338
339 CallOnPaint();
340}
341
342STDMETHODIMP_(void) CUIFObject::Show(BOOL bVisible)
343{
344 if (m_bVisible == bVisible)
345 return;
346
347 m_bVisible = bVisible;
348 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
349 m_ObjectArray[iItem]->Show(bVisible);
350
351 if (m_bVisible || m_pParent)
352 m_pParent->CallOnPaint();
353}
354
355STDMETHODIMP_(void) CUIFObject::SetFontToThis(HFONT hFont)
356{
358 if (!hFont)
360 m_hFont = hFont;
361}
362
363STDMETHODIMP_(void) CUIFObject::SetFont(HFONT hFont)
364{
365 SetFontToThis(hFont);
366
367 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
368 m_ObjectArray[iItem]->SetFont(hFont);
369
370 CallOnPaint();
371}
372
373STDMETHODIMP_(void) CUIFObject::SetStyle(DWORD style)
374{
375 m_style = style;
376}
377
378STDMETHODIMP_(void) CUIFObject::AddUIObj(CUIFObject *pObject)
379{
381 CallOnPaint();
382}
383
384STDMETHODIMP_(void) CUIFObject::RemoveUIObj(CUIFObject *pObject)
385{
387 CallOnPaint();
388}
389
391{
392 if (m_pParent)
393 return m_pParent->OnObjectNotify(pObject, wParam, lParam);
394 return 0;
395}
396
397STDMETHODIMP_(void) CUIFObject::SetToolTip(LPCWSTR pszToolTip)
398{
399 if (m_pszToolTip)
400 {
401 delete[] m_pszToolTip;
403 }
404
405 if (pszToolTip)
406 {
407 size_t cch = wcslen(pszToolTip);
408 m_pszToolTip = new(cicNoThrow) WCHAR[cch + 1];
409 if (m_pszToolTip)
410 lstrcpynW(m_pszToolTip, pszToolTip, cch + 1);
411 }
412}
413
414STDMETHODIMP_(void) CUIFObject::ClearWndObj()
415{
416 m_pWindow = NULL;
417 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
418 m_ObjectArray[iItem]->ClearWndObj();
419}
420
421STDMETHODIMP_(void) CUIFObject::ClearTheme()
422{
424 for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem)
425 m_ObjectArray[iItem]->ClearTheme();
426}
427
429{
430 if (m_pWindow)
432}
433
435{
436 if (m_pWindow)
438}
439
441{
442 return m_pWindow && (m_pWindow->m_pCaptured == this);
443}
444
445void CUIFObject::SetRect(LPCRECT prc)
446{
447 m_rc = *prc;
448 if (m_pWindow)
449 m_pWindow->OnObjectMoved(this);
450 CallOnPaint();
451}
452
454{
455 if (m_pParent)
456 return m_pParent->OnObjectNotify(this, wParam, lParam);
457 return 0;
458}
459
460void CUIFObject::DetachWndObj()
461{
462 if (m_pWindow)
463 {
464 CUIFToolTip *pToolTip = m_pWindow->m_pToolTip;
465 if (pToolTip && pToolTip->m_pToolTipTarget == this)
466 pToolTip->m_pToolTipTarget = NULL;
467
468 m_pWindow->RemoveUIObj(this);
469 m_pWindow = NULL;
470 }
471}
472
474{
475 if (!m_pWindow)
476 return FALSE;
478}
479
481{
482 if (!PtInObject(pt))
483 return NULL;
484
485 CUIFObject *pFound = this;
486 for (size_t i = 0; i < m_ObjectArray.size(); ++i)
487 {
488 CUIFObject *pObject = m_ObjectArray[i]->ObjectFromPoint(pt);
489 if (pObject)
490 pFound = pObject;
491 }
492 return pFound;
493}
494
496{
498 for (size_t i = 0; i < m_ObjectArray.size(); ++i)
499 {
500 m_ObjectArray[i]->SetScheme(scheme);
501 }
502}
503
505{
506 if (m_pWindow)
508}
509
511{
512 if (m_pWindow)
514}
515
517// CUIFColorTable...
518
519STDMETHODIMP_(void) CUIFColorTableSys::InitColor()
520{
537}
538
539STDMETHODIMP_(void) CUIFColorTableSys::InitBrush()
540{
542}
543
544STDMETHODIMP_(void) CUIFColorTableSys::DoneBrush()
545{
546 for (size_t i = 0; i < _countof(m_hBrushes); ++i)
547 {
548 if (m_hBrushes[i])
549 {
551 m_hBrushes[i] = NULL;
552 }
553 }
554}
555
557{
558 if (!m_hBrushes[iColor])
560 return m_hBrushes[iColor];
561}
562
564{
565 if (!m_hBrushes[iColor])
567 return m_hBrushes[iColor];
568}
569
571STDMETHODIMP_(void) CUIFColorTableOff10::InitColor()
572{
605}
606
607STDMETHODIMP_(void) CUIFColorTableOff10::InitBrush()
608{
610}
611
612STDMETHODIMP_(void) CUIFColorTableOff10::DoneBrush()
613{
614 for (size_t i = 0; i < _countof(m_hBrushes); ++i)
615 {
616 if (m_hBrushes[i])
617 {
619 m_hBrushes[i] = NULL;
620 }
621 }
622}
623
625// CUIFScheme
626
629{
630#if 1
631 return new(cicNoThrow) CUIFSchemeDef(type);
632#else
633 switch (type)
634 {
635 case 1: return new(cicNoThrow) CUIFSchemeOff10(1);
636 case 2: return new(cicNoThrow) CUIFSchemeOff10(2);
637 case 3: return new(cicNoThrow) CUIFSchemeOff10(3);
638 default: return new(cicNoThrow) CUIFSchemeDef(type);
639 }
640#endif
641}
642
643STDMETHODIMP_(DWORD) CUIFSchemeDef::GetType()
644{
645 return m_dwType;
646}
647
648STDMETHODIMP_(COLORREF) CUIFSchemeDef::GetColor(INT iColor)
649{
651}
652
653STDMETHODIMP_(HBRUSH) CUIFSchemeDef::GetBrush(INT iColor)
654{
656}
657
658STDMETHODIMP_(INT) CUIFSchemeDef::CyMenuItem(INT cyText)
659{
660 return cyText + 2;
661}
662
663STDMETHODIMP_(INT) CUIFSchemeDef::CxSizeFrame()
664{
665 return ::GetSystemMetrics(SM_CXSIZEFRAME);
666}
667
668STDMETHODIMP_(INT) CUIFSchemeDef::CySizeFrame()
669{
670 return ::GetSystemMetrics(SM_CYSIZEFRAME);
671}
672
673STDMETHODIMP_(void) CUIFScheme::FillRect(HDC hDC, LPCRECT prc, INT iColor)
674{
675 ::FillRect(hDC, prc, GetBrush(iColor));
676}
677
678STDMETHODIMP_(void) CUIFScheme::FrameRect(HDC hDC, LPCRECT prc, INT iColor)
679{
680 ::FrameRect(hDC, prc, GetBrush(iColor));
681}
682
683STDMETHODIMP_(void) CUIFSchemeDef::DrawSelectionRect(HDC hDC, LPCRECT prc, int)
684{
685 ::FillRect(hDC, prc, GetBrush(6));
686}
687
688STDMETHODIMP_(void)
689CUIFSchemeDef::GetCtrlFaceOffset(DWORD dwUnknownFlags, DWORD dwDrawFlags, LPSIZE pSize)
690{
692 {
693 if (dwDrawFlags & 0x2)
694 {
695 if (dwUnknownFlags & 0x10)
696 {
697 pSize->cx = pSize->cy = -1;
698 return;
699 }
700 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x20);
701 }
702 else
703 {
704 if (!(dwDrawFlags & 0x1))
705 {
706 pSize->cx = pSize->cy = -((dwUnknownFlags & 1) != 0);
707 return;
708 }
709 if (dwUnknownFlags & 0x4)
710 {
711 pSize->cx = pSize->cy = -1;
712 return;
713 }
714 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x8);
715 }
716 return;
717 }
718
719 if (!(dwUnknownFlags & 0x40))
720 {
721 pSize->cx = pSize->cy = !!(dwUnknownFlags & 0x80);
722 return;
723 }
724
725 pSize->cx = pSize->cy = -1;
726}
727
728STDMETHODIMP_(void)
729CUIFSchemeDef::DrawCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags)
730{
731 ::FillRect(hDC, prc, GetBrush(9));
732
733 if (!(dwDrawFlags & UIF_DRAW_PRESSED) && (dwDrawFlags & 0x2))
734 return;
735
736 HBRUSH hbrDither = cicCreateDitherBrush();
737 if (!hbrDither)
738 return;
739
742
743 RECT rc = *prc;
744 ::InflateRect(&rc, -2, -2);
745 ::FillRect(hDC, &rc, hbrDither);
746 ::SetTextColor(hDC, rgbOldText);
747 ::SetBkColor(hDC, rgbOldBack);
748 ::DeleteObject(hbrDither);
749}
750
751STDMETHODIMP_(void)
752CUIFSchemeDef::DrawCtrlEdge(
753 HDC hDC,
754 LPCRECT prc,
755 DWORD dwUnknownFlags,
756 DWORD dwDrawFlags)
757{
758 UINT uEdge = BDR_RAISEDINNER;
759
760 if (dwDrawFlags & 0x10)
761 {
762 if (!(dwUnknownFlags & 0x40))
763 {
764 if (dwUnknownFlags & 0x80)
765 uEdge = BDR_SUNKENOUTER;
766 else
767 return;
768 }
769 }
770 else if (dwDrawFlags & 0x2)
771 {
772 if (!(dwUnknownFlags & 0x10))
773 {
774 if (dwUnknownFlags & 0x20)
775 uEdge = BDR_SUNKENOUTER;
776 else
777 return;
778 }
779 }
780 else if (dwDrawFlags & 0x1)
781 {
782 if (!(dwUnknownFlags & 0x4))
783 {
784 if (dwUnknownFlags & 0x8)
785 uEdge = BDR_SUNKENOUTER;
786 else
787 return;
788 }
789 }
790 else if (!(dwUnknownFlags & 0x1))
791 {
792 return;
793 }
794
795 RECT rc = *prc;
796 ::DrawEdge(hDC, &rc, uEdge, BF_RECT);
797}
798
799STDMETHODIMP_(void)
800CUIFSchemeDef::DrawCtrlText(
801 HDC hDC,
802 LPCRECT prc,
803 LPCWSTR pszText,
804 INT cchText,
805 DWORD dwDrawFlags,
806 BOOL bRight)
807{
808 COLORREF rgbOldText = ::GetTextColor(hDC);
809 INT OldBkMode = ::SetBkMode(hDC, TRANSPARENT);
810
811 if (cchText == -1)
813
814 RECT rc = *prc;
816 {
817 ::OffsetRect(&rc, 1, 1);
819 ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc,
821 ::OffsetRect(&rc, -1, -1);
822 }
823
825 ::ExtTextOutW(hDC, (bRight ? rc.right : rc.left), rc.top, ETO_CLIPPED, &rc,
827
828 ::SetTextColor(hDC, rgbOldText);
829 ::SetBkMode(hDC, OldBkMode);
830}
831
832STDMETHODIMP_(void)
833CUIFSchemeDef::DrawCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize)
834{
835 if (m_bMirroring)
836 {
839 {
840 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags);
843 }
844 }
845 else
846 {
850 ::DrawState(hDC, 0, 0, (LPARAM)hIcon, 0, prc->left, prc->top, 0, 0, uFlags);
851 }
852}
853
854STDMETHODIMP_(void)
855CUIFSchemeDef::DrawCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags)
856{
857 if (m_bMirroring)
858 {
859 hbm1 = cicMirrorBitmap(hbm1, GetBrush(9));
861 }
862
863 HBRUSH hBrush = (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1);
864 BOOL bBrushCreated = FALSE;
865 if (hbm2)
866 {
869 {
870 hBitmap = cicCreateDisabledBitmap(prc, hbm2, GetBrush(9), GetBrush(11), TRUE);
871 }
872 else
873 {
874 if ((dwDrawFlags & UIF_DRAW_PRESSED) && !(dwDrawFlags & 0x2))
875 {
876 hBrush = cicCreateDitherBrush();
877 bBrushCreated = TRUE;
878 }
879
882 hBitmap = cicCreateMaskBmp(prc, hbm1, hbm2, hBrush, rgbFace, rgbHighlight);
883 }
884
885 if (hBitmap)
886 {
888 prc->left, prc->top,
889 prc->right - prc->left, prc->bottom - prc->top,
890 DST_BITMAP);
892 }
893 }
894 else
895 {
899
901 prc->left, prc->top,
902 prc->right - prc->left, prc->bottom - prc->top,
903 uFlags);
904 }
905
906 if (bBrushCreated)
907 ::DeleteObject(hBrush);
908
909 if (m_bMirroring)
910 {
913 }
914}
915
916STDMETHODIMP_(void)
917CUIFSchemeDef::DrawMenuBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags)
918{
919 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags);
920}
921
922STDMETHODIMP_(void)
923CUIFSchemeDef::DrawMenuSeparator(HDC hDC, LPCRECT prc)
924{
925 RECT rc = *prc;
926 rc.bottom = rc.top + (rc.bottom - rc.top) / 2;
927 ::FillRect(hDC, &rc, (HBRUSH)UlongToHandle(COLOR_BTNSHADOW + 1));
928
929 rc = *prc;
930 rc.top += (rc.bottom - rc.top) / 2;
932}
933
934STDMETHODIMP_(void)
935CUIFSchemeDef::DrawFrameCtrlBkgd(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags)
936{
937 DrawCtrlBkgd(hDC, prc, dwUnknownFlags, dwDrawFlags);
938}
939
940STDMETHODIMP_(void)
941CUIFSchemeDef::DrawFrameCtrlEdge(HDC hDC, LPCRECT prc, DWORD dwUnknownFlags, DWORD dwDrawFlags)
942{
943 DrawCtrlEdge(hDC, prc, dwUnknownFlags, dwDrawFlags);
944}
945
946STDMETHODIMP_(void)
947CUIFSchemeDef::DrawFrameCtrlIcon(HDC hDC, LPCRECT prc, HICON hIcon, DWORD dwDrawFlags, LPSIZE pSize)
948{
949 DrawCtrlIcon(hDC, prc, hIcon, dwDrawFlags, pSize);
950}
951
952STDMETHODIMP_(void)
953CUIFSchemeDef::DrawFrameCtrlBitmap(HDC hDC, LPCRECT prc, HBITMAP hbm1, HBITMAP hbm2, DWORD dwDrawFlags)
954{
955 DrawCtrlBitmap(hDC, prc, hbm1, hbm2, dwDrawFlags);
956}
957
958STDMETHODIMP_(void)
959CUIFSchemeDef::DrawWndFrame(HDC hDC, LPCRECT prc, DWORD type, DWORD unused1, DWORD unused2)
960{
961 RECT rc = *prc;
962 if (type && type <= 2)
964 else
965 FrameRect(hDC, &rc, 14);
966}
967
968STDMETHODIMP_(void)
969CUIFSchemeDef::DrawDragHandle(HDC hDC, LPCRECT prc, BOOL bVertical)
970{
971 RECT rc;
972 if (bVertical)
973 rc = { prc->left, prc->top + 1, prc->right, prc->top + 4 };
974 else
975 rc = { prc->left + 1, prc->top, prc->left + 4, prc->bottom };
977}
978
979STDMETHODIMP_(void)
980CUIFSchemeDef::DrawSeparator(HDC hDC, LPCRECT prc, BOOL bVertical)
981{
983 if (!hLightPen)
984 return;
985
986 HPEN hShadowPen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
987 if (!hShadowPen)
988 {
989 ::DeleteObject(hLightPen);
990 return;
991 }
992
993 HGDIOBJ hPenOld = ::SelectObject(hDC, hShadowPen);
994 if (bVertical)
995 {
996 ::MoveToEx(hDC, prc->left, prc->top + 1, NULL);
997 ::LineTo(hDC, prc->right, prc->top + 1);
998 ::SelectObject(hDC, hLightPen);
999 ::MoveToEx(hDC, prc->left, prc->top + 2, NULL);
1000 ::LineTo(hDC, prc->right, prc->top + 2);
1001 }
1002 else
1003 {
1004 ::MoveToEx(hDC, prc->left + 1, prc->top, NULL);
1005 ::LineTo(hDC, prc->left + 1, prc->bottom);
1006 ::SelectObject(hDC, hLightPen);
1007 ::MoveToEx(hDC, prc->left + 2, prc->top, NULL);
1008 ::LineTo(hDC, prc->left + 2, prc->bottom);
1009 }
1010 ::SelectObject(hDC, hPenOld);
1011
1012 ::DeleteObject(hShadowPen);
1013 ::DeleteObject(hLightPen);
1014}
1015
1017// CUIFIcon
1018
1020{
1021 if (!m_hImageList)
1022 return NULL;
1023
1024 if (m_hIcon)
1025 {
1026 SIZE iconSize;
1027 cicGetIconSize(m_hIcon, &iconSize);
1028
1030 if (bMirror)
1031 uFlags |= ILC_MIRROR;
1032
1033 m_hImageList = ImageList_Create(iconSize.cx, iconSize.cy, uFlags, 1, 0);
1034 if (m_hImageList)
1036
1037 return m_hImageList;
1038 }
1039
1040 return NULL;
1041}
1042
1044// CUIFBitmapDC
1045
1047{
1048 m_hBitmap = NULL;
1051 if (bMemory)
1053 else
1054 m_hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
1055}
1056
1058{
1059 Uninit();
1061}
1062
1064{
1065 if (m_hOldBitmap)
1066 {
1069 }
1070
1071 if (m_hOldObject)
1072 {
1075 }
1076
1077 if (!bKeep)
1078 {
1079 if (m_hBitmap)
1080 {
1082 m_hBitmap = NULL;
1083 }
1084 }
1085}
1086
1088{
1089 if (m_hDC)
1091 return TRUE;
1092}
1093
1095{
1096 m_hBitmap = ::CreateBitmap(cx, cy, cPlanes, cBitCount, 0);
1098 return TRUE;
1099}
1100
1102{
1103 BITMAPINFO bmi;
1104 ZeroMemory(&bmi, sizeof(bmi));
1105 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
1106 bmi.bmiHeader.biWidth = cx;
1107 bmi.bmiHeader.biHeight = cy;
1108 bmi.bmiHeader.biPlanes = cPlanes;
1109 bmi.bmiHeader.biBitCount = cBitCount;
1113 return TRUE;
1114}
1115
1117{
1120
1123
1126
1129}
1130
1132{
1134 {
1137 }
1138
1140 {
1143 }
1144
1146 {
1149 }
1150
1152}
1153
1155{
1156 BITMAP bm;
1157 if (!CUIFBitmapDC::s_fInitBitmapDCs || !::GetObject(hBitmap, sizeof(bm), &bm))
1158 return NULL;
1159
1161 CUIFBitmapDC::s_phdcDst->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32);
1162 CUIFBitmapDC::s_phdcMask->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32);
1163
1164 RECT rc = { 0, 0, bm.bmWidth, bm.bmHeight };
1165 FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrBack);
1166
1168
1169 ::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY);
1170
1172
1173 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, bm.bmWidth, bm.bmHeight, *CUIFBitmapDC::s_phdcMask, 1, 0, SRCCOPY);
1174
1179}
1180
1182{
1183 BYTE bytes[16];
1184 ZeroMemory(&bytes, sizeof(bytes));
1185 bytes[0] = bytes[4] = bytes[8] = bytes[12] = 0x55;
1186 bytes[2] = bytes[6] = bytes[10] = bytes[14] = 0xAA;
1187 HBITMAP hBitmap = ::CreateBitmap(8, 8, 1, 1, bytes);
1188 if (!hBitmap)
1189 return NULL;
1190
1191 LOGBRUSH lb;
1193 lb.lbStyle = BS_PATTERN;
1194 HBRUSH hbr = ::CreateBrushIndirect(&lb);
1196 return hbr;
1197}
1198
1199HBITMAP
1200cicCreateDisabledBitmap(LPCRECT prc, HBITMAP hbmMask, HBRUSH hbr1, HBRUSH hbr2, BOOL bPressed)
1201{
1203 return NULL;
1204
1205 LONG width = prc->right - prc->left, height = prc->bottom - prc->top;
1206
1210
1211 RECT rc = { 0, 0, width, height };
1213
1214 HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH);
1215 ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbrWhite);
1216
1218 if (bPressed)
1221 else
1222 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height,
1224
1226
1229
1234}
1235
1236HBITMAP
1237cicCreateShadowMaskBmp(LPRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr1, HBRUSH hbr2)
1238{
1240 return NULL;
1241
1242 --prc->left;
1243 --prc->top;
1244
1245 LONG width = prc->right - prc->left;
1246 LONG height = prc->bottom - prc->top;
1247
1248 CUIFBitmapDC bitmapDC(TRUE);
1249
1253 bitmapDC.SetDIB(width, height, 1, 32);
1254
1255 RECT rc = { 0, 0, width, height };
1256
1258 ::FillRect(bitmapDC, &rc, hbr2);
1259
1260 ::BitBlt(bitmapDC, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT);
1261 ::BitBlt(*CUIFBitmapDC::s_phdcDst, 2, 2, width, height, bitmapDC, 0, 0, SRCAND);
1264
1269}
1270
1271HBITMAP
1273{
1275 return NULL;
1276
1277 INT width = prc->right - prc->left;
1278 INT height = prc->bottom - prc->top;
1279
1280 CUIFSolidBrush brush(rgbFore);
1281
1285
1287 ::SelectObject(*CUIFBitmapDC::s_phdcDst, (HBRUSH)brush);
1289
1291 ::SetBkColor(*CUIFBitmapDC::s_phdcDst, RGB(255, 255, 255));
1294
1299}
1300
1301HBITMAP
1303{
1305 return NULL;
1306
1307 if (IS_INTRESOURCE(hBrush))
1308 hBrush = ::GetSysColorBrush(HandleToLong(hBrush) - 1);
1309
1310 LOGBRUSH lb;
1311 ::GetObject(hBrush, sizeof(lb), &lb);
1312 if (lb.lbStyle || lb.lbColor)
1313 return NULL;
1314
1315 INT width = prc->right - prc->left;
1316 INT height = prc->bottom - prc->top;
1317
1318 HBITMAP hBitmap = cicChangeBitmapColor(prc, hbm1, 0, RGB(255, 255, 255));
1319 if ( !hBitmap )
1320 return NULL;
1321
1325
1326 RECT rc = { 0, 0, width, height };
1327
1328 HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH);
1329 ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrWhite);
1330
1333
1339}
1340
1341HBITMAP
1343 HBRUSH hbr, COLORREF rgbColor, COLORREF rgbBack)
1344{
1346 return NULL;
1347
1348 INT width = prc->right - prc->left;
1349 INT height = prc->bottom - prc->top;
1350 HBITMAP hBitmap = cicConvertBlackBKGBitmap(prc, hbm1, hbm2, hbr);
1351 if (hBitmap)
1352 return hBitmap;
1353
1357
1358 RECT rc = { 0, 0, width, height };
1359
1360 COLORREF OldTextColor = ::SetTextColor(*CUIFBitmapDC::s_phdcDst, rgbColor);
1361 COLORREF OldBkColor = ::SetBkColor(*CUIFBitmapDC::s_phdcDst, rgbBack);
1365
1371
1373}
1374
1376{
1378 return FALSE;
1379
1380 SIZE size;
1381 if (pSize)
1382 {
1383 size = *pSize;
1384 }
1385 else
1386 {
1387 if (!cicGetIconSize(hIcon, &size))
1388 return FALSE;
1389 }
1390
1391 CUIFBitmapDC::s_phdcSrc->SetDIB(size.cx, size.cy, 1, 32);
1393
1394 RECT rc = { 0, 0, size.cx, size.cy };
1396
1399
1404 return TRUE;
1405}
1406
1408{
1410 return;
1411
1412 LONG cx = prc->right - prc->left, cy = prc->bottom - prc->top;
1423}
1424
1426// CUIFWindow
1427
1429 : CUIFObject(NULL, 0, NULL, style)
1430{
1431 m_hInst = hInst;
1432 m_nLeft = 200;
1433 m_nTop = 200;
1434 m_nWidth = 200;
1435 m_nHeight = 200;
1436 m_hWnd = 0;
1437 m_pWindow = this;
1438 m_pCaptured = NULL;
1440 m_pPointed = NULL;
1442 m_pToolTip = NULL;
1443 m_pShadow = NULL;
1447}
1448
1450{
1451 if (m_pToolTip)
1452 {
1453 delete m_pToolTip;
1454 m_pToolTip = NULL;
1455 }
1456 if (m_pShadow)
1457 {
1458 delete m_pShadow;
1459 m_pShadow = NULL;
1460 }
1461 for (size_t i = m_ObjectArray.size(); i > 0; )
1462 {
1463 --i;
1465 m_ObjectArray[i] = NULL;
1467 delete pObject;
1468 }
1469 if (m_pScheme)
1470 {
1471 delete m_pScheme;
1472 m_pScheme = NULL;
1473 }
1474}
1475
1477CUIFWindow::Initialize()
1478{
1479 LPCTSTR pszClass = GetClassName();
1480
1481 WNDCLASSEX wcx;
1482 ZeroMemory(&wcx, sizeof(wcx));
1483 wcx.cbSize = sizeof(WNDCLASSEXW);
1484 if (!::GetClassInfoEx(m_hInst, pszClass, &wcx))
1485 {
1486 ZeroMemory(&wcx, sizeof(wcx));
1487 wcx.cbSize = sizeof(wcx);
1490 wcx.cbClsExtra = 0;
1491 wcx.cbWndExtra = sizeof(LONG_PTR) * 2;
1492 wcx.hInstance = m_hInst;
1493 wcx.hIcon = NULL;
1495 wcx.lpszClassName = pszClass;
1496 wcx.hbrBackground = NULL;
1497 wcx.lpszMenuName = NULL;
1498 wcx.hIconSm = NULL;
1499 ::RegisterClassEx(&wcx);
1500 }
1501
1504
1506 {
1509 if (m_pToolTip)
1510 m_pToolTip->Initialize();
1511 }
1512
1514 {
1516 if (m_pShadow)
1517 m_pShadow->Initialize();
1518 }
1519
1520 return CUIFObject::Initialize();
1521}
1522
1524CUIFWindow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1525{
1526 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
1527}
1528
1529void CUIFWindow::UpdateUI(LPCRECT prc)
1530{
1531 if (::IsWindow(m_hWnd))
1533}
1534
1537{
1539}
1540
1541void
1543{
1545}
1546
1548{
1549 if (m_pScheme)
1550 {
1551 delete m_pScheme;
1552 m_pScheme = NULL;
1553 }
1554
1555 INT iScheme = 0;
1557 iScheme = 1;
1558 else if (m_style & UIF_WINDOW_USESCHEME2)
1559 iScheme = 2;
1560 else if (m_style & UIF_WINDOW_USESCHEME3)
1561 iScheme = 3;
1562
1563 m_pScheme = cicCreateUIFScheme(iScheme);
1565}
1566
1568CUIFWindow::GetWndStyle()
1569{
1570 DWORD ret;
1571
1574 else
1576
1578 ret |= WS_BORDER;
1579 else if (m_style & UIF_WINDOW_DLGFRAME)
1580 ret |= WS_DLGFRAME;
1581 else if ((m_style & UIF_WINDOW_USESCHEME2) || (m_style & 0x10))
1582 ret |= WS_BORDER;
1583
1584 return ret;
1585}
1586
1588CUIFWindow::GetWndStyleEx()
1589{
1590 DWORD ret = 0;
1592 ret |= WS_EX_TOPMOST;
1597 return ret;
1598}
1599
1601CUIFWindow::CreateWnd(HWND hwndParent)
1602{
1603 HWND hWnd = CreateWindowEx(GetWndStyleEx(), GetClassName(), GetWndTitle(), GetWndStyle(),
1605 hwndParent, NULL, m_hInst, this);
1606 if (m_pToolTip)
1607 m_pToolTip->CreateWnd(hWnd);
1608 if (m_pShadow)
1609 m_pShadow->CreateWnd(hWnd);
1610 return hWnd;
1611}
1612
1613void CUIFWindow::Show(BOOL bVisible)
1614{
1615 if (!IsWindow(m_hWnd))
1616 return;
1617
1618 if (bVisible && (m_style & UIF_WINDOW_TOPMOST))
1620
1621 m_bVisible = bVisible;
1622 ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : 0));
1623}
1624
1626CUIFWindow::AnimateWnd(DWORD dwTime, DWORD dwFlags)
1627{
1628 if (!::IsWindow(m_hWnd))
1629 return FALSE;
1630
1631 BOOL bVisible = !(dwFlags & 0x10000);
1632 OnAnimationStart();
1634 if (!ret)
1635 m_bVisible = bVisible;
1636 OnAnimationEnd();
1637 return ret;
1638}
1639
1641{
1642 if (pCaptured)
1643 {
1644 m_pCaptured = pCaptured;
1646 }
1647 else
1648 {
1649 m_pCaptured = NULL;
1651 }
1652}
1653
1654STDMETHODIMP_(void)
1655CUIFWindow::SetCapture(BOOL bSet)
1656{
1657 if (bSet)
1659 else
1660 ::ReleaseCapture();
1661}
1662
1664{
1665 if (pPointed == m_pPointed)
1666 return;
1667
1668 if (m_pCaptured)
1669 {
1671 m_pPointed->OnMouseOut(pt.x, pt.y);
1672 }
1673 else if (m_pPointed && m_pPointed->m_bEnable)
1674 {
1675 m_pPointed->OnMouseOut(pt.x, pt.y);
1676 }
1677
1678 m_pPointed = pPointed;
1679
1680 if (m_pCaptured)
1681 {
1683 m_pPointed->OnMouseIn(pt.x, pt.y);
1684 }
1685 else if (m_pPointed && m_pPointed->m_bEnable)
1686 {
1687 m_pPointed->OnMouseIn(pt.x, pt.y);
1688 }
1689}
1690
1691STDMETHODIMP_(void)
1692CUIFWindow::OnObjectMoved(CUIFObject *pObject)
1693{
1694 if (!::IsWindow(m_hWnd))
1695 return;
1696
1697 POINT pt;
1700 POINT pt2 = pt;
1701 CUIFObject *pFound = ObjectFromPoint(pt);
1702 SetObjectPointed(pFound, pt2);
1703}
1704
1705STDMETHODIMP_(void)
1706CUIFWindow::SetRect(LPCRECT prc)
1707{
1708 RECT Rect = { 0, 0, 0, 0 };
1709
1710 if (::IsWindow(m_hWnd))
1712
1713 CUIFObject::SetRect(&Rect);
1714}
1715
1716STDMETHODIMP_(void)
1717CUIFWindow::ClientRectToWindowRect(LPRECT lpRect)
1718{
1719 DWORD style, exstyle;
1720 if (::IsWindow(m_hWnd))
1721 {
1724 }
1725 else
1726 {
1727 style = GetWndStyle();
1728 exstyle = GetWndStyleEx();
1729 }
1730 ::AdjustWindowRectEx(lpRect, style, FALSE, exstyle);
1731}
1732
1733STDMETHODIMP_(void)
1734CUIFWindow::GetWindowFrameSize(LPSIZE pSize)
1735{
1736 RECT rc = { 0, 0, 0, 0 };
1737
1738 ClientRectToWindowRect(&rc);
1739 pSize->cx = (rc.right - rc.left) / 2;
1740 pSize->cy = (rc.bottom - rc.top) / 2;
1741}
1742
1743STDMETHODIMP_(void)
1744CUIFWindow::OnAnimationEnd()
1745{
1746 if (m_pShadow && m_bShowShadow)
1747 m_pShadow->Show(m_bVisible);
1748}
1749
1750STDMETHODIMP_(void)
1751CUIFWindow::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam)
1752{
1753 ClearTheme();
1754}
1755
1756LRESULT
1757CUIFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1758{
1759 switch (uMsg)
1760 {
1761 case WM_GETOBJECT:
1762 return OnGetObject(hWnd, WM_GETOBJECT, wParam, lParam);
1763
1764 case WM_SYSCOLORCHANGE:
1766 OnSysColorChange();
1767 return 0;
1768
1769 case WM_ENDSESSION:
1770 OnEndSession(hWnd, wParam, lParam);
1771 return 0;
1772
1773 case WM_SHOWWINDOW:
1774 if (m_pShadow && m_bShowShadow)
1775 m_pShadow->Show(wParam);
1776 return OnShowWindow(hWnd, WM_SHOWWINDOW, wParam, lParam);
1777
1778 case WM_SETTINGCHANGE:
1782 case WM_SETCURSOR:
1783 {
1784 POINT Point;
1787
1788 if (m_pBehindModal)
1789 {
1790 m_pBehindModal->ModalMouseNotify(HIWORD(lParam), Point.x, Point.y);
1791 return TRUE;
1792 }
1793
1794 if (!m_bPointing)
1795 {
1797 m_bPointing = TRUE;
1798 }
1799
1800 if (m_pToolTip)
1801 {
1804 }
1805
1807 HandleMouseMsg(HIWORD(lParam), Point.x, Point.y);
1808
1809 return TRUE;
1810 }
1811 case WM_MOUSEACTIVATE:
1812 return MA_NOACTIVATE;
1813 case WM_ERASEBKGND:
1814 return OnEraseBkGnd(hWnd, WM_ERASEBKGND, wParam, lParam);
1815 case WM_CREATE:
1816 SetRect(NULL);
1817 OnCreate(hWnd);
1818 return 0;
1819 case WM_DESTROY:
1824 OnDestroy(hWnd);
1825 return 0;
1826 case WM_SIZE:
1827 SetRect(NULL);
1828 return 0;
1829 case WM_ACTIVATE:
1831 case WM_SETFOCUS:
1832 OnSetFocus(hWnd);
1833 return 0;
1834 case WM_KILLFOCUS:
1835 OnKillFocus(hWnd);
1836 return 0;
1837 case WM_PAINT:
1838 {
1839 PAINTSTRUCT Paint;
1840 HDC hDC = ::BeginPaint(hWnd, &Paint);
1841 PaintObject(hDC, &Paint.rcPaint);
1842 ::EndPaint(hWnd, &Paint);
1843 return 0;
1844 }
1845 case WM_PRINTCLIENT:
1846 {
1847 PaintObject((HDC)wParam, NULL);
1848 return 0;
1849 }
1850 case WM_THEMECHANGED:
1851 {
1852 OnThemeChanged(hWnd, wParam, lParam);
1853 return 0;
1854 }
1855 case WM_COMMAND:
1856 {
1857 return 0;
1858 }
1859 case WM_TIMER:
1860 {
1861 switch (wParam)
1862 {
1863 case USER_TIMER_ID:
1864 {
1865 if (m_pTimerObject)
1866 m_pTimerObject->OnTimer();
1867 break;
1868 }
1869 case POINTING_TIMER_ID:
1870 {
1871 POINT pt;
1873
1874 POINT pt2 = pt;
1875 ::ScreenToClient(m_hWnd, &pt2);
1876
1877 RECT rc;
1878 ::GetWindowRect(m_hWnd, &rc);
1879
1880 if (::PtInRect(&rc, pt) && ::WindowFromPoint(pt) == m_hWnd)
1881 {
1882 m_pBehindModal->ModalMouseNotify(WM_MOUSEMOVE, pt2.x, pt2.y);
1883 }
1884 else
1885 {
1888 SetObjectPointed(NULL, pt2);
1889 OnMouseOutFromWindow(pt2.x, pt2.y);
1890 }
1891
1892 if (m_pToolTip)
1893 {
1894 MSG msg = { m_hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt2.x, pt2.y) };
1896 }
1897 break;
1898 }
1899 default:
1900 {
1901 OnTimer(wParam);
1902 break;
1903 }
1904 }
1905 break;
1906 }
1907 case WM_MOUSEMOVE:
1908 case WM_LBUTTONDOWN:
1909 case WM_LBUTTONDBLCLK:
1910 case WM_LBUTTONUP:
1911 case WM_MBUTTONDOWN:
1912 case WM_MBUTTONDBLCLK:
1913 case WM_MBUTTONUP:
1914 case WM_RBUTTONDOWN:
1915 case WM_RBUTTONDBLCLK:
1916 case WM_RBUTTONUP:
1917 {
1918 if (m_pBehindModal)
1919 m_pBehindModal->ModalMouseNotify(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
1920 else
1921 HandleMouseMsg(uMsg, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
1922 break;
1923 }
1924 case WM_KEYUP:
1925 {
1926 OnKeyUp(hWnd, wParam, lParam);
1927 break;
1928 }
1930 {
1931 WINDOWPOS *pwp = (WINDOWPOS *)lParam;
1932 if (m_pShadow && (pwp->flags & SWP_HIDEWINDOW))
1933 m_pShadow->Show(FALSE);
1934 if (!(pwp->flags & SWP_NOZORDER) && pwp->hwndInsertAfter == m_pShadow->m_hWnd)
1935 pwp->flags |= SWP_NOZORDER;
1937 return OnWindowPosChanging(hWnd, WM_WINDOWPOSCHANGING, wParam, lParam);
1938 }
1940 {
1941 WINDOWPOS *pwp = (WINDOWPOS *)lParam;
1942 if (m_pShadow)
1944 return OnWindowPosChanged(hWnd, WM_WINDOWPOSCHANGED, wParam, lParam);
1945 }
1946 case WM_NOTIFY:
1948 return 0;
1949 case WM_NOTIFYFORMAT:
1950 return OnNotifyFormat(hWnd, wParam, lParam);
1951 case WM_DISPLAYCHANGE:
1954 return OnDisplayChange(hWnd, WM_DISPLAYCHANGE, wParam, lParam);
1955 case WM_NCDESTROY:
1956 OnNCDestroy(hWnd);
1957 return 0;
1958 case WM_KEYDOWN:
1960 return 0;
1961 default:
1962 {
1963 if (uMsg >= WM_USER)
1964 {
1966 pThis->OnUser(hWnd, uMsg, wParam, lParam);
1967 break;
1968 }
1969 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
1970 }
1971 }
1972
1973 return 0;
1974}
1975
1978{
1980
1981 if (uMsg == WM_NCCREATE)
1982 {
1983 This = (CUIFWindow*)((CREATESTRUCT*)lParam)->lpCreateParams;
1985 This->m_hWnd = hWnd;
1986 }
1987 else
1988 {
1990 }
1991
1992 if (uMsg == WM_GETMINMAXINFO)
1993 {
1994 if (This)
1995 return This->WindowProc(hWnd, uMsg, wParam, lParam);
1996 else
1997 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
1998 }
1999
2000 if (!This)
2001 return 0;
2002
2003 if (uMsg == WM_NCDESTROY)
2004 {
2005 This->m_hWnd = NULL;
2007 }
2008
2009 return This->WindowProc(hWnd, uMsg, wParam, lParam);
2010}
2011
2012BOOL
2014{
2016 return FALSE;
2017
2018 HMONITOR hMon = ::MonitorFromRect(prcWnd, MONITOR_DEFAULTTONEAREST);
2020 mi.cbSize = sizeof(MONITORINFO);
2021 if (!hMon || !::GetMonitorInfo(hMon, &mi))
2022 {
2024 return ::SystemParametersInfo(SPI_GETWORKAREA, 0, prcWorkArea, 0);
2025
2026 prcWorkArea->left = prcWorkArea->top = 0;
2027 prcWorkArea->right = ::GetSystemMetrics(SM_CXSCREEN);
2028 prcWorkArea->bottom = ::GetSystemMetrics(SM_CYSCREEN);
2029 return TRUE;
2030 }
2031
2033 {
2034 *prcWorkArea = mi.rcWork;
2035 return TRUE;
2036 }
2037
2038 *prcWorkArea = mi.rcMonitor;
2039 return TRUE;
2040}
2041
2042void
2044{
2045 RECT rc;
2046 rc.left = m_nLeft;
2047 rc.right = m_nLeft + m_nWidth;
2048 rc.top = m_nTop;
2049 rc.bottom = m_nTop + m_nHeight;
2050
2051 RECT rcWorkArea;
2052 if (!GetWorkArea(&rc, &rcWorkArea))
2053 return;
2054
2055 if (m_nLeft < rcWorkArea.left)
2056 m_nLeft = rcWorkArea.left;
2057 if (m_nTop < rcWorkArea.top)
2058 m_nTop = rcWorkArea.top;
2059 if (m_nLeft + m_nWidth >= rcWorkArea.right)
2060 m_nLeft = rcWorkArea.right - m_nWidth;
2061 if (m_nTop + m_nHeight >= rcWorkArea.bottom)
2062 m_nTop = rcWorkArea.bottom - m_nHeight;
2063}
2064
2066{
2067 m_pBehindModal = pBehindModal;
2068}
2069
2070void CUIFWindow::SetTimerObject(CUIFObject *pTimerObject, UINT uElapse)
2071{
2072 if (pTimerObject)
2073 {
2074 m_pTimerObject = pTimerObject;
2075 ::SetTimer(m_hWnd, USER_TIMER_ID, uElapse, NULL);
2076 }
2077 else
2078 {
2081 }
2082}
2083
2084STDMETHODIMP_(void)
2085CUIFWindow::PaintObject(HDC hDC, LPCRECT prc)
2086{
2087 BOOL bGotDC = FALSE;
2088 if (!hDC)
2089 {
2090 hDC = ::GetDC(m_hWnd);
2091 bGotDC = TRUE;
2092 }
2093
2094 if (!prc)
2095 prc = &m_rc;
2096
2097 HDC hMemDC = ::CreateCompatibleDC(hDC);
2099
2100 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem);
2101 ::SetViewportOrgEx(hMemDC, -prc->left, -prc->top, NULL);
2105 {
2106 if (m_pScheme)
2107 m_pScheme->FillRect(hMemDC, prc, 22);
2108 }
2109
2110 CUIFObject::PaintObject(hMemDC, prc);
2111 ::BitBlt(hDC, prc->left, prc->top,
2112 prc->right - prc->left, prc->bottom - prc->top,
2113 hMemDC, prc->left, prc->top, SRCCOPY);
2114 ::SelectObject(hMemDC, hbmOld);
2115 ::DeleteObject(hbmMem);
2116 ::DeleteDC(hMemDC);
2117
2118 if (bGotDC)
2120}
2121
2122STDMETHODIMP_(void)
2123CUIFWindow::Move(INT x, INT y, INT nWidth, INT nHeight)
2124{
2125 m_nLeft = x;
2126 m_nTop = y;
2127 if (nWidth >= 0)
2128 m_nWidth = nWidth;
2129 if (nHeight >= 0)
2131 if (::IsWindow(m_hWnd))
2132 {
2135 }
2136}
2137
2138STDMETHODIMP_(void)
2139CUIFWindow::RemoveUIObj(CUIFObject *pRemove)
2140{
2141 if (pRemove == m_pCaptured)
2143
2144 if (pRemove == m_pTimerObject)
2145 {
2148 }
2149
2150 if (pRemove == m_pPointed)
2151 m_pPointed = NULL;
2152
2153 CUIFObject::RemoveUIObj(pRemove);
2154}
2155
2156STDMETHODIMP_(void)
2157CUIFWindow::HandleMouseMsg(UINT uMsg, LONG x, LONG y)
2158{
2159 POINT pt = { x, y };
2160
2162
2163 SetObjectPointed(pFound, pt);
2164
2165 if (m_pCaptured)
2166 pFound = m_pCaptured;
2167
2168 if (!pFound || OnSetCursor(uMsg, pt.x, pt.y))
2169 {
2170 HCURSOR hCursor = ::LoadCursor(NULL, IDC_ARROW);
2171 ::SetCursor(hCursor);
2172 }
2173
2174 if (pFound && pFound->m_bEnable)
2175 {
2176 switch (uMsg)
2177 {
2178 case WM_MOUSEMOVE:
2179 pFound->OnMouseMove(pt.x, pt.y);
2180 break;
2181 case WM_LBUTTONDOWN:
2182 pFound->OnLButtonDown(pt.x, pt.y);
2183 break;
2184 case WM_LBUTTONUP:
2185 pFound->OnLButtonUp(pt.x, pt.y);
2186 break;
2187 case WM_RBUTTONDOWN:
2188 pFound->OnRButtonDown(pt.x, pt.y);
2189 break;
2190 case WM_RBUTTONUP:
2191 pFound->OnRButtonUp(pt.x, pt.y);
2192 break;
2193 case WM_MBUTTONDOWN:
2194 pFound->OnMButtonDown(pt.x, pt.y);
2195 break;
2196 case WM_MBUTTONUP:
2197 pFound->OnMButtonUp(pt.x, pt.y);
2198 break;
2199 }
2200 }
2201}
2202
2204// CUIFShadow
2205
2209{
2210 m_pShadowOwner = pShadowOwner;
2211 m_rgbShadowColor = RGB(0, 0, 0);
2212 m_dwUnknown11[0] = 0;
2213 m_dwUnknown11[1] = 0;
2216}
2217
2219{
2220 if (m_pShadowOwner)
2222}
2223
2226{
2228 m_rgbShadowColor = RGB(128, 128, 128);
2230}
2231
2234{
2236 {
2237 //FIXME
2238 }
2239}
2240
2242{
2243 HWND hwndOwner = *m_pShadowOwner;
2244 if (!::IsWindow(m_hWnd))
2245 return;
2246
2247 RECT rc;
2248 ::GetWindowRect(hwndOwner, &rc);
2249 ::SetWindowPos(m_hWnd, hwndOwner,
2250 rc.left + m_xShadowDelta,
2251 rc.top + m_yShadowDelta,
2252 rc.right - rc.left,
2253 rc.bottom - rc.top,
2255}
2256
2258{
2260 {
2262 if (bDoSize)
2263 InitShadow();
2264 }
2265}
2266
2268CUIFShadow::Initialize()
2269{
2270 InitSettings();
2271 return CUIFWindow::Initialize();
2272}
2273
2275CUIFShadow::GetWndStyleEx()
2276{
2277 DWORD exstyle = CUIFWindow::GetWndStyleEx();
2279 exstyle |= WS_EX_LAYERED;
2280 return exstyle;
2281}
2282
2283STDMETHODIMP_(void)
2284CUIFShadow::OnPaint(HDC hDC)
2285{
2286 RECT rc = m_rc;
2287 HBRUSH hBrush = ::CreateSolidBrush(m_rgbShadowColor);
2288 ::FillRect(hDC, &rc, hBrush);
2289 ::DeleteObject(hBrush);
2290}
2291
2293CUIFShadow::OnWindowPosChanging(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
2294{
2295 WINDOWPOS *wp = (WINDOWPOS *)lParam;
2297 return ::DefWindowProc(hWnd, Msg, wParam, lParam);
2298}
2299
2301CUIFShadow::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2302{
2303 InitSettings();
2304
2305 DWORD exstyle;
2308 else
2309 exstyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
2310
2312
2314 InitShadow();
2315
2316 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
2317}
2318
2319STDMETHODIMP_(void)
2320CUIFShadow::Show(BOOL bVisible)
2321{
2322 if (bVisible && ::IsWindow(m_hWnd) && !::IsWindowVisible(m_hWnd))
2323 {
2325 InitShadow();
2326 }
2327
2328 if (::IsWindow(m_hWnd))
2329 {
2330 m_bVisible = bVisible;
2332 }
2333}
2334
2336// CUIFToolTip
2337
2340{
2341 m_pToolTipOwner = pToolTipOwner;
2348 m_dwUnknown10 = 0; //FIXME: name and type
2349 m_nDelayTimeType2 = -1;
2350 m_nDelayTimeType3 = -1;
2351 m_nDelayTimeType1 = -1;
2352 m_cxToolTipWidth = -1;
2357}
2358
2360{
2361 if (m_pToolTipOwner)
2363 if (m_pszToolTipText)
2364 delete[] m_pszToolTipText;
2365}
2366
2367LONG
2369{
2370 LONG nDelayTime;
2371 switch (uType)
2372 {
2373 case 1:
2374 {
2375 nDelayTime = m_nDelayTimeType1;
2376 if (nDelayTime == -1)
2377 return ::GetDoubleClickTime() / 5;
2378 return nDelayTime;
2379 }
2380 case 2:
2381 {
2382 nDelayTime = m_nDelayTimeType2;
2383 if (nDelayTime == -1)
2384 return 10 * ::GetDoubleClickTime();
2385 return nDelayTime;
2386 }
2387 case 3:
2388 {
2389 nDelayTime = m_nDelayTimeType3;
2390 if (nDelayTime == -1)
2391 return ::GetDoubleClickTime();
2392 return nDelayTime;
2393 }
2394 default:
2395 {
2396 return 0;
2397 }
2398 }
2399}
2400
2402{
2403 if (prc)
2405}
2406
2409{
2411 return m_rgbToolTipBkColor;
2412 return ::GetSysColor(COLOR_INFOBK);
2413}
2414
2417{
2419 return m_rgbToolTipTextColor;
2420 return ::GetSysColor(COLOR_INFOTEXT);
2421}
2422
2425{
2426 if (hWnd == *m_pToolTipOwner)
2428 return NULL;
2429}
2430
2431void
2433{
2435
2436 if (!m_pToolTipTarget)
2437 return;
2438
2439 LPCWSTR pszText = m_pToolTipTarget->GetToolTip();
2440 if (!pszText)
2441 return;
2442
2443 if (!m_pToolTipTarget || m_pToolTipTarget->OnShowToolTip())
2444 return;
2445
2446 POINT Point;
2449
2450 RECT rc;
2451 m_pToolTipTarget->GetRect(&rc);
2452 if (!::PtInRect(&rc, Point))
2453 return;
2454
2455 size_t cchText = wcslen(pszText);
2457 if (!m_pszToolTipText)
2458 return;
2459
2460 lstrcpynW(m_pszToolTipText, pszText, cchText + 1);
2461
2462 SIZE size;
2464
2465 RECT rc2 = rc;
2468 GetTipWindowRect(&rc2, size, &rc);
2469
2471 Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
2472 Show(TRUE);
2473}
2474
2475void
2477{
2480
2481 if (m_pToolTipTarget)
2482 m_pToolTipTarget->OnHideToolTip();
2483
2484 if (m_bVisible)
2485 {
2486 if (m_pszToolTipText)
2487 {
2488 delete[] m_pszToolTipText;
2490 }
2491 Show(FALSE);
2492 }
2493}
2494
2495void
2497{
2498 if (!m_pszToolTipText)
2499 return;
2500
2501 HDC hDC = ::GetDC(m_hWnd);
2502 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
2503
2504 RECT rcText = { 0, 0, 0, 0 };
2505 INT cyText;
2506 if (m_cxToolTipWidth <= 0)
2507 {
2508 cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_SINGLELINE);
2509 }
2510 else
2511 {
2512 rcText.right = m_cxToolTipWidth;
2513 cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | DT_WORDBREAK);
2514 }
2515
2516 RECT rcMargin;
2517 GetMargin(&rcMargin);
2518
2519 RECT rc;
2520 rc.left = rcText.left - rcMargin.left;
2521 rc.top = rcText.top - rcMargin.top;
2522 rc.right = rcText.right + rcMargin.right;
2523 rc.bottom = rcText.top + cyText + rcMargin.bottom;
2524 ClientRectToWindowRect(&rc);
2525
2526 pSize->cx = rc.right - rc.left;
2527 pSize->cy = rc.bottom - rc.top;
2528
2529 ::SelectObject(hDC, hFontOld);
2531}
2532
2533void
2535{
2536 POINT Point;
2538
2539 HCURSOR hCursor = ::GetCursor();
2541 INT yHotspot = 0;
2543 if (hCursor && ::GetIconInfo(hCursor, &IconInfo))
2544 {
2545 BITMAP bm;
2546 ::GetObject(IconInfo.hbmMask, sizeof(bm), &bm);
2547 if (!IconInfo.fIcon)
2548 {
2549 cyCursor = bm.bmHeight;
2550 yHotspot = IconInfo.yHotspot;
2551 if (!IconInfo.hbmColor)
2552 cyCursor = bm.bmHeight / 2;
2553 }
2554 if (IconInfo.hbmColor)
2556 if (IconInfo.hbmMask)
2558 }
2559
2560 RECT rcMonitor;
2561 rcMonitor.left = 0;
2562 rcMonitor.top = 0;
2563 rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
2564 rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
2565
2566 HMONITOR hMon = ::MonitorFromPoint(Point, MONITOR_DEFAULTTONEAREST);
2568 if (hMon)
2569 {
2570 mi.cbSize = sizeof(MONITORINFO);
2571 if (::GetMonitorInfo(hMon, &mi))
2572 rcMonitor = mi.rcMonitor;
2573 }
2574
2575 pRect->left = Point.x;
2576 pRect->right = pRect->left + toolTipSize.cx;
2577 pRect->top = Point.y + cyCursor - yHotspot;
2578 pRect->bottom = pRect->top + toolTipSize.cy;
2579
2580 if (rcMonitor.right < pRect->right)
2581 {
2582 pRect->left = rcMonitor.right - toolTipSize.cx;
2583 pRect->right = rcMonitor.right;
2584 }
2585 if (pRect->left < rcMonitor.left)
2586 {
2587 pRect->left = rcMonitor.left;
2588 pRect->right = rcMonitor.left + toolTipSize.cx;
2589 }
2590 if (rcMonitor.bottom < pRect->bottom)
2591 {
2592 pRect->top = rcMonitor.bottom - toolTipSize.cy;
2593 pRect->bottom = rcMonitor.bottom;
2594 }
2595 if (pRect->top < rcMonitor.top)
2596 {
2597 pRect->top = rcMonitor.top;
2598 pRect->bottom = rcMonitor.top + toolTipSize.cy;
2599 }
2600}
2601
2602void
2604{
2605 if (!pMsg)
2606 return;
2607
2608 switch (pMsg->message)
2609 {
2610 case WM_MOUSEMOVE:
2611 {
2612 if (m_bEnable &&
2613 ::GetKeyState(VK_LBUTTON) >= 0 &&
2614 ::GetKeyState(VK_MBUTTON) >= 0 &&
2616 {
2617 POINT pt = { (SHORT)LOWORD(pMsg->lParam), (SHORT)HIWORD(pMsg->lParam) };
2618 CUIFObject *pFound = CUIFToolTip::FindObject(pMsg->hwnd, pt);
2619 if (pFound)
2620 {
2621 if (m_pToolTipTarget != pFound)
2622 {
2623 HideTip();
2624
2625 LONG DelayTime;
2626 if (!m_bVisible)
2627 DelayTime = GetDelayTime(3);
2628 else
2629 DelayTime = GetDelayTime(1);
2630 ::SetTimer(m_hWnd, TOOLTIP_TIMER_ID, DelayTime, NULL);
2631 }
2632 }
2633 else
2634 {
2635 HideTip();
2636 }
2637 m_pToolTipTarget = pFound;
2638 }
2639 break;
2640 }
2641 case WM_LBUTTONDOWN:
2642 case WM_RBUTTONDOWN:
2643 case WM_MBUTTONDOWN:
2644 {
2645 HideTip();
2646 break;
2647 }
2648 }
2649}
2650
2651STDMETHODIMP_(void) CUIFToolTip::OnPaint(HDC hDC)
2652{
2653 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
2654 INT iBkModeOld = ::SetBkMode(hDC, TRANSPARENT);
2655
2656 COLORREF rgbTextColor = GetTipTextColor();
2657 COLORREF rgbOldTextColor = ::SetTextColor(hDC, rgbTextColor);
2658
2659 COLORREF rgbBkColor = GetTipBkColor();
2660 HBRUSH hbrBack = ::CreateSolidBrush(rgbBkColor);
2661 RECT rc = m_rc;
2662 if (hbrBack)
2663 {
2664 ::FillRect(hDC, &rc, hbrBack);
2665 ::DeleteObject(hbrBack);
2666 }
2667
2668 RECT rcMargin;
2669 GetMargin(&rcMargin);
2670
2671 rc.left += rcMargin.left;
2672 rc.top += rcMargin.top;
2673 rc.right -= rcMargin.right;
2674 rc.bottom -= rcMargin.bottom;
2675
2676 if (m_cxToolTipWidth <= 0)
2678 else
2679 ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_WORDBREAK);
2680
2681 ::SetTextColor(hDC, rgbOldTextColor);
2682 ::SetBkMode(hDC, iBkModeOld);
2683 ::SelectObject(hDC, hFontOld);
2684}
2685
2686STDMETHODIMP_(void) CUIFToolTip::Enable(BOOL bEnable)
2687{
2688 if (!bEnable)
2689 HideTip();
2690 CUIFObject::Enable(bEnable);
2691}
2692
2693STDMETHODIMP_(void) CUIFToolTip::OnTimer(WPARAM wParam)
2694{
2695 if (wParam == TOOLTIP_TIMER_ID)
2696 ShowTip();
2697}
2698
2700// CUIFButton
2701
2704 DWORD nObjectID,
2705 LPCRECT prc,
2706 DWORD style) : CUIFObject(pParent, nObjectID, prc, style)
2707{
2710 m_dwUnknown9 = 0;
2711 m_uButtonStatus = 0;
2712 m_bPressed = FALSE;
2716}
2717
2719{
2720 if (m_pszButtonText)
2721 {
2722 delete[] m_pszButtonText;
2724 }
2725
2728}
2729
2730void
2732{
2735 if (m_hbmButton2)
2736 {
2738 (HBRUSH)UlongToHandle(COLOR_BTNFACE + 1), 0, 0);
2739 ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMask, 0,
2740 prc->left + bPressed, prc->top + bPressed,
2741 width - bPressed, height - bPressed,
2743 ::DeleteObject(hbmMask);
2744 }
2745 else
2746 {
2748 prc->left + bPressed, prc->top + bPressed,
2749 width - bPressed, height - bPressed,
2751 }
2752}
2753
2754void
2756{
2757 RECT rc = *prc;
2758 if (bPressed)
2760 else
2761 ::DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);
2762}
2763
2765{
2766 INT width = prc->right - prc->left;
2767 INT height = prc->bottom - prc->top;
2768 RECT rc = { 0, 0, width, height };
2769
2770 HDC hMemDC = ::CreateCompatibleDC(hDC);
2771 if (!hMemDC)
2772 return;
2773
2775 if (!hbmMem)
2776 {
2777 ::DeleteDC(hMemDC);
2778 return;
2779 }
2780
2781 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem);
2782 if (m_bEnable)
2783 {
2784 ::BitBlt(hMemDC, rc.left, rc.top, width, height, hDC, prc->left, prc->top, SRCCOPY);
2785 }
2786 else
2787 {
2788 HBRUSH hbrWhite = (HBRUSH)::GetStockObject(WHITE_BRUSH);
2789 ::FillRect(hMemDC, &rc, hbrWhite);
2790 }
2791
2793 {
2794 ::DrawIconEx(hMemDC,
2795 2 + bPressed, 2 + bPressed,
2797 width - 4, height - 4,
2798 0, NULL, DI_NORMAL);
2799 }
2800 else
2801 {
2802 ::DrawIconEx(hMemDC,
2803 (width - 16) / 2 + bPressed,
2804 (height - 16) / 2 + bPressed,
2806 16, 16,
2807 0, NULL, DI_NORMAL);
2808 }
2809
2810 ::SelectObject(hMemDC, hbmOld);
2811 ::DrawState(hDC, NULL, NULL, (LPARAM)hbmMem, 0,
2812 prc->left, prc->top, width, height,
2814 ::DeleteObject(hbmMem);
2815 ::DeleteDC(hMemDC);
2816}
2817
2818void
2820{
2821 if (!m_pszButtonText)
2822 return;
2823
2824 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
2826 SIZE textSize;
2828
2829 INT xText, yText;
2831 xText = (m_rc.right - m_rc.left - textSize.cx) / 2;
2833 xText = m_rc.right - m_rc.left - textSize.cx;
2834 else
2835 xText = 0;
2836
2838 yText = (m_rc.bottom - m_rc.top - textSize.cy) / 2;
2840 yText = m_rc.bottom - m_rc.top - textSize.cy;
2841 else
2842 yText = 0;
2843
2845
2846 if (m_bEnable)
2847 {
2850 xText + prc->left + bPressed, yText + prc->top + bPressed,
2853 }
2854 else
2855 {
2858 xText + prc->left + bPressed + 1, yText + prc->top + bPressed + 1,
2861
2864 xText + prc->left + bPressed, yText + prc->top + bPressed,
2867 }
2868
2869 ::SelectObject(hDC, hFontOld);
2870}
2871
2872STDMETHODIMP_(void)
2873CUIFButton::Enable(BOOL bEnable)
2874{
2875 CUIFObject::Enable(bEnable);
2876 if (!m_bEnable)
2877 {
2878 SetStatus(0);
2879 if (IsCapture())
2881 }
2882}
2883
2884void
2886{
2889 {
2890 BITMAP bm;
2891 ::GetObject(IconInfo.hbmColor, sizeof(bm), &bm);
2894 pSize->cx = bm.bmWidth;
2895 pSize->cy = bm.bmHeight;
2896 }
2897 else
2898 {
2901 }
2902}
2903
2904void
2906{
2907 HDC hDC = ::GetDC(NULL);
2908 INT cchText = lstrlenW(pszText);
2909 HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
2910
2912 {
2913 RECT rc;
2914 GetThemeTextExtent(hDC, 0, pszText, cchText, 0, NULL, &rc);
2915 pSize->cx = rc.right;
2916 pSize->cy = rc.bottom;
2917 }
2918 else
2919 {
2920 ::GetTextExtentPoint32W(hDC, pszText, cchText, pSize);
2921 }
2922
2924 {
2925 INT tmp = pSize->cx;
2926 pSize->cx = pSize->cy;
2927 pSize->cy = tmp;
2928 }
2929
2930 ::SelectObject(hDC, hFontOld);
2932}
2933
2934STDMETHODIMP_(void)
2935CUIFButton::OnLButtonDown(LONG x, LONG y)
2936{
2937 SetStatus(1);
2938 StartCapture();
2939 if ((m_style & 0x30) == 0x20)
2940 NotifyCommand(1, 0);
2941}
2942
2944STDMETHODIMP_(void)
2945CUIFButton::OnLButtonUp(LONG x, LONG y)
2946{
2947 POINT pt = { x, y };
2948 BOOL bCapture = IsCapture();
2949 if (bCapture)
2950 EndCapture();
2951
2952 BOOL bNotInObject = (m_style & 0x30) == 0x20;
2953 if ((m_style & 0x30) != 0x10)
2954 {
2955 bNotInObject = !PtInObject(pt);
2956 if (bNotInObject)
2957 {
2958 SetStatus(0);
2959 return;
2960 }
2961 }
2962 else
2963 {
2964 if (!bNotInObject)
2965 {
2966 bNotInObject = !PtInObject(pt);
2967 if (!bNotInObject)
2968 {
2969 SetStatus(2);
2970 NotifyCommand(1, 0);
2971 return;
2972 }
2973 }
2974 SetStatus(0);
2975 return;
2976 }
2977
2978 SetStatus(2);
2979
2980 if (bCapture)
2981 {
2983 NotifyCommand(1, 0);
2984 }
2985}
2986
2987void CUIFButton::OnMouseIn(LONG x, LONG y)
2988{
2989 if ((m_style & 0x30) == 0x20)
2990 {
2991 if (IsCapture())
2992 SetStatus(0);
2993 else
2994 SetStatus(2);
2995 }
2996 else
2997 {
2998 if (IsCapture())
2999 SetStatus(1);
3000 else
3001 SetStatus(2);
3002 }
3003}
3004
3005void CUIFButton::OnMouseOut(LONG x, LONG y)
3006{
3007 if ((m_style & 0x30) == 0x20)
3008 SetStatus(0);
3009 else if (IsCapture())
3010 SetStatus(3);
3011 else
3012 SetStatus(0);
3013}
3014
3015STDMETHODIMP_(void)
3016CUIFButton::OnPaintNoTheme(HDC hDC)
3017{
3019
3020 if (m_bPressed && ((m_uButtonStatus == 0) || (m_uButtonStatus == 3)))
3021 {
3022 HBRUSH hbr = cicCreateDitherBrush();
3023 if (hbr)
3024 {
3027 RECT rc = m_rc;
3028 ::InflateRect(&rc, -2, -2);
3029 ::FillRect(hDC, &rc, hbr);
3030 ::SetTextColor(hDC, OldTextColor);
3031 ::SetBkColor(hDC, OldBkColor);
3032 ::DeleteObject(hbr);
3033 }
3034 }
3035
3036 BOOL bPressed = (m_bPressed || (m_uButtonStatus == 1));
3037 if (m_hbmButton1)
3038 DrawBitmapProc(hDC, &m_rc, bPressed);
3039 else if (m_ButtonIcon.m_hIcon)
3040 DrawIconProc(hDC, &m_rc, bPressed);
3041 else
3042 DrawTextProc(hDC, &m_rc, bPressed);
3043
3044 if (m_bPressed || (m_uButtonStatus == 1))
3046 else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3)
3048}
3049
3051{
3053
3056 else
3057 m_IconSize.cx = m_IconSize.cy = 0;
3058
3059 CallOnPaint();
3060}
3061
3062void CUIFButton::SetStatus(UINT uStatus)
3063{
3064 if (uStatus != m_uButtonStatus)
3065 {
3066 m_uButtonStatus = uStatus;
3067 CallOnPaint();
3068 }
3069}
3070
3072{
3073 if (m_pszButtonText)
3074 {
3075 delete[] m_pszButtonText;
3077 }
3078
3079 m_TextSize.cx = m_TextSize.cy = 0;
3080
3081 if (pszText)
3082 {
3083 INT cch = lstrlenW(pszText);
3084 m_pszButtonText = new(cicNoThrow) WCHAR[cch + 1];
3085 if (!m_pszButtonText)
3086 return;
3087
3088 lstrcpynW(m_pszButtonText, pszText, cch + 1);
3090 }
3091
3092 CallOnPaint();
3093}
3094
3096// CUIFButton2
3097
3100 DWORD nObjectID,
3101 LPCRECT prc,
3102 DWORD style) : CUIFButton(pParent, nObjectID, prc, style)
3103{
3104 m_iStateId = 0;
3106 m_pszClassList = L"TOOLBAR";
3107}
3108
3110{
3112}
3113
3115{
3116 DWORD dwDrawFlags = 0;
3117 if (m_bPressed)
3118 dwDrawFlags |= UIF_DRAW_PRESSED;
3119 if (m_uButtonStatus == 1)
3120 dwDrawFlags |= 0x2;
3121 else if (2 <= m_uButtonStatus && m_uButtonStatus <= 3)
3122 dwDrawFlags |= 0x1;
3123 if (!m_bEnable)
3124 dwDrawFlags |= UIF_DRAW_DISABLED;
3125 return dwDrawFlags;
3126}
3127
3130CUIFButton2::OnPaintTheme(HDC hDC)
3131{
3132 //FIXME
3133 return FALSE;
3134}
3135
3136STDMETHODIMP_(void)
3137CUIFButton2::OnPaintNoTheme(HDC hDC)
3138{
3139 if (!m_pScheme)
3140 return;
3141
3145 if (!hdcMem)
3146 return;
3147
3149 if ( !hbmMem )
3150 {
3152 return;
3153 }
3154
3155 HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMem);
3156 HGDIOBJ hFontOld = ::SelectObject(hdcMem, m_hFont);
3157 RECT rcBack = { 0, 0, width, height };
3158
3159 INT cxText = 0, cyText = 0, cxContent = 0, cyContent = 0;
3160 INT cxyBorders, cxButton, cyButton;
3161 if (m_pszButtonText)
3162 {
3163 cxText = m_TextSize.cx;
3164 cyText = m_TextSize.cy;
3165 }
3166
3168 {
3169 cxContent = m_IconSize.cx;
3170 cyContent = m_IconSize.cy;
3171 }
3172 else if (m_hbmButton1)
3173 {
3174 cxContent = m_BitmapSize.cx;
3175 cyContent = m_BitmapSize.cy;
3176 }
3177
3179 {
3180 cxyBorders = ((cyText && cyContent) ? 2 : 0);
3181
3182 cxButton = cxContent;
3183 cyButton = cyText + cyContent + cxyBorders;
3184 if (cxText > cxContent)
3185 cxButton = cxText;
3186 }
3187 else
3188 {
3189 cxyBorders = ((cxText && cxContent) ? 2 : 0);
3190
3191 cxButton = cxText + cxContent + cxyBorders;
3192 cyButton = cyContent;
3193 if (cyText > cyButton)
3194 cyButton = cyText;
3195 }
3196
3199 xOffset = (rcBack.left + rcBack.right - cxButton) / 2;
3201 xOffset = rcBack.right - cxText - 2;
3202 else
3203 xOffset = rcBack.left + 2;
3204
3205
3207 yOffset = (rcBack.top + rcBack.bottom - cyButton) / 2;
3209 yOffset = rcBack.bottom - cyButton - 2;
3210 else
3211 yOffset = rcBack.top + 2;
3212
3213 RECT rc = { xOffset, yOffset, xOffset + cxButton, cyButton + yOffset };
3214 SIZE offsetSize = { 0, 0 };
3215 DWORD dwDrawFlags = MakeDrawFlag();
3216 m_pScheme->GetCtrlFaceOffset(((m_style & 0x200) ? 0xA5 : 0x54),
3217 dwDrawFlags,
3218 &offsetSize);
3219 ::OffsetRect(&rc, offsetSize.cx, offsetSize.cy);
3220
3221 RECT rcImage, rcText;
3222 if (m_style & UIF_BUTTON_VERTICAL)
3223 {
3224 rcImage.left = (rc.left + rc.right - cxContent) / 2;
3225 rcImage.top = rc.top;
3226 rcImage.right = rcImage.left + cxContent;
3227 rcImage.bottom = rc.top + cyContent;
3228 rcText.left = (rc.left + rc.right - cxText) / 2;
3229 rcText.top = rc.bottom - cyText;
3230 rcText.right = rcText.left + cxText;
3231 rcText.bottom = rc.bottom;
3232 }
3233 else
3234 {
3235 rcImage.left = rc.left;
3236 rcImage.top = (rc.top + rc.bottom - cyContent) / 2;
3237 rcImage.bottom = rcImage.top + cyContent;
3238 rcImage.right = rc.left + cxContent;
3239 rcText.left = rc.right - cxText;
3240 rcText.top = (rc.top + rc.bottom - cyText) / 2;
3241 rcText.right = rc.right;
3242 rcText.bottom = rcText.top + cyText;
3243 }
3244
3245 if (IsRTL())
3246 m_pScheme->m_bMirroring = TRUE;
3247
3248 m_pScheme->DrawCtrlBkgd(hdcMem,
3249 &rcBack,
3250 ((m_style & 0x200) ? 0xA5 : 0x54),
3251 dwDrawFlags);
3252 if (m_pszButtonText)
3253 {
3254 m_pScheme->DrawCtrlText(hdcMem, &rcText, m_pszButtonText, -1, dwDrawFlags,
3255 !!(m_style & UIF_BUTTON_VERTICAL));
3256 }
3257
3258 if (m_ButtonIcon.m_hIcon)
3259 m_pScheme->DrawCtrlIcon(hdcMem, &rcImage, m_ButtonIcon.m_hIcon, dwDrawFlags, &m_IconSize);
3260 else if (m_hbmButton1)
3261 m_pScheme->DrawCtrlBitmap(hdcMem, &rcImage, m_hbmButton1, m_hbmButton2, dwDrawFlags);
3262
3263 if (IsRTL())
3264 m_pScheme->m_bMirroring = FALSE;
3265
3266 m_pScheme->DrawCtrlEdge(hdcMem,
3267 &rcBack,
3268 ((m_style & 0x200) ? 0xA5 : 0x54),
3269 dwDrawFlags);
3270
3271 ::BitBlt(hDC, m_rc.left, m_rc.top, width, height, hdcMem, 0, 0, SRCCOPY);
3272 ::SelectObject(hdcMem, hFontOld);
3273 ::SelectObject(hdcMem, hbmOld);
3274 ::DeleteObject(hbmMem);
3275}
3276
3278// CUIFGripper
3279
3281 : CUIFObject(pParent, 0, prc, style)
3282{
3283 m_iStateId = 0;
3284 m_pszClassList = L"REBAR";
3287 else
3289}
3290
3292{
3293}
3294
3295STDMETHODIMP_(void)
3296CUIFGripper::OnMouseMove(LONG x, LONG y)
3297{
3298 if (IsCapture())
3299 {
3300 POINT pt;
3302 m_pWindow->Move(pt.x - m_ptGripper.x, pt.y - m_ptGripper.y, -1, -1);
3303 }
3304}
3305
3306STDMETHODIMP_(void)
3307CUIFGripper::OnLButtonDown(LONG x, LONG y)
3308{
3309 StartCapture();
3310 m_ptGripper.x = x;
3311 m_ptGripper.y = y;
3313 RECT rc;
3315 m_ptGripper.x -= rc.left;
3316 m_ptGripper.y -= rc.top;
3317}
3318
3319STDMETHODIMP_(void)
3320CUIFGripper::OnLButtonUp(LONG x, LONG y)
3321{
3322 if (IsCapture())
3323 EndCapture();
3324}
3325
3327CUIFGripper::OnPaintTheme(HDC hDC)
3328{
3330 return FALSE;
3331
3333 {
3334 m_rc.top += 2;
3335 m_rc.bottom -= 2;
3336 }
3337 else
3338 {
3339 m_rc.left += 2;
3340 m_rc.right -= 2;
3341 }
3342
3343 if (FAILED(DrawThemeBackground(hDC, 1, &m_rc, 0)))
3344 return FALSE;
3345
3346 return TRUE;
3347}
3348
3349STDMETHODIMP_(void)
3350CUIFGripper::OnPaintNoTheme(HDC hDC)
3351{
3352 if (m_pScheme)
3353 {
3354 m_pScheme->DrawDragHandle(hDC, &m_rc, !!(m_style & UIF_GRIPPER_VERTICAL));
3355 return;
3356 }
3357
3358 RECT rc;
3360 rc = { m_rc.left, m_rc.top + 1, m_rc.right, m_rc.top + 4 };
3361 else
3362 rc = { m_rc.left + 1, m_rc.top, m_rc.left + 4, m_rc.bottom };
3363
3365}
3366
3368CUIFGripper::OnSetCursor(UINT uMsg, LONG x, LONG y)
3369{
3371 ::SetCursor(hCursor);
3372 return TRUE;
3373}
3374
3375STDMETHODIMP_(void)
3376CUIFGripper::SetStyle(DWORD style)
3377{
3378 m_style = style;
3380 SetActiveTheme(L"REBAR", RP_GRIPPERVERT, 0);
3381 else
3382 SetActiveTheme(L"REBAR", RP_GRIPPER, 0);
3383}
3384
3386// CUIFToolbarMenuButton
3387
3390 DWORD nObjectID,
3391 LPCRECT prc,
3392 DWORD style) : CUIFButton2(pParent, nObjectID, prc, style)
3393{
3395
3396 HFONT hFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, SYMBOL_CHARSET,
3397 0, 0, 0, 0, L"Marlett");
3398 SetFont(hFont);
3399 SetText(L"u"); // downward triangle
3400}
3401
3403{
3405 SetFont(NULL);
3406}
3407
3408STDMETHODIMP_(void)
3409CUIFToolbarMenuButton::OnLButtonUp(LONG x, LONG y)
3410{
3411 CUIFButton::OnLButtonUp(x, y);
3412 m_pToolbarButton->OnUnknownMouse0();
3413}
3414
3416CUIFToolbarMenuButton::OnSetCursor(UINT uMsg, LONG x, LONG y)
3417{
3418 m_pToolbarButton->OnSetCursor(uMsg, x, y);
3419 return FALSE;
3420}
3421
3423// CUIFToolbarButtonElement
3424
3427 DWORD nObjectID,
3428 LPCRECT prc,
3429 DWORD style) : CUIFButton2(pParent, nObjectID, prc, style)
3430{
3432}
3433
3435CUIFToolbarButtonElement::GetToolTip()
3436{
3437 if (m_pToolbarButton)
3438 return m_pToolbarButton->GetToolTip();
3439 return NULL;
3440}
3441
3442STDMETHODIMP_(void)
3443CUIFToolbarButtonElement::OnLButtonUp(LONG x, LONG y)
3444{
3445 CUIFButton::OnLButtonUp(x, y);
3446 if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) == 0x20000)
3447 m_pToolbarButton->OnUnknownMouse0();
3448 else
3449 m_pToolbarButton->OnLeftClick();
3450}
3451
3452STDMETHODIMP_(void)
3453CUIFToolbarButtonElement::OnRButtonUp(LONG x, LONG y)
3454{
3455 if ((m_pToolbarButton->m_dwToolbarButtonFlags & 0x30000) != 0x20000)
3456 m_pToolbarButton->OnRightClick();
3457}
3458
3460// CUIFToolbarButton
3461
3464 DWORD nObjectID,
3465 LPCRECT prc,
3466 DWORD style,
3467 DWORD dwToolbarButtonFlags,
3468 LPCWSTR pszUnknownText) : CUIFObject(pParent, nObjectID, prc, style)
3469{
3470 m_dwToolbarButtonFlags = dwToolbarButtonFlags;
3471 m_pszUnknownText = pszUnknownText;
3472}
3473
3475{
3476 RECT rc1, rc2;
3477 rc1 = rc2 = m_rc;
3478
3479 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000)
3480 {
3481 rc1.right -= 12;
3482 rc2.left = rc1.right + 1;
3483 }
3484
3486 if (m_dwToolbarButtonFlags & 0x2000)
3487 style |= 0x10;
3488 if (m_dwToolbarButtonFlags & 0x80000)
3492 return FALSE;
3493
3494 m_pToolbarButtonElement->Initialize();
3495 AddUIObj(m_pToolbarButtonElement);
3496
3497 if (!m_bEnable)
3499
3500 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000)
3501 {
3503 if (m_dwToolbarButtonFlags & 0x80000)
3505
3508 return FALSE;
3509
3510 m_pToolbarMenuButton->Initialize();
3511 AddUIObj(m_pToolbarMenuButton);
3512
3513 if (!m_bEnable)
3514 m_pToolbarMenuButton->Enable(FALSE);
3515 }
3516
3517 return TRUE;
3518}
3519
3521{
3523}
3524
3526{
3528}
3529
3530STDMETHODIMP_(void)
3531CUIFToolbarButton::ClearWndObj()
3532{
3534 m_pToolbarButtonElement->ClearWndObj();
3536 m_pToolbarMenuButton->ClearWndObj();
3537
3538 CUIFObject::ClearWndObj();
3539}
3540
3541STDMETHODIMP_(void)
3542CUIFToolbarButton::DetachWndObj()
3543{
3545 m_pToolbarButtonElement->DetachWndObj();
3547 m_pToolbarMenuButton->DetachWndObj();
3548
3549 CUIFObject::DetachWndObj();
3550}
3551
3552STDMETHODIMP_(void)
3553CUIFToolbarButton::Enable(BOOL bEnable)
3554{
3555 CUIFObject::Enable(bEnable);
3560}
3561
3563CUIFToolbarButton::GetToolTip()
3564{
3565 return CUIFObject::GetToolTip();
3566}
3567
3568STDMETHODIMP_(void)
3569CUIFToolbarButton::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId)
3570{
3572 m_pToolbarButtonElement->SetActiveTheme(pszClassList, iPartId, iStateId);
3574 m_pToolbarMenuButton->SetActiveTheme(pszClassList, iPartId, iStateId);
3575
3576 m_pszClassList = pszClassList;
3579}
3580
3581STDMETHODIMP_(void)
3582CUIFToolbarButton::SetFont(HFONT hFont)
3583{
3585}
3586
3587STDMETHODIMP_(void)
3588CUIFToolbarButton::SetRect(LPCRECT prc)
3589{
3590 CUIFObject::SetRect(prc);
3591
3592 RECT rc1, rc2;
3593 rc1 = rc2 = m_rc;
3594
3595 if ((m_dwToolbarButtonFlags & 0x30000) == 0x30000)
3596 {
3597 rc1.right -= 12;
3598 rc2.left = rc1.right + 1;
3599 }
3600
3602 m_pToolbarButtonElement->SetRect(&rc1);
3604 m_pToolbarMenuButton->SetRect(&rc2);
3605}
3606
3607STDMETHODIMP_(void)
3608CUIFToolbarButton::SetToolTip(LPCWSTR pszToolTip)
3609{
3610 CUIFObject::SetToolTip(pszToolTip);
3612 m_pToolbarButtonElement->SetToolTip(pszToolTip);
3614 m_pToolbarMenuButton->SetToolTip(pszToolTip);
3615}
3616
3618// CUIFWndFrame
3619
3622 LPCRECT prc,
3624{
3625 m_iPartId = 7;
3626 m_iStateId = 0;
3627 m_pszClassList = L"WINDOW";
3628 m_dwHitTest = 0;
3629 m_cxFrame = m_cyFrame = 0;
3630
3631 if (m_pScheme)
3632 {
3633 if ((m_style & 0xF) && (m_style & 0xF) <= 2)
3634 {
3635 m_cxFrame = m_pScheme->CxSizeFrame();
3636 m_cyFrame = m_pScheme->CySizeFrame();
3637 }
3638 else
3639 {
3640 m_cxFrame = m_pScheme->CxWndBorder();
3641 m_cyFrame = m_pScheme->CyWndBorder();
3642 }
3643 }
3644
3647}
3648
3650{
3651 pSize->cx = m_cxFrame;
3652 pSize->cy = m_cyFrame;
3653}
3654
3656{
3657 DWORD dwFlags = 0;
3658 if ( m_rc.left <= x && x < m_rc.left + m_cxFrame)
3659 dwFlags |= 0x10;
3660 if (m_rc.top <= y && y < m_rc.top + m_cyFrame )
3661 dwFlags |= 0x20;
3662 if (m_rc.right - m_cxFrame <= x && x < m_rc.right)
3663 dwFlags |= 0x40;
3664 if (m_rc.bottom - m_cyFrame <= y && y < m_rc.bottom)
3665 dwFlags |= 0x80;
3666 return dwFlags;
3667}
3668
3669STDMETHODIMP_(void)
3670CUIFWndFrame::OnMouseMove(LONG x, LONG y)
3671{
3672 if (!IsCapture())
3673 return;
3674
3675 POINT Point;
3677
3678 RECT rc = m_rcWnd;
3679
3680 if (m_dwHitTest & 0x10)
3681 rc.left = Point.x + m_rcWnd.left - m_ptHit.x;
3682
3683 if (m_dwHitTest & 0x20)
3684 rc.top = Point.y + m_rcWnd.top - m_ptHit.y;
3685
3686 if (m_dwHitTest & 0x40)
3687 {
3688 rc.right = Point.x + m_rcWnd.right - m_ptHit.x;
3689 if (rc.right <= rc.left + m_cxMin)
3690 rc.right = rc.left + m_cxMin;
3691 }
3692
3693 if (m_dwHitTest & 0x80)
3694 {
3695 rc.bottom = Point.y + m_rcWnd.bottom - m_ptHit.y;
3696 if (rc.bottom <= rc.top + m_cyMin)
3697 rc.bottom = rc.top + m_cyMin;
3698 }
3699
3700 m_pWindow->Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
3701}
3702
3703STDMETHODIMP_(void)
3704CUIFWndFrame::OnLButtonDown(LONG x, LONG y)
3705{
3706 POINT Point = { x, y };
3707 DWORD hitTest = m_style & HitTest(x, y);
3708 if (!hitTest)
3709 return;
3710
3712 m_ptHit = Point;
3714 m_dwHitTest = hitTest;
3716 StartCapture();
3717}
3718
3719STDMETHODIMP_(void)
3720CUIFWndFrame::OnLButtonUp(LONG x, LONG y)
3721{
3722 if (IsCapture())
3723 EndCapture();
3724}
3725
3727CUIFWndFrame::OnPaintTheme(HDC hDC)
3728{
3730 return FALSE;
3731
3732 RECT rc = m_rc;
3733 rc.right = m_cxFrame;
3734 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 1, NULL)))
3735 return FALSE;
3736
3737 rc = m_rc;
3738 rc.left = rc.right - m_cxFrame;
3739 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 4, NULL)))
3740 return FALSE;
3741
3742 rc = m_rc;
3743 rc.bottom = m_cyFrame;
3744 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 5, 2, NULL)))
3745 return FALSE;
3746
3747 rc = m_rc;
3748 rc.top = rc.bottom - m_cyFrame;
3749 if (FAILED(DrawThemeEdge(hDC, 0, &rc, 10, 8, NULL)))
3750 return FALSE;
3751
3752 return TRUE;
3753}
3754
3755STDMETHODIMP_(void)
3756CUIFWndFrame::OnPaintNoTheme(HDC hDC)
3757{
3758 if (!m_pScheme)
3759 return;
3760
3761 DWORD type = 0;
3762 if ((m_style & 0xF) == 1)
3763 type = 1;
3764 else if ( (m_style & 0xF) == 2 )
3765 type = 2;
3766
3767 m_pScheme->DrawWndFrame(hDC, &m_rc, type, m_cxFrame, m_cyFrame);
3768}
3769
3771CUIFWndFrame::OnSetCursor(UINT uMsg, LONG x, LONG y)
3772{
3773 DWORD dwHitTest = m_dwHitTest;
3774 if (!IsCapture())
3775 dwHitTest = m_style & HitTest(x, y);
3776
3777 LPTSTR pszCursor = NULL;
3778 switch (dwHitTest)
3779 {
3780 case 0x30:
3781 case 0xC0:
3782 pszCursor = IDC_SIZENWSE;
3783 break;
3784 case 0x90:
3785 case 0x60:
3786 pszCursor = IDC_SIZENESW;
3787 break;
3788 case 0x10:
3789 case 0x40:
3790 pszCursor = IDC_SIZEWE;
3791 break;
3792 case 0x20:
3793 case 0x80:
3794 pszCursor = IDC_SIZENS;
3795 break;
3796 default:
3797 return FALSE;
3798 }
3799
3800 HCURSOR hCursor = ::LoadCursor(NULL, pszCursor);
3801 ::SetCursor(hCursor);
3802 return TRUE;
3803}
3804
3806// CUIFBalloonButton
3807
3810 DWORD nObjectID,
3811 LPCRECT prc,
3812 DWORD style) : CUIFButton(pParent, nObjectID, prc, style)
3813{
3814 m_nCommandID = 0;
3815}
3816
3817STDMETHODIMP_(void)
3818CUIFBalloonButton::OnPaint(HDC hDC)
3819{
3820 RECT rc = m_rc;
3821 ::OffsetRect(&rc, -rc.left, -rc.top);
3822
3823 HDC hMemDC = ::CreateCompatibleDC(hDC);
3825 HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmMem);
3826
3827 BOOL bPressed;
3828 COLORREF rgbShadow, rgbBorder;
3829 if (m_uButtonStatus == 1)
3830 {
3831 bPressed = TRUE;
3832 rgbShadow = ::GetSysColor(COLOR_BTNSHADOW);
3833 rgbBorder = ::GetSysColor(COLOR_BTNHIGHLIGHT);
3834 }
3835 else
3836 {
3837 bPressed = FALSE;
3838 if (m_uButtonStatus < 4)
3839 {
3840 rgbShadow = ::GetSysColor(COLOR_BTNHIGHLIGHT);
3841 rgbBorder = ::GetSysColor(COLOR_BTNSHADOW);
3842 }
3843 else
3844 {
3845 rgbShadow = ::GetSysColor(COLOR_INFOBK);
3846 rgbBorder = ::GetSysColor(COLOR_INFOBK);
3847 }
3848 }
3849
3850 COLORREF rgbInfoBk = ::GetSysColor(COLOR_INFOBK);
3851 HBRUSH hbrBack = ::CreateSolidBrush(rgbInfoBk);
3852 ::FillRect(hMemDC, &rc, hbrBack);
3853 ::DeleteObject(hbrBack);
3854
3855 DrawTextProc(hMemDC, &rc, bPressed);
3856
3857 HBRUSH hNullBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
3858 HGDIOBJ hbrOld = ::SelectObject(hMemDC, hNullBrush);
3859
3860 HPEN hPen = ::CreatePen(PS_SOLID, 0, rgbShadow);
3861 HGDIOBJ hPenOld = ::SelectObject(hMemDC, hPen);
3862 ::RoundRect(hMemDC, rc.left, rc.top, rc.right - 1, rc.bottom - 1, 6, 6);
3863 ::SelectObject(hMemDC, hPenOld);
3864 ::DeleteObject(hPen);
3865
3866 hPen = ::CreatePen(PS_SOLID, 0, rgbBorder);
3867 hPenOld = ::SelectObject(hMemDC, hPen);
3868 ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right, rc.bottom, 6, 6);
3869 ::SelectObject(hMemDC, hPenOld);
3870 ::DeleteObject(hPen);
3871
3873 hPenOld = ::SelectObject(hMemDC, hPen);
3874 ::RoundRect(hMemDC, rc.left + 1, rc.top + 1, rc.right - 1, rc.bottom - 1, 6, 6);
3875 ::SelectObject(hMemDC, hPenOld);
<