UIButton.cpp 26 KB

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