UIHotKey.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #include "stdafx.h"
  2. #include "UIHotKey.h"
  3. namespace DuiLib{
  4. CHotKeyWnd::CHotKeyWnd(void) : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false)
  5. {
  6. }
  7. void CHotKeyWnd::Init(CHotKeyUI * pOwner)
  8. {
  9. m_pOwner = pOwner;
  10. do {
  11. if (NULL == m_pOwner) {
  12. break;
  13. }
  14. RECT rcPos = CalPos();
  15. UINT uStyle = WS_CHILD | ES_AUTOHSCROLL;
  16. HWND hWnd = Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);
  17. if (!IsWindow(hWnd)) {
  18. break;
  19. }
  20. SetWindowFont(m_hWnd, m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->hFont, TRUE);
  21. SetHotKey(m_pOwner->m_wVirtualKeyCode, m_pOwner->m_wModifiers);
  22. m_pOwner->m_sText = GetHotKeyName();
  23. ::EnableWindow(m_hWnd, m_pOwner->IsEnabled() == true);
  24. ::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);
  25. ::SetFocus(m_hWnd);
  26. m_bInit = true;
  27. } while (0);
  28. }
  29. RECT CHotKeyWnd::CalPos()
  30. {
  31. CDuiRect rcPos = m_pOwner->GetPos();
  32. RECT rcInset = m_pOwner->GetTextPadding();
  33. rcPos.left += rcInset.left;
  34. rcPos.top += rcInset.top;
  35. rcPos.right -= rcInset.right;
  36. rcPos.bottom -= rcInset.bottom;
  37. LONG lHeight = m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->tm.tmHeight;
  38. if( lHeight < rcPos.GetHeight() ) {
  39. rcPos.top += (rcPos.GetHeight() - lHeight) / 2;
  40. rcPos.bottom = rcPos.top + lHeight;
  41. }
  42. return rcPos;
  43. }
  44. LPCTSTR CHotKeyWnd::GetWindowClassName() const
  45. {
  46. return _T("HotKeyClass");
  47. }
  48. void CHotKeyWnd::OnFinalMessage(HWND /*hWnd*/)
  49. {
  50. // Clear reference and die
  51. if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);
  52. m_pOwner->m_pWindow = NULL;
  53. delete this;
  54. }
  55. LRESULT CHotKeyWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  56. {
  57. LRESULT lRes = 0;
  58. BOOL bHandled = TRUE;
  59. if( uMsg == WM_KILLFOCUS ) lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
  60. else if( uMsg == OCM_COMMAND ) {
  61. if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE ) lRes = OnEditChanged(uMsg, wParam, lParam, bHandled);
  62. else if( GET_WM_COMMAND_CMD(wParam, lParam) == EN_UPDATE ) {
  63. RECT rcClient;
  64. ::GetClientRect(m_hWnd, &rcClient);
  65. ::InvalidateRect(m_hWnd, &rcClient, FALSE);
  66. }
  67. }
  68. else if( uMsg == WM_KEYDOWN && TCHAR(wParam) == VK_RETURN ) {
  69. m_pOwner->GetManager()->SendNotify(m_pOwner, _T("return"));
  70. }
  71. else if ( (uMsg == WM_NCACTIVATE) || (uMsg == WM_NCACTIVATE) || (uMsg == WM_NCCALCSIZE) )
  72. {
  73. return 0;
  74. }
  75. else if (uMsg == WM_PAINT)
  76. {
  77. PAINTSTRUCT ps = { 0 };
  78. HDC hDC = ::BeginPaint(m_hWnd, &ps);
  79. DWORD dwTextColor = m_pOwner->GetTextColor();
  80. DWORD dwBkColor = m_pOwner->GetNativeBkColor();
  81. CDuiString strText = GetHotKeyName();
  82. ::RECT rect;
  83. ::GetClientRect(m_hWnd, &rect);
  84. ::SetBkMode(hDC, TRANSPARENT);
  85. ::SetTextColor(hDC, RGB(GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor)));
  86. HBRUSH hBrush = CreateSolidBrush( RGB(GetBValue(dwBkColor), GetGValue(dwBkColor), GetRValue(dwBkColor)) );
  87. ::FillRect(hDC, &rect, hBrush);
  88. ::DeleteObject(hBrush);
  89. HFONT hOldFont = (HFONT)SelectObject(hDC, GetWindowFont(m_hWnd));
  90. ::SIZE size = { 0 };
  91. ::GetTextExtentPoint32(hDC, strText.GetData(), strText.GetLength(), &size) ;
  92. ::DrawText(hDC, strText.GetData(), -1, &rect, DT_LEFT|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX);
  93. ::SelectObject(hDC, hOldFont);
  94. ::SetCaretPos(size.cx, 0);
  95. ::EndPaint(m_hWnd, &ps);
  96. bHandled = TRUE;
  97. }
  98. else bHandled = FALSE;
  99. if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  100. return lRes;
  101. }
  102. LPCTSTR CHotKeyWnd::GetSuperClassName() const
  103. {
  104. return HOTKEY_CLASS;
  105. }
  106. LRESULT CHotKeyWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  107. {
  108. LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
  109. ::SendMessage(m_hWnd, WM_CLOSE, 0, 0);
  110. return lRes;
  111. }
  112. LRESULT CHotKeyWnd::OnEditChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  113. {
  114. if( !m_bInit ) return 0;
  115. if( m_pOwner == NULL ) return 0;
  116. GetHotKey(m_pOwner->m_wVirtualKeyCode, m_pOwner->m_wModifiers);
  117. if (m_pOwner->m_wVirtualKeyCode == 0) {
  118. m_pOwner->m_sText = _T("ÎÞ");
  119. m_pOwner->m_wModifiers = 0;
  120. }
  121. else {
  122. m_pOwner->m_sText = GetHotKeyName();
  123. }
  124. m_pOwner->GetManager()->SendNotify(m_pOwner, _T("textchanged"));
  125. return 0;
  126. }
  127. void CHotKeyWnd::SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
  128. {
  129. ASSERT(::IsWindow(m_hWnd));
  130. ::SendMessage(m_hWnd, HKM_SETHOTKEY, MAKEWORD(wVirtualKeyCode, wModifiers), 0L);
  131. }
  132. DWORD CHotKeyWnd::GetHotKey() const
  133. {
  134. ASSERT(::IsWindow(m_hWnd));
  135. return (::SendMessage(m_hWnd, HKM_GETHOTKEY, 0, 0L));
  136. }
  137. void CHotKeyWnd::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
  138. {
  139. DWORD dw = GetHotKey();
  140. wVirtualKeyCode = LOBYTE(LOWORD(dw));
  141. wModifiers = HIBYTE(LOWORD(dw));
  142. }
  143. void CHotKeyWnd::SetRules(WORD wInvalidComb, WORD wModifiers)
  144. {
  145. ASSERT(::IsWindow(m_hWnd));
  146. ::SendMessage(m_hWnd, HKM_SETRULES, wInvalidComb, MAKELPARAM(wModifiers, 0));
  147. }
  148. CDuiString CHotKeyWnd::GetKeyName(UINT vk, BOOL fExtended)
  149. {
  150. UINT nScanCode = ::MapVirtualKeyEx( vk, 0, ::GetKeyboardLayout( 0 ) );
  151. switch( vk )
  152. {
  153. // Keys which are "extended" (except for Return which is Numeric Enter as extended)
  154. case VK_INSERT:
  155. case VK_DELETE:
  156. case VK_HOME:
  157. case VK_END:
  158. case VK_NEXT: // Page down
  159. case VK_PRIOR: // Page up
  160. case VK_LEFT:
  161. case VK_RIGHT:
  162. case VK_UP:
  163. case VK_DOWN:
  164. nScanCode |= 0x100; // Add extended bit
  165. }
  166. if (fExtended)
  167. nScanCode |= 0x01000000L;
  168. TCHAR szStr[ MAX_PATH ] = {0};
  169. ::GetKeyNameText( nScanCode << 16, szStr, MAX_PATH );
  170. return CDuiString(szStr);
  171. }
  172. CDuiString CHotKeyWnd::GetHotKeyName()
  173. {
  174. ASSERT(::IsWindow(m_hWnd));
  175. CDuiString strKeyName;
  176. WORD wCode = 0;
  177. WORD wModifiers = 0;
  178. const TCHAR szPlus[] = _T(" + ");
  179. GetHotKey(wCode, wModifiers);
  180. if (wCode != 0 || wModifiers != 0)
  181. {
  182. if (wModifiers & HOTKEYF_CONTROL)
  183. {
  184. strKeyName += GetKeyName(VK_CONTROL, FALSE);
  185. strKeyName += szPlus;
  186. }
  187. if (wModifiers & HOTKEYF_SHIFT)
  188. {
  189. strKeyName += GetKeyName(VK_SHIFT, FALSE);
  190. strKeyName += szPlus;
  191. }
  192. if (wModifiers & HOTKEYF_ALT)
  193. {
  194. strKeyName += GetKeyName(VK_MENU, FALSE);
  195. strKeyName += szPlus;
  196. }
  197. strKeyName += GetKeyName(wCode, wModifiers & HOTKEYF_EXT);
  198. }
  199. return strKeyName;
  200. }
  201. //////////////////////////////////////////////////////////////////////////
  202. IMPLEMENT_DUICONTROL(CHotKeyUI)
  203. CHotKeyUI::CHotKeyUI() : m_pWindow(NULL), m_wVirtualKeyCode(0), m_wModifiers(0), m_uButtonState(0), m_dwHotKeybkColor(0xFFFFFFFF)
  204. {
  205. SetTextPadding(CDuiRect(4, 3, 4, 3));
  206. SetBkColor(0xFFFFFFFF);
  207. }
  208. LPCTSTR CHotKeyUI::GetClass() const
  209. {
  210. return _T("HotKeyUI");
  211. }
  212. LPVOID CHotKeyUI::GetInterface(LPCTSTR pstrName)
  213. {
  214. if( _tcscmp(pstrName, _T("HotKey")) == 0 ) return static_cast<CHotKeyUI *>(this);
  215. return CLabelUI::GetInterface(pstrName);
  216. }
  217. UINT CHotKeyUI::GetControlFlags() const
  218. {
  219. if( !IsEnabled() ) return CControlUI::GetControlFlags();
  220. return UIFLAG_SETCURSOR | UIFLAG_TABSTOP;
  221. }
  222. void CHotKeyUI::DoEvent(TEventUI& event)
  223. {
  224. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  225. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  226. else CLabelUI::DoEvent(event);
  227. return;
  228. }
  229. if( event.Type == UIEVENT_SETCURSOR && IsEnabled() )
  230. {
  231. ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)));
  232. return;
  233. }
  234. if( event.Type == UIEVENT_WINDOWSIZE )
  235. {
  236. if( m_pWindow != NULL ) m_pManager->SetFocusNeeded(this);
  237. }
  238. if( event.Type == UIEVENT_SCROLLWHEEL )
  239. {
  240. if( m_pWindow != NULL ) return;
  241. }
  242. if( event.Type == UIEVENT_SETFOCUS && IsEnabled() )
  243. {
  244. if( m_pWindow ) return;
  245. m_pWindow = new CHotKeyWnd();
  246. ASSERT(m_pWindow);
  247. m_pWindow->Init(this);
  248. Invalidate();
  249. }
  250. if( event.Type == UIEVENT_KILLFOCUS && IsEnabled() )
  251. {
  252. Invalidate();
  253. }
  254. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK || event.Type == UIEVENT_RBUTTONDOWN)
  255. {
  256. if( IsEnabled() ) {
  257. GetManager()->ReleaseCapture();
  258. if( IsFocused() && m_pWindow == NULL ) {
  259. m_pWindow = new CHotKeyWnd();
  260. ASSERT(m_pWindow);
  261. m_pWindow->Init(this);
  262. }
  263. }
  264. return;
  265. }
  266. if( event.Type == UIEVENT_MOUSEMOVE )
  267. {
  268. return;
  269. }
  270. if( event.Type == UIEVENT_BUTTONUP )
  271. {
  272. return;
  273. }
  274. if( event.Type == UIEVENT_CONTEXTMENU )
  275. {
  276. return;
  277. }
  278. if( event.Type == UIEVENT_MOUSEENTER )
  279. {
  280. if( IsEnabled() ) {
  281. m_uButtonState |= UISTATE_HOT;
  282. Invalidate();
  283. }
  284. return;
  285. }
  286. if( event.Type == UIEVENT_MOUSELEAVE )
  287. {
  288. if( IsEnabled() ) {
  289. m_uButtonState &= ~UISTATE_HOT;
  290. Invalidate();
  291. }
  292. return;
  293. }
  294. CLabelUI::DoEvent(event);
  295. }
  296. void CHotKeyUI::SetEnabled(bool bEnable)
  297. {
  298. CControlUI::SetEnabled(bEnable);
  299. if( !IsEnabled() ) {
  300. m_uButtonState = 0;
  301. }
  302. }
  303. void CHotKeyUI::SetText(LPCTSTR pstrText)
  304. {
  305. m_sText = pstrText;
  306. if( m_pWindow != NULL ) Edit_SetText(*m_pWindow, m_sText);
  307. Invalidate();
  308. }
  309. LPCTSTR CHotKeyUI::GetNormalImage()
  310. {
  311. return m_sNormalImage;
  312. }
  313. void CHotKeyUI::SetNormalImage(LPCTSTR pStrImage)
  314. {
  315. m_sNormalImage = pStrImage;
  316. Invalidate();
  317. }
  318. LPCTSTR CHotKeyUI::GetHotImage()
  319. {
  320. return m_sHotImage;
  321. }
  322. void CHotKeyUI::SetHotImage(LPCTSTR pStrImage)
  323. {
  324. m_sHotImage = pStrImage;
  325. Invalidate();
  326. }
  327. LPCTSTR CHotKeyUI::GetFocusedImage()
  328. {
  329. return m_sFocusedImage;
  330. }
  331. void CHotKeyUI::SetFocusedImage(LPCTSTR pStrImage)
  332. {
  333. m_sFocusedImage = pStrImage;
  334. Invalidate();
  335. }
  336. LPCTSTR CHotKeyUI::GetDisabledImage()
  337. {
  338. return m_sDisabledImage;
  339. }
  340. void CHotKeyUI::SetDisabledImage(LPCTSTR pStrImage)
  341. {
  342. m_sDisabledImage = pStrImage;
  343. Invalidate();
  344. }
  345. void CHotKeyUI::SetNativeBkColor(DWORD dwBkColor)
  346. {
  347. m_dwHotKeybkColor = dwBkColor;
  348. }
  349. DWORD CHotKeyUI::GetNativeBkColor() const
  350. {
  351. return m_dwHotKeybkColor;
  352. }
  353. void CHotKeyUI::SetPos(RECT rc)
  354. {
  355. CControlUI::SetPos(rc);
  356. if( m_pWindow != NULL ) {
  357. RECT rcPos = m_pWindow->CalPos();
  358. ::SetWindowPos(m_pWindow->GetHWND(), NULL, rcPos.left, rcPos.top, rcPos.right - rcPos.left,
  359. rcPos.bottom - rcPos.top, SWP_NOZORDER | SWP_NOACTIVATE);
  360. }
  361. }
  362. void CHotKeyUI::SetVisible(bool bVisible)
  363. {
  364. CControlUI::SetVisible(bVisible);
  365. if( !IsVisible() && m_pWindow != NULL ) m_pManager->SetFocus(NULL);
  366. }
  367. void CHotKeyUI::SetInternVisible(bool bVisible)
  368. {
  369. if( !IsVisible() && m_pWindow != NULL ) m_pManager->SetFocus(NULL);
  370. }
  371. SIZE CHotKeyUI::EstimateSize(SIZE szAvailable)
  372. {
  373. if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetFontInfo(GetFont())->tm.tmHeight + 6);
  374. return CControlUI::EstimateSize(szAvailable);
  375. }
  376. void CHotKeyUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  377. {
  378. if( _tcscmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  379. else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  380. else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  381. else if( _tcscmp(pstrName, _T("disabledimage")) == 0 ) SetDisabledImage(pstrValue);
  382. else if( _tcscmp(pstrName, _T("nativebkcolor")) == 0 ) {
  383. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  384. LPTSTR pstr = NULL;
  385. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  386. SetNativeBkColor(clrColor);
  387. }
  388. else CLabelUI::SetAttribute(pstrName, pstrValue);
  389. }
  390. void CHotKeyUI::PaintStatusImage(HDC hDC)
  391. {
  392. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  393. else m_uButtonState &= ~ UISTATE_FOCUSED;
  394. if( !IsEnabled() ) m_uButtonState |= UISTATE_DISABLED;
  395. else m_uButtonState &= ~ UISTATE_DISABLED;
  396. if( (m_uButtonState & UISTATE_DISABLED) != 0 ) {
  397. if( !m_sDisabledImage.IsEmpty() ) {
  398. if( !DrawImage(hDC, (LPCTSTR)m_sDisabledImage) ) {}
  399. else return;
  400. }
  401. }
  402. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  403. if( !m_sFocusedImage.IsEmpty() ) {
  404. if( !DrawImage(hDC, (LPCTSTR)m_sFocusedImage) ) {}
  405. else return;
  406. }
  407. }
  408. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  409. if( !m_sHotImage.IsEmpty() ) {
  410. if( !DrawImage(hDC, (LPCTSTR)m_sHotImage) ) {}
  411. else return;
  412. }
  413. }
  414. if( !m_sNormalImage.IsEmpty() ) {
  415. if( !DrawImage(hDC, (LPCTSTR)m_sNormalImage) ) {}
  416. else return;
  417. }
  418. }
  419. void CHotKeyUI::PaintText(HDC hDC)
  420. {
  421. if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
  422. if( m_dwDisabledTextColor == 0 ) m_dwDisabledTextColor = m_pManager->GetDefaultDisabledColor();
  423. if( m_sText.IsEmpty() ) return;
  424. CDuiString sText = m_sText;
  425. RECT rc = m_rcItem;
  426. rc.left += m_rcTextPadding.left;
  427. rc.right -= m_rcTextPadding.right;
  428. rc.top += m_rcTextPadding.top;
  429. rc.bottom -= m_rcTextPadding.bottom;
  430. DWORD dwTextColor = m_dwTextColor;
  431. if(!IsEnabled())dwTextColor = m_dwDisabledTextColor;
  432. CRenderEngine::DrawText(hDC, m_pManager, rc, sText, dwTextColor, m_iFont, DT_SINGLELINE | m_uTextStyle);
  433. }
  434. DWORD CHotKeyUI::GetHotKey() const
  435. {
  436. return (MAKEWORD(m_wVirtualKeyCode, m_wModifiers));
  437. }
  438. void CHotKeyUI::GetHotKey(WORD &wVirtualKeyCode, WORD &wModifiers) const
  439. {
  440. wVirtualKeyCode = m_wVirtualKeyCode;
  441. wModifiers = m_wModifiers;
  442. }
  443. void CHotKeyUI::SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
  444. {
  445. m_wVirtualKeyCode = wVirtualKeyCode;
  446. m_wModifiers = wModifiers;
  447. if( m_pWindow ) return;
  448. m_pWindow = new CHotKeyWnd();
  449. ASSERT(m_pWindow);
  450. m_pWindow->Init(this);
  451. Invalidate();
  452. }
  453. }// Duilib