UICombo.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. #include "StdAfx.h"
  2. namespace DuiLib {
  3. /////////////////////////////////////////////////////////////////////////////////////
  4. //
  5. class CComboBodyUI : public CVerticalLayoutUI
  6. {
  7. public:
  8. CComboBodyUI::CComboBodyUI(CComboUI* pOwner);
  9. bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
  10. protected:
  11. CComboUI* m_pOwner;
  12. };
  13. CComboBodyUI::CComboBodyUI(CComboUI* pOwner) : m_pOwner(pOwner)
  14. {
  15. ASSERT(m_pOwner);
  16. }
  17. bool CComboBodyUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl) {
  18. RECT rcTemp = { 0 };
  19. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true;
  20. TListInfoUI* pListInfo = NULL;
  21. if( m_pOwner ) pListInfo = m_pOwner->GetListInfo();
  22. CRenderClip clip;
  23. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  24. CControlUI::DoPaint(hDC, rcPaint, pStopControl);
  25. if( m_items.GetSize() > 0 ) {
  26. RECT rc = m_rcItem;
  27. rc.left += m_rcInset.left;
  28. rc.top += m_rcInset.top;
  29. rc.right -= m_rcInset.right;
  30. rc.bottom -= m_rcInset.bottom;
  31. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  32. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  33. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  34. for( int it = 0; it < m_items.GetSize(); it++ ) {
  35. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  36. if( pControl == pStopControl ) return false;
  37. if( !pControl->IsVisible() ) continue;
  38. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  39. if( pControl->IsFloat() ) {
  40. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  41. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  42. }
  43. }
  44. }
  45. else {
  46. int iDrawIndex = 0;
  47. CRenderClip childClip;
  48. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  49. for( int it = 0; it < m_items.GetSize(); it++ ) {
  50. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  51. if( pControl == pStopControl ) return false;
  52. if( !pControl->IsVisible() ) continue;
  53. if( !pControl->IsFloat() ) {
  54. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  55. if( pListItem != NULL ) {
  56. pListItem->SetDrawIndex(iDrawIndex);
  57. iDrawIndex += 1;
  58. }
  59. if (pListInfo && pListInfo->iHLineSize > 0) {
  60. // 因为没有为最后一个预留分割条长度,如果list铺满,最后一条不会显示
  61. RECT rcPadding = pControl->GetPadding();
  62. const RECT& rcPos = pControl->GetPos();
  63. RECT rcBottomLine = { rcPos.left, rcPos.bottom + rcPadding.bottom, rcPos.right, rcPos.bottom + rcPadding.bottom + pListInfo->iHLineSize };
  64. if( ::IntersectRect(&rcTemp, &rcPaint, &rcBottomLine) ) {
  65. rcBottomLine.top += pListInfo->iHLineSize / 2;
  66. rcBottomLine.bottom = rcBottomLine.top;
  67. CRenderEngine::DrawLine(hDC, rcBottomLine, pListInfo->iHLineSize, GetAdjustColor(pListInfo->dwHLineColor));
  68. }
  69. }
  70. }
  71. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  72. if( pControl->IsFloat() ) {
  73. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  74. CRenderClip::UseOldClipBegin(hDC, childClip);
  75. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  76. CRenderClip::UseOldClipEnd(hDC, childClip);
  77. }
  78. else {
  79. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  80. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  81. }
  82. }
  83. }
  84. }
  85. if( m_pVerticalScrollBar != NULL ) {
  86. if( m_pVerticalScrollBar == pStopControl ) return false;
  87. if (m_pVerticalScrollBar->IsVisible()) {
  88. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  89. if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  90. }
  91. }
  92. }
  93. if( m_pHorizontalScrollBar != NULL ) {
  94. if( m_pHorizontalScrollBar == pStopControl ) return false;
  95. if (m_pHorizontalScrollBar->IsVisible()) {
  96. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  97. if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  98. }
  99. }
  100. }
  101. return true;
  102. }
  103. /////////////////////////////////////////////////////////////////////////////////////
  104. //
  105. //
  106. class CComboWnd : public CWindowWnd
  107. {
  108. public:
  109. void Init(CComboUI* pOwner);
  110. LPCTSTR GetWindowClassName() const;
  111. void OnFinalMessage(HWND hWnd);
  112. LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
  113. void EnsureVisible(int iIndex);
  114. void Scroll(int dx, int dy);
  115. #if(_WIN32_WINNT >= 0x0501)
  116. virtual UINT GetClassStyle() const;
  117. #endif
  118. public:
  119. CPaintManagerUI m_pm;
  120. CComboUI* m_pOwner;
  121. CVerticalLayoutUI* m_pLayout;
  122. int m_iOldSel;
  123. bool m_bScrollbarClicked;
  124. };
  125. void CComboWnd::Init(CComboUI* pOwner)
  126. {
  127. m_pOwner = pOwner;
  128. m_pLayout = NULL;
  129. m_iOldSel = m_pOwner->GetCurSel();
  130. m_bScrollbarClicked = false;
  131. // Position the popup window in absolute space
  132. SIZE szDrop = m_pOwner->GetDropBoxSize();
  133. RECT rcOwner = pOwner->GetPos();
  134. RECT rc = rcOwner;
  135. rc.top = rc.bottom; // 父窗口left、bottom位置作为弹出窗口起点
  136. rc.bottom = rc.top + szDrop.cy; // 计算弹出窗口高度
  137. if( szDrop.cx > 0 ) rc.right = rc.left + szDrop.cx; // 计算弹出窗口宽度
  138. SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };
  139. int cyFixed = 0;
  140. for( int it = 0; it < pOwner->GetCount(); it++ ) {
  141. CControlUI* pControl = static_cast<CControlUI*>(pOwner->GetItemAt(it));
  142. if( !pControl->IsVisible() ) continue;
  143. SIZE sz = pControl->EstimateSize(szAvailable);
  144. cyFixed += sz.cy;
  145. }
  146. cyFixed += 4; // CVerticalLayoutUI 默认的Inset 调整
  147. rc.bottom = rc.top + MIN(cyFixed, szDrop.cy);
  148. ::MapWindowRect(pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc);
  149. MONITORINFO oMonitor = {};
  150. oMonitor.cbSize = sizeof(oMonitor);
  151. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  152. CDuiRect rcWork = oMonitor.rcWork;
  153. if( rc.bottom > rcWork.bottom ) {
  154. rc.left = rcOwner.left;
  155. rc.right = rcOwner.right;
  156. if( szDrop.cx > 0 ) rc.right = rc.left + szDrop.cx;
  157. rc.top = rcOwner.top - MIN(cyFixed, szDrop.cy);
  158. rc.bottom = rcOwner.top;
  159. ::MapWindowRect(pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc);
  160. }
  161. Create(pOwner->GetManager()->GetPaintWindow(), NULL, WS_POPUP, WS_EX_TOOLWINDOW, rc);
  162. // HACK: Don't deselect the parent's caption
  163. HWND hWndParent = m_hWnd;
  164. while( ::GetParent(hWndParent) != NULL ) hWndParent = ::GetParent(hWndParent);
  165. ::ShowWindow(m_hWnd, SW_SHOW);
  166. //::SendMessage(hWndParent, WM_NCACTIVATE, TRUE, 0L);
  167. }
  168. LPCTSTR CComboWnd::GetWindowClassName() const
  169. {
  170. return _T("ComboWnd");
  171. }
  172. void CComboWnd::OnFinalMessage(HWND hWnd)
  173. {
  174. m_pOwner->m_pWindow = NULL;
  175. m_pOwner->m_uButtonState &= ~ UISTATE_PUSHED;
  176. m_pOwner->Invalidate();
  177. delete this;
  178. }
  179. LRESULT CComboWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  180. {
  181. if( uMsg == WM_CREATE ) {
  182. m_pm.SetForceUseSharedRes(true);
  183. m_pm.Init(m_hWnd);
  184. // The trick is to add the items to the new container. Their owner gets
  185. // reassigned by this operation - which is why it is important to reassign
  186. // the items back to the righfull owner/manager when the window closes.
  187. m_pLayout = new CComboBodyUI(m_pOwner);
  188. m_pLayout->SetManager(&m_pm, NULL, true);
  189. LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(_T("VerticalLayout"));
  190. if( pDefaultAttributes ) {
  191. m_pLayout->SetAttributeList(pDefaultAttributes);
  192. }
  193. m_pLayout->SetInset(CDuiRect(1, 1, 1, 1));
  194. m_pLayout->SetBkColor(0xFFFFFFFF);
  195. m_pLayout->SetBorderColor(0xFFC6C7D2);
  196. m_pLayout->SetBorderSize(1);
  197. m_pLayout->SetAutoDestroy(false);
  198. m_pLayout->EnableScrollBar();
  199. m_pLayout->SetAttributeList(m_pOwner->GetDropBoxAttributeList());
  200. for( int i = 0; i < m_pOwner->GetCount(); i++ ) {
  201. m_pLayout->Add(static_cast<CControlUI*>(m_pOwner->GetItemAt(i)));
  202. }
  203. m_pm.AttachDialog(m_pLayout);
  204. return 0;
  205. }
  206. else if( uMsg == WM_CLOSE ) {
  207. m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false);
  208. if( !m_pOwner->IsFloat() ) m_pOwner->SetPos(m_pOwner->GetPos(), false);
  209. else m_pOwner->SetPos(m_pOwner->GetRelativePos(), false);
  210. m_pOwner->SetFocus();
  211. }
  212. else if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) {
  213. POINT pt = { 0 };
  214. ::GetCursorPos(&pt);
  215. ::ScreenToClient(m_pm.GetPaintWindow(), &pt);
  216. CControlUI* pControl = m_pm.FindControl(pt);
  217. if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_SCROLLBAR) == 0 ) {
  218. m_bScrollbarClicked = true;
  219. }
  220. }
  221. else if( uMsg == WM_LBUTTONUP ) {
  222. if (m_bScrollbarClicked) {
  223. m_bScrollbarClicked = false;
  224. }
  225. else {
  226. POINT pt = { 0 };
  227. ::GetCursorPos(&pt);
  228. ::ScreenToClient(m_pm.GetPaintWindow(), &pt);
  229. CControlUI* pControl = m_pm.FindControl(pt);
  230. if( pControl && _tcscmp(pControl->GetClass(), DUI_CTR_SCROLLBAR) != 0 ) PostMessage(WM_KILLFOCUS);
  231. }
  232. }
  233. else if( uMsg == WM_KEYDOWN ) {
  234. switch( wParam ) {
  235. case VK_ESCAPE:
  236. m_pOwner->SelectItem(m_iOldSel, true);
  237. EnsureVisible(m_iOldSel);
  238. // FALL THROUGH...
  239. case VK_RETURN:
  240. PostMessage(WM_KILLFOCUS);
  241. break;
  242. default:
  243. TEventUI event;
  244. event.Type = UIEVENT_KEYDOWN;
  245. event.chKey = (TCHAR)wParam;
  246. m_pOwner->DoEvent(event);
  247. EnsureVisible(m_pOwner->GetCurSel());
  248. return 0;
  249. }
  250. }
  251. else if( uMsg == WM_MOUSEWHEEL ) {
  252. int zDelta = (int) (short) HIWORD(wParam);
  253. TEventUI event = { 0 };
  254. event.Type = UIEVENT_SCROLLWHEEL;
  255. event.wParam = MAKELPARAM(zDelta < 0 ? SB_LINEDOWN : SB_LINEUP, 0);
  256. event.lParam = lParam;
  257. event.dwTimestamp = ::GetTickCount();
  258. m_pOwner->DoEvent(event);
  259. EnsureVisible(m_pOwner->GetCurSel());
  260. return 0;
  261. }
  262. else if( uMsg == WM_KILLFOCUS ) {
  263. if( m_hWnd != (HWND) wParam ) {
  264. HWND hWnd = ::GetFocus();
  265. HWND hParentWnd = NULL;
  266. bool bIsChildFocus = false;
  267. while( hParentWnd = ::GetParent(hWnd) ) {
  268. if( m_hWnd == hParentWnd ) {
  269. bIsChildFocus = true;
  270. break;
  271. }
  272. hWnd = hParentWnd;
  273. }
  274. if (!bIsChildFocus) {
  275. PostMessage(WM_CLOSE);
  276. return 0;
  277. }
  278. }
  279. }
  280. LRESULT lRes = 0;
  281. if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
  282. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  283. }
  284. void CComboWnd::EnsureVisible(int iIndex)
  285. {
  286. if( m_pOwner->GetCurSel() < 0 ) return;
  287. m_pLayout->FindSelectable(m_pOwner->GetCurSel(), false);
  288. RECT rcItem = m_pLayout->GetItemAt(iIndex)->GetPos();
  289. RECT rcList = m_pLayout->GetPos();
  290. CScrollBarUI* pHorizontalScrollBar = m_pLayout->GetHorizontalScrollBar();
  291. if( pHorizontalScrollBar && pHorizontalScrollBar->IsVisible() ) rcList.bottom -= pHorizontalScrollBar->GetFixedHeight();
  292. int iPos = m_pLayout->GetScrollPos().cy;
  293. if( rcItem.top >= rcList.top && rcItem.bottom < rcList.bottom ) return;
  294. int dx = 0;
  295. if( rcItem.top < rcList.top ) dx = rcItem.top - rcList.top;
  296. if( rcItem.bottom > rcList.bottom ) dx = rcItem.bottom - rcList.bottom;
  297. Scroll(0, dx);
  298. }
  299. void CComboWnd::Scroll(int dx, int dy)
  300. {
  301. if( dx == 0 && dy == 0 ) return;
  302. SIZE sz = m_pLayout->GetScrollPos();
  303. m_pLayout->SetScrollPos(CDuiSize(sz.cx + dx, sz.cy + dy));
  304. }
  305. #if(_WIN32_WINNT >= 0x0501)
  306. UINT CComboWnd::GetClassStyle() const
  307. {
  308. return __super::GetClassStyle() | CS_DROPSHADOW;
  309. }
  310. #endif
  311. ////////////////////////////////////////////////////////
  312. CComboUI::CComboUI() : m_pWindow(NULL), m_iCurSel(-1), m_uButtonState(0)
  313. {
  314. m_szDropBox = CDuiSize(0, 150);
  315. ::ZeroMemory(&m_rcTextPadding, sizeof(m_rcTextPadding));
  316. m_ListInfo.nColumns = 0;
  317. m_ListInfo.uFixedHeight = 0;
  318. m_ListInfo.nFont = -1;
  319. m_ListInfo.uTextStyle = DT_VCENTER | DT_SINGLELINE;
  320. m_ListInfo.dwTextColor = 0xFF000000;
  321. m_ListInfo.dwBkColor = 0;
  322. m_ListInfo.bAlternateBk = false;
  323. m_ListInfo.dwSelectedTextColor = 0xFF000000;
  324. m_ListInfo.dwSelectedBkColor = 0xFFC1E3FF;
  325. m_ListInfo.dwHotTextColor = 0xFF000000;
  326. m_ListInfo.dwHotBkColor = 0xFFE9F5FF;
  327. m_ListInfo.dwDisabledTextColor = 0xFFCCCCCC;
  328. m_ListInfo.dwDisabledBkColor = 0xFFFFFFFF;
  329. m_ListInfo.iHLineSize = 0;
  330. m_ListInfo.dwHLineColor = 0xFF3C3C3C;
  331. m_ListInfo.iVLineSize = 0;
  332. m_ListInfo.dwVLineColor = 0xFF3C3C3C;
  333. m_ListInfo.bShowHtml = false;
  334. m_ListInfo.bMultiExpandable = false;
  335. m_bShowText = true;
  336. m_bSelectCloseFlag = true;
  337. ::ZeroMemory(&m_ListInfo.rcTextPadding, sizeof(m_ListInfo.rcTextPadding));
  338. ::ZeroMemory(&m_ListInfo.rcColumn, sizeof(m_ListInfo.rcColumn));
  339. }
  340. LPCTSTR CComboUI::GetClass() const
  341. {
  342. return DUI_CTR_COMBO;
  343. }
  344. LPVOID CComboUI::GetInterface(LPCTSTR pstrName)
  345. {
  346. if( _tcscmp(pstrName, DUI_CTR_ILISTOWNER) == 0 ) return static_cast<IListOwnerUI*>(this);
  347. if( _tcscmp(pstrName, DUI_CTR_COMBO) == 0 ) return static_cast<CComboUI*>(this);
  348. return CContainerUI::GetInterface(pstrName);
  349. }
  350. UINT CComboUI::GetControlFlags() const
  351. {
  352. return UIFLAG_TABSTOP;
  353. }
  354. void CComboUI::DoInit()
  355. {
  356. }
  357. int CComboUI::GetCurSel() const
  358. {
  359. return m_iCurSel;
  360. }
  361. bool CComboUI::GetSelectCloseFlag()
  362. {
  363. return m_bSelectCloseFlag;
  364. }
  365. void CComboUI::SetSelectCloseFlag(bool flag)
  366. {
  367. m_bSelectCloseFlag = flag;
  368. }
  369. bool CComboUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent)
  370. {
  371. if( m_bSelectCloseFlag && m_pWindow != NULL ) m_pWindow->Close();
  372. if( iIndex == m_iCurSel ) return true;
  373. int iOldSel = m_iCurSel;
  374. if( m_iCurSel >= 0 ) {
  375. CControlUI* pControl = static_cast<CControlUI*>(m_items[m_iCurSel]);
  376. if( !pControl ) return false;
  377. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  378. if( pListItem != NULL ) pListItem->Select(false, bTriggerEvent);
  379. m_iCurSel = -1;
  380. }
  381. if( iIndex < 0 ) return false;
  382. if( m_items.GetSize() == 0 ) return false;
  383. if( iIndex >= m_items.GetSize() ) iIndex = m_items.GetSize() - 1;
  384. CControlUI* pControl = static_cast<CControlUI*>(m_items[iIndex]);
  385. if( !pControl || !pControl->IsVisible() || !pControl->IsEnabled() ) return false;
  386. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  387. if( pListItem == NULL ) return false;
  388. m_iCurSel = iIndex;
  389. if( m_pWindow != NULL || bTakeFocus ) pControl->SetFocus();
  390. pListItem->Select(true, bTriggerEvent);
  391. if( m_pManager != NULL && bTriggerEvent) m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMSELECT, m_iCurSel, iOldSel);
  392. Invalidate();
  393. return true;
  394. }
  395. bool CComboUI::ExpandItem(int iIndex, bool bExpand)
  396. {
  397. return false;
  398. }
  399. int CComboUI::GetExpandedItem() const
  400. {
  401. return -1;
  402. }
  403. bool CComboUI::SetItemIndex(CControlUI* pControl, int iNewIndex)
  404. {
  405. int iOrginIndex = GetItemIndex(pControl);
  406. if( iOrginIndex == -1 ) return false;
  407. if( iOrginIndex == iNewIndex ) return true;
  408. IListItemUI* pSelectedListItem = NULL;
  409. if( m_iCurSel >= 0 ) pSelectedListItem =
  410. static_cast<IListItemUI*>(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM));
  411. if( !CContainerUI::SetItemIndex(pControl, iNewIndex) ) return false;
  412. int iMinIndex = min(iOrginIndex, iNewIndex);
  413. int iMaxIndex = max(iOrginIndex, iNewIndex);
  414. for(int i = iMinIndex; i < iMaxIndex + 1; ++i) {
  415. CControlUI* p = GetItemAt(i);
  416. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(DUI_CTR_ILISTITEM));
  417. if( pListItem != NULL ) {
  418. pListItem->SetIndex(i);
  419. }
  420. }
  421. if( m_iCurSel >= 0 && pSelectedListItem != NULL ) m_iCurSel = pSelectedListItem->GetIndex();
  422. return true;
  423. }
  424. bool CComboUI::SetMultiItemIndex(CControlUI* pStartControl, int iCount, int iNewStartIndex)
  425. {
  426. if (pStartControl == NULL || iCount < 0 || iNewStartIndex < 0) return false;
  427. int iStartIndex = GetItemIndex(pStartControl);
  428. if (iStartIndex == iNewStartIndex) return true;
  429. if (iStartIndex + iCount > GetCount()) return false;
  430. if (iNewStartIndex + iCount > GetCount()) return false;
  431. IListItemUI* pSelectedListItem = NULL;
  432. if( m_iCurSel >= 0 ) pSelectedListItem =
  433. static_cast<IListItemUI*>(GetItemAt(m_iCurSel)->GetInterface(DUI_CTR_ILISTITEM));
  434. if( !CContainerUI::SetMultiItemIndex(pStartControl, iCount, iNewStartIndex) ) return false;
  435. int iMinIndex = min(iStartIndex, iNewStartIndex);
  436. int iMaxIndex = max(iStartIndex + iCount, iNewStartIndex + iCount);
  437. for(int i = iMinIndex; i < iMaxIndex + 1; ++i) {
  438. CControlUI* p = GetItemAt(i);
  439. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(DUI_CTR_ILISTITEM));
  440. if( pListItem != NULL ) {
  441. pListItem->SetIndex(i);
  442. }
  443. }
  444. if( m_iCurSel >= 0 && pSelectedListItem != NULL ) m_iCurSel = pSelectedListItem->GetIndex();
  445. return true;
  446. }
  447. bool CComboUI::Add(CControlUI* pControl)
  448. {
  449. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  450. if( pListItem != NULL )
  451. {
  452. pListItem->SetOwner(this);
  453. pListItem->SetIndex(m_items.GetSize());
  454. }
  455. return CContainerUI::Add(pControl);
  456. }
  457. bool CComboUI::AddAt(CControlUI* pControl, int iIndex)
  458. {
  459. if (!CContainerUI::AddAt(pControl, iIndex)) return false;
  460. // The list items should know about us
  461. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  462. if( pListItem != NULL ) {
  463. pListItem->SetOwner(this);
  464. pListItem->SetIndex(iIndex);
  465. }
  466. for(int i = iIndex + 1; i < GetCount(); ++i) {
  467. CControlUI* p = GetItemAt(i);
  468. pListItem = static_cast<IListItemUI*>(p->GetInterface(DUI_CTR_ILISTITEM));
  469. if( pListItem != NULL ) {
  470. pListItem->SetIndex(i);
  471. }
  472. }
  473. if( m_iCurSel >= iIndex ) m_iCurSel += 1;
  474. return true;
  475. }
  476. bool CComboUI::Remove(CControlUI* pControl, bool bDoNotDestroy)
  477. {
  478. int iIndex = GetItemIndex(pControl);
  479. if (iIndex == -1) return false;
  480. if (!CContainerUI::RemoveAt(iIndex, bDoNotDestroy)) return false;
  481. for(int i = iIndex; i < GetCount(); ++i) {
  482. CControlUI* p = GetItemAt(i);
  483. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(DUI_CTR_ILISTITEM));
  484. if( pListItem != NULL ) {
  485. pListItem->SetIndex(i);
  486. }
  487. }
  488. if( iIndex == m_iCurSel && m_iCurSel >= 0 ) {
  489. int iSel = m_iCurSel;
  490. m_iCurSel = -1;
  491. SelectItem(FindSelectable(iSel, false));
  492. }
  493. else if( iIndex < m_iCurSel ) m_iCurSel -= 1;
  494. return true;
  495. }
  496. bool CComboUI::RemoveAt(int iIndex, bool bDoNotDestroy)
  497. {
  498. if (!CContainerUI::RemoveAt(iIndex, bDoNotDestroy)) return false;
  499. for(int i = iIndex; i < GetCount(); ++i) {
  500. CControlUI* p = GetItemAt(i);
  501. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(DUI_CTR_ILISTITEM));
  502. if( pListItem != NULL ) pListItem->SetIndex(i);
  503. }
  504. if( iIndex == m_iCurSel && m_iCurSel >= 0 ) {
  505. int iSel = m_iCurSel;
  506. m_iCurSel = -1;
  507. SelectItem(FindSelectable(iSel, false));
  508. }
  509. else if( iIndex < m_iCurSel ) m_iCurSel -= 1;
  510. return true;
  511. }
  512. void CComboUI::RemoveAll()
  513. {
  514. m_iCurSel = -1;
  515. CContainerUI::RemoveAll();
  516. }
  517. void CComboUI::DoEvent(TEventUI& event)
  518. {
  519. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  520. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  521. else CContainerUI::DoEvent(event);
  522. return;
  523. }
  524. if( event.Type == UIEVENT_SETFOCUS )
  525. {
  526. Invalidate();
  527. }
  528. if( event.Type == UIEVENT_KILLFOCUS )
  529. {
  530. Invalidate();
  531. }
  532. if( event.Type == UIEVENT_BUTTONDOWN )
  533. {
  534. if( IsEnabled() ) {
  535. Activate();
  536. m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;
  537. }
  538. return;
  539. }
  540. if( event.Type == UIEVENT_BUTTONUP )
  541. {
  542. if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
  543. m_uButtonState &= ~ UISTATE_CAPTURED;
  544. Invalidate();
  545. }
  546. return;
  547. }
  548. if( event.Type == UIEVENT_MOUSEMOVE )
  549. {
  550. return;
  551. }
  552. if( event.Type == UIEVENT_KEYDOWN )
  553. {
  554. if (IsKeyboardEnabled() && IsEnabled()) {
  555. switch( event.chKey ) {
  556. case VK_F4:
  557. Activate();
  558. case VK_UP:
  559. SetSelectCloseFlag(false);
  560. SelectItem(FindSelectable(m_iCurSel - 1, false));
  561. SetSelectCloseFlag(true);
  562. case VK_DOWN:
  563. SetSelectCloseFlag(false);
  564. SelectItem(FindSelectable(m_iCurSel + 1, true));
  565. SetSelectCloseFlag(true);
  566. case VK_PRIOR:
  567. SetSelectCloseFlag(false);
  568. SelectItem(FindSelectable(m_iCurSel - 1, false));
  569. SetSelectCloseFlag(true);
  570. case VK_NEXT:
  571. SetSelectCloseFlag(false);
  572. SelectItem(FindSelectable(m_iCurSel + 1, true));
  573. SetSelectCloseFlag(true);
  574. case VK_HOME:
  575. SetSelectCloseFlag(false);
  576. SelectItem(FindSelectable(0, false));
  577. SetSelectCloseFlag(true);
  578. case VK_END:
  579. SetSelectCloseFlag(false);
  580. SelectItem(FindSelectable(GetCount() - 1, true));
  581. SetSelectCloseFlag(true);
  582. }
  583. return;
  584. }
  585. }
  586. if( event.Type == UIEVENT_SCROLLWHEEL )
  587. {
  588. if (IsEnabled()) {
  589. bool bDownward = LOWORD(event.wParam) == SB_LINEDOWN;
  590. SetSelectCloseFlag(false);
  591. SelectItem(FindSelectable(m_iCurSel + (bDownward ? 1 : -1), bDownward));
  592. SetSelectCloseFlag(true);
  593. return;
  594. }
  595. }
  596. if( event.Type == UIEVENT_CONTEXTMENU )
  597. {
  598. return;
  599. }
  600. if( event.Type == UIEVENT_MOUSEENTER )
  601. {
  602. if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
  603. if( IsEnabled() ) {
  604. if( (m_uButtonState & UISTATE_HOT) == 0 ) {
  605. m_uButtonState |= UISTATE_HOT;
  606. Invalidate();
  607. }
  608. }
  609. }
  610. }
  611. if( event.Type == UIEVENT_MOUSELEAVE )
  612. {
  613. if( !::PtInRect(&m_rcItem, event.ptMouse ) ) {
  614. if( IsEnabled() ) {
  615. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  616. m_uButtonState &= ~UISTATE_HOT;
  617. Invalidate();
  618. }
  619. }
  620. if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this);
  621. }
  622. else {
  623. if (m_pManager) m_pManager->AddMouseLeaveNeeded(this);
  624. return;
  625. }
  626. }
  627. CControlUI::DoEvent(event);
  628. }
  629. SIZE CComboUI::EstimateSize(SIZE szAvailable)
  630. {
  631. if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8);
  632. return CControlUI::EstimateSize(szAvailable);
  633. }
  634. bool CComboUI::Activate()
  635. {
  636. if( !CControlUI::Activate() ) return false;
  637. if( m_pWindow ) return true;
  638. m_pWindow = new CComboWnd();
  639. ASSERT(m_pWindow);
  640. m_pWindow->Init(this);
  641. if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_DROPDOWN);
  642. Invalidate();
  643. return true;
  644. }
  645. CDuiString CComboUI::GetText() const
  646. {
  647. if( m_iCurSel < 0 ) return _T("");
  648. CControlUI* pControl = static_cast<CControlUI*>(m_items[m_iCurSel]);
  649. return pControl->GetText();
  650. }
  651. void CComboUI::SetEnabled(bool bEnable)
  652. {
  653. CContainerUI::SetEnabled(bEnable);
  654. if( !IsEnabled() ) m_uButtonState = 0;
  655. }
  656. CDuiString CComboUI::GetDropBoxAttributeList()
  657. {
  658. return m_sDropBoxAttributes;
  659. }
  660. void CComboUI::SetDropBoxAttributeList(LPCTSTR pstrList)
  661. {
  662. m_sDropBoxAttributes = pstrList;
  663. }
  664. SIZE CComboUI::GetDropBoxSize() const
  665. {
  666. return m_szDropBox;
  667. }
  668. void CComboUI::SetDropBoxSize(SIZE szDropBox)
  669. {
  670. m_szDropBox = szDropBox;
  671. }
  672. bool CComboUI::GetShowText() const
  673. {
  674. return m_bShowText;
  675. }
  676. void CComboUI::SetShowText(bool flag)
  677. {
  678. m_bShowText = flag;
  679. Invalidate();
  680. }
  681. RECT CComboUI::GetTextPadding() const
  682. {
  683. return m_rcTextPadding;
  684. }
  685. void CComboUI::SetTextPadding(RECT rc)
  686. {
  687. m_rcTextPadding = rc;
  688. Invalidate();
  689. }
  690. LPCTSTR CComboUI::GetNormalImage() const
  691. {
  692. return m_diNormal.sDrawString;
  693. }
  694. void CComboUI::SetNormalImage(LPCTSTR pStrImage)
  695. {
  696. if( m_diNormal.sDrawString == pStrImage && m_diNormal.pImageInfo != NULL ) return;
  697. m_diNormal.Clear();
  698. m_diNormal.sDrawString = pStrImage;
  699. Invalidate();
  700. }
  701. LPCTSTR CComboUI::GetHotImage() const
  702. {
  703. return m_diHot.sDrawString;
  704. }
  705. void CComboUI::SetHotImage(LPCTSTR pStrImage)
  706. {
  707. if( m_diHot.sDrawString == pStrImage && m_diHot.pImageInfo != NULL ) return;
  708. m_diHot.Clear();
  709. m_diHot.sDrawString = pStrImage;
  710. Invalidate();
  711. }
  712. LPCTSTR CComboUI::GetPushedImage() const
  713. {
  714. return m_diPushed.sDrawString;
  715. }
  716. void CComboUI::SetPushedImage(LPCTSTR pStrImage)
  717. {
  718. if( m_diPushed.sDrawString == pStrImage && m_diPushed.pImageInfo != NULL ) return;
  719. m_diPushed.Clear();
  720. m_diPushed.sDrawString = pStrImage;
  721. Invalidate();
  722. }
  723. LPCTSTR CComboUI::GetFocusedImage() const
  724. {
  725. return m_diFocused.sDrawString;
  726. }
  727. void CComboUI::SetFocusedImage(LPCTSTR pStrImage)
  728. {
  729. if( m_diFocused.sDrawString == pStrImage && m_diFocused.pImageInfo != NULL ) return;
  730. m_diFocused.Clear();
  731. m_diFocused.sDrawString = pStrImage;
  732. Invalidate();
  733. }
  734. LPCTSTR CComboUI::GetDisabledImage() const
  735. {
  736. return m_diDisabled.sDrawString;
  737. }
  738. void CComboUI::SetDisabledImage(LPCTSTR pStrImage)
  739. {
  740. if( m_diDisabled.sDrawString == pStrImage && m_diDisabled.pImageInfo != NULL ) return;
  741. m_diDisabled.Clear();
  742. m_diDisabled.sDrawString = pStrImage;
  743. Invalidate();
  744. }
  745. TListInfoUI* CComboUI::GetListInfo()
  746. {
  747. return &m_ListInfo;
  748. }
  749. UINT CComboUI::GetItemFixedHeight()
  750. {
  751. return m_ListInfo.uFixedHeight;
  752. }
  753. void CComboUI::SetItemFixedHeight(UINT nHeight)
  754. {
  755. m_ListInfo.uFixedHeight = nHeight;
  756. Invalidate();
  757. }
  758. int CComboUI::GetItemFont(int index)
  759. {
  760. return m_ListInfo.nFont;
  761. }
  762. void CComboUI::SetItemFont(int index)
  763. {
  764. m_ListInfo.nFont = index;
  765. Invalidate();
  766. }
  767. UINT CComboUI::GetItemTextStyle()
  768. {
  769. return m_ListInfo.uTextStyle;
  770. }
  771. void CComboUI::SetItemTextStyle(UINT uStyle)
  772. {
  773. m_ListInfo.uTextStyle = uStyle;
  774. Invalidate();
  775. }
  776. RECT CComboUI::GetItemTextPadding() const
  777. {
  778. return m_ListInfo.rcTextPadding;
  779. }
  780. void CComboUI::SetItemTextPadding(RECT rc)
  781. {
  782. m_ListInfo.rcTextPadding = rc;
  783. Invalidate();
  784. }
  785. void CComboUI::SetItemTextColor(DWORD dwTextColor)
  786. {
  787. m_ListInfo.dwTextColor = dwTextColor;
  788. Invalidate();
  789. }
  790. void CComboUI::SetItemBkColor(DWORD dwBkColor)
  791. {
  792. m_ListInfo.dwBkColor = dwBkColor;
  793. }
  794. void CComboUI::SetItemBkImage(LPCTSTR pStrImage)
  795. {
  796. if( m_ListInfo.diBk.sDrawString == pStrImage && m_ListInfo.diBk.pImageInfo != NULL ) return;
  797. m_ListInfo.diBk.Clear();
  798. m_ListInfo.diBk.sDrawString = pStrImage;
  799. }
  800. DWORD CComboUI::GetItemTextColor() const
  801. {
  802. return m_ListInfo.dwTextColor;
  803. }
  804. DWORD CComboUI::GetItemBkColor() const
  805. {
  806. return m_ListInfo.dwBkColor;
  807. }
  808. LPCTSTR CComboUI::GetItemBkImage() const
  809. {
  810. return m_ListInfo.diBk.sDrawString;
  811. }
  812. bool CComboUI::IsAlternateBk() const
  813. {
  814. return m_ListInfo.bAlternateBk;
  815. }
  816. void CComboUI::SetAlternateBk(bool bAlternateBk)
  817. {
  818. m_ListInfo.bAlternateBk = bAlternateBk;
  819. }
  820. void CComboUI::SetSelectedItemTextColor(DWORD dwTextColor)
  821. {
  822. m_ListInfo.dwSelectedTextColor = dwTextColor;
  823. }
  824. void CComboUI::SetSelectedItemBkColor(DWORD dwBkColor)
  825. {
  826. m_ListInfo.dwSelectedBkColor = dwBkColor;
  827. }
  828. void CComboUI::SetSelectedItemImage(LPCTSTR pStrImage)
  829. {
  830. if( m_ListInfo.diSelected.sDrawString == pStrImage && m_ListInfo.diSelected.pImageInfo != NULL ) return;
  831. m_ListInfo.diSelected.Clear();
  832. m_ListInfo.diSelected.sDrawString = pStrImage;
  833. }
  834. DWORD CComboUI::GetSelectedItemTextColor() const
  835. {
  836. return m_ListInfo.dwSelectedTextColor;
  837. }
  838. DWORD CComboUI::GetSelectedItemBkColor() const
  839. {
  840. return m_ListInfo.dwSelectedBkColor;
  841. }
  842. LPCTSTR CComboUI::GetSelectedItemImage() const
  843. {
  844. return m_ListInfo.diSelected.sDrawString;
  845. }
  846. void CComboUI::SetHotItemTextColor(DWORD dwTextColor)
  847. {
  848. m_ListInfo.dwHotTextColor = dwTextColor;
  849. }
  850. void CComboUI::SetHotItemBkColor(DWORD dwBkColor)
  851. {
  852. m_ListInfo.dwHotBkColor = dwBkColor;
  853. }
  854. void CComboUI::SetHotItemImage(LPCTSTR pStrImage)
  855. {
  856. if( m_ListInfo.diHot.sDrawString == pStrImage && m_ListInfo.diHot.pImageInfo != NULL ) return;
  857. m_ListInfo.diHot.Clear();
  858. m_ListInfo.diHot.sDrawString = pStrImage;
  859. }
  860. DWORD CComboUI::GetHotItemTextColor() const
  861. {
  862. return m_ListInfo.dwHotTextColor;
  863. }
  864. DWORD CComboUI::GetHotItemBkColor() const
  865. {
  866. return m_ListInfo.dwHotBkColor;
  867. }
  868. LPCTSTR CComboUI::GetHotItemImage() const
  869. {
  870. return m_ListInfo.diHot.sDrawString;
  871. }
  872. void CComboUI::SetDisabledItemTextColor(DWORD dwTextColor)
  873. {
  874. m_ListInfo.dwDisabledTextColor = dwTextColor;
  875. }
  876. void CComboUI::SetDisabledItemBkColor(DWORD dwBkColor)
  877. {
  878. m_ListInfo.dwDisabledBkColor = dwBkColor;
  879. }
  880. void CComboUI::SetDisabledItemImage(LPCTSTR pStrImage)
  881. {
  882. if( m_ListInfo.diDisabled.sDrawString == pStrImage && m_ListInfo.diDisabled.pImageInfo != NULL ) return;
  883. m_ListInfo.diDisabled.Clear();
  884. m_ListInfo.diDisabled.sDrawString = pStrImage;
  885. }
  886. DWORD CComboUI::GetDisabledItemTextColor() const
  887. {
  888. return m_ListInfo.dwDisabledTextColor;
  889. }
  890. DWORD CComboUI::GetDisabledItemBkColor() const
  891. {
  892. return m_ListInfo.dwDisabledBkColor;
  893. }
  894. LPCTSTR CComboUI::GetDisabledItemImage() const
  895. {
  896. return m_ListInfo.diDisabled.sDrawString;
  897. }
  898. int CComboUI::GetItemHLineSize() const
  899. {
  900. return m_ListInfo.iHLineSize;
  901. }
  902. void CComboUI::SetItemHLineSize(int iSize)
  903. {
  904. m_ListInfo.iHLineSize = iSize;
  905. }
  906. DWORD CComboUI::GetItemHLineColor() const
  907. {
  908. return m_ListInfo.dwHLineColor;
  909. }
  910. void CComboUI::SetItemHLineColor(DWORD dwLineColor)
  911. {
  912. m_ListInfo.dwHLineColor = dwLineColor;
  913. }
  914. int CComboUI::GetItemVLineSize() const
  915. {
  916. return m_ListInfo.iVLineSize;
  917. }
  918. void CComboUI::SetItemVLineSize(int iSize)
  919. {
  920. m_ListInfo.iVLineSize = iSize;
  921. }
  922. DWORD CComboUI::GetItemVLineColor() const
  923. {
  924. return m_ListInfo.dwVLineColor;
  925. }
  926. void CComboUI::SetItemVLineColor(DWORD dwLineColor)
  927. {
  928. m_ListInfo.dwVLineColor = dwLineColor;
  929. }
  930. bool CComboUI::IsItemShowHtml()
  931. {
  932. return m_ListInfo.bShowHtml;
  933. }
  934. void CComboUI::SetItemShowHtml(bool bShowHtml)
  935. {
  936. if( m_ListInfo.bShowHtml == bShowHtml ) return;
  937. m_ListInfo.bShowHtml = bShowHtml;
  938. Invalidate();
  939. }
  940. void CComboUI::SetPos(RECT rc, bool bNeedInvalidate)
  941. {
  942. // Put all elements out of sight
  943. RECT rcNull = { 0 };
  944. for( int i = 0; i < m_items.GetSize(); i++ ) static_cast<CControlUI*>(m_items[i])->SetPos(rcNull, false);
  945. // Position this control
  946. CControlUI::SetPos(rc, bNeedInvalidate);
  947. }
  948. void CComboUI::Move(SIZE szOffset, bool bNeedInvalidate)
  949. {
  950. CControlUI::Move(szOffset, bNeedInvalidate);
  951. }
  952. void CComboUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  953. {
  954. if( _tcscmp(pstrName, _T("textpadding")) == 0 ) {
  955. RECT rcTextPadding = { 0 };
  956. LPTSTR pstr = NULL;
  957. rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  958. rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  959. rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  960. rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  961. SetTextPadding(rcTextPadding);
  962. }
  963. else if( _tcscmp(pstrName, _T("showtext")) == 0 ) SetShowText(_tcscmp(pstrValue, _T("true")) == 0);
  964. else if( _tcscmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  965. else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  966. else if( _tcscmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
  967. else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  968. else if( _tcscmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
  969. else if( _tcscmp(pstrName, _T("dropbox")) == 0 ) SetDropBoxAttributeList(pstrValue);
  970. else if( _tcscmp(pstrName, _T("dropboxsize")) == 0)
  971. {
  972. SIZE szDropBoxSize = { 0 };
  973. LPTSTR pstr = NULL;
  974. szDropBoxSize.cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  975. szDropBoxSize.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  976. SetDropBoxSize(szDropBoxSize);
  977. }
  978. else if( _tcscmp(pstrName, _T("itemheight")) == 0 ) m_ListInfo.uFixedHeight = _ttoi(pstrValue);
  979. else if( _tcscmp(pstrName, _T("itemfont")) == 0 ) m_ListInfo.nFont = _ttoi(pstrValue);
  980. else if( _tcscmp(pstrName, _T("itemalign")) == 0 ) {
  981. if( _tcsstr(pstrValue, _T("left")) != NULL ) {
  982. m_ListInfo.uTextStyle &= ~(DT_CENTER | DT_RIGHT);
  983. m_ListInfo.uTextStyle |= DT_LEFT;
  984. }
  985. if( _tcsstr(pstrValue, _T("center")) != NULL ) {
  986. m_ListInfo.uTextStyle &= ~(DT_LEFT | DT_RIGHT);
  987. m_ListInfo.uTextStyle |= DT_CENTER;
  988. }
  989. if( _tcsstr(pstrValue, _T("right")) != NULL ) {
  990. m_ListInfo.uTextStyle &= ~(DT_LEFT | DT_CENTER);
  991. m_ListInfo.uTextStyle |= DT_RIGHT;
  992. }
  993. }
  994. if( _tcscmp(pstrName, _T("itemtextpadding")) == 0 ) {
  995. RECT rcTextPadding = { 0 };
  996. LPTSTR pstr = NULL;
  997. rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  998. rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  999. rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1000. rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1001. SetItemTextPadding(rcTextPadding);
  1002. }
  1003. else if( _tcscmp(pstrName, _T("itemtextcolor")) == 0 ) {
  1004. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1005. LPTSTR pstr = NULL;
  1006. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1007. SetItemTextColor(clrColor);
  1008. }
  1009. else if( _tcscmp(pstrName, _T("itembkcolor")) == 0 ) {
  1010. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1011. LPTSTR pstr = NULL;
  1012. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1013. SetItemBkColor(clrColor);
  1014. }
  1015. else if( _tcscmp(pstrName, _T("itembkimage")) == 0 ) SetItemBkImage(pstrValue);
  1016. else if( _tcscmp(pstrName, _T("itemaltbk")) == 0 ) SetAlternateBk(_tcscmp(pstrValue, _T("true")) == 0);
  1017. else if( _tcscmp(pstrName, _T("itemselectedtextcolor")) == 0 ) {
  1018. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1019. LPTSTR pstr = NULL;
  1020. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1021. SetSelectedItemTextColor(clrColor);
  1022. }
  1023. else if( _tcscmp(pstrName, _T("itemselectedbkcolor")) == 0 ) {
  1024. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1025. LPTSTR pstr = NULL;
  1026. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1027. SetSelectedItemBkColor(clrColor);
  1028. }
  1029. else if( _tcscmp(pstrName, _T("itemselectedimage")) == 0 ) SetSelectedItemImage(pstrValue);
  1030. else if( _tcscmp(pstrName, _T("itemhottextcolor")) == 0 ) {
  1031. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1032. LPTSTR pstr = NULL;
  1033. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1034. SetHotItemTextColor(clrColor);
  1035. }
  1036. else if( _tcscmp(pstrName, _T("itemhotbkcolor")) == 0 ) {
  1037. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1038. LPTSTR pstr = NULL;
  1039. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1040. SetHotItemBkColor(clrColor);
  1041. }
  1042. else if( _tcscmp(pstrName, _T("itemhotimage")) == 0 ) SetHotItemImage(pstrValue);
  1043. else if( _tcscmp(pstrName, _T("itemdisabledtextcolor")) == 0 ) {
  1044. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1045. LPTSTR pstr = NULL;
  1046. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1047. SetDisabledItemTextColor(clrColor);
  1048. }
  1049. else if( _tcscmp(pstrName, _T("itemdisabledbkcolor")) == 0 ) {
  1050. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1051. LPTSTR pstr = NULL;
  1052. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1053. SetDisabledItemBkColor(clrColor);
  1054. }
  1055. else if( _tcscmp(pstrName, _T("itemdisabledimage")) == 0 ) SetDisabledItemImage(pstrValue);
  1056. else if( _tcscmp(pstrName, _T("itemvlinesize")) == 0 ) {
  1057. SetItemVLineSize(_ttoi(pstrValue));
  1058. }
  1059. else if( _tcscmp(pstrName, _T("itemvlinecolor")) == 0 ) {
  1060. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1061. LPTSTR pstr = NULL;
  1062. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1063. SetItemVLineColor(clrColor);
  1064. }
  1065. else if( _tcscmp(pstrName, _T("itemhlinesize")) == 0 ) {
  1066. SetItemHLineSize(_ttoi(pstrValue));
  1067. }
  1068. else if( _tcscmp(pstrName, _T("itemhlinecolor")) == 0 ) {
  1069. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1070. LPTSTR pstr = NULL;
  1071. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1072. SetItemHLineColor(clrColor);
  1073. }
  1074. else if( _tcscmp(pstrName, _T("itemshowhtml")) == 0 ) SetItemShowHtml(_tcscmp(pstrValue, _T("true")) == 0);
  1075. else CContainerUI::SetAttribute(pstrName, pstrValue);
  1076. }
  1077. bool CComboUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  1078. {
  1079. return CControlUI::DoPaint(hDC, rcPaint, pStopControl);
  1080. }
  1081. void CComboUI::PaintStatusImage(HDC hDC)
  1082. {
  1083. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  1084. else m_uButtonState &= ~ UISTATE_FOCUSED;
  1085. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  1086. else m_uButtonState &= ~ UISTATE_DISABLED;
  1087. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  1088. if (DrawImage(hDC, m_diDisabled)) return;
  1089. }
  1090. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  1091. if (DrawImage(hDC, m_diPushed)) return;
  1092. }
  1093. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1094. if (DrawImage(hDC, m_diHot)) return;
  1095. }
  1096. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  1097. if (DrawImage(hDC, m_diFocused)) return;
  1098. }
  1099. DrawImage(hDC, m_diNormal);
  1100. }
  1101. void CComboUI::PaintText(HDC hDC)
  1102. {
  1103. if (!m_bShowText) return;
  1104. RECT rcText = m_rcItem;
  1105. rcText.left += m_rcTextPadding.left;
  1106. rcText.right -= m_rcTextPadding.right;
  1107. rcText.top += m_rcTextPadding.top;
  1108. rcText.bottom -= m_rcTextPadding.bottom;
  1109. if( m_iCurSel >= 0 ) {
  1110. CControlUI* pControl = static_cast<CControlUI*>(m_items[m_iCurSel]);
  1111. IListItemUI* pElement = static_cast<IListItemUI*>(pControl->GetInterface(DUI_CTR_ILISTITEM));
  1112. if( pElement != NULL ) {
  1113. pElement->DrawItemText(hDC, rcText);
  1114. }
  1115. else {
  1116. RECT rcOldPos = pControl->GetPos();
  1117. pControl->SetPos(rcText, false);
  1118. pControl->Paint(hDC, rcText, NULL);
  1119. pControl->SetPos(rcOldPos, false);
  1120. }
  1121. }
  1122. }
  1123. } // namespace DuiLib