Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1089 lines
26 KiB

  1. //
  2. // This is implementation of softkbd window UI.
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "softkbdui.h"
  7. #include "maskbmp.h"
  8. #include "commctrl.h"
  9. #include "cuiutil.h"
  10. #include "immxutil.h"
  11. #include "cregkey.h"
  12. HBITMAP MyLoadImage(HINSTANCE hInst, LPCSTR pResStr)
  13. {
  14. HBITMAP hBmpRes;
  15. hBmpRes = (HBITMAP)LoadBitmap(hInst, pResStr);
  16. return hBmpRes;
  17. }
  18. /* C O N V E R T L O G F O N T W T O A */
  19. /*------------------------------------------------------------------------------
  20. Convert LOGFONTW to LOGFONTA
  21. ------------------------------------------------------------------------------*/
  22. void ConvertLogFontWtoA( CONST LOGFONTW *plfW, LOGFONTA *plfA )
  23. {
  24. UINT cpg;
  25. plfA->lfHeight = plfW->lfHeight;
  26. plfA->lfWidth = plfW->lfWidth;
  27. plfA->lfEscapement = plfW->lfEscapement;
  28. plfA->lfOrientation = plfW->lfOrientation;
  29. plfA->lfWeight = plfW->lfWeight;
  30. plfA->lfItalic = plfW->lfItalic;
  31. plfA->lfUnderline = plfW->lfUnderline;
  32. plfA->lfStrikeOut = plfW->lfStrikeOut;
  33. plfA->lfCharSet = plfW->lfCharSet;
  34. plfA->lfOutPrecision = plfW->lfOutPrecision;
  35. plfA->lfClipPrecision = plfW->lfClipPrecision;
  36. plfA->lfQuality = plfW->lfQuality;
  37. plfA->lfPitchAndFamily = plfW->lfPitchAndFamily;
  38. DWORD dwChs = plfW->lfCharSet;
  39. CHARSETINFO ChsInfo = {0};
  40. if (dwChs != SYMBOL_CHARSET && TranslateCharsetInfo( &dwChs, &ChsInfo, TCI_SRCCHARSET ))
  41. {
  42. cpg = ChsInfo.ciACP;
  43. }
  44. else
  45. cpg = GetACP();
  46. WideCharToMultiByte( cpg,
  47. 0,
  48. plfW->lfFaceName,
  49. -1,
  50. plfA->lfFaceName,
  51. ARRAYSIZE(plfA->lfFaceName),
  52. NULL,
  53. NULL );
  54. }
  55. ///////////////////////////////////////////////////////////////////////////////
  56. //
  57. //class CSoftkbdButton
  58. //
  59. ///////////////////////////////////////////////////////////////////////////////
  60. CSoftkbdButton::CSoftkbdButton(CUIFObject *pParent, DWORD dwID, const RECT *prc, DWORD dwStyle, KEYID keyId) : CUIFButton2 (pParent, dwID, prc, dwStyle)
  61. {
  62. m_keyId = keyId;
  63. CUIFWindow *pUIWnd;
  64. pUIWnd = pParent->GetUIWnd( );
  65. m_hFont = pUIWnd->GetFont( );
  66. }
  67. CSoftkbdButton::~CSoftkbdButton( void )
  68. {
  69. if ( m_hBmp )
  70. {
  71. ::DeleteObject( (HGDIOBJ) m_hBmp );
  72. m_hBmp = NULL;
  73. }
  74. if ( m_hBmpMask )
  75. {
  76. ::DeleteObject( (HGDIOBJ)m_hBmpMask );
  77. m_hBmpMask = NULL;
  78. }
  79. if ( m_hIcon )
  80. {
  81. ::DestroyIcon(m_hIcon);
  82. m_hIcon = NULL;
  83. }
  84. }
  85. HRESULT CSoftkbdButton::SetSoftkbdBtnBitmap(HINSTANCE hResDll, WCHAR * wszBitmapStr)
  86. {
  87. HRESULT hr = S_OK;
  88. char pBitmapAnsiName[MAX_PATH];
  89. HBITMAP hBitMap;
  90. WideCharToMultiByte(CP_ACP, 0, wszBitmapStr, -1, pBitmapAnsiName, MAX_PATH, NULL, NULL);
  91. hBitMap = (HBITMAP) MyLoadImage(hResDll, pBitmapAnsiName);
  92. if ( hBitMap == NULL )
  93. {
  94. if ( hResDll != g_hInst )
  95. {
  96. // cannot load it from client-supplied resource dll,
  97. // try our softkbd.dll to see if there is one internal bitmap for this label.
  98. hBitMap = (HBITMAP) MyLoadImage(g_hInst, pBitmapAnsiName);
  99. }
  100. }
  101. if ( hBitMap == NULL )
  102. {
  103. hr = E_FAIL;
  104. return hr;
  105. }
  106. CMaskBitmap maskBmp(hBitMap);
  107. maskBmp.Init(GetSysColor(COLOR_BTNTEXT));
  108. SetBitmap( maskBmp.GetBmp() );
  109. SetBitmapMask( maskBmp.GetBmpMask() );
  110. ::DeleteObject(hBitMap);
  111. return hr;
  112. };
  113. HRESULT CSoftkbdButton::ReleaseButtonResouce( )
  114. {
  115. HRESULT hr = S_OK;
  116. if ( m_hBmp )
  117. {
  118. ::DeleteObject( (HGDIOBJ) m_hBmp );
  119. m_hBmp = NULL;
  120. }
  121. if ( m_hBmpMask )
  122. {
  123. ::DeleteObject( (HGDIOBJ)m_hBmpMask );
  124. m_hBmpMask = NULL;
  125. }
  126. if ( m_hIcon )
  127. {
  128. ::DestroyIcon(m_hIcon);
  129. m_hIcon = NULL;
  130. }
  131. if (m_pwchText != NULL) {
  132. delete m_pwchText;
  133. m_pwchText = NULL;
  134. }
  135. return hr;
  136. }
  137. //////////////////////////////////////////////////////////////////////////////
  138. //
  139. // CStaticBitmap
  140. //
  141. //////////////////////////////////////////////////////////////////////////////
  142. CStaticBitmap::CStaticBitmap(CUIFObject *pParent, DWORD dwID, const RECT *prc, DWORD dwStyle) : CUIFObject(pParent, dwID, prc, dwStyle )
  143. {
  144. m_hBmp = NULL;
  145. m_hBmpMask = NULL;
  146. }
  147. CStaticBitmap::~CStaticBitmap( void )
  148. {
  149. if ( m_hBmp )
  150. {
  151. ::DeleteObject(m_hBmp);
  152. m_hBmp = NULL;
  153. }
  154. if ( m_hBmpMask )
  155. {
  156. ::DeleteObject(m_hBmpMask);
  157. m_hBmpMask = NULL;
  158. }
  159. }
  160. HRESULT CStaticBitmap::SetStaticBitmap(HINSTANCE hResDll, WCHAR * wszBitmapStr )
  161. {
  162. HRESULT hr = S_OK;
  163. char pBitmapAnsiName[MAX_PATH];
  164. HBITMAP hBitMap;
  165. WideCharToMultiByte(CP_ACP, 0, wszBitmapStr, -1, pBitmapAnsiName, MAX_PATH, NULL, NULL);
  166. hBitMap = (HBITMAP) MyLoadImage(hResDll, pBitmapAnsiName);
  167. if ( hBitMap == NULL )
  168. {
  169. if ( hResDll != g_hInst )
  170. {
  171. // cannot load it from client-supplied resource dll,
  172. // try our softkbd.dll to see if there is one internal bitmap for this label.
  173. hBitMap = (HBITMAP) MyLoadImage(g_hInst, pBitmapAnsiName);
  174. }
  175. }
  176. if ( hBitMap == NULL )
  177. {
  178. hr = E_FAIL;
  179. return hr;
  180. }
  181. CMaskBitmap maskBmp(hBitMap);
  182. maskBmp.Init(GetSysColor(COLOR_BTNTEXT));
  183. m_hBmp = maskBmp.GetBmp();
  184. m_hBmpMask = maskBmp.GetBmpMask();
  185. ::DeleteObject(hBitMap);
  186. return hr;
  187. }
  188. void CStaticBitmap::OnPaint( HDC hDC )
  189. {
  190. if ( !hDC || !m_hBmp ||!m_hBmpMask )
  191. return;
  192. const RECT *prc = &GetRectRef();
  193. const int nWidth = prc->right - prc->left;
  194. const int nHeight= prc->bottom - prc->top;
  195. HBITMAP hBmp = CreateMaskBmp(&GetRectRef(),
  196. m_hBmp,
  197. m_hBmpMask,
  198. (HBRUSH)(COLOR_3DFACE + 1) , 0, 0);
  199. DrawState(hDC,
  200. NULL,
  201. NULL,
  202. (LPARAM)hBmp,
  203. 0,
  204. prc->left,
  205. prc->top,
  206. nWidth,
  207. nHeight,
  208. DST_BITMAP);
  209. DeleteObject(hBmp);
  210. }
  211. //////////////////////////////////////////////////////////////////////////////
  212. //
  213. // CTitleUIGripper
  214. //
  215. //////////////////////////////////////////////////////////////////////////////
  216. void CTitleUIGripper::OnPaint(HDC hDC) {
  217. RECT rc ;
  218. if (GetRectRef().right-GetRectRef().left <= GetRectRef().bottom-GetRectRef().top) {
  219. ::SetRect(&rc, GetRectRef().left + 1,
  220. GetRectRef().top,
  221. GetRectRef().left + 4,
  222. GetRectRef().bottom);
  223. } else {
  224. ::SetRect(&rc, GetRectRef().left,
  225. GetRectRef().top + 1,
  226. GetRectRef().right,
  227. GetRectRef().top+4);
  228. }
  229. DrawEdge(hDC, &rc, BDR_RAISEDINNER, BF_RECT);
  230. }
  231. void CTitleUIGripper::OnLButtonUp( POINT pt )
  232. {
  233. CSoftkbdUIWnd *pUIWnd;
  234. // call base class's member function first.
  235. CUIFGripper::OnLButtonUp(pt);
  236. pUIWnd = (CSoftkbdUIWnd *)GetUIWnd( );
  237. if ( pUIWnd != NULL )
  238. {
  239. // Notify the Window position move.
  240. pUIWnd->_OnWindowMove( );
  241. }
  242. return;
  243. }
  244. //////////////////////////////////////////////////////////////////////////////
  245. //
  246. // CTitleBarUIObj
  247. //
  248. //////////////////////////////////////////////////////////////////////////////
  249. CTitleBarUIObj::CTitleBarUIObj(CUIFObject *pWndFrame, const RECT *prc, TITLEBAR_TYPE TitleBar_Type)
  250. : CUIFObject(pWndFrame, 0, prc, 0)
  251. {
  252. m_TitlebarType = TitleBar_Type;
  253. m_pCloseButton = NULL;
  254. m_pIconButton = NULL;
  255. }
  256. CTitleBarUIObj::~CTitleBarUIObj(void)
  257. {
  258. HBITMAP hBitmap;
  259. HBITMAP hBitmapMask;
  260. if ( m_pCloseButton )
  261. {
  262. if (hBitmap=m_pCloseButton->GetBitmap()) {
  263. m_pCloseButton->SetBitmap((HBITMAP) NULL);
  264. ::DeleteObject(hBitmap);
  265. }
  266. if (hBitmapMask=m_pCloseButton->GetBitmapMask()) {
  267. m_pCloseButton->SetBitmapMask((HBITMAP) NULL);
  268. ::DeleteObject(hBitmapMask);
  269. }
  270. }
  271. }
  272. //----------------------------------------------------------------------------
  273. HRESULT CTitleBarUIObj::_Init(WORD wIconId, WORD wCloseId)
  274. {
  275. HRESULT hr = S_OK;
  276. RECT rectObj = {0,0,0,0};
  277. RECT rectGripper;
  278. if ( m_TitlebarType == TITLEBAR_NONE )
  279. return hr;
  280. GetRect(&rectGripper);
  281. rectObj = rectGripper;
  282. long lIconWidth=rectObj.bottom-rectObj.top + 1;
  283. this->m_pointPreferredSize.y=lIconWidth;
  284. if ( m_TitlebarType == TITLEBAR_GRIPPER_VERTI_ONLY )
  285. {
  286. // This is a vertical gripper only title bar.
  287. rectGripper.left += 2;
  288. rectGripper.right-= 2;
  289. rectGripper.top += 2;
  290. rectGripper.bottom -= 2;
  291. CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
  292. if ( !pUIFObject )
  293. return E_OUTOFMEMORY;
  294. pUIFObject->Initialize();
  295. this->AddUIObj(pUIFObject);
  296. return hr;
  297. }
  298. if ( m_TitlebarType == TITLEBAR_GRIPPER_HORIZ_ONLY )
  299. {
  300. // This is a Horizontal gripper only title bar.
  301. rectGripper.left += 2;
  302. rectGripper.right -= 2;
  303. rectGripper.top += 2;
  304. rectGripper.bottom -= 2;
  305. CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
  306. if ( !pUIFObject )
  307. return E_OUTOFMEMORY;
  308. pUIFObject->Initialize();
  309. this->AddUIObj(pUIFObject);
  310. return hr;
  311. }
  312. if ( wIconId != 0 )
  313. {
  314. rectObj.right=rectObj.left+lIconWidth;
  315. m_pIconButton=new CStaticBitmap(this,wIconId,&rectObj,0);
  316. if (m_pIconButton)
  317. {
  318. m_pIconButton->Initialize();
  319. m_pIconButton->SetStaticBitmap(g_hInst, L"IDB_ICON");
  320. m_pIconButton->m_pointPreferredSize.x=lIconWidth;
  321. this->AddUIObj(m_pIconButton);
  322. }
  323. rectGripper.left = rectObj.right + 4;
  324. }
  325. if ( wCloseId != 0 )
  326. {
  327. rectObj.left=rectGripper.right - lIconWidth -1;
  328. rectObj.right=rectGripper.right;
  329. m_pCloseButton=new CSoftkbdButton(this,wCloseId,&rectObj,UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER, 0);
  330. if (m_pCloseButton)
  331. {
  332. m_pCloseButton->Initialize();
  333. m_pCloseButton->SetSoftkbdBtnBitmap(g_hInst, L"IDB_CLOSE");
  334. m_pCloseButton->m_pointPreferredSize.x=lIconWidth;
  335. this->AddUIObj(m_pCloseButton);
  336. }
  337. rectGripper.right = rectObj.left - 4;
  338. }
  339. rectGripper.top += 3;
  340. CUIFObject *pUIFObject=new CTitleUIGripper(this,&rectGripper);
  341. if ( !pUIFObject )
  342. return E_OUTOFMEMORY;
  343. pUIFObject->Initialize();
  344. this->AddUIObj(pUIFObject);
  345. return hr;
  346. }
  347. ///////////////////////////////////////////////////////////////////////////
  348. //
  349. // CSoftkbdUIWnd
  350. //
  351. ///////////////////////////////////////////////////////////////////////////
  352. CSoftkbdUIWnd::CSoftkbdUIWnd(CSoftKbd *pSoftKbd, HINSTANCE hInst,UINT uiWindowStyle) : CUIFWindow(hInst, uiWindowStyle)
  353. {
  354. m_pSoftKbd = pSoftKbd;
  355. m_TitleBar = NULL;
  356. m_Titlebar_Type = TITLEBAR_NONE;
  357. m_bAlpha = 0;
  358. m_fShowAlphaBlend =TRUE;
  359. m_hUserTextFont = NULL;
  360. }
  361. CSoftkbdUIWnd::~CSoftkbdUIWnd( )
  362. {
  363. // if there is hwnd, detroy it and all the children objects.
  364. if ( m_hWnd && IsWindow(m_hWnd) )
  365. {
  366. ::DestroyWindow( m_hWnd );
  367. m_hWnd = NULL;
  368. }
  369. if ( m_hUserTextFont )
  370. {
  371. SetFont((HFONT)NULL);
  372. DeleteObject(m_hUserTextFont);
  373. m_hUserTextFont = NULL;
  374. }
  375. }
  376. const TCHAR c_szCTFLangBar[] = TEXT("Software\\Microsoft\\CTF\\LangBar");
  377. const TCHAR c_szTransparency[] = TEXT("Transparency");
  378. // Get the Alpha Blending set value from registry:
  379. //
  380. // HKCU\Software\Microsoft\CTF\LangBar: Transparency : REG_DWORD
  381. //
  382. INT CSoftkbdUIWnd::_GetAlphaSetFromReg( )
  383. {
  384. LONG lret = ERROR_SUCCESS;
  385. CMyRegKey regkey;
  386. DWORD dw = 255;
  387. lret = regkey.Open(HKEY_CURRENT_USER,
  388. c_szCTFLangBar,
  389. KEY_READ);
  390. if (ERROR_SUCCESS == lret)
  391. {
  392. lret = regkey.QueryValue(dw, c_szTransparency);
  393. regkey.Close();
  394. }
  395. return (INT)dw;
  396. }
  397. LRESULT CSoftkbdUIWnd::OnObjectNotify(CUIFObject * pUIObj, DWORD dwCode, LPARAM lParam)
  398. {
  399. KEYID keyId;
  400. DWORD dwObjId;
  401. UNREFERENCED_PARAMETER(dwCode);
  402. UNREFERENCED_PARAMETER(lParam);
  403. if ( m_pSoftKbd == NULL )
  404. return 0;
  405. dwObjId = pUIObj->GetID();
  406. if ( dwObjId != 0 )
  407. {
  408. // This is button object, not gripper object.
  409. CSoftkbdButton *pButton;
  410. if ( dwCode == UIBUTTON_PRESSED )
  411. {
  412. pButton = (CSoftkbdButton * )pUIObj;
  413. if ( dwObjId <= MAX_KEY_NUM )
  414. {
  415. // regular keys in the keyboard layout.
  416. keyId = pButton->GetKeyId( );
  417. m_pSoftKbd->_HandleKeySelection(keyId);
  418. }
  419. else
  420. {
  421. // Titlebar buttons
  422. m_pSoftKbd->_HandleTitleBarEvent(dwObjId);
  423. }
  424. }
  425. }
  426. return 0;
  427. }
  428. CUIFObject *CSoftkbdUIWnd::Initialize( void )
  429. {
  430. //
  431. // Get the current active keyboard layout and register window class
  432. // not to send VK_PROCESSKEY by mouse down/up in Korean SoftKbd.
  433. // Related bug#472946 #495890
  434. //
  435. LANGID langId = LOWORD(HandleToUlong(GetKeyboardLayout(0)));
  436. if (PRIMARYLANGID(langId) == LANG_KOREAN)
  437. {
  438. //
  439. // Here register candidate window class.
  440. //
  441. WNDCLASSEX WndClass;
  442. LPCTSTR pszClassName = GetClassName();
  443. memset(&WndClass, 0, sizeof(WndClass));
  444. WndClass.cbSize = sizeof(WndClass);
  445. // Added CS_IME style not to send VK_PROCESSKEY for mouse down/up.
  446. WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_IME;
  447. WndClass.lpfnWndProc = WindowProcedure;
  448. WndClass.cbClsExtra = 0;
  449. WndClass.cbWndExtra = 8;
  450. WndClass.hInstance = g_hInst;
  451. WndClass.hIcon = NULL;
  452. WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  453. WndClass.hbrBackground = NULL;
  454. WndClass.lpszMenuName = NULL;
  455. WndClass.lpszClassName = pszClassName;
  456. WndClass.hIconSm = NULL;
  457. RegisterClassEx(&WndClass);
  458. }
  459. CUIFObject *pUIObjRet;
  460. // call CUIFWindow::Initialize() to create tooltip window
  461. pUIObjRet = CUIFWindow::Initialize();
  462. return pUIObjRet;
  463. }
  464. HWND CSoftkbdUIWnd::_CreateSoftkbdWindow(HWND hOwner, TITLEBAR_TYPE Titlebar_type, INT xPos, INT yPos, INT width, INT height)
  465. {
  466. HWND hWnd;
  467. hWnd = CreateWnd(hOwner);
  468. Move(xPos, yPos, width, height);
  469. m_Titlebar_Type = Titlebar_type;
  470. return hWnd;
  471. }
  472. HRESULT CSoftkbdUIWnd::_GenerateWindowLayout( )
  473. {
  474. HRESULT hr=S_OK;
  475. int i;
  476. KBDLAYOUT *realKbdLayout=NULL;
  477. KBDLAYOUTDES *lpCurKbdLayout=NULL;
  478. CSoftkbdButton *pButton = NULL;
  479. int nChild;
  480. if ( m_pSoftKbd == NULL )
  481. return E_FAIL;
  482. if ( (m_TitleBar == NULL) && ( m_Titlebar_Type != TITLEBAR_NONE) )
  483. {
  484. RECT *prc;
  485. // Get the titlebar rect.
  486. prc = m_pSoftKbd->_GetTitleBarRect( );
  487. m_TitleBar = (CTitleBarUIObj *) new CTitleBarUIObj(this, prc, m_Titlebar_Type);
  488. if ( m_TitleBar == NULL )
  489. return E_FAIL;
  490. m_TitleBar->Initialize( );
  491. m_TitleBar->_Init(KID_ICON, KID_CLOSE);
  492. AddUIObj(m_TitleBar);
  493. }
  494. // If there is any existing object in this window object, just delete all of them, except for Titlebar object
  495. nChild = m_ChildList.GetCount();
  496. for (i=nChild; i>0; i--) {
  497. CUIFObject *pUIObj = m_ChildList.Get(i-1);
  498. if ( pUIObj->GetID( ) != 0 )
  499. {
  500. // This is not Gripper
  501. m_ChildList.Remove(pUIObj);
  502. delete pUIObj;
  503. }
  504. }
  505. // Add all the keys contained in current layout to this window object as its children objects.
  506. // every key should have already been calculated the correct position and size.
  507. lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
  508. if ( lpCurKbdLayout == NULL )
  509. return E_FAIL;
  510. realKbdLayout = &(lpCurKbdLayout->kbdLayout);
  511. if ( realKbdLayout == NULL ) return E_FAIL;
  512. for ( i=0; i<realKbdLayout->wNumberOfKeys; i++) {
  513. KEYID keyId;
  514. RECT keyRect={0,0,0,0};
  515. keyId = realKbdLayout->lpKeyDes[i].keyId;
  516. keyRect.left = realKbdLayout->lpKeyDes[i].wLeft;
  517. keyRect.top = realKbdLayout->lpKeyDes[i].wTop;
  518. keyRect.right = realKbdLayout->lpKeyDes[i].wWidth + keyRect.left - 1;
  519. keyRect.bottom = realKbdLayout->lpKeyDes[i].wHeight + keyRect.top - 1;
  520. if ( realKbdLayout->lpKeyDes[i].tModifier == none )
  521. {
  522. // This is a normal key
  523. pButton = new CSoftkbdButton(this, i+1, &keyRect, UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER, keyId);
  524. }
  525. else
  526. {
  527. // This is toggle key, Modifier key.
  528. pButton = new CSoftkbdButton(this, i+1, &keyRect, UIBUTTON_SUNKENONMOUSEDOWN | UIBUTTON_CENTER | UIBUTTON_VCENTER | UIBUTTON_TOGGLE, keyId);
  529. }
  530. Assert(pButton);
  531. if ( !pButton || !pButton->Initialize() )
  532. {
  533. // may need to release all created buttons.
  534. return E_FAIL;
  535. }
  536. // add this button to this window container.
  537. // button lable ( text or bitmap, or Icon ) will be set later when user selects modification status.
  538. AddUIObj(pButton);
  539. }
  540. return hr;
  541. }
  542. HRESULT CSoftkbdUIWnd::_SetKeyLabel( )
  543. {
  544. HRESULT hr=S_OK;
  545. CSoftkbdButton *pButton;
  546. int i, iIndex;
  547. ACTIVELABEL *pCurLabel;
  548. KEYID keyId;
  549. HINSTANCE hResDll;
  550. KBDLAYOUTDES *lpCurKbdLayout=NULL;
  551. KBDLAYOUT *realKbdLayout=NULL;
  552. int nChild;
  553. int nCur;
  554. if ( m_pSoftKbd == NULL )
  555. return E_FAIL;
  556. lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
  557. if ( lpCurKbdLayout == NULL )
  558. return E_FAIL;
  559. realKbdLayout = &(lpCurKbdLayout->kbdLayout);
  560. if ( realKbdLayout == NULL ) return E_FAIL;
  561. if ( (lpCurKbdLayout->lpKeyMapList)->wszResource[0] == L'\0' )
  562. {
  563. //
  564. // There is no separate dll to keep picture key.
  565. // probably, it is a standard soft keyboard layout.
  566. // so just use internal resource kept in this dll.
  567. //
  568. hResDll = g_hInst;
  569. }
  570. else
  571. {
  572. // There is a separate DLL to keep the bitmap resource.
  573. CHAR lpszAnsiResFile[MAX_PATH];
  574. WideCharToMultiByte(CP_ACP, 0, (lpCurKbdLayout->lpKeyMapList)->wszResource, -1,
  575. lpszAnsiResFile, MAX_PATH, NULL, NULL );
  576. hResDll = (HINSTANCE) LoadLibraryA( lpszAnsiResFile );
  577. if ( hResDll == NULL )
  578. {
  579. Assert(hResDll!=NULL);
  580. return E_FAIL;
  581. }
  582. }
  583. // All the keys are already added to this window container.
  584. // we need to set the label ( text or picture) based on current m_pSoftKbd setting.
  585. pCurLabel = m_pSoftKbd->_GetCurLabel( );
  586. nChild = m_ChildList.GetCount();
  587. for (nCur = 0; nCur < nChild; nCur++) {
  588. DWORD dwObjId;
  589. pButton = (CSoftkbdButton *)(m_ChildList.Get(nCur));
  590. dwObjId = pButton->GetID( );
  591. if ( dwObjId == 0 )
  592. {
  593. continue;
  594. }
  595. // Get the keyindex in CurLabel array.
  596. keyId = pButton->GetKeyId( );
  597. iIndex = -1;
  598. for ( i=0; i<MAX_KEY_NUM; i++ )
  599. {
  600. if ( pCurLabel[i].keyId == keyId )
  601. {
  602. iIndex = i;
  603. break;
  604. }
  605. }
  606. if ( iIndex == -1 )
  607. {
  608. // Cannot find this key,
  609. // return error.
  610. hr = E_FAIL;
  611. goto CleanUp;
  612. }
  613. // Found it, set the label
  614. //
  615. // if it is text key, call pButton->SetText( )
  616. // if it is picture key, call pButton->SetBitmap( )
  617. // Before we set the lable, we need to release all the previous resources
  618. // for this key button, so that we will not cause resource leak.
  619. pButton->ReleaseButtonResouce( );
  620. if ( pCurLabel[iIndex].LabelType == LABEL_TEXT )
  621. pButton->SetText( pCurLabel[iIndex].lpLabelText);
  622. else
  623. {
  624. pButton->SetSoftkbdBtnBitmap(hResDll, pCurLabel[iIndex].lpLabelText);
  625. }
  626. // if it is Disp_Active, call pButton->Enable(TRUE)
  627. // if it is gray key, call pButton->Enable(FALSE)
  628. if ( pCurLabel[iIndex].LabelDisp == LABEL_DISP_ACTIVE )
  629. {
  630. pButton->Enable(TRUE);
  631. }
  632. else
  633. {
  634. pButton->Enable(FALSE);
  635. }
  636. if ( realKbdLayout->lpKeyDes[dwObjId-1].tModifier != none )
  637. {
  638. // this is a modifier key ( Toggle key )
  639. // check to see if this key is pressed.
  640. MODIFYTYPE tModifier;
  641. tModifier = realKbdLayout->lpKeyDes[dwObjId-1].tModifier;
  642. if ( lpCurKbdLayout->ModifierStatus & (1 << tModifier) )
  643. {
  644. // this modifier key has been pressed.
  645. pButton->SetToggleState(TRUE);
  646. }
  647. else
  648. pButton->SetToggleState(FALSE);
  649. }
  650. }
  651. CleanUp:
  652. // Release the resource DLL if there is a separate one.
  653. if ( (lpCurKbdLayout->lpKeyMapList)->wszResource[0] != L'\0' )
  654. {
  655. // There is a separate DLL to keep the bitmap resource.
  656. FreeLibrary(hResDll);
  657. }
  658. return hr;
  659. }
  660. void CSoftkbdUIWnd::Show( INT iShow )
  661. {
  662. KBDLAYOUTDES *lpCurKbdLayout=NULL;
  663. KBDLAYOUT *realKbdLayout=NULL;
  664. int nChild;
  665. int i;
  666. if ( m_pSoftKbd == NULL )
  667. return;
  668. lpCurKbdLayout = m_pSoftKbd->_GetCurKbdLayout( );
  669. if ( lpCurKbdLayout == NULL )
  670. return;
  671. realKbdLayout = &(lpCurKbdLayout->kbdLayout);
  672. if ( realKbdLayout == NULL ) return;
  673. if ( !(iShow & SOFTKBD_SHOW) || (iShow & SOFTKBD_DONT_SHOW_ALPHA_BLEND) )
  674. m_fShowAlphaBlend = FALSE;
  675. else
  676. m_fShowAlphaBlend = TRUE;
  677. m_bAlphaSet = _GetAlphaSetFromReg( );
  678. if ( iShow )
  679. {
  680. // check the togglable key's state.
  681. CSoftkbdButton *pButton;
  682. nChild = m_ChildList.GetCount();
  683. for (i = 0; i < nChild; i++) {
  684. DWORD dwObjId;
  685. pButton = (CSoftkbdButton *)m_ChildList.Get(i);
  686. dwObjId = pButton->GetID( );
  687. if ( dwObjId == 0 )
  688. {
  689. continue;
  690. }
  691. if ( realKbdLayout->lpKeyDes[dwObjId-1].tModifier != none )
  692. {
  693. // this is a modifier key ( Toggle key )
  694. // check to see if this key is pressed.
  695. MODIFYTYPE tModifier;
  696. tModifier = realKbdLayout->lpKeyDes[dwObjId-1].tModifier;
  697. if ( lpCurKbdLayout->ModifierStatus & (1 << tModifier) )
  698. {
  699. // this modifier key has been pressed.
  700. pButton->SetToggleState(TRUE);
  701. }
  702. else
  703. pButton->SetToggleState(FALSE);
  704. }
  705. }
  706. }
  707. CUIFWindow::Show((iShow & SOFTKBD_SHOW) ? TRUE : FALSE);
  708. POINT ptScrn;
  709. GetCursorPos(&ptScrn);
  710. if (WindowFromPoint(ptScrn) == GetWnd())
  711. SetAlpha(255);
  712. else
  713. SetAlpha(m_bAlphaSet);
  714. return;
  715. }
  716. void CSoftkbdUIWnd::UpdateFont( LOGFONTW *plfFont )
  717. {
  718. if ( !plfFont )
  719. return;
  720. HFONT hNewFont;
  721. if ( IsOnNT( ) )
  722. hNewFont = CreateFontIndirectW( plfFont );
  723. else
  724. {
  725. LOGFONTA lfTextFontA;
  726. ConvertLogFontWtoA(plfFont, &lfTextFontA);
  727. hNewFont = CreateFontIndirectA( &lfTextFontA );
  728. }
  729. if ( hNewFont )
  730. {
  731. SetFont(hNewFont);
  732. if ( m_hUserTextFont )
  733. DeleteObject( m_hUserTextFont );
  734. m_hUserTextFont = hNewFont;
  735. }
  736. }
  737. HRESULT CSoftkbdUIWnd::_OnWindowMove( )
  738. {
  739. HRESULT hr = S_OK;
  740. ISoftKbdWindowEventSink *pskbdwndes;
  741. if ( m_pSoftKbd == NULL )
  742. return E_FAIL;
  743. pskbdwndes = m_pSoftKbd->_GetSoftKbdWndES( );
  744. if ( pskbdwndes != NULL )
  745. {
  746. pskbdwndes->AddRef( );
  747. hr = pskbdwndes->OnWindowMove(_xWnd, _yWnd, _nWidth, _nHeight);
  748. pskbdwndes->Release( );
  749. }
  750. return hr;
  751. }
  752. typedef BOOL (WINAPI * SETLAYERWINDOWATTRIBUTE)(HWND, COLORREF, BYTE, DWORD);
  753. void CSoftkbdUIWnd::SetAlpha(INT bAlpha)
  754. {
  755. if ( !m_fShowAlphaBlend )
  756. return;
  757. if ( m_bAlpha == bAlpha )
  758. return;
  759. if ( IsOnNT5() )
  760. {
  761. HINSTANCE hUser32;
  762. DWORD dwExStyle = GetWindowLong(GetWnd(), GWL_EXSTYLE);
  763. SetWindowLong(GetWnd(), GWL_EXSTYLE, dwExStyle | WS_EX_LAYERED);
  764. hUser32 = GetSystemModuleHandle(TEXT("user32.dll"));
  765. SETLAYERWINDOWATTRIBUTE pfnSetLayeredWindowAttributes;
  766. if (pfnSetLayeredWindowAttributes = (SETLAYERWINDOWATTRIBUTE)GetProcAddress(hUser32, TEXT("SetLayeredWindowAttributes")))
  767. pfnSetLayeredWindowAttributes(GetWnd(), 0, (BYTE)bAlpha, LWA_ALPHA);
  768. m_bAlpha = bAlpha;
  769. }
  770. return;
  771. }
  772. void CSoftkbdUIWnd::HandleMouseMsg( UINT uMsg, POINT pt )
  773. {
  774. POINT ptScrn = pt;
  775. ClientToScreen(GetWnd(), &ptScrn);
  776. if (WindowFromPoint(ptScrn) == GetWnd())
  777. SetAlpha(255);
  778. else
  779. SetAlpha(m_bAlphaSet);
  780. CUIFWindow::HandleMouseMsg(uMsg, pt);
  781. }
  782. void CSoftkbdUIWnd::OnMouseOutFromWindow( POINT pt )
  783. {
  784. UNREFERENCED_PARAMETER(pt);
  785. SetAlpha(m_bAlphaSet);
  786. }