soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SComboBase.cpp
1#include "souistd.h"
2#include "control/SComboBase.h"
3
4SNSBEGIN
5
6const wchar_t *KStyle_Dropdown = L"dropdownStyle"; //下拉列表风格,只包含root节点
7const wchar_t *KStyle_Edit = L"editStyle"; //编辑框风格
8
9//////////////////////////////////////////////////////////////////////////
10// CComboEdit
14
18
19void SComboEdit::OnMouseHover(WPARAM wParam, CPoint ptPos)
20{
21 SEdit::OnMouseHover((UINT)wParam, ptPos);
22 GetOwner()->SSendMessage(WM_MOUSEHOVER, wParam, MAKELPARAM(ptPos.x, ptPos.y));
23}
24
26{
27 __baseCls::OnMouseLeave();
28 GetOwner()->SSendMessage(WM_MOUSELEAVE);
29}
30
31void SComboEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
32{
33 SWindow *pOwner = GetOwner();
34 if (pOwner && (nChar == VK_DOWN || nChar == VK_UP || nChar == VK_ESCAPE))
35 {
36 pOwner->SSendMessage(WM_KEYDOWN, nChar, MAKELONG(nFlags, nRepCnt));
37 return;
38 }
39
40 SetMsgHandled(FALSE);
41}
42
43BOOL SComboEdit::FireEvent(IEvtArgs *evt)
44{
45 if (evt->GetID() == EVT_RE_NOTIFY)
46 { //转发richedit的txNotify消息
47 evt->SetIdFrom(GetOwner()->GetID());
48 evt->SetNameFrom(GetOwner()->GetName());
49 }
50 return SEdit::FireEvent(evt);
51}
52
53void SComboEdit::OnKillFocus(SWND wndFocus)
54{
55 __baseCls::OnKillFocus(wndFocus);
56 GetOwner()->SSendMessage(WM_KILLFOCUS, wndFocus);
57}
58
59//////////////////////////////////////////////////////////////////////////
60// SDropDownWnd_ComboBox
61BOOL SDropDownWnd_ComboBox::PreTranslateMessage(MSG *pMsg)
62{
64 return TRUE;
65 if (pMsg->message == WM_MOUSEWHEEL || ((pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)))
66 { //截获滚轮及上下键消息
67 SNativeWnd::SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
68 return TRUE;
69 }
70 return FALSE;
71}
72
73//////////////////////////////////////////////////////////////////////////
74// SComboBoxBase
75SComboBase::SComboBase(void)
76 : m_pSkinBtn(GETBUILTINSKIN(SKIN_SYS_DROPBTN))
77 , m_pEdit(NULL)
78 , m_bDropdown(TRUE)
79 , m_nDropHeight(200, SLayoutSize::dp)
80 , m_dwBtnState(WndState_Normal)
81 , m_nAnimTime(200)
82 , m_pDropDownWnd(NULL)
83 , m_iInitSel(-1)
84 , m_bAutoFitDropBtn(TRUE)
85 , m_crCue(RGBA(0xcc, 0xcc, 0xcc, 0xff))
86 , m_strCue(this)
87 , m_LastPressTime(0)
88 , m_bAutoMatch(FALSE)
89 , m_bAutoDropdown(FALSE)
90 , m_nTextLength(0)
91{
92 m_bFocusable = TRUE;
93 m_style.SetAlign(SwndStyle::Align_Left);
94 m_style.SetVAlign(SwndStyle::VAlign_Middle);
95
96 m_evtSet.addEvent(EVENTID(EventCBSelChange));
97 m_evtSet.addEvent(EVENTID(EventRENotify));
98 m_evtSet.addEvent(EVENTID(EventCBDropdown));
99 m_evtSet.addEvent(EVENTID(EventCBBeforeCloseUp));
100}
101
102SComboBase::~SComboBase(void)
103{
104}
105
106BOOL SComboBase::CreateChildren(SXmlNode xmlNode)
107{
108 m_xmlDropdownStyle.root().append_copy(xmlNode.child(KStyle_Dropdown));
109 //创建edit对象
110 SXmlNode xmlEditStyle = xmlNode.child(KStyle_Edit);
111 SStringW strEditClass = xmlEditStyle.attribute(L"wndclass").as_string(SComboEdit::GetClassName());
112 m_pEdit = sobj_cast<SComboEdit>(CreateChildByName(strEditClass));
113 if (!m_pEdit)
114 return FALSE;
115 m_pEdit->SetOwner(this);
116 InsertChild(m_pEdit);
117 m_pEdit->GetEventSet()->setMutedState(TRUE);
118 if (xmlEditStyle)
119 m_pEdit->InitFromXml(&xmlEditStyle);
120 else
121 m_pEdit->SSendMessage(WM_CREATE);
122 m_pEdit->GetEventSet()->setMutedState(FALSE);
123
124 m_pEdit->SetID(IDC_CB_EDIT);
125 m_pEdit->SSendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE);
126 m_pEdit->SetVisible(!m_bDropdown);
127 GetEventSet()->setMutedState(TRUE);
128 BOOL ret = CreateListBox(xmlNode);
129 GetEventSet()->setMutedState(FALSE);
130 return ret;
131}
132
133void SComboBase::GetDropBtnRect(LPRECT prc)
134{
135 SIZE szBtn = m_pSkinBtn->GetSkinSize();
136 CRect rcClient = GetClientRect();
137 CRect rcPadding = GetStyle().GetPadding();
138 rcClient.DeflateRect(rcPadding);
139 *prc = rcClient;
140
141 int nHei = prc->bottom - prc->top;
142 prc->left = prc->right - nHei * szBtn.cx / szBtn.cy;
143 if (m_bAutoFitDropBtn && szBtn.cy < nHei)
144 {
145 prc->top += (prc->bottom - prc->top - szBtn.cy) / 2;
146 prc->left = prc->right - szBtn.cx;
147 prc->right = prc->left + szBtn.cx;
148 prc->bottom = prc->top + szBtn.cy;
149 }
150}
151
152void SComboBase::GetTextRect(LPRECT pRect)
153{
154 CRect rc = GetClientRect();
155 rc.DeflateRect(GetStyle().GetPadding());
156 CRect rcBtn;
157 GetDropBtnRect(&rcBtn);
158 rc.right -= rcBtn.Width();
159 *pRect = rc;
160}
161
162void SComboBase::OnPaint(IRenderTarget *pRT)
163{
164 SPainter painter;
165
166 BeforePaint(pRT, painter);
167 if (m_bDropdown)
168 {
169 CRect rcText;
170 GetTextRect(rcText);
171 if (GetCurSel() != -1)
172 {
173 SStringT strText = GetWindowText();
174 DrawText(pRT, strText, strText.GetLength(), rcText, GetTextAlign());
175 }
176 else
177 {
178 SStringT strCue = GetCueText();
179 if (!strCue.IsEmpty())
180 {
181 COLORREF crOld = pRT->SetTextColor(m_crCue);
182 DrawText(pRT, strCue, strCue.GetLength(), rcText, GetTextAlign());
183 pRT->SetTextColor(crOld);
184 }
185 }
186 }
187 // draw focus rect
188 if (IsFocused())
189 {
190 DrawFocus(pRT);
191 }
192 AfterPaint(pRT, painter);
193 CRect rcBtn;
194 GetDropBtnRect(&rcBtn);
195 m_pSkinBtn->DrawByState(pRT, rcBtn, m_dwBtnState);
196}
197
198void SComboBase::OnLButtonDown(UINT nFlags, CPoint pt)
199{
200 if (m_bFocusable)
201 SetFocus();
202 DropDown();
203}
204
205void SComboBase::OnMouseMove(UINT nFlags, CPoint pt)
206{
207 if (m_dwBtnState == WndState_PushDown)
208 return;
209
210 __baseCls::OnMouseHover(nFlags, pt);
211 CRect rcBtn;
212 GetDropBtnRect(&rcBtn);
213 if (rcBtn.PtInRect(pt))
214 {
215 m_dwBtnState = WndState_Hover;
216 InvalidateRect(rcBtn);
217 }
218 else if (m_dwBtnState == WndState_Hover)
219 {
220 m_dwBtnState = WndState_Normal;
221 InvalidateRect(rcBtn);
222 }
223}
224
225void SComboBase::OnMouseLeave()
226{
227 if (m_dwBtnState == WndState_PushDown)
228 return;
229
230 if (GetState() & WndState_Hover)
231 __baseCls::OnMouseLeave();
232 if (m_dwBtnState == WndState_Hover)
233 {
234 m_dwBtnState = WndState_Normal;
235 CRect rcBtn;
236 GetDropBtnRect(&rcBtn);
237 InvalidateRect(rcBtn);
238 }
239}
240
241void SComboBase::OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags)
242{
243 //方向键改变当前选项
244 switch (nChar)
245 {
246 case VK_DOWN:
247 case VK_RIGHT:
248 {
249 int iSel = GetCurSel();
250 iSel += 1;
251 if (iSel < GetCount())
252 SetCurSel(iSel);
253 }
254 break;
255 case VK_UP:
256 case VK_LEFT:
257 {
258 int iSel = GetCurSel();
259 iSel -= 1;
260 if (iSel < GetCount() && iSel >= 0)
261 SetCurSel(iSel);
262 }
263 break;
264 default:
265 {
266 if (isprint(nChar))
267 {
268 if ((GetTickCount() - m_LastPressTime) > 300)
269 {
270 m_strMatch.Empty();
271 }
272 m_LastPressTime = GetTickCount();
273 m_strMatch += nChar;
274 int iCurSel = GetCurSel();
275 int iStart = iCurSel + 1;
276 bool matched = false;
277 while (iStart < GetCount())
278 {
279 SStringT itemText = GetLBText(iStart);
280 if (itemText.StartsWith(m_strMatch, true))
281 {
282 SetCurSel(iStart);
283 matched = true;
284 break;
285 }
286 iStart++;
287 }
288 if (!matched)
289 {
290 iStart = 0;
291 while (iStart <= iCurSel)
292 {
293 SStringT itemText = GetLBText(iStart);
294 if (itemText.StartsWith(m_strMatch, true))
295 {
296 SetCurSel(iStart);
297 matched = true;
298 break;
299 }
300 iStart++;
301 }
302 }
303 }
304 }
305 }
306}
307
308BOOL SComboBase::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
309{
310 //鼠标滚轮改变当前选项
311 if (zDelta > 0) // 上滚
312 {
313 int iSel = GetCurSel();
314 iSel -= 1;
315 if (iSel < GetCount() && iSel >= 0)
316 SetCurSel(iSel);
317 }
318 else // 下滚
319 {
320 int iSel = GetCurSel();
321 iSel += 1;
322 if (iSel < GetCount())
323 SetCurSel(iSel);
324 }
325 return TRUE;
326}
327
328void SComboBase::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
329{
330 if (!m_bDropdown)
331 {
332 SComboEdit *pEdit = static_cast<SComboEdit *>(FindChildByID(IDC_CB_EDIT));
333 if (pEdit)
334 pEdit->SSendMessage(WM_CHAR, nChar, MAKELONG(nFlags, nRepCnt));
335 return;
336 }
337}
338
339UINT SComboBase::OnGetDlgCode() const
340{
341 return SC_WANTARROWS;
342}
343
344BOOL SComboBase::IsFocusable() const
345{
346 if (m_bDropdown && m_bFocusable)
347 return TRUE;
348 return FALSE;
349}
350
351SWindow *SComboBase::GetDropDownOwner()
352{
353 return this;
354}
355
356static const wchar_t *KAttrTrCtx = L"trCtx";
357void SComboBase::OnCreateDropDown(SDropDownWnd *pDropDown)
358{
360 SXmlNode xmlDropdownStyleNode = m_xmlDropdownStyle.root().child(KStyle_Dropdown);
361 if (xmlDropdownStyleNode)
362 {
363 if (!xmlDropdownStyleNode.attribute(KAttrTrCtx))
364 {
365 xmlDropdownStyleNode.append_attribute(KAttrTrCtx).set_value(GetTrCtx());
366 }
367 pDropDown->InitFromXml(&xmlDropdownStyleNode);
368 }
369 else
370 {
371 pDropDown->GetHostAttr().SetTrCtx(GetTrCtx());
372 }
374 m_dwBtnState = WndState_PushDown;
375 CRect rcBtn;
376 GetDropBtnRect(&rcBtn);
377 InvalidateRect(rcBtn);
378}
379
380void SComboBase::OnDestroyDropDown(SDropDownWnd *pDropDown)
381{
382 if (!m_bDropdown)
383 {
384 m_pEdit->SetFocus();
385 }
386
387 m_dwBtnState = WndState_Normal;
388 m_pDropDownWnd = NULL;
389 CRect rcBtn;
390 GetDropBtnRect(&rcBtn);
391 InvalidateRect(rcBtn);
392 ModifyState(0, WndState_Hover, TRUE);
393 CPoint pt;
394 GetCursorPos(&pt);
395 ScreenToClient(GetContainer()->GetHostHwnd(), &pt);
396 ::PostMessage(GetContainer()->GetHostHwnd(), WM_MOUSEMOVE, 0, MAKELPARAM(pt.x, pt.y));
397
398 if (pDropDown->GetExitCode() == IDOK)
399 {
400 OnSelChanged();
401 }
402}
403
404BOOL SComboBase::CalcPopupRect(int nHeight, CRect &rcPopup)
405{
406 CRect rcWnd = GetWindowRect();
407 GetContainer()->FrameToHost(&rcWnd);
408
409 ClientToScreen(GetContainer()->GetHostHwnd(), (LPPOINT)&rcWnd);
410 ClientToScreen(GetContainer()->GetHostHwnd(), ((LPPOINT)&rcWnd) + 1);
411
412 HMONITOR hMonitor = ::MonitorFromWindow(GetContainer()->GetHostHwnd(), MONITOR_DEFAULTTONULL);
413 CRect rcMonitor;
414 if (hMonitor)
415 {
416 MONITORINFO mi = { sizeof(MONITORINFO) };
417 ::GetMonitorInfo(hMonitor, &mi);
418 rcMonitor = mi.rcMonitor;
419 }
420 else
421 {
422 rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
423 rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
424 }
425 if (rcWnd.bottom + nHeight <= rcMonitor.bottom)
426 {
427 rcPopup = CRect(rcWnd.left, rcWnd.bottom, rcWnd.right, rcWnd.bottom + nHeight);
428 return TRUE;
429 }
430 else
431 {
432 rcPopup = CRect(rcWnd.left, rcWnd.top - nHeight, rcWnd.right, rcWnd.top);
433 return FALSE;
434 }
435}
436
437void SComboBase::DropDown()
438{
439 if (m_dwBtnState == WndState_PushDown)
440 return;
441
442 if (!m_pDropDownWnd)
443 {
444 m_pDropDownWnd = new SDropDownWnd_ComboBox(this);
445 }
446
447 EventCBDropdown evt(this);
448 evt.pDropDown = m_pDropDownWnd;
449 SStringT strInput = GetWindowText(TRUE);
450 evt.strInput = NULL;
451 FireEvent(&evt);
452 m_pDropDownWnd->Create(CRect(0, 0, 100, 100), 0);
453 m_pDropDownWnd->GetRoot()->SDispatchMessage(UM_SETSCALE, GetScale(), 0);
454
455 CRect rcPadding = m_pDropDownWnd->GetRoot()->GetStyle().GetPadding();
456 CRect rcMargin = m_pDropDownWnd->GetRoot()->GetStyle().GetMargin();
457 int nDropHeight = GetListBoxHeight() + rcPadding.top + rcPadding.bottom + rcMargin.top + rcMargin.bottom;
458
459 CRect rcPopup;
460 BOOL bDown = CalcPopupRect(nDropHeight, rcPopup);
461 m_pDropDownWnd->MoveWindow(rcPopup.left, rcPopup.top, rcPopup.Width(), rcPopup.Height());
462 m_pDropDownWnd->GetRoot()->UpdateChildrenPosition();
463
464#ifdef _WIN32
465 if (m_nAnimTime > 0)
466 m_pDropDownWnd->AnimateHostWindow(m_nAnimTime, AW_SLIDE | (bDown ? AW_VER_POSITIVE : AW_VER_NEGATIVE));
467 else
468 m_pDropDownWnd->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
469#else
470 m_pDropDownWnd->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
471#endif
472 m_pDropDownWnd->SNativeWnd::SetCapture();
473}
474
475void SComboBase::UpdateDropdown(const SStringT &strInput)
476{
477 if (!m_pDropDownWnd)
478 {
479 m_pDropDownWnd = new SDropDownWnd_ComboBox(this);
480 m_pDropDownWnd->GetRoot()->SDispatchMessage(UM_SETSCALE, GetScale(), 0);
481 }
482
483 EventCBDropdown evt(this);
484 evt.pDropDown = m_pDropDownWnd;
485 evt.strInput = &strInput;
486 FireEvent(&evt);
487 BOOL bNewPopup = !m_pDropDownWnd->IsWindow();
488 if (bNewPopup)
489 m_pDropDownWnd->Create(CRect(0, 0, 100, 100), 0);
490
491 CRect rcPadding = m_pDropDownWnd->GetRoot()->GetStyle().GetPadding();
492 CRect rcMargin = m_pDropDownWnd->GetRoot()->GetStyle().GetMargin();
493 int nDropHeight = GetListBoxHeight() + rcPadding.top + rcPadding.bottom + rcMargin.top + rcMargin.bottom;
494
495 CRect rcPopup;
496 BOOL bDown = CalcPopupRect(nDropHeight, rcPopup);
497 m_pDropDownWnd->MoveWindow(rcPopup.left, rcPopup.top, rcPopup.Width(), rcPopup.Height());
498 m_pDropDownWnd->GetRoot()->UpdateChildrenPosition();
499
500#ifdef _WIN32
501 if (m_nAnimTime > 0 && bNewPopup)
502 m_pDropDownWnd->AnimateHostWindow(m_nAnimTime, AW_SLIDE | (bDown ? AW_VER_POSITIVE : AW_VER_NEGATIVE));
503 else
504 m_pDropDownWnd->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
505#else
506 m_pDropDownWnd->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
507#endif
508 m_pDropDownWnd->SNativeWnd::SetCapture();
509}
510
511void SComboBase::CloseUp()
512{
513 EventCBBeforeCloseUp evt(this);
514 evt.bCloseBlock = FALSE;
515 FireEvent(&evt);
516
517 if (!evt.bCloseBlock && m_pDropDownWnd)
518 {
519 m_pDropDownWnd->EndDropDown(IDCANCEL);
520 }
521}
522
523void SComboBase::OnDestroy()
524{
525 CloseUp();
526 __baseCls::OnDestroy();
527}
528
529int SComboBase::OnCreate(LPVOID)
530{
531 int ret = __baseCls::OnCreate(NULL);
532 if (ret != 0)
533 return ret;
534 if (!m_pSkinBtn)
535 return -1;
536 return 0;
537}
538
539void SComboBase::OnSelChanged()
540{
541 EventCBSelChange evt(this);
542 evt.nCurSel = GetCurSel();
543 FireEvent(&evt);
544}
545
546BOOL SComboBase::FireEvent(IEvtArgs *evt)
547{
548 if (evt->GetID() == EventRENotify::EventID)
549 {
550 EventRENotify *evtRe = (EventRENotify *)evt;
551 if (evtRe->iNotify == EN_CHANGE && !m_pEdit->GetEventSet()->isMuted())
552 {
553 m_pEdit->GetEventSet()->setMutedState(true);
554 SStringT strTxt = m_pEdit->GetWindowText();
555 if (m_bAutoMatch)
556 {
557 if (strTxt.GetLength() > m_nTextLength)
558 {
559 int iItem = FindString(strTxt, -1, TRUE);
560 if (iItem != -1)
561 {
562 SStringT strItem = GetLBText(iItem);
563 m_pEdit->SetWindowText(strItem);
564 m_pEdit->SetSel(strTxt.GetLength(), strItem.GetLength(), TRUE);
565 }
566 }
567 m_nTextLength = strTxt.GetLength();
568 }
569 if (m_bAutoDropdown)
570 {
571 UpdateDropdown(strTxt);
572 }
573
574 GetEventSet()->setMutedState(true);
575 SetCurSel(-1);
576 GetEventSet()->setMutedState(false);
577 m_pEdit->GetEventSet()->setMutedState(false);
578 }
579 }
580 return SWindow::FireEvent(evt);
581}
582
583int SComboBase::FindString(LPCTSTR pszFind, int iFindAfter /*=-1*/, BOOL bPartMatch /*=TRUE*/)
584{
585 if (iFindAfter < 0)
586 iFindAfter = -1;
587 int iStart = iFindAfter + 1;
588 for (int i = 0; i < GetCount(); i++)
589 {
590 int iTarget = (i + iStart) % GetCount();
591 SStringT strItem = GetLBText(iTarget, TRUE);
592 if (bPartMatch)
593 {
594 if (strItem.StartsWith(pszFind))
595 return iTarget;
596 }
597 else
598 {
599 if (strItem.Compare(pszFind) == 0)
600 return iTarget;
601 }
602 }
603 return -1;
604}
605
606void SComboBase::GetDesiredSize(SIZE *psz, int nParentWid, int nParentHei)
607{
608 CSize szRet(-1, -1);
609 if (GetLayoutParam()->IsSpecifiedSize(Horz))
610 { //检查设置大小
611 szRet.cx = GetLayoutParam()->GetSpecifiedSize(Horz).toPixelSize(GetScale());
612 }
613 else if (GetLayoutParam()->IsMatchParent(Horz))
614 {
615 szRet.cx = nParentWid;
616 }
617
618 if (GetLayoutParam()->IsSpecifiedSize(Vert))
619 { //检查设置大小
620 szRet.cy = GetLayoutParam()->GetSpecifiedSize(Vert).toPixelSize(GetScale());
621 }
622 else if (GetLayoutParam()->IsMatchParent(Vert))
623 {
624 szRet.cy = nParentHei;
625 }
626
627 if (szRet.cx != -1 && szRet.cy != -1)
628 {
629 *psz = szRet;
630 return;
631 }
632 int nTestDrawMode = GetTextAlign() & ~(DT_CENTER | DT_RIGHT | DT_VCENTER | DT_BOTTOM);
633
634 CRect rcPadding = GetStyle().GetPadding();
635 //计算文本大小
636 CRect rcTest(0, 0, 100000, 100000);
637
638 SAutoRefPtr<IRenderTarget> pRT;
639 GETRENDERFACTORY->CreateRenderTarget(&pRT, 0, 0);
640 BeforePaintEx(pRT);
641
642 SStringT strText = GetWindowText(FALSE);
643 SStringT strForText = strText.IsEmpty() ? SStringT(_T("A")) : strText;
644 DrawText(pRT, strForText, strForText.GetLength(), rcTest, nTestDrawMode | DT_CALCRECT);
645 if (strText.IsEmpty())
646 rcTest.right = rcTest.left;
647
648 SIZE szBtn = m_pSkinBtn->GetSkinSize();
649 rcTest.right += szBtn.cx;
650 rcTest.bottom = smax(rcTest.Height(), szBtn.cy);
651
652 rcTest.InflateRect(m_style.GetMargin());
653 rcTest.InflateRect(rcPadding);
654
655 if (GetLayoutParam()->IsWrapContent(Horz))
656 szRet.cx = rcTest.Width();
657 if (GetLayoutParam()->IsWrapContent(Vert))
658 szRet.cy = rcTest.Height();
659
660 *psz = szRet;
661}
662
663SStringT SComboBase::GetWindowText(BOOL bRawText /*=TRUE*/)
664{
665 if (!m_bDropdown)
666 {
667 return GetEditText();
668 }
669 if (GetCurSel() == -1)
670 return _T("");
671 return GetLBText(GetCurSel(), bRawText);
672}
673
674void SComboBase::SetWindowText(LPCTSTR pszText)
675{
676 SWindow::SetWindowText(pszText);
677 m_pEdit->SetWindowText(pszText);
678 m_nTextLength = (int)_tcslen(pszText);
679}
680
681void SComboBase::OnKillFocus(SWND wndFocus)
682{
683 __baseCls::OnKillFocus(wndFocus);
684 CloseUp();
685}
686
687HRESULT SComboBase::OnAttrDropDown(const SStringW &strValue, BOOL bLoading)
688{
689 m_bDropdown = STRINGASBOOL(strValue);
690 if (bLoading)
691 return S_OK;
692 m_pEdit->SetVisible(!m_bDropdown, TRUE);
693 return S_OK;
694}
695
696void SComboBase::UpdateChildrenPosition()
697{
698 __baseCls::UpdateChildrenPosition();
699 SIZE szBtn = m_pSkinBtn->GetSkinSize();
700 CRect rcPadding = GetStyle().GetPadding();
701 CRect rcEdit = GetClientRect();
702 CRect rcBtn;
703 GetDropBtnRect(&rcBtn);
704 rcEdit.right = rcBtn.left;
705 m_pEdit->Move(rcEdit);
706}
707
708void SComboBase::OnColorize(COLORREF cr)
709{
710 __baseCls::OnColorize(cr);
711 if (m_pSkinBtn)
712 m_pSkinBtn->OnColorize(cr);
713 if (m_pDropDownWnd)
714 {
715 m_pDropDownWnd->GetRoot()->SDispatchMessage(UM_SETCOLORIZE, cr, 0);
716 }
717}
718
719HRESULT SComboBase::OnLanguageChanged()
720{
721 HRESULT hr = __baseCls::OnLanguageChanged();
722 if (m_pDropDownWnd)
723 {
724 m_pDropDownWnd->GetRoot()->SDispatchMessage(UM_SETLANGUAGE, 0, 0);
725 }
726 return hr;
727}
728
729void SComboBase::OnScaleChanged(int nScale)
730{
731 __baseCls::OnScaleChanged(nScale);
732 if (m_pDropDownWnd)
733 {
734 m_pDropDownWnd->GetRoot()->SDispatchMessage(UM_SETSCALE, nScale, 0);
735 }
736 GetScaleSkin(m_pSkinBtn, nScale);
737}
738
739BOOL SComboBase::IsDropdown() const
740{
741 return m_bDropdown;
742}
743
744void SComboBase::SetDropdown(BOOL bDropdown)
745{
746 m_bDropdown = bDropdown;
747 m_pEdit->SetVisible(!m_bDropdown, TRUE);
748}
749
750SStringT SComboBase::GetCueText(BOOL bRawText) const
751{
752 return m_strCue.GetText(bRawText);
753}
754
755void SComboBase::SetFocus()
756{
757 if (!m_bDropdown)
758 m_pEdit->SetFocus();
759 else
760 __baseCls::SetFocus();
761}
762
763SStringT SComboBase::GetLBText(int iItem, BOOL bRawText /*= FALSE*/)
764{
765 SStringT str;
766 GetItemText(iItem, bRawText, &str);
767 return str;
768}
769
770SNSEND
@ EVT_RE_NOTIFY
丰富编辑控件通知事件
Definition SEvents.h:111
@ WndState_Hover
Definition SWnd.h:76
@ WndState_Normal
Definition SWnd.h:75
@ WndState_PushDown
Definition SWnd.h:77
virtual ~SComboEdit()
Destructor.
void OnMouseHover(WPARAM wParam, CPoint ptPos)
Handle mouse hover event.
SComboEdit()
Constructor.
void OnMouseLeave()
Handle mouse leave event.
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
Notify event.
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
Handle key down event.
void OnKillFocus(SWND wndFocus)
Handle kill focus event.
Dropdown Window Class.
Definition SDropDown.h:43
UINT GetExitCode() const
Get the exit code of the dropdown window.
Definition SDropDown.h:84
virtual BOOL WINAPI PreTranslateMessage(MSG *pMsg)
Pre-translate messages.
void setMutedState(BOOL setting)
设置事件集的静音状态
void SetTrCtx(const SStringW &strTrCtx)
Sets the translation context.
Definition shostwnd.cpp:130
BOOL InitFromXml(IXmlNode *pNode) OVERRIDE
Initializes the host window from an XML node.
Definition shostwnd.cpp:440
SHostWndAttr & GetHostAttr()
Gets the host window attributes.
Definition SHostWnd.h:719
布局大小类
Definition SLayoutSize.h:10
int toPixelSize(int scale) const
将大小转换为像素值
LRESULT SendMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Sends a message to the window.
BOOL IsEmpty() SCONST
Checks if the string is empty.
A class representing an ASCII string.
Definition sstringw.h:96
Base class for SOUI DUI windows.
Definition SWnd.h:286
virtual LPCWSTR GetTrCtx() const
Get translation context.
Definition Swnd.cpp:3258
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
Fires an event.
Definition Swnd.cpp:1540
DWORD GetState() SCONST OVERRIDE
Retrieves the current state of the window.
Definition Swnd.cpp:437
SwndStyle m_style
Definition SWnd.h:2596
UINT GetTextAlign() const
Retrieves the text alignment of the window.
Definition Swnd.cpp:218
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
ISwndContainer * GetContainer() OVERRIDE
Retrieves the container associated with this window.
Definition Swnd.cpp:679
BOOL IsFocused() SCONST OVERRIDE
Checks if the window has focus.
Definition Swnd.cpp:2639
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
Definition Swnd.cpp:243
void InsertChild(SWindow *pNewChild, SWindow *pInsertAfter=NULL)
Inserts a child window into the window tree.
Definition Swnd.cpp:538
LRESULT SSendMessage(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0, BOOL *pbMsgHandled=NULL) OVERRIDE
Sends a message to the window.
Definition Swnd.cpp:364
virtual void BeforePaint(IRenderTarget *pRT, SPainter &painter)
Prepare rendering environment.
Definition Swnd.cpp:1755
void InvalidateRect(LPCRECT lprect) OVERRIDE
Invalidates a specific rectangle area of the window.
Definition Swnd.cpp:1444
BOOL m_bFocusable
Definition SWnd.h:2609
virtual SWindow * CreateChildByName(LPCWSTR pszName)
Create child window by name.
Definition Swnd.cpp:935
virtual void DrawFocus(IRenderTarget *pRT)
Draw focus state.
Definition Swnd.cpp:1973
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
virtual void DrawText(IRenderTarget *pRT, LPCTSTR pszBuf, int cchText, LPRECT pRect, UINT uFormat)
Draw text content.
Definition Swnd.cpp:1968
SEventSet * GetEventSet()
Retrieves the event set associated with the window.
Definition SWnd.h:1290
void SetWindowText(LPCTSTR lpszText) OVERRIDE
Sets the window text.
Definition Swnd.cpp:311
void GetScaleSkin(SAutoRefPtr< ISkinObj > &pSkin, int nScale)
Retrieves a scaled skin object based on the current scale factor.
Definition Swnd.cpp:3290
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
HWND GetHostHwnd() OVERRIDE
Retrieves the host window handle.
Definition Swnd.cpp:3616
SWindow * FindChildByID(int nID, int nDeep=-1)
Finds a child window by its ID.
Definition Swnd.cpp:781
void BeforePaintEx(IRenderTarget *pRT)
Prepares the drawing environment for the current window's RenderTarget, starting from the top-level w...
Definition Swnd.cpp:1767
bool set_value(const wchar_t *rhs)
Sets the attribute value.
Definition SXml.cpp:130
const wchar_t * as_string(const wchar_t *def=L"") const
Gets the attribute value as a string.
Definition SXml.cpp:95
Class representing an XML node.
Definition SXml.h:352
SXmlAttr attribute(const wchar_t *name, bool bCaseSensitive=false) const
Gets the attribute with the specified name.
Definition SXml.cpp:428
SXmlAttr append_attribute(const wchar_t *name)
Adds an attribute with the specified name.
Definition SXml.cpp:458
SXmlNode child(const wchar_t *name, bool bCaseSensitive=false) const
Gets the child node, attribute, or next/previous sibling with the specified name.
Definition SXml.cpp:423
CRect GetPadding() const
Retrieves the padding rectangle.
Interface for rendering target objects.
Definition SRender-i.h:1440
COLORREF SetTextColor(COLORREF color) PURE
Sets the current text color.
void FrameToHost(RECT *rc) SCONST PURE
Converts the rectangle coordinates of the current frame to the final host coordinates.
void EnableHostPrivateUiDef(BOOL bEnable) PURE
Enables or disables the host's private UI definitions.