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.

1109 lines
36 KiB

  1. #include "hwxobj.h"
  2. #include "memmgr.h"
  3. #include "resource.h"
  4. #include "hwxfe.h"
  5. #include "dbg.h"
  6. #include "cmnhdr.h"
  7. #ifdef UNDER_CE // Windows CE Stub for unsupported APIs
  8. #include "stub_ce.h"
  9. #endif // UNDER_CE
  10. #ifdef FE_JAPANESE
  11. // for character comment
  12. BOOL FGetFarEastInfo(HWXRESULTPRI *pResult, DWORD *pdwID, LPIMEFAREASTINFO *ppInfo);
  13. #endif
  14. // implementation of CHwxMB
  15. CHwxMB::CHwxMB(CHwxInkWindow * pInk,HINSTANCE hInst):CHwxObject(hInst)
  16. {
  17. m_pInk = pInk;
  18. m_pCHwxThreadMB = NULL;
  19. m_pCHwxStroke = NULL;
  20. m_hMBWnd = NULL;
  21. // m_hInstance = hInst;
  22. SetRect(&m_clipRect,0,0,0,0);
  23. m_ptClient.x = m_ptClient.y = 0;
  24. #ifdef FE_CHINESE_SIMPLIFIED
  25. m_CurrentMask = m_lastMaskSent = ALC_CHS_EXTENDED;
  26. #else
  27. m_CurrentMask = m_lastMaskSent = ALC_JPN_EXTENDED;
  28. #endif
  29. m_lastCharSent = INVALID_CHAR;
  30. memset(m_Context, '\0', sizeof(m_Context));
  31. m_bHiPri = FALSE;
  32. if ( pInk )
  33. m_boxSize = (USHORT)pInk->GetMBHeight();
  34. else
  35. m_boxSize = PadWnd_Height;
  36. m_bDown = FALSE;
  37. m_bRightClick = FALSE;
  38. m_bNoInk = TRUE;
  39. m_cLogicalBox = 0;
  40. m_curBox = TOTALLOGICALBOX;
  41. m_iBoxPrev = TOTALLOGICALBOX;
  42. m_hdcMouse = NULL;
  43. m_hCursor = LoadCursor(NULL,IDC_ARROW);
  44. m_bResize = FALSE;
  45. m_firstX = 0;
  46. m_bTimerStarted = FALSE;
  47. m_timeoutValue = 0;
  48. m_pImeStringCandidate = NULL;
  49. m_pImeStringCandidateInfo = NULL;
  50. m_bErase = FALSE;
  51. }
  52. CHwxMB::~CHwxMB()
  53. {
  54. m_pInk = NULL;
  55. // m_hInstance = NULL;
  56. if ( m_hMBWnd )
  57. {
  58. DestroyWindow(m_hMBWnd);
  59. m_hMBWnd = NULL;
  60. }
  61. if ( m_pCHwxThreadMB )
  62. {
  63. delete m_pCHwxThreadMB;
  64. m_pCHwxThreadMB = NULL;
  65. }
  66. if ( m_pCHwxStroke )
  67. {
  68. delete m_pCHwxStroke;
  69. m_pCHwxStroke = NULL;
  70. }
  71. if ( m_pImeStringCandidate )
  72. {
  73. MemFree((void *)m_pImeStringCandidate);
  74. m_pImeStringCandidate = NULL;
  75. }
  76. if ( m_pImeStringCandidateInfo )
  77. {
  78. MemFree((void *)m_pImeStringCandidateInfo);
  79. m_pImeStringCandidateInfo = NULL;
  80. }
  81. }
  82. BOOL CHwxMB::Initialize(TCHAR * pClsName)
  83. {
  84. BOOL bRet = CHwxObject::Initialize(pClsName);
  85. if ( bRet )
  86. {
  87. WNDCLASS wndClass;
  88. wndClass.style = CS_HREDRAW | CS_VREDRAW;
  89. wndClass.lpfnWndProc = MBWndProc;
  90. wndClass.cbClsExtra = 0;
  91. wndClass.cbWndExtra = sizeof(void *);
  92. wndClass.hInstance = m_hInstance;
  93. wndClass.hIcon = 0;
  94. wndClass.hCursor = LoadCursor(NULL,MAKEINTRESOURCE(32631));
  95. #ifndef UNDER_CE
  96. wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  97. #else // UNDER_CE
  98. wndClass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  99. #endif // UNDER_CE
  100. wndClass.lpszMenuName = NULL;
  101. wndClass.lpszClassName = TEXT("WPad");
  102. RegisterClass(&wndClass);
  103. int tmpSize = sizeof(IMESTRINGCANDIDATE) + MB_NUM_CANDIDATES * sizeof(LPWSTR);
  104. m_pImeStringCandidate = (LPIMESTRINGCANDIDATE)MemAlloc(tmpSize);
  105. if ( !m_pImeStringCandidate )
  106. {
  107. return FALSE;
  108. }
  109. tmpSize = sizeof(IMESTRINGCANDIDATEINFO) + MB_NUM_CANDIDATES * sizeof(LPWSTR);
  110. m_pImeStringCandidateInfo = (LPIMESTRINGCANDIDATEINFO)MemAlloc(tmpSize);
  111. if ( !m_pImeStringCandidateInfo )
  112. {
  113. return FALSE;
  114. }
  115. m_pCHwxThreadMB = new CHwxThreadMB(this,m_boxSize);
  116. if ( !m_pCHwxThreadMB )
  117. {
  118. MemFree((void *)m_pImeStringCandidate);
  119. m_pImeStringCandidate = NULL;
  120. MemFree((void *)m_pImeStringCandidateInfo);
  121. m_pImeStringCandidateInfo = NULL;
  122. return FALSE;
  123. }
  124. m_pCHwxStroke = new CHwxStroke(TRUE,32);
  125. if ( !m_pCHwxStroke )
  126. {
  127. MemFree((void *)m_pImeStringCandidate);
  128. m_pImeStringCandidate = NULL;
  129. MemFree((void *)m_pImeStringCandidateInfo);
  130. m_pImeStringCandidateInfo = NULL;
  131. delete m_pCHwxThreadMB;
  132. m_pCHwxThreadMB = NULL;
  133. return FALSE;
  134. }
  135. bRet = m_pCHwxThreadMB->Initialize(TEXT("CHwxThreadMB"));
  136. if ( !bRet )
  137. {
  138. MemFree((void *)m_pImeStringCandidate);
  139. m_pImeStringCandidate = NULL;
  140. MemFree((void *)m_pImeStringCandidateInfo);
  141. m_pImeStringCandidateInfo = NULL;
  142. delete m_pCHwxThreadMB;
  143. m_pCHwxThreadMB = NULL;
  144. delete m_pCHwxStroke;
  145. m_pCHwxStroke = NULL;
  146. return FALSE;
  147. }
  148. bRet = m_pCHwxStroke->Initialize(TEXT("CHwxStrokeMB"));
  149. if ( !bRet )
  150. {
  151. MemFree((void *)m_pImeStringCandidate);
  152. m_pImeStringCandidate = NULL;
  153. MemFree((void *)m_pImeStringCandidateInfo);
  154. m_pImeStringCandidateInfo = NULL;
  155. delete m_pCHwxThreadMB;
  156. m_pCHwxThreadMB = NULL;
  157. delete m_pCHwxStroke;
  158. m_pCHwxStroke = NULL;
  159. return FALSE;
  160. }
  161. }
  162. return bRet;
  163. }
  164. BOOL CHwxMB::CreateUI(HWND hwnd)
  165. {
  166. m_hMBWnd = CreateWindowEx( 0,
  167. TEXT("WPad"),
  168. TEXT(""),
  169. WS_CHILD | WS_VISIBLE,
  170. 0, 0,
  171. 0, 0,
  172. hwnd,
  173. (HMENU)IDC_MBINPUT, //980706:for #1624. for "?" help
  174. m_hInstance,
  175. this);
  176. if( !m_hMBWnd )
  177. {
  178. return FALSE;
  179. }
  180. return TRUE;
  181. }
  182. void CHwxMB::HandlePaint(HWND hwnd)
  183. {
  184. int x, i;
  185. RECT rc;
  186. HBRUSH hbr, hbrOld;
  187. int mbWidth = m_pInk->GetMBWidth();
  188. int mbHeight = m_pInk->GetMBHeight();
  189. int numBoxes = m_pInk->GetMBBoxNumber();
  190. // Erase the whole thing first
  191. //
  192. PAINTSTRUCT ps;
  193. BeginPaint(hwnd, &ps);
  194. if ( ps.fErase )
  195. {
  196. rc.left = rc.top = 0;
  197. rc.right = mbWidth;
  198. rc.bottom = Box_Border;
  199. #ifndef UNDER_CE
  200. FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1));
  201. #else // UNDER_CE
  202. FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE));
  203. #endif // UNDER_CE
  204. rc.left = 0;
  205. rc.top = mbHeight - Box_Border;
  206. rc.right = mbWidth;
  207. rc.bottom = mbHeight;
  208. #ifndef UNDER_CE
  209. FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1));
  210. #else // UNDER_CE
  211. FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE));
  212. #endif // UNDER_CE
  213. x = 0;
  214. for ( i = 0; i < numBoxes; i++)
  215. {
  216. rc.left = x;
  217. rc.top = Box_Border;
  218. rc.right = rc.left + Box_Border;
  219. rc.bottom = mbHeight - Box_Border;
  220. #ifndef UNDER_CE
  221. FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1));
  222. #else // UNDER_CE
  223. FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE));
  224. #endif // UNDER_CE
  225. rc.left = x + m_boxSize - Box_Border;
  226. rc.top = Box_Border;
  227. rc.right = rc.left + Box_Border;
  228. rc.bottom = mbHeight - Box_Border;
  229. #ifndef UNDER_CE
  230. FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1));
  231. #else // UNDER_CE
  232. FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE));
  233. #endif // UNDER_CE
  234. x += m_boxSize;
  235. }
  236. }
  237. // Draw all the boxes.
  238. //
  239. //----------------------------------------------------------------
  240. //980803:ToshiaK merge with PRC
  241. //use COLOR_WINDOW instead of WHITE_BRUSH
  242. //----------------------------------------------------------------
  243. hbr = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
  244. hbrOld = (HBRUSH)::SelectObject(ps.hdc, hbr);
  245. x = 0;
  246. for (i=0; i < numBoxes; i++)
  247. {
  248. Rectangle(ps.hdc, x+Box_Border, Box_Border,
  249. x+m_boxSize-Box_Border,
  250. m_boxSize-Box_Border);
  251. rc.top = Box_Border;
  252. rc.left= x+Box_Border;
  253. rc.right=x+m_boxSize-Box_Border;
  254. rc.bottom=m_boxSize-Box_Border;
  255. DrawEdge(ps.hdc,&rc,EDGE_SUNKEN,BF_RECT);
  256. m_pInk->DrawHwxGuide(ps.hdc,&rc);
  257. x += m_boxSize;
  258. }
  259. m_iBoxPrev = TOTALLOGICALBOX;
  260. //
  261. // Redraw the current character.
  262. //
  263. m_pCHwxStroke->DrawStroke(ps.hdc,0,TRUE);
  264. ::SelectObject(ps.hdc, hbrOld);
  265. ::DeleteObject(hbr); //980803:ToshiaK.PRC merge
  266. EndPaint(hwnd, &ps);
  267. }
  268. BOOL CHwxMB::IsInInkBox(PPOINT ppt)
  269. {
  270. int iBox = ppt->x / m_boxSize;
  271. POINT pt = *ppt;
  272. RECT rc;
  273. rc.left = iBox*m_boxSize + Box_Border;
  274. rc.top = Box_Border;
  275. rc.right = rc.left + m_boxSize - 2*Box_Border;
  276. rc.bottom = m_boxSize - Box_Border;
  277. return PtInRect(&rc,pt);
  278. }
  279. BOOL CHwxMB::IsPointInResizeBox(PPOINT ppt)
  280. {
  281. int iBox = (ppt->x-1) / m_boxSize;
  282. int numBox = m_pInk->GetMBBoxNumber();
  283. if ( numBox == ( iBox + 1) )
  284. return FALSE;
  285. POINT pt = *ppt;
  286. RECT rc;
  287. rc.left = (iBox+1)*m_boxSize - Box_Border;
  288. rc.top = Box_Border + 2;
  289. rc.right = rc.left + 2*Box_Border;
  290. rc.bottom = m_boxSize - Box_Border - 2;
  291. return PtInRect(&rc,pt);
  292. }
  293. void CHwxMB::recognize(void)
  294. {
  295. PostThreadMessage(m_pCHwxThreadMB->GetID() , THRDMSG_RECOGNIZE, (WPARAM)m_cLogicalBox, (LONG) 0);
  296. m_cLogicalBox = 0;
  297. }
  298. void CHwxMB::SetLogicalBox(int iBox)
  299. {
  300. if (iBox != m_curBox) // Are we in a new box ?
  301. {
  302. //
  303. // We need to blow away the strokes we saved for redrawing the screen
  304. //
  305. m_pCHwxStroke->DeleteAllStroke();
  306. if (iBox == TOTALLOGICALBOX) // If the new box is TOTALLOGICALBOX we need to recognize everything.
  307. {
  308. recognize();
  309. }
  310. else
  311. {
  312. m_cLogicalBox++;
  313. }
  314. }
  315. }
  316. void CHwxMB::SetContext()
  317. {
  318. if (m_lastMaskSent != m_CurrentMask)
  319. {
  320. PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETMASK,
  321. (WPARAM) m_CurrentMask,
  322. 0);
  323. m_lastMaskSent = m_CurrentMask;
  324. }
  325. WCHAR wch = 0x0000;
  326. memset(m_Context, '\0', sizeof(m_Context));
  327. if ( S_OK == ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),IMEPADREQ_GETCOMPOSITIONSTRING,(WPARAM)m_Context,100) &&
  328. (wch = findLastContext()) )
  329. {
  330. if (m_lastCharSent != wch )
  331. {
  332. PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETCONTEXT,
  333. (WPARAM)wch,
  334. 0);
  335. m_lastCharSent = wch;
  336. }
  337. }
  338. else
  339. {
  340. if (m_lastCharSent != INVALID_CHAR)
  341. {
  342. PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETCONTEXT,
  343. (WPARAM) INVALID_CHAR,
  344. 0);
  345. m_lastCharSent = INVALID_CHAR;
  346. }
  347. }
  348. }
  349. void CHwxMB::DrawMBInkBox(HDC hdc, WORD iBox)
  350. {
  351. RECT rc;
  352. HBRUSH hbr = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
  353. HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, hbr);
  354. PatBlt(hdc,
  355. (m_boxSize * iBox) + Box_Border,
  356. Box_Border,
  357. m_boxSize-Box_Border*2,
  358. m_boxSize-Box_Border*2,
  359. PATCOPY);
  360. rc.left = (m_boxSize * iBox) + Box_Border;
  361. rc.top = Box_Border;
  362. rc.right = m_boxSize * (1 + iBox) - Box_Border;
  363. rc.bottom = m_boxSize - Box_Border;
  364. DrawEdge(hdc,&rc,EDGE_SUNKEN,BF_RECT);
  365. m_pInk->DrawHwxGuide(hdc,&rc);
  366. SelectObject(hdc, hbrOld);
  367. ::DeleteObject(hbr);
  368. }
  369. BOOL CHwxMB::HandleMouseEvent(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
  370. {
  371. POINT pt;
  372. POINT ptTmp;
  373. int x,y;
  374. int iBox,len;
  375. //----------------------------------------------------------------
  376. //Satori #2763.
  377. //must cast (short) first.
  378. //pt.x = (unsigned short)LOWORD(lp);
  379. //pt.y = (unsigned short)HIWORD(lp);
  380. //----------------------------------------------------------------
  381. pt.x = (LONG)(short)LOWORD(lp);
  382. pt.y = (LONG)(short)HIWORD(lp);
  383. #ifdef UNDER_CE // LBUTTON + ALT key handling
  384. //Standard way for RBUTTON handling is combination w/ LBUTTON + ALT key
  385. if(msg == WM_LBUTTONDOWN){
  386. if(GetAsyncKeyState(VK_MENU))
  387. msg = WM_RBUTTONDOWN;
  388. }
  389. else if(msg == WM_LBUTTONUP){
  390. if(GetAsyncKeyState(VK_MENU))
  391. msg = WM_RBUTTONUP;
  392. }
  393. #endif // UNDER_CE
  394. switch (msg)
  395. {
  396. case WM_LBUTTONDBLCLK:
  397. case WM_LBUTTONDOWN:
  398. {
  399. // Pump up our thread priority by 1 level
  400. if ( !m_bDown && IsInInkBox(&pt) && !m_bResize )
  401. {
  402. if ( m_bRightClick )
  403. return TRUE;
  404. if (!m_bHiPri)
  405. {
  406. SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  407. m_bHiPri = TRUE;
  408. }
  409. if (m_bTimerStarted)
  410. {
  411. KillTimer(hwnd, TIMER_ID);
  412. m_bTimerStarted = FALSE;
  413. }
  414. SetCapture(hwnd);
  415. m_bDown = TRUE;
  416. // Now possibly sending the previous ink to the recognizer
  417. // and closing any open alt-lists.
  418. iBox = pt.x / m_boxSize;
  419. SetLogicalBox(iBox);
  420. m_bErase = FALSE;
  421. // Setup the clipRect and region for the DC if it's
  422. // not already set up.
  423. if (m_hdcMouse == NULL)
  424. {
  425. m_hdcMouse = GetDC(hwnd);
  426. }
  427. if (iBox != m_curBox)
  428. {
  429. m_clipRect.left = iBox*m_boxSize + Box_Border;
  430. m_clipRect.top = Box_Border;
  431. m_clipRect.right = m_clipRect.left +
  432. m_boxSize - 2*Box_Border;
  433. m_clipRect.bottom = m_boxSize - Box_Border;
  434. // adjust clip rectangle to have ink staying in the box
  435. //990602:for KOTAE #818
  436. m_clipRect.left += 2;
  437. m_clipRect.top += 2;
  438. m_clipRect.right -= 2;
  439. m_clipRect.bottom -= 2;
  440. #if 0 //OLD code
  441. m_clipRect.left += 1;
  442. m_clipRect.top += 1;
  443. m_clipRect.right -= 1;
  444. m_clipRect.bottom -= 1;
  445. #endif
  446. }
  447. if (pt.x < m_clipRect.left)
  448. {
  449. pt.x = m_clipRect.left;
  450. }
  451. else if (pt.x >= m_clipRect.right)
  452. {
  453. pt.x = m_clipRect.right - 1;
  454. }
  455. if (pt.y < m_clipRect.top)
  456. {
  457. pt.y = m_clipRect.top ;
  458. }
  459. else if (pt.y >= m_clipRect.bottom)
  460. {
  461. pt.y = m_clipRect.bottom - 1;
  462. }
  463. // Get the offset to the window so we can convert the
  464. // screen points to window points without doing a call on each one.
  465. if ( m_pCHwxStroke->AddPoint(pt) )
  466. {
  467. m_ptClient.x = m_ptClient.y = 0;
  468. ScreenToClient(hwnd, &(m_ptClient));
  469. // Save away the current and previous box info.
  470. m_iBoxPrev = m_curBox;
  471. m_curBox = (USHORT)iBox;
  472. return TRUE;
  473. }
  474. else
  475. return FALSE;
  476. }
  477. else if (IsPointInResizeBox(&pt))
  478. {
  479. if ( !m_bResize )
  480. {
  481. SetCapture(hwnd);
  482. m_bResize = TRUE;
  483. m_firstX = pt.x;
  484. ptTmp = pt;
  485. ClientToScreen(hwnd,&ptTmp);
  486. SetCursorPos(ptTmp.x,ptTmp.y);
  487. if ( GetStrokeCount() )
  488. {
  489. HandleUserMessage(hwnd,MB_WM_ERASE,0,0);
  490. }
  491. }
  492. return TRUE;
  493. }
  494. break;
  495. }
  496. case WM_LBUTTONUP:
  497. {
  498. if (m_bDown)
  499. {
  500. m_bDown = FALSE;
  501. x = (short)pt.x;
  502. y = (short)pt.y;
  503. if (x < m_clipRect.left)
  504. {
  505. pt.x = m_clipRect.left;
  506. }
  507. else if (x >= m_clipRect.right)
  508. {
  509. pt.x = m_clipRect.right - 1;
  510. }
  511. if (y < m_clipRect.top)
  512. {
  513. pt.y = m_clipRect.top;
  514. }
  515. else if (y >= m_clipRect.bottom)
  516. {
  517. pt.y = m_clipRect.bottom - 1;
  518. }
  519. m_pCHwxStroke->AddPoint(pt);
  520. ReleaseCapture();
  521. m_pCHwxStroke->AddBoxStroke(m_cLogicalBox-1,m_curBox,m_boxSize);
  522. if (m_bNoInk)
  523. {
  524. m_bNoInk = FALSE;
  525. //
  526. // First Stroke in the box is done, set the context info now.
  527. //
  528. SetContext();
  529. }
  530. //
  531. // Send the Recognizer stroke off.
  532. //
  533. PSTROKE pstRecog = m_pCHwxStroke->CopyCurrentStroke();
  534. if ( pstRecog )
  535. //----------------------------------------------------------------
  536. //00/07/03: Hail pointed out.
  537. //for Win64. (LPARAM) is better than LONG_PTR.
  538. //LONG_PTR is not defined in VC6(only Platform SDK)
  539. //----------------------------------------------------------------
  540. PostThreadMessage(m_pCHwxThreadMB->GetID(),
  541. THRDMSG_ADDINK,
  542. (WPARAM)m_boxSize,
  543. (LPARAM)pstRecog);
  544. //
  545. // Erase the old ink, we have a tiny slice of time before the next
  546. // stroke can begin.
  547. //
  548. if ((m_curBox != m_iBoxPrev) &&
  549. (m_iBoxPrev != TOTALLOGICALBOX))
  550. {
  551. DrawMBInkBox(m_hdcMouse, m_iBoxPrev);
  552. m_iBoxPrev = TOTALLOGICALBOX;
  553. }
  554. // Now start timer
  555. //
  556. // If timeout value is 0, it means no timeout. Don't
  557. // start timer
  558. if( m_timeoutValue )
  559. {
  560. SetTimer(hwnd, TIMER_ID, m_timeoutValue, NULL);
  561. m_bTimerStarted = TRUE;
  562. }
  563. return TRUE;
  564. }
  565. else if (IsPointInResizeBox(&pt))
  566. {
  567. if ( m_bResize )
  568. {
  569. len = pt.x - m_firstX;
  570. iBox = (m_firstX-4) / m_boxSize;
  571. m_boxSize += (USHORT)len;
  572. m_boxSize = (USHORT)(m_boxSize > INKBOXSIZE_MIN ? m_boxSize : INKBOXSIZE_MIN);
  573. m_pInk->SetMBHeight(m_boxSize);
  574. ptTmp.x = (iBox + 1) * m_boxSize;
  575. ptTmp.y = pt.y;
  576. ClientToScreen(hwnd,&ptTmp);
  577. SetCursorPos(ptTmp.x,ptTmp.y);
  578. m_firstX = (iBox+1) * m_boxSize;
  579. m_pInk->ChangeIMEPADSize(FALSE);
  580. m_pInk->ChangeLayout(FALSE);
  581. ReleaseCapture();
  582. m_bResize = FALSE;
  583. UpdateWindow(GetParent(m_pInk->GetInkWindow()));
  584. UpdateWindow(m_pInk->GetInkWindow());
  585. return TRUE;
  586. }
  587. }
  588. else
  589. {
  590. if ( m_bResize )
  591. {
  592. if ( hwnd == GetCapture() )
  593. ReleaseCapture();
  594. m_hCursor = LoadCursor(NULL,IDC_ARROW);
  595. SetCursor(m_hCursor);
  596. m_bResize = FALSE;
  597. }
  598. }
  599. break;
  600. }
  601. case WM_MOUSEMOVE:
  602. {
  603. //char szbuf[256];
  604. //wsprintf(szbuf, "WM_MOUSEMOVE pt.x [%d] pt.y[%d]\n", pt.x, pt.y);
  605. //OutputDebugString(szbuf);
  606. }
  607. if (m_bDown && !m_bResize)
  608. {
  609. //UINT cbPt = 1;
  610. x = (short)pt.x;
  611. y = (short)pt.y;
  612. if ( x < m_clipRect.left)
  613. {
  614. pt.x = m_clipRect.left;
  615. }
  616. else if ( x >= m_clipRect.right )
  617. {
  618. pt.x = m_clipRect.right - 1;
  619. }
  620. if ( y < m_clipRect.top )
  621. {
  622. pt.y = m_clipRect.top;
  623. }
  624. else if ( y >= m_clipRect.bottom )
  625. {
  626. pt.y = m_clipRect.bottom - 1;
  627. }
  628. if ( m_pCHwxStroke->AddPoint(pt) )
  629. {
  630. m_pCHwxStroke->DrawStroke(m_hdcMouse,2,FALSE);
  631. }
  632. return TRUE;
  633. }
  634. else if ( hwnd == GetCapture() || IsPointInResizeBox(&pt))
  635. {
  636. //990602:KOTAE #245.
  637. //If mouse move is too fast, back ground is NOT repainted.
  638. //So, This is little bit hack but work well.
  639. //This sleep change context switch and remove too much WM_MOUSEMOVE message.
  640. #if 1
  641. static DWORD g_dwTick;
  642. DWORD dwTick = ::GetTickCount();
  643. if(dwTick - g_dwTick < 20) {
  644. return TRUE;
  645. }
  646. g_dwTick = dwTick;
  647. #endif
  648. HCURSOR hCur = LoadCursor(NULL,IDC_SIZEWE);
  649. #ifndef UNDER_CE // CE specific
  650. m_hCursor = SetCursor(hCur);
  651. #else // UNDER_CE
  652. SetCursor(hCur);
  653. #endif // UNDER_CE
  654. if ( m_bResize )
  655. {
  656. Dbg(("Resizing Multibox \n"));
  657. //990621:KOTAE #1229
  658. pt.x = (short)pt.x;
  659. if(pt.x < 0) {
  660. return TRUE;
  661. }
  662. iBox = (m_firstX-4) / m_boxSize;
  663. len = pt.x - m_firstX;
  664. m_boxSize += (USHORT)len;
  665. Dbg(("=>new m_boxSize %d\n", m_boxSize));
  666. //wsprintf(szbuf, "new m_boxSize [%d]\n", m_boxSize);
  667. //OutputDebugString(szbuf);
  668. //----------------------------------------------------------------
  669. //980821:ToshiaKCheck max size of m_boxSize,
  670. //To prevent resize boxsize inifinitly.
  671. //----------------------------------------------------------------
  672. INT cxScreen = ::GetSystemMetrics(SM_CXFULLSCREEN)/2;
  673. INT cyScreen = ::GetSystemMetrics(SM_CYFULLSCREEN)/2;
  674. if(m_boxSize >= INKBOXSIZE_MIN) {
  675. if(m_boxSize >= cxScreen || m_boxSize >= cyScreen) {
  676. m_boxSize = (USHORT)(cxScreen < cyScreen ? cxScreen : cyScreen);
  677. }
  678. }
  679. else {
  680. m_boxSize = INKBOXSIZE_MIN;
  681. }
  682. //----------------------------------------------------------------
  683. //Old code
  684. //----------------------------------------------------------------
  685. //m_boxSize = m_boxSize > INKBOXSIZE_MIN ? m_boxSize : INKBOXSIZE_MIN ;
  686. m_pInk->SetMBHeight( m_boxSize );
  687. ptTmp.x = (iBox+1) * m_boxSize;
  688. ptTmp.y = pt.y;
  689. ClientToScreen(hwnd,&ptTmp);
  690. SetCursorPos(ptTmp.x,ptTmp.y);
  691. m_pInk->ChangeIMEPADSize(FALSE);
  692. m_pInk->ChangeLayout(FALSE);
  693. UpdateWindow(GetParent(m_pInk->GetInkWindow()));
  694. UpdateWindow(m_pInk->GetInkWindow());
  695. //990602:KOTAE #245.
  696. ::InvalidateRect(m_pInk->GetInkWindow(), NULL, TRUE);
  697. m_firstX = (iBox+1) * m_boxSize;
  698. }
  699. return TRUE;
  700. }
  701. else
  702. {
  703. if ( !m_bResize )
  704. {
  705. m_hCursor = LoadCursor(NULL,IDC_ARROW); // SATORI #164
  706. SetCursor(m_hCursor);
  707. }
  708. return TRUE;
  709. }
  710. break;
  711. case WM_RBUTTONDOWN:
  712. {
  713. if ( IsInInkBox(&pt) )
  714. {
  715. m_bRightClick = TRUE;
  716. return TRUE;
  717. }
  718. }
  719. break;
  720. case WM_RBUTTONUP:
  721. {
  722. // 980408:kwada - IME98A #304
  723. // No popup menu when left button is down.
  724. if(m_bDown) {
  725. m_bRightClick = FALSE;
  726. break;
  727. }
  728. if ( IsInInkBox(&pt) )
  729. {
  730. HMENU hMenu;
  731. HMENU hMenuTrackPopup;
  732. //----------------------------------------------------------------
  733. //fixed MSKK #5035.Need to load specified language's menu resource
  734. //BUGBUG::hMenu = LoadMenu (m_hInstance, MAKEINTRESOURCE(IDR_MB));
  735. //----------------------------------------------------------------
  736. hMenu = CHwxFE::GetMenu(m_hInstance, MAKEINTRESOURCE(IDR_MB));
  737. if (!hMenu)
  738. {
  739. m_bRightClick = FALSE;
  740. return FALSE;
  741. }
  742. hMenuTrackPopup = GetSubMenu (hMenu, 0);
  743. ClientToScreen(m_hMBWnd,&pt);
  744. #ifndef UNDER_CE // Windows CE does not support TPM_LEFTBUTTON on TrackPopupMenu
  745. TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0,m_hMBWnd, NULL);
  746. #else // UNDER_CE
  747. TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN, pt.x, pt.y, 0,m_hMBWnd, NULL);
  748. #endif // UNDER_CE
  749. DestroyMenu (hMenu);
  750. m_bRightClick = FALSE;
  751. return TRUE;
  752. }
  753. }
  754. break;
  755. default:
  756. break;
  757. }
  758. return FALSE;
  759. Unref(wp);
  760. }
  761. LRESULT CHwxMB::HandleUserMessage(HWND hwnd, UINT iMsg,WPARAM wp,LPARAM lp)
  762. {
  763. LRESULT lRet = 0;
  764. switch (iMsg)
  765. {
  766. //
  767. // We sometimes don't get a WM_LBUTTONUP message due to the system
  768. // design. We need to simulate one here if we think we are in a
  769. // down state or risk flaky behaviour. The hwxpad assumes we will
  770. // get one and may leak resources if we don't.
  771. //
  772. case MB_WM_ERASE:
  773. case MB_WM_DETERMINE:
  774. {
  775. //
  776. // In either case, do the recognition, for erase then send a
  777. // backspace key through.
  778. //
  779. if (m_cLogicalBox)
  780. {
  781. // TOTALLOGICALBOX represents invalid box number, force it to recognize
  782. // the ink in the current box.
  783. if (m_hdcMouse == NULL)
  784. {
  785. m_hdcMouse = GetDC(hwnd);
  786. }
  787. DrawMBInkBox(m_hdcMouse, m_curBox);
  788. SetLogicalBox(TOTALLOGICALBOX);
  789. lRet = 1;
  790. m_bErase = FALSE;
  791. if (iMsg == MB_WM_ERASE)
  792. {
  793. //
  794. // Send a backspace key in to erase the last garbage character.
  795. //
  796. // PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_CHAR, VK_BACK, 0);
  797. m_bErase = TRUE;
  798. }
  799. }
  800. m_bNoInk = TRUE; // We have no more ink for sure now.
  801. //
  802. // In either case erase/time-out/recog-button we no longer have
  803. // a current box, or a need for a DC or a need to be HighPriority.
  804. //
  805. if (m_hdcMouse)
  806. {
  807. ReleaseDC(hwnd, m_hdcMouse);
  808. m_hdcMouse = NULL;
  809. }
  810. m_curBox = TOTALLOGICALBOX; // There's no more ink, init state again.
  811. if (m_bHiPri)
  812. {
  813. SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  814. m_bHiPri = FALSE;
  815. }
  816. break;
  817. }
  818. case MB_WM_COPYINK:
  819. m_pInk->CopyInkFromMBToCAC(* m_pCHwxStroke,m_clipRect.left-Box_Border,0);
  820. break;
  821. case MB_WM_HWXCHAR:
  822. {
  823. HWXRESULTPRI * pResult = (HWXRESULTPRI *)wp;
  824. HWXRESULTPRI * pPrev = pResult;
  825. while ( pResult )
  826. {
  827. if ( m_bErase && NULL == pResult->pNext )
  828. {
  829. // delete the last node
  830. MemFree((void *)pResult);
  831. break;
  832. }
  833. if ( pResult->cbCount )
  834. {
  835. #ifndef FE_JAPANESE
  836. for ( short i = 0; i < pResult->cbCount; i++)
  837. {
  838. m_StringCandidate[i][0] = pResult->chCandidate[i];
  839. m_StringCandidate[i][1] = 0x0000;
  840. m_pImeStringCandidate->lpwstr[i] = m_StringCandidate[i];
  841. }
  842. m_pImeStringCandidate->uCount = pResult->cbCount;
  843. (m_pInk->GetAppletPtr())->SendHwxStringCandidate(m_pImeStringCandidate);
  844. #else
  845. DWORD dwFarEastid;
  846. LPIMEFAREASTINFO lpFarEastInfo = NULL;
  847. if (FGetFarEastInfo( pResult, &dwFarEastid, &lpFarEastInfo ))
  848. {
  849. for ( short i = 0; i < pResult->cbCount; i++)
  850. {
  851. m_StringCandidate[i][0] = pResult->chCandidate[i];
  852. m_StringCandidate[i][1] = 0x0000;
  853. m_pImeStringCandidateInfo->lpwstr[i] = m_StringCandidate[i];
  854. }
  855. m_pImeStringCandidateInfo->dwFarEastId = dwFarEastid;
  856. m_pImeStringCandidateInfo->lpFarEastInfo = lpFarEastInfo;
  857. m_pImeStringCandidateInfo->fInfoMask = INFOMASK_NONE;
  858. m_pImeStringCandidateInfo->iSelIndex = 0;
  859. m_pImeStringCandidateInfo->uCount = pResult->cbCount;
  860. (m_pInk->GetAppletPtr())->SendHwxStringCandidateInfo(m_pImeStringCandidateInfo);
  861. if (lpFarEastInfo)
  862. MemFree(lpFarEastInfo);
  863. }
  864. else
  865. {
  866. for ( short i = 0; i < pResult->cbCount; i++)
  867. {
  868. m_StringCandidate[i][0] = pResult->chCandidate[i];
  869. m_StringCandidate[i][1] = 0x0000;
  870. m_pImeStringCandidate->lpwstr[i] = m_StringCandidate[i];
  871. }
  872. m_pImeStringCandidate->uCount = pResult->cbCount;
  873. (m_pInk->GetAppletPtr())->SendHwxStringCandidate(m_pImeStringCandidate);
  874. }
  875. #endif
  876. }
  877. pResult = pResult->pNext;
  878. pPrev->pNext = NULL;
  879. MemFree((void *)pPrev);
  880. pPrev = pResult;
  881. }
  882. break;
  883. }
  884. // case MB_WM_COMCHAR:
  885. // ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),IMEPADREQ_SENDCONTROL,IMEPADCTRL_CARETBACKSPACE,0);
  886. // break;
  887. default:
  888. break;
  889. }
  890. return lRet;
  891. Unref(lp);
  892. }
  893. LRESULT CHwxMB::HandleCommand(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
  894. {
  895. UINT uCode =(UINT)LOWORD(wp);
  896. switch ( uCode )
  897. {
  898. case IDM_MBRECOG:
  899. return HandleUserMessage(hwnd,MB_WM_DETERMINE,0,0);
  900. case IDM_MBDELETE:
  901. return HandleUserMessage(hwnd,MB_WM_ERASE,0,0);
  902. case IDM_MBPROP:
  903. // This is a hack fix. I think we should use Request().
  904. //((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),
  905. // IMEPADREQ_CONFIGSELF,0,0);
  906. // IDM_CONFIGAPPLET == 0x7009
  907. if(m_pInk &&
  908. m_pInk->GetAppletPtr() &&
  909. m_pInk->GetAppletPtr()->GetIImePad()) {
  910. ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),
  911. IMEPADREQ_POSTMODALNOTIFY,
  912. IMEPN_CONFIG,
  913. 0);
  914. }
  915. //PostMessage(GetParent(GetParent(hwnd)), WM_COMMAND,0x7009,NULL);
  916. return 0;
  917. default:
  918. break;
  919. }
  920. return DefWindowProc(hwnd, msg, wp, lp);
  921. }
  922. //----------------------------------------------------------------
  923. //990618:ToshiaK for KOTAE #1329
  924. //----------------------------------------------------------------
  925. void
  926. CHwxMB::OnSettingChange(UINT msg, WPARAM wp,LPARAM lp)
  927. {
  928. #ifndef UNDER_CE // Unsupported.
  929. if(wp == SPI_SETNONCLIENTMETRICS) {
  930. if(m_pCHwxStroke) {
  931. m_pCHwxStroke->ResetPen();
  932. }
  933. }
  934. #else // UNDER_CE
  935. if(m_pCHwxStroke) {
  936. m_pCHwxStroke->ResetPen();
  937. }
  938. #endif // UNDER_CE
  939. UNREFERENCED_PARAMETER(msg);
  940. UNREFERENCED_PARAMETER(lp);
  941. }
  942. void CHwxMB::SetBoxSize(WORD w)
  943. {
  944. m_boxSize = w;
  945. }
  946. WCHAR CHwxMB::findLastContext()
  947. {
  948. WCHAR prev,curr;
  949. prev = curr = 0x0000;
  950. for(int i = 0; i < sizeof(m_Context)/sizeof(WCHAR); i++)
  951. {
  952. if ( curr = m_Context[i] )
  953. {
  954. prev = curr;
  955. }
  956. else
  957. {
  958. return prev;
  959. }
  960. }
  961. return prev;
  962. }
  963. #ifdef FE_JAPANESE
  964. // for character comment
  965. #include "..\..\imeknl\iconvert\chcomnt.h"
  966. BOOL FGetFarEastInfo(HWXRESULTPRI *pResult, DWORD *pdwID, LPIMEFAREASTINFO *ppInfo)
  967. {
  968. // count char number
  969. INT i;
  970. INT len;
  971. WCHAR *wszComment;
  972. for ( i = len = 0; i < pResult->cbCount; i++)
  973. {
  974. wszComment = WSZGetCharComment(pResult->chCandidate[i], COMMENTCLIENT_HW);
  975. if (wszComment)
  976. len += lstrlenW(wszComment);
  977. len++; // for NULL
  978. }
  979. if ((*ppInfo = (LPIMEFAREASTINFO)MemAlloc(sizeof(IMEFAREASTINFO)+len*sizeof(WCHAR)))==NULL)
  980. return FALSE;
  981. *pdwID = FEID_JAPANESE;
  982. (*ppInfo)->dwSize = sizeof(IMEFAREASTINFO)+len*sizeof(WCHAR);
  983. (*ppInfo)->dwType = IMEFAREASTINFO_TYPE_COMMENT;
  984. INT ip;
  985. WCHAR *wszBuf;
  986. ip = 0;
  987. wszBuf = (WCHAR*)((*ppInfo)->dwData);
  988. for ( i = 0; i < pResult->cbCount; i++)
  989. {
  990. wszComment = WSZGetCharComment(pResult->chCandidate[i], COMMENTCLIENT_HW);
  991. if (wszComment)
  992. {
  993. memcpy( wszBuf+ip, wszComment, (lstrlenW(wszComment)+1)*sizeof(WCHAR));
  994. ip += lstrlenW(wszComment)+1;
  995. }
  996. else
  997. {
  998. wszBuf[ip++] = 0;
  999. }
  1000. }
  1001. return TRUE;
  1002. }
  1003. #endif