UIButton.cpp 25 KB

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