soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SCmnCtrl.cpp
1//////////////////////////////////////////////////////////////////////////
2// File Name: duicmnctrl.h
3//////////////////////////////////////////////////////////////////////////
4
5#include "souistd.h"
6#include "control/SCmnCtrl.h"
7
8SNSBEGIN
9
10//////////////////////////////////////////////////////////////////////////
11// Static Control
12//
13
15 : m_nLineInter(5)
16 , m_bWordbreak(false)
17{
18 m_bMsgTransparent = TRUE;
19 m_style.SetAlign(DT_LEFT);
20}
21
22void SStatic::DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
23{
24 if (!GetStyle().GetMultiLines())
25 {
26 OnDrawLine(pRT, pszBuf, 0, cchText, pRect, uFormat);
27 }
28 else
29 {
30 if (uFormat & (DT_VCENTER | DT_BOTTOM) && !(uFormat & DT_CALCRECT))
31 {
32 // static 多行控件支持垂直居中及底对齐
33 CRect rcText = *pRect;
34 DrawMultiLine(pRT, pszBuf, cchText, &rcText, uFormat | DT_CALCRECT);
35 CSize szTxt = rcText.Size();
36 rcText = *pRect;
37 switch (GetStyle().GetTextAlign() & (DT_VCENTER | DT_BOTTOM))
38 {
39 case DT_VCENTER:
40 rcText.DeflateRect(0, (rcText.Height() - szTxt.cy) / 2);
41 break;
42 case DT_BOTTOM:
43 rcText.DeflateRect(0, (rcText.Height() - szTxt.cy));
44 break;
45 }
46 DrawMultiLine(pRT, pszBuf, cchText, &rcText, uFormat);
47 }
48 else
49 {
50 DrawMultiLine(pRT, pszBuf, cchText, pRect, uFormat);
51 }
52 }
53}
54
55void SStatic::OnDrawLine(IRenderTarget *pRT, LPCTSTR pszBuf, int iBegin, int cchText, LPRECT pRect, UINT uFormat)
56{
57 pRT->DrawText(pszBuf + iBegin, cchText, pRect, uFormat);
58}
59
60static bool IsAlpha(TCHAR c)
61{
62 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
63}
64
65static bool IsNumber(TCHAR c)
66{
67 return c >= '0' && c <= '9';
68}
69
70static bool IsHex(TCHAR c)
71{
72 return IsNumber(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
73}
74
75static bool IsDigit(TCHAR c)
76{
77 return IsNumber(c) || c == '.' || c == ',';
78}
79
80static LPCTSTR SkipWord(LPCTSTR p)
81{
82 if (IsAlpha(*p))
83 {
84 while (*p)
85 {
86 p = CharNext(p);
87 if (!IsAlpha(*p))
88 break;
89 }
90 }
91 return p;
92}
93
94static LPCTSTR SkipNumber(LPCTSTR p)
95{
96 if (*p && *(p + 1) && (_tcsncmp(p, _T("0x"), 2) == 0 || _tcsncmp(p, _T("0X"), 2) == 0))
97 { // test for hex number
98 p = p + 2;
99 while (*p)
100 {
101 if (!IsHex(*p))
102 break;
103 p++;
104 }
105 return p;
106 }
107 else
108 {
109 while (*p)
110 {
111 if (!IsDigit(*p))
112 break;
113 p++;
114 }
115 return p;
116 }
117}
118
119static LPCTSTR WordNext(LPCTSTR pszBuf, bool bWordbreak)
120{
121 SASSERT(pszBuf);
122 LPCTSTR p = CharNext(pszBuf);
123 if (!bWordbreak)
124 return p;
125 LPCTSTR pWord = SkipWord(pszBuf);
126 if (pWord > pszBuf)
127 return pWord;
128 LPCTSTR pNum = SkipNumber(pszBuf);
129 if (pNum > pszBuf)
130 return pNum;
131 return p;
132}
133
134void SStatic::DrawMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
135{
136 int i = 0, nLine = 1;
137 if (cchText == -1)
138 cchText = (int)_tcslen(pszBuf);
139 LPCTSTR p1 = pszBuf;
140 POINT pt = { pRect->left, pRect->top };
141 SIZE szWord = OnMeasureText(pRT, _T("A"), 1);
142 int nLineHei = szWord.cy;
143 int nRight = pRect->right;
144 int nLineWid = pRect->right - pRect->left;
145 pRect->right = pRect->left;
146
147 LPCTSTR pLineHead = p1, pLineTail = p1;
148
149 LPCTSTR pPrev = NULL;
150 while (i < cchText)
151 {
152 LPCTSTR p2 = WordNext(p1, m_bWordbreak);
153 SASSERT(p2 > p1);
154 if ((*p1 == _T('\n') && p2))
155 {
156 if (pLineTail > pLineHead && !(uFormat & DT_CALCRECT))
157 {
158 CRect rcText(pRect->left, pt.y, nRight, pt.y + nLineHei);
159 OnDrawLine(pRT, pszBuf, (int)(pLineHead - pszBuf), (int)(pLineTail - pLineHead), &rcText, uFormat);
160 }
161 pt.y += nLineHei + m_nLineInter;
162 pt.x = pRect->left;
163 nLine++;
164 i += (int)(p2 - p1);
165 p1 = p2;
166 pLineHead = p2;
167 continue;
168 }
169 if (m_bWordbreak && *p1 == 0x20 && pt.x == pRect->left && (!pPrev || *pPrev != 0x20))
170 { // skip the first space for a new line.
171 i += (int)(p2 - p1);
172 pPrev = p1;
173 p1 = p2;
174 pLineTail = pLineHead = p2;
175 continue;
176 }
177 szWord = OnMeasureText(pRT, p1, (int)(p2 - p1));
178 if (pt.x + szWord.cx > nRight)
179 { //检测到一行超过边界时还要保证当前行不为空
180
181 if (pLineTail > pLineHead)
182 {
183 if (!(uFormat & DT_CALCRECT))
184 {
185 CRect rcText(pRect->left, pt.y, nRight, pt.y + nLineHei);
186 OnDrawLine(pRT, pszBuf, (int)(pLineHead - pszBuf), (int)(pLineTail - pLineHead), &rcText, uFormat);
187 }
188
189 // modify by baozi 20190312
190 // 显示多行文本时,如果下一行文字的高度超过了文本框,则不再输出下一行文字内容。
191 if (pt.y + nLineHei + m_nLineInter > pRect->bottom)
192 { //将绘制限制在有效区。
193 pLineHead = pLineTail;
194 break;
195 }
196
197 pLineHead = p1;
198
199 pt.y += nLineHei + m_nLineInter;
200 pt.x = pRect->left;
201 nLine++;
202
203 continue;
204 }
205 else
206 { // word is too long to draw in a single line
207 LPCTSTR p3 = p1;
208 SIZE szChar;
209 szWord.cx = 0;
210 while (p3 < p2)
211 {
212 LPCTSTR p4 = CharNext(p3);
213 szChar = OnMeasureText(pRT, p3, (int)(p4 - p3));
214 if (szWord.cx + szChar.cx > nLineWid)
215 {
216 if (p3 == p1)
217 { // a line will contain at least one char.
218 p2 = p4;
219 szWord.cx = szChar.cx;
220 }
221 else
222 {
223 p2 = p3;
224 }
225 break;
226 }
227 szWord.cx += szChar.cx;
228 p3 = p4;
229 }
230 }
231 }
232 pt.x += szWord.cx;
233 if (pt.x > pRect->right && uFormat & DT_CALCRECT)
234 pRect->right = pt.x;
235 i += (int)(p2 - p1);
236 pPrev = p1;
237 pLineTail = p1 = p2;
238 }
239
240 if (uFormat & DT_CALCRECT)
241 {
242 if (pRect->bottom > pt.y + nLineHei)
243 pRect->bottom = pt.y + nLineHei;
244 }
245 else if (pLineTail > pLineHead)
246 {
247 CRect rcText(pRect->left, pt.y, nRight, pt.y + nLineHei);
248 OnDrawLine(pRT, pszBuf, (int)(pLineHead - pszBuf), (int)(pLineTail - pLineHead), &rcText, uFormat);
249 }
250}
251
252SIZE SStatic::OnMeasureText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText)
253{
254 SIZE szRet = { 0 };
255 pRT->MeasureText(pszBuf, cchText, &szRet);
256 return szRet;
257}
258
259//////////////////////////////////////////////////////////////////////////
260// Link Control
261// Only For Header Drag Test
262// Usage: <link>inner text example</link>
263//
264
266{
267 m_style.SetAlign(DT_LEFT);
268}
269
270void SLink::DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
271{
272 if (!(uFormat & DT_CALCRECT))
273 {
274 CRect rc;
275 pRT->DrawText(pszBuf, cchText, &rc, DT_LEFT | DT_CALCRECT);
276
277 if (m_style.GetTextAlign() & DT_CENTER)
278 {
279 m_rcText.left = pRect->left + (pRect->right - pRect->left - rc.Width()) / 2;
280 m_rcText.right = m_rcText.left + rc.Width();
281 }
282 else if (m_style.GetTextAlign() & DT_RIGHT)
283 {
284 m_rcText.left = pRect->right - rc.Width();
285 m_rcText.right = pRect->right;
286 }
287 else
288 {
289 m_rcText.left = pRect->left;
290 m_rcText.right = pRect->left + rc.Width();
291 }
292
293 if (m_style.GetTextAlign() & DT_VCENTER)
294 {
295 m_rcText.top = pRect->top + (pRect->bottom - pRect->top - rc.Height()) / 2;
296 m_rcText.bottom = m_rcText.top + rc.Height();
297 }
298 else if (m_style.GetTextAlign() & DT_BOTTOM)
299 {
300 m_rcText.bottom = m_rcText.bottom;
301 m_rcText.top = m_rcText.bottom - rc.Height();
302 }
303 else
304 {
305 m_rcText.top = m_rcText.top;
306 m_rcText.bottom = m_rcText.top + rc.Height();
307 }
308 }
309 __baseCls::DrawText(pRT, pszBuf, cchText, pRect, uFormat);
310}
311
313{
314 __baseCls::OnInitFinished(pNode);
315 if (m_strToolTipText.GetText(TRUE).IsEmpty())
317}
318
319BOOL SLink::OnSetCursor(const CPoint &pt)
320{
321 if (!m_rcText.PtInRect(pt))
322 return FALSE;
323 HCURSOR hCursor = GETRESPROVIDER->LoadCursor(m_style.m_strCursor);
324 ::SetCursor(hCursor);
325 return TRUE;
326}
327
328void SLink::OnLButtonDown(UINT nFlags, CPoint pt)
329{
330 if (!m_rcText.PtInRect(pt))
331 return;
332 __baseCls::OnLButtonDown(nFlags, pt);
333}
334
335void SLink::OnLButtonUp(UINT nFlags, CPoint pt)
336{
337 if (!m_rcText.PtInRect(pt))
338 {
340 return;
341 }
342 __baseCls::OnLButtonUp(nFlags, pt);
343
344 SStringT strUrl = m_strLinkUrl;
345 if (m_strLinkUrl.IsEmpty())
346 strUrl = GetWindowText();
347 ::ShellExecute(NULL, _T("open"), strUrl, NULL, NULL, SW_SHOWNORMAL);
348}
349
350void SLink::OnMouseMove(UINT nFlags, CPoint pt)
351{
352 if (!m_rcText.PtInRect(pt))
353 {
355 OnMouseLeave();
356 }
357 else
358 {
359 if (!(m_dwState & WndState_Hover))
360 OnMouseHover(nFlags, pt);
361 }
362}
363
364void SLink::OnMouseHover(WPARAM wParam, CPoint pt)
365{
366 if (!m_rcText.PtInRect(pt))
367 return;
368 SWindow::OnMouseHover((UINT)wParam, pt);
369}
370//////////////////////////////////////////////////////////////////////////
371// Button Control
372// Use id attribute to process click event
373//
374// Usage: <button name=xx skin=xx>inner text example</button>
375//
376
378 : m_accel(0)
379 , m_bAnimate(FALSE)
380 , m_byAlphaAni(0xFF)
381 , m_nAniStep(25)
383{
384 m_pBgSkin = GETBUILTINSKIN(SKIN_SYS_BTN_NORMAL);
385 m_bFocusable = TRUE;
386}
387
389{
390 if (!m_pBgSkin)
391 return;
392 CRect rcClient;
393 GetClientRect(&rcClient);
394 if (m_byAlphaAni == 0xFF)
395 { //不在动画过程中
396 m_pBgSkin->DrawByState(pRT, rcClient, GetState());
397 }
398 else
399 { //在动画过程中
400 BYTE byNewAlpha = (BYTE)(((UINT)m_byAlphaAni * m_pBgSkin->GetAlpha()) >> 8);
401 if (GetState() & WndState_Hover)
402 {
403 // get hover
404 m_pBgSkin->DrawByState2(pRT, rcClient, WndState_Normal, m_pBgSkin->GetAlpha());
405 m_pBgSkin->DrawByState2(pRT, rcClient, WndState_Hover, byNewAlpha);
406 }
407 else
408 {
409 // lose hover
410 m_pBgSkin->DrawByState2(pRT, rcClient, WndState_Normal, m_pBgSkin->GetAlpha());
411 m_pBgSkin->DrawByState2(pRT, rcClient, WndState_Hover, m_pBgSkin->GetAlpha() - byNewAlpha);
412 }
413 }
414
415 SWindow::OnPaint(pRT);
416}
417
418void SButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
419{
420 if (nChar == VK_SPACE || nChar == VK_RETURN)
421 {
423 }
424 else
425 {
426 SetMsgHandled(FALSE);
427 }
428}
429
430void SButton::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
431{
432 if (nChar == VK_SPACE || nChar == VK_RETURN)
433 {
435 {
437 FireCommand();
438 }
439 }
440 else
441 {
442 SetMsgHandled(FALSE);
443 }
444}
445
447{
448 if (IsDisabled(TRUE))
449 return FALSE;
451 return FALSE;
452 FireCommand();
453 return TRUE;
454}
455
457{
458 BOOL bRet = SWindow::InitFromXml(pNode);
459 SStringT strText = GetWindowText(TRUE);
460
461 if (!strText.IsEmpty() && (strText[strText.GetLength() - 1] == _T(')')))
462 {
463 int pos = strText.ReverseFind(_T('('));
464 if ((pos != -1) && (strText[++pos] == _T('&')))
465 {
466 SStringT strAccelT = _T("alt+");
467 strAccelT += strText[++pos];
469 if (m_accel)
470 {
473 }
474 }
475 }
476 return bRet;
477}
478
480{
481 if (m_accel)
482 {
485 }
487 __baseCls::OnDestroy();
488}
489
490HRESULT SButton::OnAttrAccel(SStringW strAccel, BOOL bLoading)
491{
492 SStringT strAccelT = S_CW2T(strAccel);
493 if (m_accel)
494 {
497 }
499 if (m_accel)
500 {
503 }
504 return S_FALSE;
505}
506
507void SButton::OnStateChanged(DWORD dwOldState, DWORD dwNewState)
508{
509 __baseCls::OnStateChanged(dwOldState, dwNewState);
511
512 if (GetCapture() == m_swnd) //点击中
513 return;
514
515 if (m_bAnimate && ((dwOldState == WndState_Normal && dwNewState == WndState_Hover) || (dwOldState == WndState_Hover && dwNewState == WndState_Normal)))
516 { //启动动画
517 m_byAlphaAni = 50;
519 }
520}
521
522void SButton::OnSize(UINT nType, CSize size)
523{
524 __baseCls::OnSize(nType, size);
526}
527
528//中止原来的动画
534
536{
538 if (m_byAlphaAni >= 0xFF)
539 {
540 m_byAlphaAni = 0xFF;
542 }
543 Invalidate();
544}
545
547{
548 if (pOldContainer)
549 pOldContainer->UnregisterTimelineHandler(this);
550 SWindow::OnContainerChanged(pOldContainer, pNewContainer);
551}
552
553//////////////////////////////////////////////////////////////////////////
558
559SIZE SImageButton::MeasureContent(int wid, int hei)
560{
561 if (!m_pBgSkin)
562 return CSize(0, 0);
563 return m_pBgSkin->GetSkinSize();
564}
565//////////////////////////////////////////////////////////////////////////
566// Image Control
567// Use src attribute specify a resource id
568//
569// Usage: <img skin="skin" sub="0"/>
570//
572 : m_iIcon(0)
573 , m_pSkin(NULL)
574 , m_fl(kNone_FilterLevel)
575 , m_bManaged(FALSE)
576 , m_iTile(0)
577 , m_bKeepAspect(0)
578{
579 m_bMsgTransparent = TRUE;
580}
581
583{
584 if (m_bManaged && m_pSkin)
585 {
586 m_pSkin->Release();
587 }
588 m_pSkin = NULL;
589}
590
592{
593 CRect rcWnd = GetWindowRect();
594 if (rcWnd.IsRectEmpty())
595 return;
596 if (m_bKeepAspect)
597 {
598 CSize szImg;
599 if (m_pImg)
600 szImg = m_pImg->Size();
601 else if (m_pSkin)
602 szImg = m_pSkin->GetSkinSize();
603 if (szImg.cx == 0 || szImg.cy == 0)
604 return;
605
606 float fWndRatio = rcWnd.Width() * 1.0f / rcWnd.Height();
607 float fImgRatio = szImg.cx * 1.0f / szImg.cy;
608 if (fWndRatio > fImgRatio)
609 {
610 int nWid = (int)(rcWnd.Height() * fImgRatio);
611 rcWnd.DeflateRect((rcWnd.Width() - nWid) / 2, 0);
612 }
613 else
614 {
615 int nHei = (int)(rcWnd.Width() / fImgRatio);
616 rcWnd.DeflateRect(0, (rcWnd.Height() - nHei) / 2);
617 }
618 }
619
620 if (m_pImg)
621 {
622 CRect rcImg(CPoint(0, 0), m_pImg->Size());
623 if (m_iTile == 0)
624 pRT->DrawBitmapEx(rcWnd, m_pImg, &rcImg, MAKELONG(EM_STRETCH, m_fl), 0xff);
625 else if (m_iTile == 1)
626 pRT->DrawBitmapEx(rcWnd, m_pImg, &rcImg, MAKELONG(EM_NULL, m_fl), 0xff);
627 else if (m_iTile == 2)
628 pRT->DrawBitmapEx(rcWnd, m_pImg, &rcImg, MAKELONG(EM_TILE, m_fl), 0xff);
629 }
630 else if (m_pSkin)
631 {
632 m_pSkin->DrawByIndex(pRT, rcWnd, m_iIcon);
633 }
634}
635
636BOOL SImageWnd::SetSkin(ISkinObj *pSkin, int iFrame /*=0*/, BOOL bAutoFree /*=TRUE*/)
637{
638 if (IsVisible(TRUE))
639 Invalidate();
640 if (m_bManaged && m_pSkin)
641 {
642 m_pSkin->Release();
643 m_pSkin = NULL;
644 m_bManaged = FALSE;
645 }
646 if (!pSkin)
647 return FALSE;
648 m_pSkin = pSkin;
649 m_iIcon = iFrame;
650 m_pImg = NULL;
651 if (bAutoFree)
652 {
653 m_pSkin->AddRef();
654 m_bManaged = TRUE;
655 }
656 else
657 {
658 m_bManaged = FALSE;
659 }
660
661 SASSERT(GetParent());
662
663 if (GetLayoutParam()->IsWrapContent(Any) && GetParent())
664 {
665 //重新计算坐标
667 }
668 if (IsVisible(TRUE))
669 Invalidate();
670 return TRUE;
671}
672
673void SImageWnd::SetImage(IBitmapS *pBitmap, FilterLevel fl)
674{
675 m_pImg = pBitmap;
676 m_fl = fl;
678}
679
681{
682 return m_pImg;
683}
684
685BOOL SImageWnd::SetIcon(int nSubID)
686{
687 if (!m_pSkin)
688 return FALSE;
689 if (nSubID < 0 || nSubID > m_pSkin->GetStates() - 1)
690 return FALSE;
691 m_iIcon = nSubID;
692 Invalidate();
693 return TRUE;
694}
695
696SIZE SImageWnd::MeasureContent(int wid, int hei)
697{
698 CSize szRet;
699 if (m_pImg)
700 szRet = m_pImg->Size();
701 else if (m_pSkin)
702 szRet = m_pSkin->GetSkinSize();
703 CRect rcPadding = GetStyle().GetPadding();
704 szRet.cx += rcPadding.left + rcPadding.right;
705 szRet.cy += rcPadding.top + rcPadding.bottom;
706 return szRet;
707}
708
709void SImageWnd::OnColorize(COLORREF cr)
710{
711 __baseCls::OnColorize(cr);
712 if (m_pSkin)
713 m_pSkin->OnColorize(cr);
714}
715
717{
718 __baseCls::OnScaleChanged(scale);
719 GetScaleSkin(m_pSkin, scale);
720}
721
723{
724 return m_pSkin;
725}
726
728 : m_pSkin(NULL)
729 , m_iCurFrame(0)
730 , m_nSpeed(50)
731 , m_bAutoStart(TRUE)
732 , m_bPlaying(FALSE)
733 , m_iTimeFrame(0)
734 , m_nRepeat(-1)
735 , m_iRepeat(0)
736{
737 m_bMsgTransparent = TRUE;
738 GetEventSet()->addEvent(EVENTID(EventImageAnimateStart));
739 GetEventSet()->addEvent(EVENTID(EventImageAnimateStop));
740 GetEventSet()->addEvent(EVENTID(EventImageAnimateRepeat));
741}
742
744{
745 if (m_pSkin)
746 m_pSkin->DrawByIndex(pRT, GetWindowRect(), m_iCurFrame);
747}
748
750{
751 if (!m_bPlaying)
752 {
753 if (IsVisible(TRUE))
755 m_iRepeat = 0;
756 m_bPlaying = TRUE;
757 m_iCurFrame = 0;
758 EventImageAnimateStart evt(this);
759 FireEvent(evt);
760 }
761}
762
764{
765 if (m_bPlaying)
766 {
767 m_bPlaying = FALSE;
768 EventImageAnimateStop evt(this);
769 FireEvent(evt);
770 }
772}
773
775{
776 Stop();
777 __baseCls::OnDestroy();
778}
779
780SIZE SAnimateImgWnd::MeasureContent(int wid, int hei)
781{
782 CSize szRet;
783 if (m_pSkin)
784 szRet = m_pSkin->GetSkinSize();
785 return szRet;
786}
787
788void SAnimateImgWnd::OnShowWindow(BOOL bShow, UINT nStatus)
789{
790 __baseCls::OnShowWindow(bShow, nStatus);
791 if (!bShow)
792 {
793 if (IsPlaying())
795 }
796 else
797 {
798 if (IsPlaying())
800 else if (m_bAutoStart)
801 Start();
802 }
803}
804
806{
807 if (!m_pSkin)
809 else
810 {
811 if (m_iTimeFrame > (m_nSpeed / 10))
812 m_iTimeFrame = 0;
813 if (m_iTimeFrame == 0)
814 {
815 int nStates = m_pSkin->GetStates();
816 m_iCurFrame++;
817 Invalidate();
818
819 if (m_iCurFrame == nStates)
820 {
821 m_iCurFrame = 0;
822 if (m_nRepeat != -1 && ++m_iRepeat == m_nRepeat)
823 { //检查重复次数
824 Stop();
825 }
826 else
827 {
828 EventImageAnimateRepeat evt(this);
829 FireEvent(evt);
830 }
831 }
832 }
833 m_iTimeFrame++;
834 }
835}
836
838{
839 __baseCls::OnColorize(cr);
840 if (m_pSkin)
841 m_pSkin->OnColorize(cr);
842}
843
845{
846 if (IsPlaying())
847 {
848 if (pOldContainer)
849 pOldContainer->UnregisterTimelineHandler(this);
850 if (pNewContainer)
851 pNewContainer->RegisterTimelineHandler(this);
852 }
853 SWindow::OnContainerChanged(pOldContainer, pNewContainer);
854}
855
857{
858 __baseCls::OnScaleChanged(scale);
859 GetScaleSkin(m_pSkin, scale);
860}
861
862//////////////////////////////////////////////////////////////////////////
863// Progress Control
864// Use id attribute to process click event
865//
866// Usage: <progress bgskin=xx posskin=xx min=0 max=100 value=10,showpercent=0/>
867//
868
870 : m_nMinValue(0)
871 , m_nMaxValue(100)
872 , m_nValue(0)
873 , m_bShowPercent(FALSE)
874 , m_pSkinBg(NULL)
875 , m_pSkinPos(NULL)
876 , m_bVertical(FALSE)
877{
878 m_bFocusable = TRUE;
879}
880
881void SProgress::GetDesiredSize(SIZE *psz, int wid, int hei)
882{
883 CSize szRet;
884 SIZE sizeBg = m_pSkinBg->GetSkinSize();
885 CRect rcMargin = GetStyle().GetMargin();
886 if (IsVertical())
887 {
888 szRet.cx = sizeBg.cx + rcMargin.left + rcMargin.right;
889 if (GetLayoutParam()->IsSpecifiedSize(Vert))
890 szRet.cy = GetLayoutParam()->GetSpecifiedSize(Vert).toPixelSize(GetScale());
891 else
892 szRet.cy = sizeBg.cy + rcMargin.top + rcMargin.bottom;
893 }
894 else
895 {
896 szRet.cy = sizeBg.cy + rcMargin.top + rcMargin.bottom;
897 if (GetLayoutParam()->IsSpecifiedSize(Horz))
898 szRet.cx = GetLayoutParam()->GetSpecifiedSize(Horz).toPixelSize(GetScale());
899 else
900 szRet.cx = sizeBg.cx + rcMargin.left + rcMargin.right;
901 }
902 *psz = szRet;
903}
904
906{
907 SPainter painter;
908
909 BeforePaint(pRT, painter);
910
911 CRect rcClient;
912 GetClientRect(&rcClient);
913 if (m_pSkinBg)
914 m_pSkinBg->DrawByState(pRT, rcClient, WndState_Normal);
915 CRect rcValue = rcClient;
916
917 if (IsVertical())
918 {
919 rcValue.bottom = rcClient.bottom;
920 rcValue.top = rcValue.bottom - (int)(((__int64)rcValue.Height()) * (m_nValue - m_nMinValue) / (__int64)(m_nMaxValue - m_nMinValue));
921 }
922 else
923 {
924 rcValue.right = rcValue.left + (int)(((__int64)rcValue.Width()) * (m_nValue - m_nMinValue) / (__int64)(m_nMaxValue - m_nMinValue));
925 }
927 {
928 m_pSkinPos->DrawByState(pRT, rcValue, WndState_Normal);
929 }
930
931 if (m_bShowPercent && !IsVertical())
932 {
933 SStringT strPercent;
934 strPercent.Format(_T("%d%%"), (int)((m_nValue - m_nMinValue) * 100 / (m_nMaxValue - m_nMinValue)));
935 pRT->DrawText(strPercent, strPercent.GetLength(), GetWindowRect(), DT_SINGLELINE | DT_CENTER | DT_VCENTER);
936 }
937 AfterPaint(pRT, painter);
938}
939
941{
942 if (!m_pSkinBg)
943 m_pSkinBg = GETBUILTINSKIN(IsVertical() ? SKIN_SYS_VERT_PROG_BKGND : SKIN_SYS_PROG_BKGND);
944 if (!m_pSkinPos)
945 m_pSkinPos = GETBUILTINSKIN(IsVertical() ? SKIN_SYS_VERT_PROG_BAR : SKIN_SYS_PROG_BAR);
946 return 0;
947}
948
949BOOL SProgress::SetValue(int dwValue)
950{
951 if (dwValue < m_nMinValue)
952 dwValue = m_nMinValue;
953 if (dwValue > m_nMaxValue)
954 dwValue = m_nMaxValue;
955 m_nValue = dwValue;
956
957 Invalidate();
958 return TRUE;
959}
960
961void SProgress::SetRange(int nMin, int nMax)
962{
963 if (nMax <= nMin)
964 {
965 SSLOGW() << "invalid range: min=" << nMin << " max=" << nMax;
966 return;
967 }
968 m_nMaxValue = nMax;
969 m_nMinValue = nMin;
970 if (m_nValue > m_nMaxValue)
972 if (m_nValue < nMin)
974 Invalidate();
975}
976
977void SProgress::GetRange(int *pMin, int *pMax) const
978{
979 if (pMin)
980 *pMin = m_nMinValue;
981 if (pMax)
982 *pMax = m_nMaxValue;
983}
984
985void SProgress::OnColorize(COLORREF cr)
986{
987 __baseCls::OnColorize(cr);
988 if (m_pSkinBg)
989 m_pSkinBg->OnColorize(cr);
990 if (m_pSkinPos)
991 m_pSkinPos->OnColorize(cr);
992}
993
995{
996 __baseCls::OnScaleChanged(scale);
997 GetScaleSkin(m_pSkinBg, scale);
998 GetScaleSkin(m_pSkinPos, scale);
999}
1000
1001//////////////////////////////////////////////////////////////////////////
1002// Line Control
1003// Simple HTML "HR" tag
1004
1006 : m_nLineStyle(PS_SOLID)
1007 , m_nLineSize(1)
1008 , m_mode(HR_HORZ)
1009 , m_crLine(RGBA(0, 0, 0, 255))
1010{
1011}
1012
1014{
1015 CPoint pts[2];
1016 CRect rcWnd = GetWindowRect();
1017 pts[0] = rcWnd.TopLeft();
1018 switch (m_mode)
1019 {
1020 case HR_HORZ:
1021 pts[1].x = rcWnd.right, pts[1].y = rcWnd.top;
1022 break;
1023 case HR_VERT:
1024 pts[1].x = rcWnd.left, pts[1].y = rcWnd.bottom;
1025 break;
1026 case HR_TILT:
1027 pts[1] = rcWnd.BottomRight();
1028 break;
1029 }
1030 SAutoRefPtr<IPenS> curPen, oldPen;
1031 pRT->CreatePen(m_nLineStyle, m_crLine, m_nLineSize, &curPen);
1032 pRT->SelectObject(curPen, (IRenderObj **)&oldPen);
1033 pRT->DrawLines(pts, 2);
1034 pRT->SelectObject(oldPen, NULL);
1035}
1036
1037//////////////////////////////////////////////////////////////////////////
1038// Check Box
1039
1041 : m_pSkin(GETBUILTINSKIN(SKIN_SYS_CHECKBOX))
1042 , m_pFocusSkin(GETBUILTINSKIN(SKIN_SYS_FOCUSCHECKBOX))
1043{
1044 m_style.SetAlign(DT_LEFT);
1045 m_bFocusable = TRUE;
1046}
1047
1049{
1050 CRect rcClient;
1051 GetClientRect(rcClient);
1052 if (!m_pSkin)
1053 return CRect();
1054 CSize szCheck = m_pSkin->GetSkinSize();
1055 CRect rcCheckBox(rcClient.TopLeft(), szCheck);
1056 rcCheckBox.OffsetRect(0, (rcClient.Height() - szCheck.cy) / 2);
1057 return rcCheckBox;
1058}
1059
1060void SCheckBox::GetTextRect(LPRECT pRect)
1061{
1062 GetClientRect(pRect);
1063 CSize szCheck;
1064 if (m_pSkin)
1065 szCheck = m_pSkin->GetSkinSize();
1066 pRect->left += szCheck.cx + CheckBoxSpacing;
1067}
1068
1070{
1071 CRect rcCheckBox = GetCheckRect();
1072 m_pSkin->DrawByState(pRT, rcCheckBox, GetState());
1073 __baseCls::OnPaint(pRT);
1074}
1075
1077{
1078 if (m_pFocusSkin)
1079 {
1080 CRect rcCheckBox = GetCheckRect();
1081 m_pFocusSkin->DrawByIndex(pRT, rcCheckBox, 0);
1082 }
1083 else
1084 {
1085 __baseCls::DrawFocus(pRT);
1086 }
1087}
1088
1089SIZE SCheckBox::MeasureContent(int wid, int hei)
1090{
1091 if (!m_pSkin)
1092 return __baseCls::MeasureContent(wid, hei);
1093 CSize szCheck = m_pSkin->GetSkinSize();
1094 CSize szRet = __baseCls::MeasureContent(wid, hei);
1095 szRet.cx += szCheck.cx + CheckBoxSpacing;
1096 szRet.cy = smax(szRet.cy, szCheck.cy);
1097 return szRet;
1098}
1099
1100void SCheckBox::OnLButtonUp(UINT nFlags, CPoint point)
1101{
1102 if ((GetState() & WndState_PushDown) && GetWindowRect().PtInRect(point))
1103 {
1104 SetCheck(!IsChecked());
1105 }
1106 SWindow::OnLButtonUp(nFlags, point);
1107}
1108
1109void SCheckBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
1110{
1111 if (nChar == VK_SPACE)
1112 {
1113 if (IsChecked())
1114 ModifyState(0, WndState_Check, TRUE);
1115 else
1116 ModifyState(WndState_Check, 0, TRUE);
1117
1118 FireCommand();
1119 }
1120}
1121
1122HRESULT SCheckBox::OnAttrCheck(const SStringW &strValue, BOOL bLoading)
1123{
1124 SetCheck(STRINGASBOOL(strValue));
1125 return S_FALSE;
1126}
1127
1128void SCheckBox::OnColorize(COLORREF cr)
1129{
1130 __baseCls::OnColorize(cr);
1131 if (m_pFocusSkin)
1132 m_pFocusSkin->OnColorize(cr);
1133 if (m_pSkin)
1134 m_pSkin->OnColorize(cr);
1135}
1136
1138{
1139 __baseCls::OnScaleChanged(nScale);
1140 GetScaleSkin(m_pSkin, nScale);
1141 GetScaleSkin(m_pFocusSkin, nScale);
1142}
1143
1144//////////////////////////////////////////////////////////////////////////
1145// Icon Control
1146
1148 : m_theIcon(0)
1149{
1150}
1151
1153{
1154 if (m_theIcon)
1155 DestroyIcon(m_theIcon);
1156}
1157
1159{
1160 CRect rcClient;
1161 GetClientRect(&rcClient);
1162 if (m_theIcon)
1163 pRT->DrawIconEx(rcClient.left, rcClient.top, m_theIcon, rcClient.Width(), rcClient.Height(), DI_NORMAL);
1164}
1165
1166SIZE SIconWnd::MeasureContent(int wid, int hei)
1167{
1168 if (!m_theIcon)
1169 return CSize();
1170 ICONINFO iconInfo = { 0 };
1171 GetIconInfo(m_theIcon, &iconInfo);
1172 if (iconInfo.hbmColor)
1173 DeleteObject(iconInfo.hbmColor);
1174 if (iconInfo.hbmMask)
1175 DeleteObject(iconInfo.hbmMask);
1176
1177 return CSize(iconInfo.xHotspot * 2, iconInfo.yHotspot * 2);
1178}
1179
1180void SIconWnd::SetIcon(HICON hIcon)
1181{
1182 if (m_theIcon == hIcon)
1183 return;
1184 if (m_theIcon)
1185 DestroyIcon(m_theIcon);
1186 m_theIcon = hIcon;
1187 Invalidate();
1188}
1189
1190HRESULT SIconWnd::OnAttrIcon(const SStringW &value, BOOL bLoading)
1191{
1192 m_theIcon = LOADICON2(value);
1193 m_strIconSrc = value;
1194 return bLoading ? S_FALSE : S_OK;
1195}
1196
1198{
1199 if (!m_strIconSrc.IsEmpty())
1200 {
1201 SStringT strIconID2 = S_CW2T(m_strIconSrc);
1202 SStringTList strLst;
1203 int nSegs = ParseResID(strIconID2, strLst);
1204 if (nSegs == 2)
1205 {
1206 int cx = _ttoi(strLst[1]) * scale / 100;
1207 HICON hNew = SApplication::getSingletonPtr()->GetResProviderMgr()->LoadIcon(strLst[0], cx, cx);
1208 if (hNew)
1209 {
1210 if (m_theIcon)
1211 DestroyIcon(m_theIcon);
1212 m_theIcon = hNew;
1213 }
1214 }
1215 }
1216}
1217
1218//////////////////////////////////////////////////////////////////////////
1219// Radio Box
1220//
1221// Usage: <radio state=1>This is a check-box</radio>
1222//
1223
1225 : m_pSkin(GETBUILTINSKIN(SKIN_SYS_RADIO))
1226 , m_pFocusSkin(GETBUILTINSKIN(SKIN_SYS_FOCUSRADIO))
1227 , m_uIconAlign(SwndStyle::Align_Left)
1228 , m_uIconVAlign(SwndStyle::VAlign_Middle)
1230{
1231 m_style.SetAlign(DT_LEFT);
1232 m_bFocusable = TRUE;
1233}
1234
1236{
1237 CRect rcClient;
1238 GetClientRect(rcClient);
1239 if (!m_pSkin)
1240 return CRect();
1241 CSize szRadioBox = m_pSkin->GetSkinSize();
1242 CRect rcRadioBox = rcClient;
1243
1244 switch (m_uIconAlign)
1245 {
1246 case SwndStyle::Align_Center:
1247 rcRadioBox.left += (rcClient.Width() - szRadioBox.cx) / 2;
1248 break;
1249 case SwndStyle::Align_Right:
1250 rcRadioBox.left = rcClient.right - szRadioBox.cx;
1251 break;
1252 }
1253 switch (m_uIconVAlign)
1254 {
1255 case SwndStyle::VAlign_Middle:
1256 rcRadioBox.top += (rcClient.Height() - szRadioBox.cy) / 2;
1257 break;
1258 case SwndStyle::VAlign_Bottom:
1259 rcRadioBox.top = rcClient.bottom - szRadioBox.cy;
1260 break;
1261 }
1262 rcRadioBox.right = rcRadioBox.left + szRadioBox.cx;
1263 rcRadioBox.bottom = rcRadioBox.top + szRadioBox.cy;
1264
1265 return rcRadioBox;
1266}
1267
1268void SRadioBox::GetTextRect(LPRECT pRect)
1269{
1270 GetClientRect(pRect);
1271 CSize szRadioBox;
1272 if (m_pSkin)
1273 szRadioBox = m_pSkin->GetSkinSize();
1274
1275 switch (m_uIconAlign)
1276 {
1277 case SwndStyle::Align_Left:
1278 pRect->left += (szRadioBox.cx + m_nRadioBoxSpacing);
1279 break;
1280 case SwndStyle::Align_Right:
1281 pRect->right -= (szRadioBox.cx + m_nRadioBoxSpacing);
1282 break;
1283 }
1284 switch (m_uIconVAlign)
1285 {
1286 case SwndStyle::VAlign_Top:
1287 pRect->top += (szRadioBox.cy + m_nRadioBoxSpacing);
1288 break;
1289 case SwndStyle::VAlign_Bottom:
1290 pRect->bottom -= (szRadioBox.cy + m_nRadioBoxSpacing);
1291 break;
1292 }
1293}
1294
1296{
1297 CRect rcRadioBox = GetRadioRect();
1298 m_pSkin->DrawByState(pRT, rcRadioBox, GetState());
1299 __baseCls::OnPaint(pRT);
1300}
1301
1303{
1305 {
1306 CRect rcCheckBox = GetRadioRect();
1307 m_pFocusSkin->DrawByIndex(pRT, rcCheckBox, 0);
1308 }
1309 else
1310 {
1311 __baseCls::DrawFocus(pRT);
1312 }
1313}
1314
1315SIZE SRadioBox::MeasureContent(int wid, int hei)
1316{
1317 CSize szRet = __baseCls::MeasureContent(wid, hei);
1318 CSize szRaio = m_pSkin->GetSkinSize();
1319 szRet.cx += szRaio.cx + m_nRadioBoxSpacing;
1320 szRet.cy = smax(szRet.cy, szRaio.cy);
1321 return szRet;
1322}
1323
1325{
1326 return TRUE;
1327}
1328
1330{
1332 {
1333 if (!IsChecked())
1334 SetCheck(TRUE);
1335 }
1336 Invalidate();
1337}
1338
1339void SRadioBox::OnLButtonUp(UINT nFlags, CPoint pt)
1340{
1341 if ((GetState() & WndState_PushDown) && GetWindowRect().PtInRect(pt))
1342 {
1343 if (!IsChecked())
1344 SetCheck(TRUE);
1345 }
1346 SWindow::OnLButtonUp(nFlags, pt);
1347}
1348
1350{
1351 SWindow *pParent = GetParent();
1352 SASSERT(pParent);
1353 SWindow *pSibling = pParent->GetWindow(GSW_FIRSTCHILD);
1354 while (pSibling)
1355 {
1356 if (pSibling->IsClass(GetClassName()))
1357 {
1358 SRadioBox *pRadio = (SRadioBox *)pSibling;
1359 if (pRadio->IsChecked())
1360 return pRadio;
1361 }
1362 pSibling = pSibling->GetWindow(GSW_NEXTSIBLING);
1363 }
1364 return NULL;
1365}
1366
1367HRESULT SRadioBox::OnAttrCheck(const SStringW &strValue, BOOL bLoading)
1368{
1369 if (bLoading)
1370 {
1371 GetEventSet()->setMutedState(true);
1372 SetCheck(strValue != L"0");
1373 GetEventSet()->setMutedState(false);
1374 }
1375 else
1376 {
1377 SetCheck(strValue != L"0");
1378 }
1379 return S_FALSE;
1380}
1381
1382void SRadioBox::OnStateChanging(DWORD dwOldState, DWORD dwNewState)
1383{
1384 if ((dwNewState & WndState_Check) && !(dwOldState & WndState_Check))
1385 {
1386 SRadioBox *pCurChecked = (SRadioBox *)GetSelectedSiblingInGroup();
1387 if (pCurChecked)
1388 {
1389 pCurChecked->GetEventSet()->setMutedState(true);
1390 pCurChecked->SetCheck(FALSE);
1391 pCurChecked->GetEventSet()->setMutedState(false);
1392 }
1393 }
1394}
1395
1396void SRadioBox::OnColorize(COLORREF cr)
1397{
1398 __baseCls::OnColorize(cr);
1399 if (m_pFocusSkin)
1400 m_pFocusSkin->OnColorize(cr);
1401 if (m_pSkin)
1402 m_pSkin->OnColorize(cr);
1403}
1404
1406{
1407 __baseCls::OnScaleChanged(nScale);
1408 GetScaleSkin(m_pSkin, nScale);
1409 GetScaleSkin(m_pFocusSkin, nScale);
1410}
1411
1412//////////////////////////////////////////////////////////////////////////
1413// SRadioGroup
1415{
1416 GetEventSet()->addEvent(EVENTID(EventRadioGroupCheckChanged));
1417}
1418
1420{
1421 SWindow *pChild = FindChildByID(nID);
1422 if (!pChild)
1423 return FALSE;
1424 pChild->SetCheck(TRUE);
1425 return TRUE;
1426}
1427
1428BOOL SRadioGroup::Check(LPCTSTR pszName)
1429{
1430 SWindow *pChild = FindChildByName(pszName);
1431 if (!pChild)
1432 return FALSE;
1433 pChild->SetCheck(TRUE);
1434 return TRUE;
1435}
1436
1438{
1439 SWindow *pChild = GetWindow(GSW_FIRSTCHILD);
1440 while (pChild)
1441 {
1442 SRadioBox *pRadio = sobj_cast<SRadioBox>(pChild);
1443 if (pRadio && pRadio->IsChecked())
1444 {
1445 pRadio->SetCheck(FALSE);
1446 return TRUE;
1447 }
1448 pChild = pChild->GetWindow(GSW_NEXTSIBLING);
1449 }
1450 return FALSE;
1451}
1452
1453BOOL SRadioGroup::FireEvent(IEvtArgs *evt)
1454{
1455 if (evt->Sender() == this)
1456 {
1457 return SWindow::FireEvent(evt);
1458 }
1459 if (evt->GetID() == EventSwndStateChanged::EventID && evt->Sender() && evt->Sender()->IsClass(SRadioBox::GetClassName()))
1460 {
1461 EventSwndStateChanged *evt2 = sobj_cast<EventSwndStateChanged>(evt);
1462 if (EventSwndStateChanged_CheckState(evt2, WndState_Check))
1463 {
1464 EventRadioGroupCheckChanged evt3(this);
1465 SRadioBox *pSender = sobj_cast<SRadioBox>(evt->Sender());
1466 evt3.pChecked = pSender->IsChecked() ? pSender : NULL;
1467 return SWindow::FireEvent(evt3);
1468 }
1469 }
1470 return GetContainer()->OnFireEvent(evt);
1471}
1472
1474{
1475 pChild->SetOwner(this);
1476}
1477
1479{
1480 pChild->SetOwner(NULL);
1481}
1482
1483//////////////////////////////////////////////////////////////////////////
1484// SToggle
1486{
1487 m_pSkin = GETBUILTINSKIN(SKIN_SYS_TREE_TOGGLE);
1488}
1489
1490void SToggle::SetToggle(BOOL bToggle, BOOL bUpdate /*=TRUE*/)
1491{
1492 SetCheck(bToggle);
1493 if (bUpdate)
1494 Invalidate();
1495}
1496
1498{
1499 return IsChecked();
1500}
1501
1503{
1504 if (!m_pSkin)
1505 return;
1506 m_pSkin->DrawByState(pRT, GetWindowRect(), GetState());
1507}
1508
1509SIZE SToggle::MeasureContent(int wid, int hei)
1510{
1511 CSize sz;
1512 if (m_pSkin)
1513 sz = m_pSkin->GetSkinSize();
1514 return sz;
1515}
1516
1517#define GROUP_HEADER 20
1518#define GROUP_ROUNDCORNOR 4
1519
1521 : m_crLine1(RGBA(0xF0, 0xF0, 0xF0, 0xFF))
1522 , m_crLine2(RGBA(0xA0, 0xA0, 0xA0, 0xFF))
1523{
1524 m_nRound.setSize(GROUP_ROUNDCORNOR, SLayoutSize::dp);
1525 m_nHeaderHeight.setSize(GROUP_HEADER, SLayoutSize::dp);
1526}
1527
1529{
1530
1531 SPainter painter;
1532
1533 BeforePaint(pRT, painter);
1534
1535 CSize szFnt;
1536 pRT->MeasureText(m_strText.GetText(FALSE), m_strText.GetText(FALSE).GetLength(), &szFnt);
1537
1538 CRect rcText = GetClientRect();
1539 rcText.left += GROUP_HEADER, rcText.right -= GROUP_HEADER;
1540 rcText.bottom = rcText.top + szFnt.cy + 2;
1541 if (GetTextAlign() & DT_CENTER)
1542 {
1543 rcText.left += (rcText.Width() - szFnt.cx) / 2;
1544 rcText.right = rcText.left + szFnt.cx;
1545 }
1546 else if (GetTextAlign() & DT_RIGHT)
1547 {
1548 rcText.left = rcText.right - szFnt.cx;
1549 }
1550 else
1551 {
1552 rcText.right = rcText.left + szFnt.cx;
1553 }
1554
1555 if (!m_strText.GetText(FALSE).IsEmpty())
1556 {
1557 CRect rcClip = rcText;
1558 rcClip.InflateRect(5, 5, 5, 5);
1559 pRT->PushClipRect(&rcClip, RGN_DIFF);
1560 }
1561
1562 {
1563 CRect rcGroupBox = GetClientRect();
1564
1565 if (!m_strText.GetText(FALSE).IsEmpty())
1566 rcGroupBox.top += szFnt.cy / 2;
1567 rcGroupBox.DeflateRect(1, 1, 1, 0);
1568
1569 SAutoRefPtr<IPenS> pen1, pen2, oldPen;
1570 pRT->CreatePen(PS_SOLID, m_crLine1, 1, &pen1);
1571 pRT->CreatePen(PS_SOLID, m_crLine2, 1, &pen2);
1572 pRT->SelectObject(pen1, (IRenderObj **)&oldPen);
1573
1574 int nRound = m_nRound.toPixelSize(GetScale());
1575 pRT->DrawRoundRect(&rcGroupBox, CPoint(nRound, nRound));
1576
1577 pRT->SelectObject(pen2, NULL);
1578 rcGroupBox.InflateRect(1, 1, 1, -1);
1579 pRT->DrawRoundRect(&rcGroupBox, CPoint(nRound, nRound));
1580
1581 pRT->SelectObject(oldPen, NULL);
1582 }
1583
1584 if (!m_strText.GetText(FALSE).IsEmpty())
1585 {
1586 pRT->PopClip();
1587 pRT->DrawText(m_strText.GetText(FALSE), m_strText.GetText(FALSE).GetLength(), rcText, DT_SINGLELINE | DT_VCENTER);
1588 }
1589
1590 AfterPaint(pRT, painter);
1591}
1592
1594{
1595 __baseCls::GetChildrenLayoutRect(prc);
1596 prc->top += m_nHeaderHeight.toPixelSize(GetScale());
1597}
1598
1599void SGroup::GetDesiredSize(SIZE *psz, int nParentWid, int nParentHei)
1600{
1601 __baseCls::GetDesiredSize(psz, nParentWid, nParentHei);
1602 if (GetLayoutParam()->IsWrapContent(Vert))
1603 psz->cy += m_nHeaderHeight.toPixelSize(GetScale());
1604}
1605
1606SNSEND
通用控件
@ GSW_FIRSTCHILD
Definition SWnd.h:195
@ GSW_NEXTSIBLING
Definition SWnd.h:198
@ WndState_Hover
Definition SWnd.h:76
@ WndState_Check
Definition SWnd.h:78
@ WndState_Normal
Definition SWnd.h:75
@ WndState_PushDown
Definition SWnd.h:77
Accelerator key mapping.
static DWORD TranslateAccelKey(LPCTSTR pszKeyName)
Translates a string to an accelerator key value.
void OnNextFrame() OVERRIDE
处理下一帧事件
Definition SCmnCtrl.cpp:805
void OnScaleChanged(int scale) override
处理缩放变化事件
Definition SCmnCtrl.cpp:856
void WINAPI Start()
启动动画
Definition SCmnCtrl.cpp:749
int m_nSpeed
速度
Definition SCmnCtrl.h:632
SAnimateImgWnd()
构造函数
Definition SCmnCtrl.cpp:727
BOOL WINAPI IsPlaying() SCONST
判断动画运行状态
Definition SCmnCtrl.h:554
BOOL m_bPlaying
是否运行中
Definition SCmnCtrl.h:647
int m_nRepeat
播放循环次数,-1代表无限循环
Definition SCmnCtrl.h:657
void OnDestroy()
处理销毁事件
Definition SCmnCtrl.cpp:774
void OnPaint(IRenderTarget *pRT)
绘制控件
Definition SCmnCtrl.cpp:743
virtual SIZE MeasureContent(int wid, int hei)
测量内容大小
Definition SCmnCtrl.cpp:780
virtual void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
容器改变处理函数
Definition SCmnCtrl.cpp:844
void WINAPI Stop()
停止动画
Definition SCmnCtrl.cpp:763
int m_iCurFrame
当前帧
Definition SCmnCtrl.h:637
SAutoRefPtr< ISkinObj > m_pSkin
动画图片
Definition SCmnCtrl.h:627
BOOL m_bAutoStart
是否自动启动
Definition SCmnCtrl.h:642
void OnShowWindow(BOOL bShow, UINT nStatus)
处理显示窗口事件
Definition SCmnCtrl.cpp:788
int m_iRepeat
当前播放循环轮次
Definition SCmnCtrl.h:662
virtual void OnColorize(COLORREF cr)
处理颜色化事件
Definition SCmnCtrl.cpp:837
int m_iTimeFrame
OnNextFrame的执行次数
Definition SCmnCtrl.h:652
IResProviderMgr * GetResProviderMgr() OVERRIDE
Get the resource provider manager.
Definition SApp.cpp:727
Smart pointer class for managing COM-style reference-counted objects.
virtual BOOL WINAPI OnAcceleratorPressed(const IAccelerator *accelerator) OVERRIDE
处理加速键按下事件
Definition SCmnCtrl.cpp:446
BOOL m_bDisableAccelIfInvisible
禁用不可见时的加速键
Definition SCmnCtrl.h:341
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
处理按键按下事件
Definition SCmnCtrl.cpp:418
virtual BOOL WINAPI InitFromXml(IXmlNode *pNode) OVERRIDE
从XML初始化控件
Definition SCmnCtrl.cpp:456
void OnDestroy()
处理销毁事件
Definition SCmnCtrl.cpp:479
void OnSize(UINT nType, CSize size)
处理大小改变事件
Definition SCmnCtrl.cpp:522
BYTE m_nAniStep
alpha for animate step
Definition SCmnCtrl.h:336
BOOL m_bAnimate
动画标志
Definition SCmnCtrl.h:326
HRESULT OnAttrAccel(SStringW strAccel, BOOL bLoading)
处理自定义属性accel
Definition SCmnCtrl.cpp:490
void OnNextFrame() OVERRIDE
处理下一帧事件
Definition SCmnCtrl.cpp:535
DWORD m_accel
加速键
Definition SCmnCtrl.h:321
void StopCurAnimate()
停止动画
Definition SCmnCtrl.cpp:529
SButton()
构造函数
Definition SCmnCtrl.cpp:377
virtual void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
容器改变处理函数
Definition SCmnCtrl.cpp:546
virtual void OnStateChanged(DWORD dwOldState, DWORD dwNewState)
状态改变处理函数
Definition SCmnCtrl.cpp:507
void OnPaint(IRenderTarget *pRT)
绘制控件
Definition SCmnCtrl.cpp:388
void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
处理按键释放事件
Definition SCmnCtrl.cpp:430
WORD m_byAlphaAni
动画状态
Definition SCmnCtrl.h:331
void OnLButtonUp(UINT nFlags, CPoint pt)
处理鼠标左键释放事件
CRect GetCheckRect()
获取复选框矩形区域
SCheckBox()
构造函数
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
处理按键按下事件
virtual void OnScaleChanged(int scale)
处理缩放变化事件
void OnPaint(IRenderTarget *pRT)
处理绘制事件
virtual void GetTextRect(LPRECT pRect)
获取文本显示区域的大小
SAutoRefPtr< ISkinObj > m_pSkin
状态图片资源
Definition SCmnCtrl.h:900
virtual void DrawFocus(IRenderTarget *pRT)
绘制焦点样式
virtual void OnColorize(COLORREF cr)
处理颜色化事件
SIZE MeasureContent(int wid, int hei) override
测量内容所需的大小
SAutoRefPtr< ISkinObj > m_pFocusSkin
焦点状态资源
Definition SCmnCtrl.h:906
HRESULT OnAttrCheck(const SStringW &strValue, BOOL bLoading)
处理自定义属性 "checked"
BOOL addEvent(DWORD dwEventID, LPCWSTR pszEventHandlerName)
添加一个新事件到事件集
void setMutedState(BOOL setting)
设置事件集的静音状态
FocusChangeReason
Reason for focus change.
SGroup()
构造函数
SLayoutSize m_nRound
圆角半径
Definition SCmnCtrl.h:1417
void GetDesiredSize(SIZE *psz, int wid, int hei) OVERRIDE
获取预期大小
SLayoutSize m_nHeaderHeight
头部高度
Definition SCmnCtrl.h:1422
void OnPaint(IRenderTarget *pRT)
绘制控件
void GetChildrenLayoutRect(RECT *prc) SCONST OVERRIDE
获取子控件布局矩形
COLORREF m_crLine1
group 3D显示使用的两种颜色
Definition SCmnCtrl.h:1412
HICON m_theIcon
Definition SCmnCtrl.h:1077
SIconWnd()
构造函数
SIZE MeasureContent(int wid, int hei) override
测量内容大小
virtual ~SIconWnd()
析构函数
void OnScaleChanged(int scale) override
Called when the scale of the window changes.
void OnPaint(IRenderTarget *pRT)
绘制控件
void SetIcon(HICON hIcon) OVERRIDE
设置图标
SImageButton()
构造函数
Definition SCmnCtrl.cpp:554
SIZE MeasureContent(int wid, int hei) override
测量内容大小
Definition SCmnCtrl.cpp:559
virtual SIZE MeasureContent(int nParentWid, int nParentHei)
测量内容大小
Definition SCmnCtrl.cpp:696
virtual void OnColorize(COLORREF cr)
处理颜色化事件
Definition SCmnCtrl.cpp:709
BOOL m_bManaged
是否要自动释放当前的m_pSkin对象
Definition SCmnCtrl.h:471
SImageWnd()
构造函数
Definition SCmnCtrl.cpp:571
SAutoRefPtr< IBitmapS > m_pImg
使用代码设定的图片
Definition SCmnCtrl.h:486
int m_iIcon
绘制状态索引
Definition SCmnCtrl.h:476
virtual void OnScaleChanged(int scale)
处理缩放变化事件
Definition SCmnCtrl.cpp:716
BOOL SetIcon(int nSubID) OVERRIDE
设置图标
Definition SCmnCtrl.cpp:685
void OnPaint(IRenderTarget *pRT)
绘制控件
Definition SCmnCtrl.cpp:591
FilterLevel m_fl
绘制图片的放大精度
Definition SCmnCtrl.h:491
bool m_bKeepAspect
保持纵横比
Definition SCmnCtrl.h:496
void SetImage(IBitmapS *pBitmap, FilterLevel fl=kNone_FilterLevel) OVERRIDE
设置绘制图片
Definition SCmnCtrl.cpp:673
SAutoRefPtr< ISkinObj > m_pSkin
ISkinObj对象
Definition SCmnCtrl.h:481
BOOL SetSkin(ISkinObj *pSkin, int iFrame=0, BOOL bAutoFree=TRUE) OVERRIDE
设置skin
Definition SCmnCtrl.cpp:636
int m_iTile
绘制是否平铺, 0–位伸(默认),1–不变常规绘制, 2–平铺
Definition SCmnCtrl.h:466
virtual ~SImageWnd()
析构函数
Definition SCmnCtrl.cpp:582
ISkinObj * GetSkin() OVERRIDE
获取资源
Definition SCmnCtrl.cpp:722
IBitmapS * GetImage() OVERRIDE
获取当前设置的IBitmapS对象
Definition SCmnCtrl.cpp:680
int toPixelSize(int scale) const
将大小转换为像素值
void OnPaint(IRenderTarget *pRT)
绘制控件
int m_nLineStyle
线条样式
Definition SCmnCtrl.h:829
int m_nLineSize
线条大小
Definition SCmnCtrl.h:834
SLine()
构造函数
COLORREF m_crLine
线条颜色
Definition SCmnCtrl.h:839
BOOL IsClass(LPCWSTR lpszName) SCONST OVERRIDE
Checks if the object is of a specific class.
Definition Sobject.hpp:228
static LPCWSTR GetClassName()
Definition Sobject.hpp:41
Helper class for painting.
Definition SWnd.h:178
SAutoRefPtr< ISkinObj > m_pSkinPos
前景资源
Definition SCmnCtrl.h:786
SProgress()
构造函数
Definition SCmnCtrl.cpp:869
virtual void OnColorize(COLORREF cr)
处理颜色化事件
Definition SCmnCtrl.cpp:985
void OnPaint(IRenderTarget *pRT)
绘制控件
Definition SCmnCtrl.cpp:905
BOOL SetValue(int nValue) OVERRIDE
设置进度条进度值
Definition SCmnCtrl.cpp:949
int m_nValue
进度值
Definition SCmnCtrl.h:766
int m_nMaxValue
进度最大值
Definition SCmnCtrl.h:761
BOOL m_bShowPercent
是否显示百分比
Definition SCmnCtrl.h:771
virtual void OnScaleChanged(int scale)
处理缩放变化事件
Definition SCmnCtrl.cpp:994
BOOL IsVertical() SCONST OVERRIDE
判断进度条是否为竖直状态
Definition SCmnCtrl.h:714
int m_nMinValue
进度最小值
Definition SCmnCtrl.h:756
SAutoRefPtr< ISkinObj > m_pSkinBg
背景资源
Definition SCmnCtrl.h:781
BOOL m_bVertical
是否竖直状态
Definition SCmnCtrl.h:776
void GetRange(int *pMin, int *pMax) SCONST OVERRIDE
获取进度值最小大值
Definition SCmnCtrl.cpp:977
int OnCreate(void *)
处理创建事件
Definition SCmnCtrl.cpp:940
void GetDesiredSize(SIZE *psz, int wid, int hei) OVERRIDE
获取预期大小
Definition SCmnCtrl.cpp:881
void SetRange(int nMin, int nMax) OVERRIDE
设置进度值最小大值
Definition SCmnCtrl.cpp:961
单选框控件类
Definition SCmnCtrl.h:1086
virtual void OnColorize(COLORREF cr)
处理颜色化事件
void OnLButtonUp(UINT nFlags, CPoint pt)
处理鼠标左键释放事件
SIZE MeasureContent(int wid, int hei) OVERRIDE
测量内容所需的大小
SAutoRefPtr< ISkinObj > m_pFocusSkin
焦点皮肤资源
Definition SCmnCtrl.h:1241
SRadioBox()
构造函数
void OnSetFocus(SWND wndOld, SFocusManager::FocusChangeReason reason)
处理焦点改变事件
HRESULT OnAttrCheck(const SStringW &strValue, BOOL bLoading)
处理自定义属性 "checked"
virtual void GetTextRect(LPRECT pRect)
获取文本显示区域的大小
virtual void DrawFocus(IRenderTarget *pRT)
绘制焦点样式
SAutoRefPtr< ISkinObj > m_pSkin
定义控件的消息映射
Definition SCmnCtrl.h:1236
UINT m_uIconVAlign
图标垂直对齐方式
Definition SCmnCtrl.h:1251
CRect GetRadioRect()
获取单选框显示位置的矩形区域
int m_nRadioBoxSpacing
单选框与文本之间的间距
Definition SCmnCtrl.h:1256
virtual BOOL NeedRedrawWhenStateChange()
判断状态改变时是否需要重绘控件
virtual void OnScaleChanged(int nScale)
处理缩放变化事件
UINT m_uIconAlign
图标水平对齐方式
Definition SCmnCtrl.h:1246
virtual SWindow * GetSelectedSiblingInGroup()
获取当前组中被选中的兄弟控件
virtual void OnStateChanging(DWORD dwOldState, DWORD dwNewState)
处理状态变化事件
void OnPaint(IRenderTarget *pRT)
绘制控件
virtual void OnBeforeRemoveChild(SWindow *pChild)
在移除子控件前处理
BOOL ClearCheck()
清除所有选中的单选按钮
SRadioGroup()
构造函数
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
触发事件
virtual void OnAfterInsertChild(SWindow *pChild)
在插入子控件后处理
BOOL Check(int nID)
检查指定ID的单选按钮
static SApplication * getSingletonPtr(void)
Definition SSingleton.h:73
virtual void OnDrawLine(IRenderTarget *pRT, LPCTSTR pszBuf, int iBegin, int cchText, LPRECT pRect, UINT uFormat)
绘制单行文本
Definition SCmnCtrl.cpp:55
SStatic()
构造函数
Definition SCmnCtrl.cpp:14
bool m_bWordbreak
是否自动换行
Definition SCmnCtrl.h:87
void DrawMultiLine(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
绘制多行文本
Definition SCmnCtrl.cpp:134
int m_nLineInter
行间距
Definition SCmnCtrl.h:82
virtual void DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
绘制文本
Definition SCmnCtrl.cpp:22
virtual SIZE OnMeasureText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText)
测量文本大小
Definition SCmnCtrl.cpp:252
A class representing an ASCII string.
Definition sstringw.h:96
SIZE MeasureContent(int nParentWid, int nParentHei) override
测量内容大小
BOOL GetToggle()
获取Toggle属性
void SetToggle(BOOL bToggle, BOOL bUpdate=TRUE)
设置Toggle属性
SToggle()
构造函数
void OnPaint(IRenderTarget *pRT)
绘制控件
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
Fires an event.
Definition Swnd.cpp:1540
virtual void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
Called when the container of the window changes.
Definition Swnd.cpp:3407
SWindow * GetParent() const
Retrieves the parent window.
Definition Swnd.cpp:3488
void OnMouseHover(UINT nFlags, CPoint ptPos)
Handles the mouse hover event.
Definition Swnd.cpp:2135
DWORD GetState() SCONST OVERRIDE
Retrieves the current state of the window.
Definition Swnd.cpp:437
SwndStyle m_style
Definition SWnd.h:2596
int GetWindowText(TCHAR *pBuf, int nBufLen, BOOL bRawText) OVERRIDE
Retrieves the window text.
Definition Swnd.cpp:263
UINT GetTextAlign() const
Retrieves the text alignment of the window.
Definition Swnd.cpp:218
void OnPaint(IRenderTarget *pRT)
Handles the painting of the window.
Definition Swnd.cpp:1785
int GetScale() SCONST OVERRIDE
Retrieves the scale factor of the window.
Definition Swnd.cpp:3266
CRect GetWindowRect() const
Retrieves the bounding rectangle of the window.
Definition Swnd.cpp:230
BOOL IsVisible(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is visible.
Definition Swnd.cpp:646
virtual void OnContentChanged()
Called when the content of the window changes.
Definition Swnd.cpp:329
ISwndContainer * GetContainer() OVERRIDE
Retrieves the container associated with this window.
Definition Swnd.cpp:679
BOOL m_bMsgTransparent
Definition SWnd.h:2608
void OnMouseLeave()
Handles the mouse leave event.
Definition Swnd.cpp:2147
void SetOwner(SWindow *pOwner)
Sets the owner of the window.
Definition Swnd.cpp:701
BOOL m_bDrawFocusRect
Definition SWnd.h:2610
SWindow * FindChildByName(LPCWSTR strName, int nDeep=-1)
Finds a child window by its name.
Definition Swnd.cpp:795
BOOL m_dwState
Definition SWnd.h:2603
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
Definition Swnd.cpp:243
void OnLButtonUp(UINT nFlags, CPoint pt)
Handles the left mouse button up event.
Definition Swnd.cpp:2105
void SetCheck(BOOL bCheck) OVERRIDE
Sets the check state of the window.
Definition Swnd.cpp:671
virtual void BeforePaint(IRenderTarget *pRT, SPainter &painter)
Prepare rendering environment.
Definition Swnd.cpp:1755
BOOL IsChecked() SCONST OVERRIDE
Checks if the window is checked.
Definition Swnd.cpp:633
STrText m_strToolTipText
Definition SWnd.h:2598
BOOL m_bFocusable
Definition SWnd.h:2609
SWindow()
Constructor.
Definition Swnd.cpp:104
SWND GetCapture() SCONST OVERRIDE
Retrieves the window that has captured the mouse.
Definition Swnd.cpp:2470
virtual void AfterPaint(IRenderTarget *pRT, SPainter &painter)
Restore rendering environment.
Definition Swnd.cpp:1776
ILayoutParam * GetLayoutParam() SCONST OVERRIDE
Retrieves the layout parameter object associated with the window.
Definition SWnd.h:405
SWindow * GetWindow(int uCode) const
Retrieves a window based on a given code.
Definition Swnd.cpp:3456
BOOL IsDisabled(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is disabled.
Definition Swnd.cpp:638
SEventSet * GetEventSet()
Retrieves the event set associated with the window.
Definition SWnd.h:1290
BOOL IsFocusable() SCONST OVERRIDE
Checks if the window is focusable.
Definition Swnd.cpp:1996
SAutoRefPtr< ISkinObj > m_pBgSkin
Definition SWnd.h:2622
void Invalidate() OVERRIDE
Invalidates the entire window.
Definition Swnd.cpp:1437
STrText m_strText
Definition SWnd.h:2597
void RequestRelayout() OVERRIDE
Requests a relayout of the window.
Definition Swnd.cpp:2225
void GetWindowRect(LPRECT prect) SCONST OVERRIDE
Retrieves the bounding rectangle of the window.
void SetMsgHandled(BOOL bHandled)
Sets the message handled flag.
Definition Swnd.cpp:212
void GetScaleSkin(SAutoRefPtr< ISkinObj > &pSkin, int nScale)
Retrieves a scaled skin object based on the current scale factor.
Definition Swnd.cpp:3290
BOOL InitFromXml(IXmlNode *pNode) OVERRIDE
Initializes the window from an XML node.
Definition Swnd.cpp:946
BOOL FireCommand() OVERRIDE
Fires a command event.
Definition Swnd.cpp:2713
DWORD ModifyState(DWORD dwStateAdd, DWORD dwStateRemove, BOOL bUpdate=FALSE) OVERRIDE
Modifies the state of the window.
Definition Swnd.cpp:443
const SwndStyle & GetStyle() const
Retrieves the style of the window.
Definition Swnd.cpp:716
SWND m_swnd
Member variables representing various properties of the window.
Definition SWnd.h:2577
SWindow * FindChildByID(int nID, int nDeep=-1)
Finds a child window by its ID.
Definition Swnd.cpp:781
BOOL ReleaseCapture() OVERRIDE
Releases the mouse capture from the window.
Definition Swnd.cpp:2491
Manages the style attributes of SOUI windows.
Definition SWndStyle.h:28
CRect GetMargin() const
Retrieves the margin rectangle.
CRect GetPadding() const
Retrieves the padding rectangle.
Interface for an accelerator key.
void UnregisterAccelerator(const IAccelerator *pAcc, IAcceleratorTarget *target) PURE
Unregister a keyboard accelerator for the specified target.
void RegisterAccelerator(const IAccelerator *pAcc, IAcceleratorTarget *target) PURE
Register a keyboard accelerator for the specified target.
Bitmap object interface.
Definition SRender-i.h:420
Base class for all renderable objects.
Definition SRender-i.h:145
Interface for rendering target objects.
Definition SRender-i.h:1440
HRESULT DrawText(LPCTSTR pszText, int cchLen, LPRECT pRc, UINT uFormat) PURE
Draw text within a rectangle.
HRESULT DrawBitmapEx(LPCRECT pRcDest, const IBitmapS *pBitmap, LPCRECT pRcSrc, UINT expendMode, BYTE byAlpha=0xFF) PURE
Draws a bitmap with expansion mode.
HRESULT SelectObject(IRenderObj *pObj, IRenderObj **pOldObj=NULL) PURE
Selects a new rendering object and optionally retrieves the previous one.
HRESULT PushClipRect(LPCRECT pRect, UINT mode=RGN_AND) PURE
Push a rectangular clip region.
HRESULT CreatePen(int iStyle, COLORREF cr, int cWidth, IPenS **ppPen) PURE
Create a pen object.
HRESULT PopClip() PURE
Pop the last clip region from the stack.
HRESULT DrawRoundRect(LPCRECT pRect, POINT pt) PURE
Draw a rounded rectangle outline.
HRESULT DrawLines(LPPOINT pPt, size_t nCount) PURE
Draw a series of connected lines.
HRESULT DrawIconEx(int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT diFlags) PURE
Draw an icon.
HRESULT MeasureText(LPCTSTR pszText, int cchLen, SIZE *psz) PURE
Measure the size of the text.
Interface for Skin Objects.
Definition SSkinobj-i.h:29
SOUI Window Container Interface.
BOOL RegisterTimelineHandler(ITimelineHandler *pHandler) PURE
Registers an animation frame handler.
IAcceleratorMgr * GetAcceleratorMgr() PURE
Retrieves the accelerator manager.
BOOL OnFireEvent(IEvtArgs *evt) PURE
Fires an event.
BOOL UnregisterTimelineHandler(ITimelineHandler *pHandler) PURE
Unregisters an animation frame handler.
Interface for XML nodes.
Definition sxml-i.h:128