UIButton.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. #include "StdAfx.h"
  2. #include "UIButton.h"
  3. namespace DuiLib
  4. {
  5. IMPLEMENT_DUICONTROL(CButtonUI)
  6. CButtonUI::CButtonUI()
  7. : m_uButtonState(0)
  8. , m_iHotFont(-1)
  9. , m_iPushedFont(-1)
  10. , m_iFocusedFont(-1)
  11. , m_dwHotTextColor(0)
  12. , m_dwPushedTextColor(0)
  13. , m_dwFocusedTextColor(0)
  14. , m_dwHotBkColor(0)
  15. , m_dwPushedBkColor(0)
  16. , m_dwDisabledBkColor(0)
  17. , m_dwHotBorderColor(0)
  18. , m_dwPushedBorderColor(0)
  19. , m_dwDisabledBorderColor(0)
  20. , m_iBindTabIndex(-1)
  21. , m_nStateCount(0)
  22. {
  23. m_uTextStyle = DT_SINGLELINE | DT_VCENTER | DT_CENTER;
  24. }
  25. LPCTSTR CButtonUI::GetClass() const
  26. {
  27. return _T("ButtonUI");
  28. }
  29. LPVOID CButtonUI::GetInterface(LPCTSTR pstrName)
  30. {
  31. if( _tcsicmp(pstrName, DUI_CTR_BUTTON) == 0 ) return static_cast<CButtonUI*>(this);
  32. return CLabelUI::GetInterface(pstrName);
  33. }
  34. UINT CButtonUI::GetControlFlags() const
  35. {
  36. return (IsKeyboardEnabled() ? UIFLAG_TABSTOP : 0) | (IsEnabled() ? UIFLAG_SETCURSOR : 0);
  37. }
  38. void CButtonUI::DoEvent(TEventUI& event)
  39. {
  40. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  41. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  42. else CLabelUI::DoEvent(event);
  43. return;
  44. }
  45. if( event.Type == UIEVENT_SETFOCUS )
  46. {
  47. Invalidate();
  48. }
  49. if( event.Type == UIEVENT_KILLFOCUS )
  50. {
  51. Invalidate();
  52. }
  53. if( event.Type == UIEVENT_KEYDOWN )
  54. {
  55. if (IsKeyboardEnabled()) {
  56. if( event.chKey == VK_SPACE || event.chKey == VK_RETURN ) {
  57. Activate();
  58. return;
  59. }
  60. }
  61. }
  62. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK)
  63. {
  64. if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled() ) {
  65. m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;
  66. Invalidate();
  67. if(IsRichEvent()) m_pManager->SendNotify(this, DUI_MSGTYPE_BUTTONDOWN);
  68. }
  69. return;
  70. }
  71. // ------------------------------------------------------------------
  72. // [触屏] 触摸按下:与 UIEVENT_BUTTONDOWN 等价,建立 UISTATE_CAPTURED。
  73. //
  74. // ⚠️ 这条分支是"触摸能点击"的关键,不能省。
  75. //
  76. // 背景:触摸通道(CPaintManagerUI::BeginTouchSlideGesture)在 DOWN 阶段**只**派发
  77. // UIEVENT_TOUCHDOWN,不会派发 UIEVENT_BUTTONDOWN(那是原生鼠标路径的事,而原生
  78. // 路径在触摸手势期间被有意让开了)。所以如果本函数不认 TOUCHDOWN,按钮的
  79. // m_uButtonState 里就**永远没有 UISTATE_CAPTURED**。
  80. //
  81. // 后果:抬手时(无论由触摸链合成的 UIEVENT_BUTTONUP,还是原生 WM_LBUTTONUP 分支
  82. // 派发的)都会卡在下面这条守卫上:
  83. // if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { ... Activate(); }
  84. // 因为 CAPTURED 始料未及地没被置位 ⇒ 整块跳过 ⇒ **Activate 根本不被调用**
  85. // ⇒ 按钮的 DUI_MSGTYPE_CLICK 永远发不出去(表现为"看得见按下高亮,抬手没反应")。
  86. //
  87. // 注意:这里必须与 UIEVENT_BUTTONDOWN 一样**顺手置起来 CAPTURED**(而不是只做视觉
  88. // 高亮),因为 BUTTONUP 的守卫就是按 CAPTURED 判的 —— 它同时承担了
  89. // "这次按键是否由我起头"的记账职责。
  90. // ------------------------------------------------------------------
  91. if( event.Type == UIEVENT_TOUCHDOWN )
  92. {
  93. if( ::PtInRect(&m_rcItem, event.ptMouse) && IsEnabled() ) {
  94. m_uButtonState |= UISTATE_PUSHED | UISTATE_CAPTURED;
  95. Invalidate();
  96. }
  97. return;
  98. }
  99. // ------------------------------------------------------------------
  100. // [触屏] 触摸抬起:与 UIEVENT_BUTTONUP 等价。
  101. //
  102. // 为什么不能只靠"合成的 UIEVENT_BUTTONUP":触摸链(EndTouchSlideGesture →
  103. // 调用方 OnTouchInput / OnPointerInput 的轻点分支)合成的确实是 BUTTONDOWN/BUTTONUP,
  104. // 那条路能走通;但为了让滚动条之外的所有控件在两种驱动方式下行为一致
  105. // (TOUCHDOWN/MOVE/UP 与 BUTTONDOWN/UP 语义等价 —— 这与 CScrollBarUI 的处理方式
  106. // 保持一致),这里把 TOUCHUP 也认下来。
  107. //
  108. // 判定与 BUTTONUP 完全对齐:清 PUSHED|CAPTURED、且抬手点仍落在按钮内才 Activate。
  109. // 位移越阈值时(m_bTouchMoved)触摸链不会合成点击,但 TOUCHUP 仍会派发到这里 ——
  110. // 此时若手指已滑出按钮 rect,PtInRect 自然失败,不会误触发;若恰好滑完还停在按钮上,
  111. // 触摸链的 tap 判定(EndTouchSlideGesture 的返回值)已经决定不派发点击,所以这里
  112. // **只做状态清理**,不主动 Activate,避免"滑动误点"回归。
  113. // ------------------------------------------------------------------
  114. if( event.Type == UIEVENT_TOUCHUP )
  115. {
  116. if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
  117. m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
  118. Invalidate();
  119. }
  120. return;
  121. }
  122. if( event.Type == UIEVENT_MOUSEMOVE )
  123. {
  124. if ((m_uButtonState & UISTATE_CAPTURED) != 0)
  125. {
  126. if (::PtInRect(&m_rcItem, event.ptMouse))
  127. m_uButtonState |= UISTATE_PUSHED;
  128. else m_uButtonState &= ~UISTATE_PUSHED;
  129. Invalidate();
  130. }
  131. return;
  132. }
  133. if( event.Type == UIEVENT_BUTTONUP)
  134. {
  135. if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
  136. m_uButtonState &= ~(UISTATE_PUSHED | UISTATE_CAPTURED);
  137. Invalidate();
  138. if( ::PtInRect(&m_rcItem, event.ptMouse) ) Activate();
  139. }
  140. return;
  141. }
  142. if( event.Type == UIEVENT_CONTEXTMENU )
  143. {
  144. if( IsContextMenuUsed() ) {
  145. m_pManager->SendNotify(this, DUI_MSGTYPE_MENU, event.wParam, event.lParam);
  146. }
  147. return;
  148. }
  149. if( event.Type == UIEVENT_MOUSEENTER )
  150. {
  151. if( IsEnabled() ) {
  152. m_uButtonState |= UISTATE_HOT;
  153. Invalidate();
  154. if(IsRichEvent()) m_pManager->SendNotify(this, DUI_MSGTYPE_MOUSEENTER);
  155. }
  156. }
  157. if( event.Type == UIEVENT_MOUSELEAVE )
  158. {
  159. if( IsEnabled() ) {
  160. m_uButtonState &= ~UISTATE_HOT;
  161. Invalidate();
  162. if(IsRichEvent()) m_pManager->SendNotify(this, DUI_MSGTYPE_MOUSELEAVE);
  163. }
  164. }
  165. CLabelUI::DoEvent(event);
  166. }
  167. bool CButtonUI::Activate()
  168. {
  169. // ------------------------------------------------------------------
  170. // [已移除] 曾在这里挂过一段写 touch_trace.log 的 "BUTTON-ACTIVATE" 临时诊断。
  171. //
  172. // 它当初是为了定位"触摸点击不生效到底卡在哪个守卫上":触摸路径与纯鼠标路径
  173. // 不同 —— DOWN 阶段只发 UIEVENT_TOUCHDOWN,按钮不会自己进
  174. // UISTATE_PUSHED|UISTATE_CAPTURED,所以 BUTTONUP 分支的
  175. // `if ((m_uButtonState & UISTATE_CAPTURED) != 0)`
  176. // 可能直接不进、本函数压根不被调用;CControlUI::Activate 里的捕获保护
  177. // (!IsCaptured() && !CAPTURED)也会拦住 —— 这两个失败点都不会在任何
  178. // 现有日志里体现,所以单独打了一条。
  179. //
  180. // 结论(问题已解决,诊断不再需要):
  181. // · 根因是 EndTouchSlideGesture 的释放捕获时序 —— 原先是"先 ReleaseCapture
  182. // 再派发 TOUCHUP",导致两个捕获条件都已为假 ⇒ 本函数永不被调用;
  183. // 现已改为"先 TOUCHUP、后 ReleaseCapture",见 EndTouchSlideGesture 里的说明。
  184. // · 另一处根因是"无可滑动对象时仍按拖动吞掉点击",已在两条通道的 UP 分支
  185. // 统一修正(日志前缀 no-scrollable-target)。
  186. //
  187. // ⚠️ 若将来又出现"按钮按下有高亮、抬手没反应",请优先复查上面这两处,
  188. // 而不是重新加回日志 —— 那两条注释里写了完整的因果链。
  189. // ------------------------------------------------------------------
  190. if( !CControlUI::Activate() ) return false;
  191. if( m_pManager != NULL )
  192. {
  193. m_pManager->SendNotify(this, DUI_MSGTYPE_CLICK);
  194. BindTriggerTabSel();
  195. }
  196. return true;
  197. }
  198. void CButtonUI::SetEnabled(bool bEnable)
  199. {
  200. CControlUI::SetEnabled(bEnable);
  201. if (!IsEnabled()) {
  202. m_uButtonState |= UISTATE_DISABLED;
  203. }
  204. else {
  205. m_uButtonState &= ~UISTATE_DISABLED;
  206. }
  207. }
  208. void CButtonUI::SetHotFont(int index)
  209. {
  210. m_iHotFont = index;
  211. Invalidate();
  212. }
  213. int CButtonUI::GetHotFont() const
  214. {
  215. return m_iHotFont;
  216. }
  217. void CButtonUI::SetPushedFont(int index)
  218. {
  219. m_iPushedFont = index;
  220. Invalidate();
  221. }
  222. int CButtonUI::GetPushedFont() const
  223. {
  224. return m_iPushedFont;
  225. }
  226. void CButtonUI::SetFocusedFont(int index)
  227. {
  228. m_iFocusedFont = index;
  229. Invalidate();
  230. }
  231. int CButtonUI::GetFocusedFont() const
  232. {
  233. return m_iFocusedFont;
  234. }
  235. void CButtonUI::SetHotBkColor( DWORD dwColor )
  236. {
  237. m_dwHotBkColor = dwColor;
  238. Invalidate();
  239. }
  240. DWORD CButtonUI::GetHotBkColor() const
  241. {
  242. return m_dwHotBkColor;
  243. }
  244. void CButtonUI::SetPushedBkColor( DWORD dwColor )
  245. {
  246. m_dwPushedBkColor = dwColor;
  247. Invalidate();
  248. }
  249. DWORD CButtonUI::GetPushedBkColor() const
  250. {
  251. return m_dwPushedBkColor;
  252. }
  253. void CButtonUI::SetDisabledBkColor( DWORD dwColor )
  254. {
  255. m_dwDisabledBkColor = dwColor;
  256. Invalidate();
  257. }
  258. DWORD CButtonUI::GetDisabledBkColor() const
  259. {
  260. return m_dwDisabledBkColor;
  261. }
  262. void CButtonUI::SetHotTextColor(DWORD dwColor)
  263. {
  264. m_dwHotTextColor = dwColor;
  265. }
  266. DWORD CButtonUI::GetHotTextColor() const
  267. {
  268. return m_dwHotTextColor;
  269. }
  270. void CButtonUI::SetPushedTextColor(DWORD dwColor)
  271. {
  272. m_dwPushedTextColor = dwColor;
  273. }
  274. DWORD CButtonUI::GetPushedTextColor() const
  275. {
  276. return m_dwPushedTextColor;
  277. }
  278. void CButtonUI::SetFocusedTextColor(DWORD dwColor)
  279. {
  280. m_dwFocusedTextColor = dwColor;
  281. }
  282. DWORD CButtonUI::GetFocusedTextColor() const
  283. {
  284. return m_dwFocusedTextColor;
  285. }
  286. void CButtonUI::SetHotBorderColor(DWORD dwColor)
  287. {
  288. if (m_dwHotBorderColor == dwColor) return;
  289. m_dwHotBorderColor = dwColor;
  290. Invalidate();
  291. }
  292. DWORD CButtonUI::GetHotBorderColor() const
  293. {
  294. return m_dwHotBorderColor;
  295. }
  296. void CButtonUI::SetPushedBorderColor(DWORD dwColor)
  297. {
  298. if (m_dwPushedBorderColor == dwColor) return;
  299. m_dwPushedBorderColor = dwColor;
  300. Invalidate();
  301. }
  302. DWORD CButtonUI::GetPushedBorderColor() const
  303. {
  304. return m_dwPushedBorderColor;
  305. }
  306. void CButtonUI::SetDisabledBorderColor(DWORD dwColor)
  307. {
  308. if (m_dwDisabledBorderColor == dwColor) return;
  309. m_dwDisabledBorderColor = dwColor;
  310. Invalidate();
  311. }
  312. DWORD CButtonUI::GetDisabledBorderColor() const
  313. {
  314. return m_dwDisabledBorderColor;
  315. }
  316. LPCTSTR CButtonUI::GetNormalImage()
  317. {
  318. return m_sNormalImage;
  319. }
  320. void CButtonUI::SetNormalImage(LPCTSTR pStrImage)
  321. {
  322. m_sNormalImage = pStrImage;
  323. Invalidate();
  324. }
  325. LPCTSTR CButtonUI::GetHotImage()
  326. {
  327. return m_sHotImage;
  328. }
  329. void CButtonUI::SetHotImage(LPCTSTR pStrImage)
  330. {
  331. m_sHotImage = pStrImage;
  332. Invalidate();
  333. }
  334. LPCTSTR CButtonUI::GetPushedImage()
  335. {
  336. return m_sPushedImage;
  337. }
  338. void CButtonUI::SetPushedImage(LPCTSTR pStrImage)
  339. {
  340. m_sPushedImage = pStrImage;
  341. Invalidate();
  342. }
  343. LPCTSTR CButtonUI::GetFocusedImage()
  344. {
  345. return m_sFocusedImage;
  346. }
  347. void CButtonUI::SetFocusedImage(LPCTSTR pStrImage)
  348. {
  349. m_sFocusedImage = pStrImage;
  350. Invalidate();
  351. }
  352. LPCTSTR CButtonUI::GetDisabledImage()
  353. {
  354. return m_sDisabledImage;
  355. }
  356. void CButtonUI::SetDisabledImage(LPCTSTR pStrImage)
  357. {
  358. m_sDisabledImage = pStrImage;
  359. Invalidate();
  360. }
  361. LPCTSTR CButtonUI::GetHotForeImage()
  362. {
  363. return m_sHotForeImage;
  364. }
  365. void CButtonUI::SetHotForeImage( LPCTSTR pStrImage )
  366. {
  367. m_sHotForeImage = pStrImage;
  368. Invalidate();
  369. }
  370. LPCTSTR CButtonUI::GetPushedForeImage()
  371. {
  372. return m_sPushedForeImage;
  373. }
  374. void CButtonUI::SetPushedForeImage(LPCTSTR pStrImage)
  375. {
  376. m_sPushedForeImage = pStrImage;
  377. Invalidate();
  378. }
  379. void CButtonUI::SetStateCount(int nCount)
  380. {
  381. m_nStateCount = nCount;
  382. Invalidate();
  383. }
  384. int CButtonUI::GetStateCount() const
  385. {
  386. return m_nStateCount;
  387. }
  388. LPCTSTR CButtonUI::GetStateImage()
  389. {
  390. return m_sStateImage;
  391. }
  392. void CButtonUI::SetStateImage( LPCTSTR pStrImage )
  393. {
  394. m_sNormalImage.Empty();
  395. m_sStateImage = pStrImage;
  396. Invalidate();
  397. }
  398. void CButtonUI::BindTabIndex(int _BindTabIndex )
  399. {
  400. if( _BindTabIndex >= 0)
  401. m_iBindTabIndex = _BindTabIndex;
  402. }
  403. void CButtonUI::BindTabLayoutName( LPCTSTR _TabLayoutName )
  404. {
  405. if(_TabLayoutName)
  406. m_sBindTabLayoutName = _TabLayoutName;
  407. }
  408. void CButtonUI::BindTriggerTabSel( int _SetSelectIndex /*= -1*/ )
  409. {
  410. LPCTSTR pstrName = GetBindTabLayoutName();
  411. if(pstrName == NULL || (GetBindTabLayoutIndex() < 0 && _SetSelectIndex < 0))
  412. return;
  413. CTabLayoutUI* pTabLayout = static_cast<CTabLayoutUI*>(GetManager()->FindControl(pstrName));
  414. if(!pTabLayout) return;
  415. pTabLayout->SelectItem(_SetSelectIndex >=0?_SetSelectIndex:GetBindTabLayoutIndex());
  416. }
  417. void CButtonUI::RemoveBindTabIndex()
  418. {
  419. m_iBindTabIndex = -1;
  420. m_sBindTabLayoutName.Empty();
  421. }
  422. int CButtonUI::GetBindTabLayoutIndex()
  423. {
  424. return m_iBindTabIndex;
  425. }
  426. LPCTSTR CButtonUI::GetBindTabLayoutName()
  427. {
  428. return m_sBindTabLayoutName;
  429. }
  430. void CButtonUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  431. {
  432. if( _tcsicmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  433. else if( _tcsicmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  434. else if( _tcsicmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
  435. else if( _tcsicmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  436. else if( _tcsicmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
  437. else if (_tcsicmp(pstrName, _T("hotforeimage")) == 0) SetHotForeImage(pstrValue);
  438. else if (_tcsicmp(pstrName, _T("pushedforeimage")) == 0) SetPushedForeImage(pstrValue);
  439. else if( _tcsicmp(pstrName, _T("stateimage")) == 0 ) SetStateImage(pstrValue);
  440. else if( _tcsicmp(pstrName, _T("statecount")) == 0 ) SetStateCount(_ttoi(pstrValue));
  441. else if( _tcsicmp(pstrName, _T("bindtabindex")) == 0 ) BindTabIndex(_ttoi(pstrValue));
  442. else if( _tcsicmp(pstrName, _T("bindtablayoutname")) == 0 ) BindTabLayoutName(pstrValue);
  443. else if( _tcsicmp(pstrName, _T("hotbkcolor")) == 0 )
  444. {
  445. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  446. LPTSTR pstr = NULL;
  447. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  448. SetHotBkColor(clrColor);
  449. }
  450. else if( _tcsicmp(pstrName, _T("pushedbkcolor")) == 0 )
  451. {
  452. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  453. LPTSTR pstr = NULL;
  454. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  455. SetPushedBkColor(clrColor);
  456. }
  457. else if( _tcsicmp(pstrName, _T("disabledbkcolor")) == 0 )
  458. {
  459. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  460. LPTSTR pstr = NULL;
  461. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  462. SetDisabledBkColor(clrColor);
  463. }
  464. else if( _tcsicmp(pstrName, _T("hottextcolor")) == 0 )
  465. {
  466. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  467. LPTSTR pstr = NULL;
  468. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  469. SetHotTextColor(clrColor);
  470. }
  471. else if( _tcsicmp(pstrName, _T("pushedtextcolor")) == 0 )
  472. {
  473. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  474. LPTSTR pstr = NULL;
  475. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  476. SetPushedTextColor(clrColor);
  477. }
  478. else if( _tcsicmp(pstrName, _T("focusedtextcolor")) == 0 )
  479. {
  480. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  481. LPTSTR pstr = NULL;
  482. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  483. SetFocusedTextColor(clrColor);
  484. }
  485. else if (_tcscmp(pstrName, _T("hotbordercolor")) == 0)
  486. {
  487. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  488. LPTSTR pstr = NULL;
  489. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  490. SetHotBorderColor(clrColor);
  491. }
  492. else if (_tcscmp(pstrName, _T("pushedbordercolor")) == 0)
  493. {
  494. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  495. LPTSTR pstr = NULL;
  496. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  497. SetPushedBorderColor(clrColor);
  498. }
  499. else if (_tcscmp(pstrName, _T("disabledbordercolor")) == 0)
  500. {
  501. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  502. LPTSTR pstr = NULL;
  503. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  504. SetDisabledBorderColor(clrColor);
  505. }
  506. else if( _tcsicmp(pstrName, _T("hotfont")) == 0 ) SetHotFont(_ttoi(pstrValue));
  507. else if( _tcsicmp(pstrName, _T("pushedfont")) == 0 ) SetPushedFont(_ttoi(pstrValue));
  508. else if( _tcsicmp(pstrName, _T("focuedfont")) == 0 ) SetFocusedFont(_ttoi(pstrValue));
  509. else CLabelUI::SetAttribute(pstrName, pstrValue);
  510. }
  511. void CButtonUI::PaintText(HDC hDC)
  512. {
  513. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  514. else m_uButtonState &= ~ UISTATE_FOCUSED;
  515. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  516. else m_uButtonState &= ~ UISTATE_DISABLED;
  517. if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
  518. if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
  519. CDuiString sText = GetText();
  520. if( sText.IsEmpty() ) return;
  521. RECT m_rcTextPadding = CButtonUI::m_rcTextPadding;
  522. GetManager()->GetDPIObj()->Scale(&m_rcTextPadding);
  523. int nLinks = 0;
  524. RECT rc = m_rcItem;
  525. rc.left += m_rcTextPadding.left;
  526. rc.right -= m_rcTextPadding.right;
  527. rc.top += m_rcTextPadding.top;
  528. rc.bottom -= m_rcTextPadding.bottom;
  529. DWORD clrColor = IsEnabled()?m_dwTextColor:m_dwDisabledTextColor;
  530. if( ((m_uButtonState & UISTATE_PUSHED) != 0) && (GetPushedTextColor() != 0) )
  531. clrColor = GetPushedTextColor();
  532. else if( ((m_uButtonState & UISTATE_HOT) != 0) && (GetHotTextColor() != 0) )
  533. clrColor = GetHotTextColor();
  534. else if( ((m_uButtonState & UISTATE_FOCUSED) != 0) && (GetFocusedTextColor() != 0) )
  535. clrColor = GetFocusedTextColor();
  536. int iFont = GetFont();
  537. if( ((m_uButtonState & UISTATE_PUSHED) != 0) && (GetPushedFont() != -1) )
  538. iFont = GetPushedFont();
  539. else if( ((m_uButtonState & UISTATE_HOT) != 0) && (GetHotFont() != -1) )
  540. iFont = GetHotFont();
  541. else if( ((m_uButtonState & UISTATE_FOCUSED) != 0) && (GetFocusedFont() != -1) )
  542. iFont = GetFocusedFont();
  543. if( m_bShowHtml )
  544. CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, sText, clrColor, \
  545. NULL, NULL, nLinks, iFont, m_uTextStyle);
  546. else
  547. CRenderEngine::DrawText(hDC, m_pManager, rc, sText, clrColor, \
  548. iFont, m_uTextStyle);
  549. }
  550. void CButtonUI::PaintBkColor(HDC hDC)
  551. {
  552. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  553. if(m_dwDisabledBkColor != 0) {
  554. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwDisabledBkColor));
  555. return;
  556. }
  557. }
  558. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  559. if(m_dwPushedBkColor != 0) {
  560. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwPushedBkColor));
  561. return;
  562. }
  563. }
  564. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  565. if(m_dwHotBkColor != 0) {
  566. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwHotBkColor));
  567. return;
  568. }
  569. }
  570. return CControlUI::PaintBkColor(hDC);
  571. }
  572. void CButtonUI::PaintStatusImage(HDC hDC)
  573. {
  574. if(!m_sStateImage.IsEmpty() && m_nStateCount > 0)
  575. {
  576. TDrawInfo info;
  577. info.Parse(m_sStateImage, _T(""), m_pManager);
  578. const TImageInfo* pImage = m_pManager->GetImageEx(info.sImageName, info.sResType, info.dwMask, info.bHSL, info.bGdiplus);
  579. if(m_sNormalImage.IsEmpty() && pImage != NULL)
  580. {
  581. SIZE szImage = {pImage->nX, pImage->nY};
  582. SIZE szStatus = {pImage->nX / m_nStateCount, pImage->nY};
  583. if( szImage.cx > 0 && szImage.cy > 0 )
  584. {
  585. RECT rcSrc = {0, 0, szImage.cx, szImage.cy};
  586. if(m_nStateCount > 0) {
  587. int iLeft = rcSrc.left + 0 * szStatus.cx;
  588. int iRight = iLeft + szStatus.cx;
  589. int iTop = rcSrc.top;
  590. int iBottom = iTop + szStatus.cy;
  591. m_sNormalImage.Format(_T("res='%s' restype='%s' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'"), info.sImageName.GetData(), info.sResType.GetData(), info.rcDest.left, info.rcDest.top, info.rcDest.right, info.rcDest.bottom, iLeft, iTop, iRight, iBottom);
  592. }
  593. if(m_nStateCount > 1) {
  594. int iLeft = rcSrc.left + 1 * szStatus.cx;
  595. int iRight = iLeft + szStatus.cx;
  596. int iTop = rcSrc.top;
  597. int iBottom = iTop + szStatus.cy;
  598. m_sHotImage.Format(_T("res='%s' restype='%s' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'"), info.sImageName.GetData(), info.sResType.GetData(), info.rcDest.left, info.rcDest.top, info.rcDest.right, info.rcDest.bottom, iLeft, iTop, iRight, iBottom);
  599. m_sPushedImage.Format(_T("res='%s' restype='%s' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'"), info.sImageName.GetData(), info.sResType.GetData(), info.rcDest.left, info.rcDest.top, info.rcDest.right, info.rcDest.bottom, iLeft, iTop, iRight, iBottom);
  600. }
  601. if(m_nStateCount > 2) {
  602. int iLeft = rcSrc.left + 2 * szStatus.cx;
  603. int iRight = iLeft + szStatus.cx;
  604. int iTop = rcSrc.top;
  605. int iBottom = iTop + szStatus.cy;
  606. m_sPushedImage.Format(_T("res='%s' restype='%s' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'"), info.sImageName.GetData(), info.sResType.GetData(), info.rcDest.left, info.rcDest.top, info.rcDest.right, info.rcDest.bottom, iLeft, iTop, iRight, iBottom);
  607. }
  608. if(m_nStateCount > 3) {
  609. int iLeft = rcSrc.left + 3 * szStatus.cx;
  610. int iRight = iLeft + szStatus.cx;
  611. int iTop = rcSrc.top;
  612. int iBottom = iTop + szStatus.cy;
  613. m_sDisabledImage.Format(_T("res='%s' restype='%s' dest='%d,%d,%d,%d' source='%d,%d,%d,%d'"), info.sImageName.GetData(), info.sResType.GetData(), info.rcDest.left, info.rcDest.top, info.rcDest.right, info.rcDest.bottom, iLeft, iTop, iRight, iBottom);
  614. }
  615. }
  616. }
  617. }
  618. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  619. else m_uButtonState &= ~ UISTATE_FOCUSED;
  620. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  621. else m_uButtonState &= ~ UISTATE_DISABLED;
  622. if(!::IsWindowEnabled(m_pManager->GetPaintWindow())) {
  623. m_uButtonState &= UISTATE_DISABLED;
  624. }
  625. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  626. if( !m_sDisabledImage.IsEmpty() ) {
  627. if( !DrawImage(hDC, (LPCTSTR)m_sDisabledImage) ) {}
  628. else return;
  629. }
  630. }
  631. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  632. if( !m_sPushedImage.IsEmpty() ) {
  633. if( !DrawImage(hDC, (LPCTSTR)m_sPushedImage) ) {}
  634. else return;
  635. }
  636. }
  637. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  638. if( !m_sHotImage.IsEmpty() ) {
  639. if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) {}
  640. else return;
  641. }
  642. }
  643. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  644. if( !m_sFocusedImage.IsEmpty() ) {
  645. if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) {}
  646. else return;
  647. }
  648. }
  649. if( !m_sNormalImage.IsEmpty() ) {
  650. if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) {}
  651. }
  652. }
  653. void CButtonUI::PaintBorder(HDC hDC)
  654. {
  655. if ((m_uButtonState & UISTATE_DISABLED) != 0) {
  656. if (m_dwDisabledBorderColor != 0) {
  657. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwDisabledBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  658. return;
  659. }
  660. }
  661. else if ((m_uButtonState & UISTATE_PUSHED) != 0) {
  662. if (m_dwPushedBorderColor != 0) {
  663. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwPushedBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  664. return;
  665. }
  666. }
  667. else if ((m_uButtonState & UISTATE_HOT) != 0) {
  668. if (m_dwHotBorderColor != 0) {
  669. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwHotBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  670. return;
  671. }
  672. }
  673. return CControlUI::PaintBorder(hDC);
  674. }
  675. void CButtonUI::PaintForeImage(HDC hDC)
  676. {
  677. if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  678. if( !m_sPushedForeImage.IsEmpty() ) {
  679. if( !DrawImage(hDC, (LPCTSTR)m_sPushedForeImage) ) {}
  680. else return;
  681. }
  682. }
  683. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  684. if( !m_sHotForeImage.IsEmpty() ) {
  685. if( !DrawImage(hDC, (LPCTSTR)m_sHotForeImage) ) {}
  686. else return;
  687. }
  688. }
  689. if(!m_sForeImage.IsEmpty() ) {
  690. if( !DrawImage(hDC, (LPCTSTR)m_sForeImage) ) {}
  691. }
  692. }
  693. void CButtonUI::DrawBorder(HDC hDC, const RECT& rcItem, const DWORD& dwBorderColor, const int& nBorderSize, const RECT& rcBorderSize, const SIZE& cxyBorderRound, const int& nBorderStyle)
  694. {
  695. if (dwBorderColor != 0) {
  696. //画圆角边框
  697. if (nBorderSize > 0 && (cxyBorderRound.cx > 0 || cxyBorderRound.cy > 0)) {
  698. CRenderEngine::DrawRoundRect(hDC, rcItem, nBorderSize, cxyBorderRound.cx, cxyBorderRound.cy, GetAdjustColor(dwBorderColor), nBorderStyle);
  699. }
  700. else {
  701. if (rcBorderSize.left > 0 || rcBorderSize.top > 0 || rcBorderSize.right > 0 || rcBorderSize.bottom > 0) {
  702. RECT rcBorder;
  703. if (rcBorderSize.left > 0) {
  704. rcBorder = rcItem;
  705. rcBorder.right = rcBorder.left;
  706. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.left, GetAdjustColor(dwBorderColor), nBorderStyle);
  707. }
  708. if (rcBorderSize.top > 0) {
  709. rcBorder = rcItem;
  710. rcBorder.bottom = rcBorder.top;
  711. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.top, GetAdjustColor(dwBorderColor), nBorderStyle);
  712. }
  713. if (rcBorderSize.right > 0) {
  714. rcBorder = rcItem;
  715. rcBorder.right -= 1;
  716. rcBorder.left = rcBorder.right;
  717. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.right, GetAdjustColor(dwBorderColor), nBorderStyle);
  718. }
  719. if (rcBorderSize.bottom > 0) {
  720. rcBorder = rcItem;
  721. rcBorder.bottom -= 1;
  722. rcBorder.top = rcBorder.bottom;
  723. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.bottom, GetAdjustColor(dwBorderColor), nBorderStyle);
  724. }
  725. }
  726. else if (nBorderSize > 0) {
  727. CRenderEngine::DrawRect(hDC, rcItem, nBorderSize, GetAdjustColor(dwBorderColor), nBorderStyle);
  728. }
  729. }
  730. }
  731. }
  732. }