UIButton.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  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. void CButtonUI::ClearPushedState()
  168. {
  169. // 三位置假:PUSHED(0x10) | CAPTURED(0x40) | HOT(0x08)。
  170. // 三者都可能因为"弹框把 manager 搬走 / 手势被中途打断"而残留,
  171. // 而它们各自对应的清理路径(BUTTONUP / TOUCHUP / MOUSELEAVE)都可能没到达。
  172. // 这里一次性清干净并重绘,作为按需调用的兜底。
  173. //
  174. // ⚠️ 只清"显示状态位",不动焦点、不动业务数据 —— 调用方(MessageHandler)
  175. // 只在"模态搬家"与"触摸抬起"这两个确定性时点调用,不参与正常点击流程。
  176. const UINT uMask = UISTATE_PUSHED | UISTATE_CAPTURED | UISTATE_HOT;
  177. if( (m_uButtonState & uMask) != 0 )
  178. {
  179. m_uButtonState &= ~uMask;
  180. Invalidate();
  181. }
  182. }
  183. bool CButtonUI::Activate()
  184. {
  185. // 触摸路径与纯鼠标路径不同:DOWN 阶段只发 UIEVENT_TOUCHDOWN,按钮不会自己进
  186. // UISTATE_PUSHED|UISTATE_CAPTURED ⇒ 本函数(以及 CControlUI::Activate 里的捕获保护)
  187. // 可能压根不被调用。排查"按下有高亮、抬手没反应"时先看这里。
  188. if( !CControlUI::Activate() ) return false;
  189. if( m_pManager != NULL )
  190. {
  191. m_pManager->SendNotify(this, DUI_MSGTYPE_CLICK);
  192. BindTriggerTabSel();
  193. }
  194. return true;
  195. }
  196. void CButtonUI::SetEnabled(bool bEnable)
  197. {
  198. CControlUI::SetEnabled(bEnable);
  199. if (!IsEnabled()) {
  200. m_uButtonState |= UISTATE_DISABLED;
  201. }
  202. else {
  203. m_uButtonState &= ~UISTATE_DISABLED;
  204. }
  205. }
  206. void CButtonUI::SetHotFont(int index)
  207. {
  208. m_iHotFont = index;
  209. Invalidate();
  210. }
  211. int CButtonUI::GetHotFont() const
  212. {
  213. return m_iHotFont;
  214. }
  215. void CButtonUI::SetPushedFont(int index)
  216. {
  217. m_iPushedFont = index;
  218. Invalidate();
  219. }
  220. int CButtonUI::GetPushedFont() const
  221. {
  222. return m_iPushedFont;
  223. }
  224. void CButtonUI::SetFocusedFont(int index)
  225. {
  226. m_iFocusedFont = index;
  227. Invalidate();
  228. }
  229. int CButtonUI::GetFocusedFont() const
  230. {
  231. return m_iFocusedFont;
  232. }
  233. void CButtonUI::SetHotBkColor( DWORD dwColor )
  234. {
  235. m_dwHotBkColor = dwColor;
  236. Invalidate();
  237. }
  238. DWORD CButtonUI::GetHotBkColor() const
  239. {
  240. return m_dwHotBkColor;
  241. }
  242. void CButtonUI::SetPushedBkColor( DWORD dwColor )
  243. {
  244. m_dwPushedBkColor = dwColor;
  245. Invalidate();
  246. }
  247. DWORD CButtonUI::GetPushedBkColor() const
  248. {
  249. return m_dwPushedBkColor;
  250. }
  251. void CButtonUI::SetDisabledBkColor( DWORD dwColor )
  252. {
  253. m_dwDisabledBkColor = dwColor;
  254. Invalidate();
  255. }
  256. DWORD CButtonUI::GetDisabledBkColor() const
  257. {
  258. return m_dwDisabledBkColor;
  259. }
  260. void CButtonUI::SetHotTextColor(DWORD dwColor)
  261. {
  262. m_dwHotTextColor = dwColor;
  263. }
  264. DWORD CButtonUI::GetHotTextColor() const
  265. {
  266. return m_dwHotTextColor;
  267. }
  268. void CButtonUI::SetPushedTextColor(DWORD dwColor)
  269. {
  270. m_dwPushedTextColor = dwColor;
  271. }
  272. DWORD CButtonUI::GetPushedTextColor() const
  273. {
  274. return m_dwPushedTextColor;
  275. }
  276. void CButtonUI::SetFocusedTextColor(DWORD dwColor)
  277. {
  278. m_dwFocusedTextColor = dwColor;
  279. }
  280. DWORD CButtonUI::GetFocusedTextColor() const
  281. {
  282. return m_dwFocusedTextColor;
  283. }
  284. void CButtonUI::SetHotBorderColor(DWORD dwColor)
  285. {
  286. if (m_dwHotBorderColor == dwColor) return;
  287. m_dwHotBorderColor = dwColor;
  288. Invalidate();
  289. }
  290. DWORD CButtonUI::GetHotBorderColor() const
  291. {
  292. return m_dwHotBorderColor;
  293. }
  294. void CButtonUI::SetPushedBorderColor(DWORD dwColor)
  295. {
  296. if (m_dwPushedBorderColor == dwColor) return;
  297. m_dwPushedBorderColor = dwColor;
  298. Invalidate();
  299. }
  300. DWORD CButtonUI::GetPushedBorderColor() const
  301. {
  302. return m_dwPushedBorderColor;
  303. }
  304. void CButtonUI::SetDisabledBorderColor(DWORD dwColor)
  305. {
  306. if (m_dwDisabledBorderColor == dwColor) return;
  307. m_dwDisabledBorderColor = dwColor;
  308. Invalidate();
  309. }
  310. DWORD CButtonUI::GetDisabledBorderColor() const
  311. {
  312. return m_dwDisabledBorderColor;
  313. }
  314. LPCTSTR CButtonUI::GetNormalImage()
  315. {
  316. return m_sNormalImage;
  317. }
  318. void CButtonUI::SetNormalImage(LPCTSTR pStrImage)
  319. {
  320. m_sNormalImage = pStrImage;
  321. Invalidate();
  322. }
  323. LPCTSTR CButtonUI::GetHotImage()
  324. {
  325. return m_sHotImage;
  326. }
  327. void CButtonUI::SetHotImage(LPCTSTR pStrImage)
  328. {
  329. m_sHotImage = pStrImage;
  330. Invalidate();
  331. }
  332. LPCTSTR CButtonUI::GetPushedImage()
  333. {
  334. return m_sPushedImage;
  335. }
  336. void CButtonUI::SetPushedImage(LPCTSTR pStrImage)
  337. {
  338. m_sPushedImage = pStrImage;
  339. Invalidate();
  340. }
  341. LPCTSTR CButtonUI::GetFocusedImage()
  342. {
  343. return m_sFocusedImage;
  344. }
  345. void CButtonUI::SetFocusedImage(LPCTSTR pStrImage)
  346. {
  347. m_sFocusedImage = pStrImage;
  348. Invalidate();
  349. }
  350. LPCTSTR CButtonUI::GetDisabledImage()
  351. {
  352. return m_sDisabledImage;
  353. }
  354. void CButtonUI::SetDisabledImage(LPCTSTR pStrImage)
  355. {
  356. m_sDisabledImage = pStrImage;
  357. Invalidate();
  358. }
  359. LPCTSTR CButtonUI::GetHotForeImage()
  360. {
  361. return m_sHotForeImage;
  362. }
  363. void CButtonUI::SetHotForeImage( LPCTSTR pStrImage )
  364. {
  365. m_sHotForeImage = pStrImage;
  366. Invalidate();
  367. }
  368. LPCTSTR CButtonUI::GetPushedForeImage()
  369. {
  370. return m_sPushedForeImage;
  371. }
  372. void CButtonUI::SetPushedForeImage(LPCTSTR pStrImage)
  373. {
  374. m_sPushedForeImage = pStrImage;
  375. Invalidate();
  376. }
  377. void CButtonUI::SetStateCount(int nCount)
  378. {
  379. m_nStateCount = nCount;
  380. Invalidate();
  381. }
  382. int CButtonUI::GetStateCount() const
  383. {
  384. return m_nStateCount;
  385. }
  386. LPCTSTR CButtonUI::GetStateImage()
  387. {
  388. return m_sStateImage;
  389. }
  390. void CButtonUI::SetStateImage( LPCTSTR pStrImage )
  391. {
  392. m_sNormalImage.Empty();
  393. m_sStateImage = pStrImage;
  394. Invalidate();
  395. }
  396. void CButtonUI::BindTabIndex(int _BindTabIndex )
  397. {
  398. if( _BindTabIndex >= 0)
  399. m_iBindTabIndex = _BindTabIndex;
  400. }
  401. void CButtonUI::BindTabLayoutName( LPCTSTR _TabLayoutName )
  402. {
  403. if(_TabLayoutName)
  404. m_sBindTabLayoutName = _TabLayoutName;
  405. }
  406. void CButtonUI::BindTriggerTabSel( int _SetSelectIndex /*= -1*/ )
  407. {
  408. LPCTSTR pstrName = GetBindTabLayoutName();
  409. if(pstrName == NULL || (GetBindTabLayoutIndex() < 0 && _SetSelectIndex < 0))
  410. return;
  411. CTabLayoutUI* pTabLayout = static_cast<CTabLayoutUI*>(GetManager()->FindControl(pstrName));
  412. if(!pTabLayout) return;
  413. pTabLayout->SelectItem(_SetSelectIndex >=0?_SetSelectIndex:GetBindTabLayoutIndex());
  414. }
  415. void CButtonUI::RemoveBindTabIndex()
  416. {
  417. m_iBindTabIndex = -1;
  418. m_sBindTabLayoutName.Empty();
  419. }
  420. int CButtonUI::GetBindTabLayoutIndex()
  421. {
  422. return m_iBindTabIndex;
  423. }
  424. LPCTSTR CButtonUI::GetBindTabLayoutName()
  425. {
  426. return m_sBindTabLayoutName;
  427. }
  428. void CButtonUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  429. {
  430. if( _tcsicmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  431. else if( _tcsicmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  432. else if( _tcsicmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
  433. else if( _tcsicmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  434. else if( _tcsicmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
  435. else if (_tcsicmp(pstrName, _T("hotforeimage")) == 0) SetHotForeImage(pstrValue);
  436. else if (_tcsicmp(pstrName, _T("pushedforeimage")) == 0) SetPushedForeImage(pstrValue);
  437. else if( _tcsicmp(pstrName, _T("stateimage")) == 0 ) SetStateImage(pstrValue);
  438. else if( _tcsicmp(pstrName, _T("statecount")) == 0 ) SetStateCount(_ttoi(pstrValue));
  439. else if( _tcsicmp(pstrName, _T("bindtabindex")) == 0 ) BindTabIndex(_ttoi(pstrValue));
  440. else if( _tcsicmp(pstrName, _T("bindtablayoutname")) == 0 ) BindTabLayoutName(pstrValue);
  441. else if( _tcsicmp(pstrName, _T("hotbkcolor")) == 0 )
  442. {
  443. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  444. LPTSTR pstr = NULL;
  445. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  446. SetHotBkColor(clrColor);
  447. }
  448. else if( _tcsicmp(pstrName, _T("pushedbkcolor")) == 0 )
  449. {
  450. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  451. LPTSTR pstr = NULL;
  452. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  453. SetPushedBkColor(clrColor);
  454. }
  455. else if( _tcsicmp(pstrName, _T("disabledbkcolor")) == 0 )
  456. {
  457. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  458. LPTSTR pstr = NULL;
  459. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  460. SetDisabledBkColor(clrColor);
  461. }
  462. else if( _tcsicmp(pstrName, _T("hottextcolor")) == 0 )
  463. {
  464. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  465. LPTSTR pstr = NULL;
  466. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  467. SetHotTextColor(clrColor);
  468. }
  469. else if( _tcsicmp(pstrName, _T("pushedtextcolor")) == 0 )
  470. {
  471. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  472. LPTSTR pstr = NULL;
  473. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  474. SetPushedTextColor(clrColor);
  475. }
  476. else if( _tcsicmp(pstrName, _T("focusedtextcolor")) == 0 )
  477. {
  478. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  479. LPTSTR pstr = NULL;
  480. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  481. SetFocusedTextColor(clrColor);
  482. }
  483. else if (_tcscmp(pstrName, _T("hotbordercolor")) == 0)
  484. {
  485. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  486. LPTSTR pstr = NULL;
  487. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  488. SetHotBorderColor(clrColor);
  489. }
  490. else if (_tcscmp(pstrName, _T("pushedbordercolor")) == 0)
  491. {
  492. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  493. LPTSTR pstr = NULL;
  494. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  495. SetPushedBorderColor(clrColor);
  496. }
  497. else if (_tcscmp(pstrName, _T("disabledbordercolor")) == 0)
  498. {
  499. if (*pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  500. LPTSTR pstr = NULL;
  501. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  502. SetDisabledBorderColor(clrColor);
  503. }
  504. else if( _tcsicmp(pstrName, _T("hotfont")) == 0 ) SetHotFont(_ttoi(pstrValue));
  505. else if( _tcsicmp(pstrName, _T("pushedfont")) == 0 ) SetPushedFont(_ttoi(pstrValue));
  506. else if( _tcsicmp(pstrName, _T("focuedfont")) == 0 ) SetFocusedFont(_ttoi(pstrValue));
  507. else CLabelUI::SetAttribute(pstrName, pstrValue);
  508. }
  509. void CButtonUI::PaintText(HDC hDC)
  510. {
  511. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  512. else m_uButtonState &= ~ UISTATE_FOCUSED;
  513. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  514. else m_uButtonState &= ~ UISTATE_DISABLED;
  515. if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
  516. if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
  517. CDuiString sText = GetText();
  518. if( sText.IsEmpty() ) return;
  519. RECT m_rcTextPadding = CButtonUI::m_rcTextPadding;
  520. GetManager()->GetDPIObj()->Scale(&m_rcTextPadding);
  521. int nLinks = 0;
  522. RECT rc = m_rcItem;
  523. rc.left += m_rcTextPadding.left;
  524. rc.right -= m_rcTextPadding.right;
  525. rc.top += m_rcTextPadding.top;
  526. rc.bottom -= m_rcTextPadding.bottom;
  527. DWORD clrColor = IsEnabled()?m_dwTextColor:m_dwDisabledTextColor;
  528. if( ((m_uButtonState & UISTATE_PUSHED) != 0) && (GetPushedTextColor() != 0) )
  529. clrColor = GetPushedTextColor();
  530. else if( ((m_uButtonState & UISTATE_HOT) != 0) && (GetHotTextColor() != 0) )
  531. clrColor = GetHotTextColor();
  532. else if( ((m_uButtonState & UISTATE_FOCUSED) != 0) && (GetFocusedTextColor() != 0) )
  533. clrColor = GetFocusedTextColor();
  534. int iFont = GetFont();
  535. if( ((m_uButtonState & UISTATE_PUSHED) != 0) && (GetPushedFont() != -1) )
  536. iFont = GetPushedFont();
  537. else if( ((m_uButtonState & UISTATE_HOT) != 0) && (GetHotFont() != -1) )
  538. iFont = GetHotFont();
  539. else if( ((m_uButtonState & UISTATE_FOCUSED) != 0) && (GetFocusedFont() != -1) )
  540. iFont = GetFocusedFont();
  541. if( m_bShowHtml )
  542. CRenderEngine::DrawHtmlText(hDC, m_pManager, rc, sText, clrColor, \
  543. NULL, NULL, nLinks, iFont, m_uTextStyle);
  544. else
  545. CRenderEngine::DrawText(hDC, m_pManager, rc, sText, clrColor, \
  546. iFont, m_uTextStyle);
  547. }
  548. void CButtonUI::PaintBkColor(HDC hDC)
  549. {
  550. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  551. if(m_dwDisabledBkColor != 0) {
  552. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwDisabledBkColor));
  553. return;
  554. }
  555. }
  556. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  557. if(m_dwPushedBkColor != 0) {
  558. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwPushedBkColor));
  559. return;
  560. }
  561. }
  562. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  563. if(m_dwHotBkColor != 0) {
  564. CRenderEngine::DrawColor(hDC, m_rcPaint, GetAdjustColor(m_dwHotBkColor));
  565. return;
  566. }
  567. }
  568. return CControlUI::PaintBkColor(hDC);
  569. }
  570. void CButtonUI::PaintStatusImage(HDC hDC)
  571. {
  572. if(!m_sStateImage.IsEmpty() && m_nStateCount > 0)
  573. {
  574. TDrawInfo info;
  575. info.Parse(m_sStateImage, _T(""), m_pManager);
  576. const TImageInfo* pImage = m_pManager->GetImageEx(info.sImageName, info.sResType, info.dwMask, info.bHSL, info.bGdiplus);
  577. if(m_sNormalImage.IsEmpty() && pImage != NULL)
  578. {
  579. SIZE szImage = {pImage->nX, pImage->nY};
  580. SIZE szStatus = {pImage->nX / m_nStateCount, pImage->nY};
  581. if( szImage.cx > 0 && szImage.cy > 0 )
  582. {
  583. RECT rcSrc = {0, 0, szImage.cx, szImage.cy};
  584. if(m_nStateCount > 0) {
  585. int iLeft = rcSrc.left + 0 * szStatus.cx;
  586. int iRight = iLeft + szStatus.cx;
  587. int iTop = rcSrc.top;
  588. int iBottom = iTop + szStatus.cy;
  589. 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);
  590. }
  591. if(m_nStateCount > 1) {
  592. int iLeft = rcSrc.left + 1 * szStatus.cx;
  593. int iRight = iLeft + szStatus.cx;
  594. int iTop = rcSrc.top;
  595. int iBottom = iTop + szStatus.cy;
  596. 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);
  597. 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);
  598. }
  599. if(m_nStateCount > 2) {
  600. int iLeft = rcSrc.left + 2 * szStatus.cx;
  601. int iRight = iLeft + szStatus.cx;
  602. int iTop = rcSrc.top;
  603. int iBottom = iTop + szStatus.cy;
  604. 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);
  605. }
  606. if(m_nStateCount > 3) {
  607. int iLeft = rcSrc.left + 3 * szStatus.cx;
  608. int iRight = iLeft + szStatus.cx;
  609. int iTop = rcSrc.top;
  610. int iBottom = iTop + szStatus.cy;
  611. 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);
  612. }
  613. }
  614. }
  615. }
  616. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  617. else m_uButtonState &= ~ UISTATE_FOCUSED;
  618. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  619. else m_uButtonState &= ~ UISTATE_DISABLED;
  620. if(!::IsWindowEnabled(m_pManager->GetPaintWindow())) {
  621. m_uButtonState &= UISTATE_DISABLED;
  622. }
  623. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  624. if( !m_sDisabledImage.IsEmpty() ) {
  625. if( !DrawImage(hDC, (LPCTSTR)m_sDisabledImage) ) {}
  626. else return;
  627. }
  628. }
  629. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  630. if( !m_sPushedImage.IsEmpty() ) {
  631. if( !DrawImage(hDC, (LPCTSTR)m_sPushedImage) ) {}
  632. else return;
  633. }
  634. }
  635. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  636. if( !m_sHotImage.IsEmpty() ) {
  637. if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) {}
  638. else return;
  639. }
  640. }
  641. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  642. if( !m_sFocusedImage.IsEmpty() ) {
  643. if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) {}
  644. else return;
  645. }
  646. }
  647. if( !m_sNormalImage.IsEmpty() ) {
  648. if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) {}
  649. }
  650. }
  651. void CButtonUI::PaintBorder(HDC hDC)
  652. {
  653. if ((m_uButtonState & UISTATE_DISABLED) != 0) {
  654. if (m_dwDisabledBorderColor != 0) {
  655. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwDisabledBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  656. return;
  657. }
  658. }
  659. else if ((m_uButtonState & UISTATE_PUSHED) != 0) {
  660. if (m_dwPushedBorderColor != 0) {
  661. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwPushedBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  662. return;
  663. }
  664. }
  665. else if ((m_uButtonState & UISTATE_HOT) != 0) {
  666. if (m_dwHotBorderColor != 0) {
  667. DrawBorder(hDC, m_rcItem, GetAdjustColor(m_dwHotBorderColor), m_nBorderSize, m_rcBorderSize, m_cxyBorderRound, m_nBorderStyle);
  668. return;
  669. }
  670. }
  671. return CControlUI::PaintBorder(hDC);
  672. }
  673. void CButtonUI::PaintForeImage(HDC hDC)
  674. {
  675. if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  676. if( !m_sPushedForeImage.IsEmpty() ) {
  677. if( !DrawImage(hDC, (LPCTSTR)m_sPushedForeImage) ) {}
  678. else return;
  679. }
  680. }
  681. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  682. if( !m_sHotForeImage.IsEmpty() ) {
  683. if( !DrawImage(hDC, (LPCTSTR)m_sHotForeImage) ) {}
  684. else return;
  685. }
  686. }
  687. if(!m_sForeImage.IsEmpty() ) {
  688. if( !DrawImage(hDC, (LPCTSTR)m_sForeImage) ) {}
  689. }
  690. }
  691. void CButtonUI::DrawBorder(HDC hDC, const RECT& rcItem, const DWORD& dwBorderColor, const int& nBorderSize, const RECT& rcBorderSize, const SIZE& cxyBorderRound, const int& nBorderStyle)
  692. {
  693. if (dwBorderColor != 0) {
  694. //画圆角边框
  695. if (nBorderSize > 0 && (cxyBorderRound.cx > 0 || cxyBorderRound.cy > 0)) {
  696. CRenderEngine::DrawRoundRect(hDC, rcItem, nBorderSize, cxyBorderRound.cx, cxyBorderRound.cy, GetAdjustColor(dwBorderColor), nBorderStyle);
  697. }
  698. else {
  699. if (rcBorderSize.left > 0 || rcBorderSize.top > 0 || rcBorderSize.right > 0 || rcBorderSize.bottom > 0) {
  700. RECT rcBorder;
  701. if (rcBorderSize.left > 0) {
  702. rcBorder = rcItem;
  703. rcBorder.right = rcBorder.left;
  704. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.left, GetAdjustColor(dwBorderColor), nBorderStyle);
  705. }
  706. if (rcBorderSize.top > 0) {
  707. rcBorder = rcItem;
  708. rcBorder.bottom = rcBorder.top;
  709. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.top, GetAdjustColor(dwBorderColor), nBorderStyle);
  710. }
  711. if (rcBorderSize.right > 0) {
  712. rcBorder = rcItem;
  713. rcBorder.right -= 1;
  714. rcBorder.left = rcBorder.right;
  715. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.right, GetAdjustColor(dwBorderColor), nBorderStyle);
  716. }
  717. if (rcBorderSize.bottom > 0) {
  718. rcBorder = rcItem;
  719. rcBorder.bottom -= 1;
  720. rcBorder.top = rcBorder.bottom;
  721. CRenderEngine::DrawLine(hDC, rcBorder, rcBorderSize.bottom, GetAdjustColor(dwBorderColor), nBorderStyle);
  722. }
  723. }
  724. else if (nBorderSize > 0) {
  725. CRenderEngine::DrawRect(hDC, rcItem, nBorderSize, GetAdjustColor(dwBorderColor), nBorderStyle);
  726. }
  727. }
  728. }
  729. }
  730. }