Source code of Windows XP (NT5)
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.

2673 lines
75 KiB

  1. /******************************************************************************/
  2. /* Tedit.CPP: IMPLEMENTATION OF THE CTedit CLASS */
  3. /* */
  4. /* */
  5. /******************************************************************************/
  6. /* */
  7. /* Methods in this file */
  8. /* */
  9. /* Edit Control Object */
  10. /* CAttrEdit::OnPaint */
  11. /* CAttrEdit::OnEraseBkgnd */
  12. /* CAttrEdit::OnRButtonDown */
  13. /* CAttrEdit::OnChar */
  14. /* CAttrEdit::OnMouseMove */
  15. /* */
  16. /******************************************************************************/
  17. /* */
  18. /* Text Edit Control Parent Window (Parent of Edit Control) */
  19. /* CTedit::CTedit */
  20. /* CTedit::CTedit */
  21. /* CTedit::~CTedit */
  22. /* */
  23. /* Miscellaneous Methods */
  24. /* CTedit::RefreshWindow */
  25. /* CTedit::SetTextColor */
  26. /* CTedit::SetBackColor */
  27. /* CTedit::SetTransparentMode */
  28. /* CTedit::Undo */
  29. /* CTedit::ShowFontPalette */
  30. /* CTedit::IsFontPaletteVisible */
  31. /* CTedit::GetBitmap */
  32. /* CTedit::PostNcDestroy */
  33. /* CTedit::GetDefaultMinSize */
  34. /* */
  35. /* Edit Control Notification and processing methods */
  36. /* CTedit::OnAttrEditEnChange */
  37. /* CTedit::OnAttrEditFontChange */
  38. /* */
  39. /* Control Notification/Window Messages */
  40. /* CTedit::OnEraseBkgnd */
  41. /* CTedit::OnSize */
  42. /* CTedit::OnMove */
  43. /* CTedit::OnCtlColor */
  44. /* CTedit::OnNcCalcSize */
  45. /* CTedit::OnNcPaint */
  46. /* CTedit::OnNcHitTest */
  47. /* CTedit::OnRButtonDown */
  48. /* */
  49. /* Popup Menu Control Notification/Window Messages */
  50. /* CTedit::OnTextPlain */
  51. /* CTedit::OnTextBold */
  52. /* CTedit::OnTextItalic */
  53. /* CTedit::OnTextUnderline */
  54. /* CTedit::OnTextSelectfont */
  55. /* CTedit::OnTextSelectpointsize */
  56. /* CTedit::OnEditCut */
  57. /* CTedit::OnEditCopy */
  58. /* CTedit::OnEditPaste */
  59. /* CTedit::OnTextDelete */
  60. /* CTedit::OnTextSelectall */
  61. /* CTedit::OnTextPlace */
  62. /* CTedit::OnTextTexttool */
  63. /* */
  64. /* CTedit::OnUpdateTextPlain */
  65. /* CTedit::OnUpdateTextBold */
  66. /* CTedit::OnUpdateTextItalic */
  67. /* CTedit::OnUpdateTextUnderline */
  68. /* CTedit::OnUpdateTextTexttool */
  69. /* */
  70. /******************************************************************************/
  71. // TEDIT.CPP: IMPLEMENTATION OF THE CTEDIT CLASS
  72. //
  73. #include "stdafx.h"
  74. #include "global.h"
  75. #include "pbrush.h"
  76. #include "pbrusvw.h"
  77. #include "pbrusfrm.h"
  78. #include "imgwnd.h"
  79. #include "pictures.h"
  80. #include "minifwnd.h"
  81. #include "tfont.h"
  82. #include "tedit.h"
  83. #include "tracker.h"
  84. #include <imm.h>
  85. #include "imgsuprt.h"
  86. #ifndef WM_SYSTIMER
  87. #define WM_SYSTIMER 0x118
  88. #endif //WM_SYSTIMER
  89. #ifdef _DEBUG
  90. #undef THIS_FILE
  91. static CHAR BASED_CODE THIS_FILE[] = __FILE__;
  92. #endif
  93. IMPLEMENT_DYNCREATE( CAttrEdit, CEdit )
  94. IMPLEMENT_DYNCREATE( CTedit, CWnd )
  95. #include "memtrace.h"
  96. /******************************************************************************/
  97. // CAttrEdit
  98. BEGIN_MESSAGE_MAP( CAttrEdit, CEdit )
  99. //{{AFX_MSG_MAP(CAttrEdit)
  100. ON_WM_PAINT()
  101. ON_WM_ERASEBKGND()
  102. ON_WM_RBUTTONDOWN()
  103. ON_WM_CHAR()
  104. ON_MESSAGE(WM_IME_CHAR, OnImeChar)
  105. ON_MESSAGE(WM_IME_COMPOSITION, OnImeComposition)
  106. ON_MESSAGE(WM_INPUTLANGCHANGE, OnInputLangChange)
  107. ON_WM_KILLFOCUS()
  108. ON_WM_NCHITTEST()
  109. ON_WM_SETFOCUS()
  110. ON_WM_SIZE()
  111. ON_WM_LBUTTONDBLCLK()
  112. ON_WM_LBUTTONDOWN()
  113. ON_WM_MOUSEMOVE()
  114. ON_WM_LBUTTONUP()
  115. ON_WM_KEYDOWN()
  116. ON_MESSAGE(WM_SYSTIMER, OnSysTimer)
  117. //}}AFX_MSG_MAP
  118. END_MESSAGE_MAP()
  119. /******************************************************************************/
  120. CAttrEdit::CAttrEdit()
  121. {
  122. m_bBackgroundTransparent = TRUE;
  123. m_pParentWnd = NULL;
  124. m_uiLastChar[0] = 32;
  125. m_uiLastChar[1] = 32;
  126. m_rectUpdate.SetRectEmpty();
  127. m_strResult.Empty();
  128. m_bMouseDown = FALSE;
  129. m_hHCursor = theApp.LoadStandardCursor( IDC_IBEAM );
  130. m_hVCursor = theApp.LoadCursor( IDCUR_HIBEAM );
  131. m_hOldCursor = NULL;
  132. m_rectFmt.SetRectEmpty();
  133. m_iPrevStart = -1;
  134. m_bResizeOnly = FALSE;
  135. }
  136. /******************************************************************************/
  137. void CAttrEdit::OnPaint()
  138. {
  139. GetUpdateRect( &m_rectUpdate );
  140. if ( !m_pParentWnd->m_bVertEdit )
  141. {
  142. Default();
  143. return;
  144. }
  145. else
  146. {
  147. CFont* pFont;
  148. CFont* pOldFont = NULL;
  149. CPalette* ppalOld = NULL;
  150. int OldBkMode;
  151. COLORREF OldTxtColor;
  152. CRect rc = m_rectFmt;
  153. int cnt = 0;
  154. int i = 0, h = 0;
  155. int nLen;
  156. CString cStr;
  157. LPTSTR lpStr;
  158. int nStart, nEnd;
  159. CDC* pDC = NULL;
  160. PAINTSTRUCT ps;
  161. const MSG *pCurrentMessage = GetCurrentMessage();
  162. //wParam is DC
  163. if ( pCurrentMessage->wParam )
  164. {
  165. HDC hDC = (HDC) pCurrentMessage->wParam;
  166. pDC = CDC::FromHandle( hDC );
  167. }
  168. else
  169. pDC = BeginPaint( &ps );
  170. if (pDC == NULL || pDC->m_hDC == NULL)
  171. {
  172. theApp.SetGdiEmergency();
  173. return;
  174. }
  175. OldBkMode = pDC->GetBkMode();
  176. OldTxtColor = pDC->GetTextColor();
  177. ppalOld = PBSelectPalette(pDC, theApp.m_pPalette, FALSE);
  178. m_pParentWnd->SendMessage( WM_CTLCOLOREDIT, (WPARAM)pDC->m_hDC,
  179. (LPARAM) m_hWnd );
  180. pFont = GetFont();
  181. pOldFont = pDC->SelectObject( pFont );
  182. h = m_pParentWnd->m_iLineHeight;
  183. cnt = GetLineCount();
  184. GetSel( nStart, nEnd );
  185. if ( nStart == nEnd )
  186. {
  187. for ( i = 0; i < cnt; i++ )
  188. {
  189. nLen = LineLength( LineIndex( i ) );
  190. lpStr = cStr.GetBufferSetLength( nLen );
  191. GetLine( i, lpStr, nLen );
  192. TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
  193. (LPTSTR)lpStr, nLen, FALSE );
  194. }
  195. }
  196. else
  197. {
  198. int nStartLn, nEndLn;
  199. int nMaxText = GetWindowTextLength();
  200. int nChar = 0;
  201. nStartLn = LineFromChar( nStart );
  202. nEndLn = LineFromChar( nEnd );
  203. //Before Start
  204. for ( i = 0; i < nStartLn; i++ )
  205. {
  206. nLen = LineLength( LineIndex( i ) );
  207. lpStr = cStr.GetBufferSetLength( nLen );
  208. GetLine( i, lpStr, nLen );
  209. TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
  210. (LPTSTR)lpStr, nLen, FALSE );
  211. nChar = LineIndex( i + 1 );
  212. }
  213. nLen = LineLength( LineIndex( i ) );
  214. lpStr = cStr.GetBufferSetLength( nLen );
  215. GetLine( i, lpStr, nLen );
  216. TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
  217. (LPTSTR)lpStr, nStart - nChar, FALSE );
  218. //Selected Text
  219. COLORREF bkColor = pDC->SetBkColor( GetSysColor(COLOR_HIGHLIGHT) );
  220. COLORREF txtColor = pDC->SetTextColor( GetSysColor(COLOR_HIGHLIGHTTEXT) );
  221. int bkMode = pDC->SetBkMode( OPAQUE );
  222. CPoint ptStart( (DWORD)SendMessage( EM_POSFROMCHAR, nStart ) );
  223. if ( nStartLn == nEndLn )
  224. {
  225. TabTextOut( pDC, nStart, rc.right - h * i, ptStart.x,
  226. (LPTSTR)lpStr + (nStart - nChar), nEnd - nStart, TRUE );
  227. }
  228. else
  229. {
  230. TabTextOut( pDC, nStart, rc.right - h * i, ptStart.x,
  231. (LPTSTR)lpStr + (nStart - nChar), nLen + nChar - nStart, TRUE );
  232. nChar = LineIndex( i + 1 );
  233. for ( i++; i < nEndLn; i++ )
  234. {
  235. nLen = LineLength( LineIndex( i ) );
  236. lpStr = cStr.GetBufferSetLength( nLen );
  237. GetLine( i, lpStr, nLen );
  238. TabTextOut( pDC, nChar, rc.right - h * i, 0,
  239. (LPTSTR)lpStr, nLen, TRUE );
  240. nChar = LineIndex( i + 1 );
  241. }
  242. nLen = LineLength( LineIndex( i ) );
  243. lpStr = cStr.GetBufferSetLength( nLen );
  244. GetLine( i, lpStr, nLen );
  245. TabTextOut( pDC, nChar, rc.right - h * i, 0,
  246. (LPTSTR)lpStr, nEnd - nChar, TRUE );
  247. }
  248. pDC->SetBkColor( bkColor );
  249. pDC->SetTextColor( txtColor );
  250. pDC->SetBkMode( bkMode );
  251. //After End
  252. if ( nEnd < nMaxText )
  253. {
  254. CPoint ptEnd( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
  255. TabTextOut( pDC, nEnd, rc.right - h * i, ptEnd.x,
  256. (LPTSTR)lpStr + (nEnd - nChar), nChar + nLen - nEnd, FALSE );
  257. for ( i++; i < cnt; i++ )
  258. {
  259. nLen = LineLength( LineIndex( i ) );
  260. lpStr = cStr.GetBufferSetLength( nLen );
  261. GetLine( i, lpStr, nLen );
  262. TabTextOut( pDC, LineIndex( i ), rc.right - h * i, 0,
  263. (LPTSTR)lpStr, nLen, FALSE );
  264. }
  265. }
  266. }
  267. cStr.Empty();
  268. if (pOldFont) pDC->SelectObject( pOldFont );
  269. if (ppalOld) pDC->SelectPalette( ppalOld, FALSE );
  270. pDC->SetBkMode( OldBkMode );
  271. pDC->SetTextColor( OldTxtColor );
  272. if ( !pCurrentMessage->wParam )
  273. EndPaint( &ps );
  274. }
  275. }
  276. /******************************************************************************/
  277. BOOL CAttrEdit::OnEraseBkgnd( CDC* pDC )
  278. {
  279. if (m_pParentWnd == NULL)
  280. return CEdit::OnEraseBkgnd( pDC );
  281. ASSERT( m_pParentWnd->m_pImgWnd->m_pImg != NULL );
  282. ASSERT( m_pParentWnd->m_pImgWnd->m_pImg->hDC != NULL );
  283. CPalette* ppalOld = NULL;
  284. if (m_rectUpdate.IsRectEmpty())
  285. {
  286. if (! GetUpdateRect( &m_rectUpdate, FALSE ))
  287. GetClientRect( &m_rectUpdate );
  288. ValidateRect( &m_rectUpdate );
  289. }
  290. CRect destRect = m_rectUpdate;
  291. ClientToScreen( &m_rectUpdate );
  292. m_pParentWnd->m_pImgWnd->ScreenToClient( &m_rectUpdate );
  293. ppalOld = PBSelectPalette(pDC, theApp.m_pPalette, FALSE);
  294. if (m_bBackgroundTransparent)
  295. m_pParentWnd->m_pImgWnd->DrawImage( pDC, &m_rectUpdate, &destRect );
  296. else
  297. pDC->FillRect( &destRect, &m_pParentWnd->m_hbrBkColor );
  298. if (ppalOld)
  299. pDC->SelectPalette( ppalOld, FALSE );
  300. m_rectUpdate.SetRectEmpty();
  301. return TRUE;
  302. }
  303. /******************************************************************************/
  304. void CAttrEdit::OnRButtonDown(UINT nFlags, CPoint point)
  305. {
  306. const MSG *pCurrentMessage = GetCurrentMessage();
  307. m_pParentWnd->SendMessage( pCurrentMessage->message,
  308. pCurrentMessage->wParam,
  309. pCurrentMessage->lParam);
  310. }
  311. /******************************************************************************/
  312. void CAttrEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  313. {
  314. m_uiLastChar[0] = m_uiLastChar[1];
  315. #ifndef UNICODE
  316. //
  317. // For DBCS we have to peek for the trail byte if the current
  318. // byte is a lead byte
  319. //
  320. if (IsDBCSLeadByte((BYTE)nChar))
  321. {
  322. MSG msg;
  323. ZeroMemory (&msg, sizeof(msg));
  324. ::PeekMessage (&msg, m_hWnd, WM_CHAR, WM_CHAR, PM_NOREMOVE);
  325. m_uiLastChar[1] = (UINT)MAKEWORD((BYTE)msg.wParam, (BYTE)nChar);
  326. }
  327. else
  328. #endif // UNICODE
  329. m_uiLastChar[1] = nChar;
  330. if ( m_pParentWnd->m_bVertEdit )
  331. {
  332. SetCaretPosition( TRUE, NULL, -1 );
  333. UpdateInput();
  334. HideCaret();
  335. }
  336. CEdit::OnChar( nChar, nRepCnt, nFlags );
  337. if ( m_pParentWnd->m_bVertEdit )
  338. {
  339. SetCaretShape();
  340. UpdateInput();
  341. ShowCaret();
  342. }
  343. BOOL bRefresh = FALSE;
  344. switch (nChar)
  345. {
  346. case VK_BACK:
  347. case VK_DELETE:
  348. case VK_INSERT:
  349. bRefresh = TRUE;
  350. break;
  351. }
  352. if (bRefresh)
  353. m_pParentWnd->RefreshWindow(); /* enhance to do only the character involved */
  354. //
  355. // The edit control may have to resize
  356. //
  357. m_bResizeOnly = TRUE;
  358. m_pParentWnd->OnEnMaxText ();
  359. m_bResizeOnly = FALSE;
  360. }
  361. /******************************************************************************/
  362. LRESULT CAttrEdit::OnInputLangChange( WPARAM wParam, LPARAM lParam )
  363. {
  364. LRESULT lRet = Default();
  365. if ( m_pParentWnd->m_bVertEdit )
  366. {
  367. SetCaretPosition( TRUE, NULL, -1 );
  368. }
  369. return lRet;
  370. }
  371. /******************************************************************************/
  372. LRESULT CAttrEdit::OnImeChar( WPARAM wParam, LPARAM lParam )
  373. {
  374. if ( m_pParentWnd->m_bVertEdit )
  375. {
  376. SetCaretPosition( TRUE, NULL, -1 );
  377. UpdateInput();
  378. HideCaret();
  379. }
  380. return Default();
  381. }
  382. /******************************************************************************/
  383. LRESULT CAttrEdit::OnImeComposition( WPARAM wParam, LPARAM lParam )
  384. {
  385. // Use Faster Way undr Japanese Keyboard Layout (Japanese IME)
  386. // Japanese IME may generate lots of chars at one time.
  387. // This way is better than waiting WM_CHAR.
  388. DWORD dwKeyboardLayout = PRIMARYLANGID(LOWORD(GetKeyboardLayout(0)));
  389. if ( dwKeyboardLayout == LANG_JAPANESE)
  390. {
  391. if (lParam & GCS_RESULTSTR)
  392. {
  393. HIMC hIMC = ImmGetContext(m_hWnd);
  394. DWORD dwSize;
  395. if (hIMC &&
  396. (dwSize = ImmGetCompositionString(hIMC,GCS_RESULTSTR,NULL,0L)))
  397. {
  398. // ImmGetCompositionString returns the buffer size, IN BYTES.
  399. // even if Unicode version.
  400. LPTSTR lp = m_strResult.GetBufferSetLength(dwSize);
  401. ImmGetCompositionString(hIMC,GCS_RESULTSTR,lp,dwSize+sizeof(TCHAR));
  402. *(lp + dwSize/sizeof(TCHAR)) = TEXT('\0');
  403. ReplaceSel(lp);
  404. m_strResult.Empty();
  405. }
  406. ImmReleaseContext(m_hWnd, hIMC);
  407. lParam &= ~( GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR | GCS_RESULTCLAUSE);
  408. if (lParam)
  409. DefWindowProc(WM_IME_COMPOSITION,wParam,lParam);
  410. // We'are not sure, how IME hide its composiiton window.
  411. m_pParentWnd->RefreshWindow();
  412. return 0;
  413. }
  414. }
  415. else if ( dwKeyboardLayout == LANG_KOREAN)
  416. {
  417. if ( m_pParentWnd->m_bVertEdit ) {
  418. Default();
  419. SetCaretPosition( FALSE, NULL, -2);
  420. // We should update current composition string.
  421. UpdateInput();
  422. return 0;
  423. }
  424. else {
  425. // We should update current composition string.
  426. UpdateInput();
  427. return Default();
  428. }
  429. }
  430. return Default();
  431. }
  432. /******************************************************************************/
  433. void CAttrEdit::OnKillFocus(CWnd* pNewWnd)
  434. {
  435. HIMC hIMC = ImmGetContext(m_hWnd);
  436. ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0L);
  437. ImmReleaseContext(m_hWnd, hIMC);
  438. CEdit::OnKillFocus(pNewWnd);
  439. if ( m_pParentWnd->m_bVertEdit )
  440. {
  441. SetFmtRect();
  442. Repaint();
  443. }
  444. }
  445. /******************************************************************************/
  446. UINT CAttrEdit::OnNcHitTest( CPoint point )
  447. {
  448. const MSG *pCurrentMessage = GetCurrentMessage();
  449. UINT uiHitTestCode = (UINT)DefWindowProc( pCurrentMessage->message,
  450. pCurrentMessage->wParam,
  451. pCurrentMessage->lParam);
  452. if ( (uiHitTestCode == HTCLIENT) )
  453. {
  454. if ( (m_pParentWnd->m_bVertEdit) ) SetVCursorShape();
  455. else SetHCursorShape();
  456. }
  457. return uiHitTestCode;
  458. }
  459. /******************************************************************************/
  460. void CAttrEdit::OnSetFocus( CWnd* pOldWnd )
  461. {
  462. Default();
  463. if ( m_pParentWnd->m_bVertEdit )
  464. {
  465. SetCaretShape();
  466. SetCaretPosition( FALSE, NULL, -1 );
  467. Repaint();
  468. }
  469. }
  470. /******************************************************************************/
  471. void CAttrEdit::OnSize( UINT nType, int cx, int cy )
  472. {
  473. Default();
  474. m_rectFmt.left = m_rectFmt.top = 0;
  475. m_rectFmt.right = cx;
  476. m_rectFmt.bottom = cy;
  477. SetFmtRect();
  478. }
  479. /******************************************************************************/
  480. void CAttrEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
  481. {
  482. if ( !m_pParentWnd->m_bVertEdit )
  483. {
  484. Default();
  485. return;
  486. }
  487. HideCaret();
  488. UpdateSel();
  489. SetStartSelect();
  490. int tt = point.y;
  491. point.y = m_rectFmt.right - point.x;
  492. point.x = tt;
  493. const MSG *pCurrentMessage = GetCurrentMessage();
  494. DefWindowProc( pCurrentMessage->message,
  495. pCurrentMessage->wParam,
  496. MAKELPARAM( point.x, point.y ));
  497. SetCaretPosition( TRUE, &point, -1 );
  498. ShowCaret();
  499. UpdateSel();
  500. UpdateWindow();
  501. }
  502. /******************************************************************************/
  503. void CAttrEdit::OnLButtonDown(UINT nFlags, CPoint point)
  504. {
  505. if ( !m_pParentWnd->m_bVertEdit )
  506. {
  507. Default();
  508. return;
  509. }
  510. HideCaret();
  511. UpdateSel();
  512. SetStartSelect();
  513. int iPrevEnd;
  514. GetSel( m_iPrevStart, iPrevEnd );
  515. int tt = point.y;
  516. point.y = m_rectFmt.right - point.x;
  517. point.x = tt;
  518. //reset caret position to get correct caret position
  519. CPoint pt( -20000, -20000 );
  520. SetCaretPos( pt );
  521. const MSG *pCurrentMessage = GetCurrentMessage();
  522. DefWindowProc( pCurrentMessage->message,
  523. pCurrentMessage->wParam,
  524. MAKELPARAM( point.x, point.y ));
  525. SetCaretPosition( TRUE, &point, m_iPrevStart );
  526. if ( GetKeyState(VK_SHIFT) >= 0 ) //not extend selection
  527. GetSel( m_iPrevStart, iPrevEnd );
  528. ShowCaret();
  529. UpdateSel();
  530. UpdateWindow();
  531. m_bMouseDown = TRUE;
  532. }
  533. /******************************************************************************/
  534. void CAttrEdit::OnLButtonUp(UINT nFlags, CPoint point)
  535. {
  536. if ( !m_pParentWnd->m_bVertEdit )
  537. {
  538. Default();
  539. return;
  540. }
  541. m_bMouseDown = FALSE;
  542. HideCaret();
  543. UpdateSel();
  544. SetStartSelect();
  545. int tt = point.y;
  546. point.y = m_rectFmt.right - point.x;
  547. point.x = tt;
  548. const MSG *pCurrentMessage = GetCurrentMessage();
  549. DefWindowProc( pCurrentMessage->message,
  550. pCurrentMessage->wParam,
  551. MAKELPARAM( point.x, point.y ));
  552. SetCaretPosition( TRUE, &point, m_iPrevStart );
  553. ShowCaret();
  554. UpdateSel();
  555. UpdateWindow();
  556. }
  557. /******************************************************************************/
  558. void CAttrEdit::OnMouseMove(UINT nFlags, CPoint point)
  559. {
  560. if ( !m_pParentWnd->m_bVertEdit )
  561. {
  562. Default();
  563. return;
  564. }
  565. if ( m_bMouseDown )
  566. {
  567. HideCaret();
  568. UpdateSel();
  569. SetStartSelect();
  570. int tt = point.y;
  571. point.y = m_rectFmt.right - point.x;
  572. point.x = tt;
  573. const MSG *pCurrentMessage = GetCurrentMessage();
  574. DefWindowProc( pCurrentMessage->message,
  575. pCurrentMessage->wParam,
  576. MAKELPARAM( point.x, point.y ));
  577. SetCaretPosition( TRUE, &point, m_iPrevStart );
  578. ShowCaret();
  579. UpdateSel();
  580. UpdateWindow();
  581. }
  582. else CEdit::OnMouseMove( nFlags, point );
  583. }
  584. /******************************************************************************/
  585. void CAttrEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  586. {
  587. if ( !m_pParentWnd->m_bVertEdit )
  588. {
  589. CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  590. return;
  591. }
  592. BOOL bPrev = FALSE;
  593. HideCaret();
  594. switch (nChar)
  595. {
  596. case VK_LEFT:
  597. case VK_RIGHT:
  598. case VK_UP:
  599. case VK_DOWN:
  600. case VK_HOME:
  601. case VK_END:
  602. {
  603. UpdateSel();
  604. CPoint ptCaretPos = GetCaretPos();
  605. if ( ptCaretPos.y != 0 ) bPrev = TRUE;
  606. int iPrevEnd;
  607. GetSel( m_iPrevStart, iPrevEnd );
  608. SetStartSelect(); //for VK_RETURN
  609. //reset caret position to get correct caret position
  610. CPoint pt( -20000, -20000 );
  611. SetCaretPos( pt );
  612. break;
  613. }
  614. }
  615. switch (nChar)
  616. {
  617. case VK_LEFT: nChar = VK_DOWN; break;
  618. case VK_RIGHT: nChar = VK_UP; break;
  619. case VK_UP: nChar = VK_LEFT; bPrev = FALSE; break;
  620. case VK_DOWN: nChar = VK_RIGHT; bPrev = FALSE; break;
  621. case VK_HOME: bPrev = FALSE; break;
  622. case VK_END: bPrev = TRUE; break;
  623. }
  624. const MSG *pCurrentMessage = GetCurrentMessage();
  625. DefWindowProc( pCurrentMessage->message,
  626. nChar,
  627. pCurrentMessage->lParam);
  628. switch (nChar)
  629. {
  630. case VK_LEFT:
  631. case VK_RIGHT:
  632. case VK_UP:
  633. case VK_DOWN:
  634. case VK_HOME:
  635. case VK_END:
  636. {
  637. SetCaretPosition( bPrev, NULL, m_iPrevStart );
  638. UpdateSel();
  639. UpdateWindow();
  640. break;
  641. }
  642. case VK_HANJA:
  643. // For Korea hanja conversion.
  644. SetCaretPosition( FALSE, NULL, -2);
  645. break;
  646. }
  647. ShowCaret();
  648. }
  649. /******************************************************************************/
  650. void CAttrEdit::SetStartSelect( void )
  651. {
  652. int nStart, nEnd;
  653. CPoint ptCaretPos = GetCaretPos();
  654. if ( ptCaretPos.y == 0 )
  655. {
  656. GetSel( nStart, nEnd );
  657. if ( nStart == nEnd ) SetSel( nStart, nEnd );
  658. }
  659. }
  660. /******************************************************************************/
  661. void CAttrEdit::SetCaretPosition( BOOL bPrev, CPoint* ptMouse, int iPrevStart )
  662. {
  663. HideCaret();
  664. // Get Caret Position
  665. CPoint ptCaretPos;
  666. // Get End Selected Position to be Caret Position
  667. int nStart, nEnd;
  668. GetSel( nStart, nEnd );
  669. if ( iPrevStart != -1 && nStart < iPrevStart )
  670. nEnd = nStart;
  671. #ifdef UNICODE
  672. // When NT bug 116057 is fixed, remove this code
  673. // For composition string support
  674. if ( m_pParentWnd->m_bVertEdit && iPrevStart == -2)
  675. nEnd -= 1 * sizeof(WCHAR)/sizeof(TCHAR);
  676. #endif //UNICODE
  677. CPoint ptPos( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
  678. if ( nEnd >= GetWindowTextLength() ||
  679. ( ptPos.x == 0 && (bPrev) && (ptMouse == NULL ||
  680. ptMouse->y < ptPos.y ) ) )
  681. {
  682. CString cStr;
  683. CDC* pDC = GetDC();
  684. CFont* pFont = GetFont();
  685. CFont* pOldFont;
  686. int nLine = ( (ptPos.x < 0) ? GetLineCount() : LineFromChar( nEnd ) ) - 1;
  687. int nChar = LineIndex( nLine );
  688. int nLen = LineLength( nChar );
  689. LPTSTR lpStr = cStr.GetBufferSetLength( nLen );
  690. TEXTMETRIC tm;
  691. pOldFont = pDC->SelectObject( pFont );
  692. GetLine( nLine, lpStr, nLen );
  693. pDC->GetTextMetrics( &tm );
  694. if ( !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH) )
  695. m_iTabPos = tm.tmAveCharWidth;
  696. else
  697. {
  698. CPoint len( pDC->GetTextExtent( TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), 52) );
  699. m_iTabPos = (len.x / 26 + 1) / 2;
  700. if ( m_iTabPos <= 0 ) m_iTabPos = tm.tmAveCharWidth;
  701. }
  702. m_iTabPos *= 8;
  703. if ( m_iTabPos <= 0 ) m_iTabPos = 1;
  704. CPoint tt( 0, 0 );
  705. if ( nLen > 0 )
  706. {
  707. if ( *(lpStr + nLen - 1) == TEXT('\t') )
  708. {
  709. tt = (CPoint) (DWORD)SendMessage( EM_POSFROMCHAR, nChar + nLen - 1 );
  710. tt.x = min( (tt.x / m_iTabPos + 1) * m_iTabPos, m_rectFmt.bottom - 1 );
  711. }
  712. else
  713. {
  714. LPTSTR lpChar = lpStr + nLen - 1;
  715. int nCnt;
  716. for ( nCnt = 0; nCnt < nLen && *lpChar != TEXT('\t'); nCnt++, lpChar-- );
  717. lpChar++;
  718. tt = (CPoint) (DWORD)SendMessage( EM_POSFROMCHAR, nChar + nLen - nCnt );
  719. tt.Offset( pDC->GetTextExtent( lpChar, nCnt ) );
  720. }
  721. }
  722. cStr.Empty();
  723. ptCaretPos.x = tt.x;
  724. ptCaretPos.y = m_pParentWnd->m_iLineHeight * nLine;
  725. pDC->SelectObject( pOldFont );
  726. ReleaseDC( pDC );
  727. }
  728. else
  729. {
  730. ptCaretPos.x = ptPos.x;
  731. ptCaretPos.y = ptPos.y;
  732. }
  733. // H -> V
  734. CPoint pt( m_rectFmt.right - ptCaretPos.y - m_pParentWnd->m_iLineHeight,
  735. ptCaretPos.x );
  736. //
  737. // for some reason, typing spaces pushes the caret beyond the bottom of the rect.
  738. // Cover that case by forcing the caret to be at the bottom of the rect.
  739. //
  740. if (pt.y > m_rectFmt.bottom)
  741. {
  742. pt.y = m_rectFmt.bottom-2;
  743. }
  744. SetCaretPos( pt );
  745. //Set IME composition window position
  746. HIMC himc;
  747. if (himc=ImmGetContext(m_hWnd))
  748. {
  749. COMPOSITIONFORM cf;
  750. RECT rcClient;
  751. cf.dwStyle = CFS_RECT;
  752. cf.ptCurrentPos.x = m_rectFmt.right - ptCaretPos.y - 1;
  753. cf.ptCurrentPos.y = pt.y;
  754. GetClientRect( &rcClient );
  755. cf.rcArea = rcClient;
  756. ImmSetCompositionWindow(himc,&cf);
  757. ImmReleaseContext(m_hWnd, himc);
  758. }
  759. #ifndef WINNT // don't call ImmSetCompositionWindow at this time.
  760. SetFmtRect(); //it should be called after set IME position
  761. #endif
  762. ShowCaret();
  763. }
  764. /******************************************************************************/
  765. void CAttrEdit::SetCaretShape( void )
  766. {
  767. HideCaret();
  768. ::DestroyCaret();
  769. ::CreateCaret( m_hWnd, NULL, m_pParentWnd->m_iLineHeight, 2 );
  770. ShowCaret();
  771. }
  772. /******************************************************************************/
  773. void CAttrEdit::SetFmtRect()
  774. {
  775. RECT rc;
  776. rc.left = rc.top = 0;
  777. if ( m_pParentWnd->m_bVertEdit )
  778. {
  779. rc.right = m_rectFmt.bottom;
  780. rc.bottom = m_rectFmt.right;
  781. }
  782. else
  783. {
  784. rc.right = m_rectFmt.right;
  785. rc.bottom = m_rectFmt.bottom;
  786. }
  787. HIMC himc;
  788. COMPOSITIONFORM cf;
  789. BOOL bResult = FALSE;
  790. if (himc=ImmGetContext(m_hWnd)) {
  791. bResult = ImmGetCompositionWindow(himc,&cf);
  792. }
  793. SetRectNP( &rc );
  794. if (himc && bResult) {
  795. ImmSetCompositionWindow(himc,&cf);
  796. }
  797. }
  798. /******************************************************************************/
  799. void CAttrEdit::Repaint(void)
  800. {
  801. InvalidateRect( NULL, TRUE );
  802. UpdateWindow();
  803. }
  804. /******************************************************************************/
  805. void CAttrEdit::UpdateSel(void)
  806. {
  807. int nStart, nEnd;
  808. GetSel( nStart, nEnd );
  809. if (nStart != nEnd )
  810. {
  811. RECT rc = m_rectFmt;
  812. if ( nStart > nEnd )
  813. {
  814. int tt = nStart;
  815. nStart = nEnd;
  816. nEnd = tt;
  817. }
  818. CPoint ptStart( (DWORD)SendMessage( EM_POSFROMCHAR, nStart ) );
  819. rc.right -= ptStart.y;
  820. if ( nEnd < GetWindowTextLength() )
  821. {
  822. CPoint ptEnd( (DWORD)SendMessage( EM_POSFROMCHAR, nEnd ) );
  823. rc.left = m_rectFmt.right - ptEnd.y - m_pParentWnd->m_iLineHeight;
  824. }
  825. InvalidateRect( &rc );
  826. }
  827. }
  828. /******************************************************************************/
  829. void CAttrEdit::UpdateInput(void)
  830. {
  831. RECT rc = m_rectFmt;
  832. CPoint pt( GetCaretPos() );
  833. rc.right = pt.x + m_pParentWnd->m_iLineHeight;
  834. InvalidateRect( &rc );
  835. }
  836. /******************************************************************************/
  837. LRESULT CAttrEdit::OnSysTimer( WPARAM wParam, LPARAM lParam )
  838. {
  839. if ( !m_pParentWnd->m_bVertEdit )
  840. {
  841. Default();
  842. return 1L;
  843. }
  844. return 1L;
  845. }
  846. /******************************************************************************/
  847. void CAttrEdit::SetHCursorShape(void)
  848. {
  849. if ( GetSafeHwnd() )
  850. {
  851. ShowCursor( FALSE );
  852. SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_hHCursor );
  853. ShowCursor( TRUE );
  854. }
  855. }
  856. /******************************************************************************/
  857. void CAttrEdit::SetVCursorShape(void)
  858. {
  859. if ( GetSafeHwnd() )
  860. {
  861. ShowCursor( FALSE );
  862. SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_hVCursor );
  863. ShowCursor( TRUE );
  864. }
  865. }
  866. /******************************************************************************/
  867. void CAttrEdit::TabTextOut( CDC* pDC, int nCharIndex, int x, int y, LPCTSTR lpStr, int nCount, BOOL bSelect )
  868. {
  869. int i, nCnt;
  870. LPCTSTR lpChar = lpStr;
  871. CPoint pt;
  872. CPoint ptEnd;
  873. RECT rc;
  874. BOOL bReverse;
  875. CSize s1 = pDC->GetTextExtent( TEXT("a"), 1 );
  876. CSize s2 = pDC->GetTextExtent( TEXT("aa"), 2 );
  877. bReverse = (s1.cx == s2.cx);
  878. rc.left = x - m_pParentWnd->m_iLineHeight;
  879. rc.right = x;
  880. for ( i = 0, nCnt = 0; i < nCount; i++, nCnt++, lpStr++ )
  881. {
  882. if ( *lpStr == TEXT('\t') )
  883. {
  884. pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
  885. if ( nCnt > 0 )
  886. {
  887. pDC->TextOut( x, pt.x, lpChar, nCnt );
  888. }
  889. nCharIndex += nCnt + 1;
  890. nCnt = -1;
  891. lpChar = lpStr + 1;
  892. if ( bSelect )
  893. {
  894. pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex - 1 );
  895. rc.top = pt.x;
  896. if ( i < (nCount - 1) )
  897. {
  898. pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
  899. rc.bottom = pt.x;
  900. }
  901. else
  902. {
  903. rc.bottom = min( (pt.x / m_iTabPos + 1) * m_iTabPos,
  904. m_rectFmt.bottom - 1 );
  905. }
  906. pDC->ExtTextOut( x, rc.top, 0 /*ETO_OPAQUE*/, &rc, NULL, 0, NULL );
  907. }
  908. }
  909. }
  910. if ( nCnt > 0 )
  911. {
  912. pt = (CPoint)(DWORD)SendMessage( EM_POSFROMCHAR, nCharIndex );
  913. pDC->TextOut( x, pt.x, lpChar, nCnt );
  914. }
  915. }
  916. /******************************************************************************/
  917. /******************************************************************************/
  918. // CTedit
  919. BEGIN_MESSAGE_MAP( CTedit, CWnd )
  920. //{{AFX_MSG_MAP(CTedit)
  921. ON_WM_SIZE()
  922. ON_WM_MOVE()
  923. ON_WM_CTLCOLOR()
  924. ON_WM_NCCALCSIZE()
  925. ON_WM_NCPAINT()
  926. ON_WM_NCHITTEST()
  927. ON_WM_RBUTTONDOWN()
  928. ON_COMMAND(ID_TEXT_PLAIN, OnTextPlain)
  929. ON_COMMAND(ID_TEXT_BOLD, OnTextBold)
  930. ON_COMMAND(ID_TEXT_ITALIC, OnTextItalic)
  931. ON_COMMAND(ID_TEXT_UNDERLINE, OnTextUnderline)
  932. ON_COMMAND(ID_TEXT_SELECTFONT, OnTextSelectfont)
  933. ON_COMMAND(ID_TEXT_SELECTPOINTSIZE, OnTextSelectpointsize)
  934. ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  935. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  936. ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  937. ON_COMMAND(ID_EDIT_CLEAR, OnTextDelete)
  938. ON_COMMAND(ID_EDIT_SELECT_ALL, OnTextSelectall)
  939. ON_COMMAND(ID_EDIT_UNDO, OnTextUndo)
  940. ON_COMMAND(ID_TEXT_PLACE, OnTextPlace)
  941. ON_COMMAND(ID_VIEW_TEXT_TOOLBAR, OnTextTexttool)
  942. ON_WM_LBUTTONDOWN()
  943. //}}AFX_MSG_MAP
  944. ON_WM_GETMINMAXINFO()
  945. ON_MESSAGE(WM_MOVING, OnMoving)
  946. ON_EN_CHANGE(IDC_ATTREDIT, OnAttrEditEnChange)
  947. ON_EN_MAXTEXT(IDC_ATTREDIT, OnEnMaxText)
  948. ON_EN_UPDATE(IDC_ATTREDIT, OnEnUpdate)
  949. ON_WM_DESTROY()
  950. END_MESSAGE_MAP()
  951. /******************************************************************************/
  952. // CTedit construction/destruction
  953. CTedit::CTedit()
  954. {
  955. m_eLastAction = eNO_CHANGE;
  956. m_bCleanupBKBrush = FALSE;
  957. m_bStarting = TRUE;
  958. m_bPasting = FALSE;
  959. m_bExpand = FALSE;
  960. m_bChanged = FALSE;
  961. m_uiHitArea = HTNOWHERE;
  962. m_crFGColor = ::GetSysColor( COLOR_WINDOWTEXT );
  963. m_crBKColor = ::GetSysColor( COLOR_WINDOW );
  964. // Need to be initialized during first GETMINMAXINFO call
  965. m_SizeMinimum.cx = 1;
  966. m_SizeMinimum.cy = 1;
  967. m_bBackgroundTransparent = TRUE;
  968. m_cRectOldPos.SetRectEmpty();
  969. m_cRectWindow.SetRectEmpty();
  970. m_bVertEdit = FALSE;
  971. m_bAssocIMC = FALSE;
  972. m_hIMCEdit = NULL;
  973. m_hIMCFace = NULL;
  974. m_hIMCSize = NULL;
  975. m_hWndFace = NULL;
  976. m_hWndSize = NULL;
  977. }
  978. /******************************************************************************/
  979. CTedit::~CTedit()
  980. {
  981. if (m_bCleanupBKBrush)
  982. {
  983. m_hbrBkColor.DeleteObject(); //Set in SetTransparentMode
  984. m_bCleanupBKBrush = FALSE;
  985. }
  986. }
  987. /******************************************************************************/
  988. BOOL CTedit::Create( CImgWnd* pParentWnd,
  989. COLORREF crefForeground,
  990. COLORREF crefBackground,
  991. CRect& rectPos,
  992. BOOL bBackTransparent )
  993. {
  994. if (! m_bStarting)
  995. return FALSE;
  996. // Initialize member variables
  997. m_pImgWnd = pParentWnd;
  998. m_crBKColor = crefBackground;
  999. m_crFGColor = crefForeground;
  1000. m_bBackgroundTransparent = bBackTransparent; // Do this or else
  1001. SetTransparentMode( bBackTransparent );
  1002. CRect rectText = rectPos;
  1003. rectText.InflateRect( CTracker::HANDLE_SIZE, CTracker::HANDLE_SIZE );
  1004. rectText.right += CTracker::HANDLE_SIZE * 2;
  1005. rectText.bottom += CTracker::HANDLE_SIZE * 2;
  1006. if (! CWnd::Create( NULL, TEXT(""), WS_CHILD | WS_THICKFRAME, rectText, pParentWnd, IDC_ATTREDIT + 1 ))
  1007. return FALSE;
  1008. CRect rectEditArea;
  1009. GetClientRect( &rectEditArea );
  1010. m_cEdit.m_pParentWnd = this;
  1011. if (! m_cEdit.Create( WS_CHILD | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL | ES_WANTRETURN, rectEditArea, this, IDC_ATTREDIT ))
  1012. {
  1013. theApp.SetMemoryEmergency();
  1014. DestroyWindow();
  1015. return FALSE;
  1016. }
  1017. ClientToScreen( &rectEditArea ); // use this to let the font tool where not to cover
  1018. m_pcTfont = new CTfont( this ); // this is the class Text Font Pallette
  1019. // it is derived from cframewnd and will
  1020. ASSERT( m_pcTfont != NULL ); // auto destruct when this window
  1021. // 'CTedit' is Destroyed
  1022. if (m_pcTfont == NULL || ! m_pcTfont->Create( rectEditArea ))
  1023. {
  1024. theApp.SetMemoryEmergency();
  1025. DestroyWindow();
  1026. m_pcTfont = NULL;
  1027. return FALSE;
  1028. }
  1029. // reset the width and height to the minimum if nessesary
  1030. CSize size = GetDefaultMinSize(); // must call after ctfont object created (it sets our font).
  1031. m_cRectWindow = CRect( rectText.TopLeft(), size );
  1032. SetWindowPos( &wndTop, 0, 0, size.cx, size.cy, SWP_NOACTIVATE | SWP_NOMOVE );
  1033. ShowWindow( SW_SHOWNOACTIVATE );
  1034. GetClientRect( &rectEditArea );
  1035. m_cEdit.SetWindowPos( &wndTopMost, 0, 0, rectEditArea.Width(),
  1036. rectEditArea.Height(), 0 );
  1037. m_cEdit.ShowWindow( SW_SHOWNOACTIVATE );
  1038. m_bStarting = FALSE;
  1039. //get all control windows on ToolBar for controling IME
  1040. CWnd* pcWndFace = m_pcTfont->GetFontFaceControl();
  1041. if ( (pcWndFace != NULL) && (pcWndFace->GetSafeHwnd() != NULL) )
  1042. m_hWndFace = pcWndFace->m_hWnd; //static
  1043. CWnd* pcWndSize = m_pcTfont->GetFontSizeControl();
  1044. if ( (pcWndSize != NULL) && (
  1045. pcWndSize->GetSafeHwnd() != NULL) )
  1046. {
  1047. CWnd* pcWndEditSize = pcWndSize->GetWindow( GW_CHILD ); //edit
  1048. if ( (pcWndEditSize != NULL) && (
  1049. pcWndEditSize->GetSafeHwnd() != NULL) )
  1050. m_hWndSize = pcWndEditSize->m_hWnd; //edit
  1051. }
  1052. //save original Edit control
  1053. if ( m_cEdit.GetSafeHwnd() )
  1054. m_cEdit.m_hOldCursor = (HCURSOR) SetClassLongPtr( m_cEdit.m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_cEdit.m_hHCursor );
  1055. //only DBCS font would enable IME
  1056. CFont* pcFont = m_cEdit.GetFont();
  1057. LOGFONT lf;
  1058. pcFont->GetObject( sizeof( LOGFONT ), &lf );
  1059. if ( !IS_DBCS_CHARSET( lf.lfCharSet ) )
  1060. {
  1061. m_bAssocIMC = TRUE;
  1062. if (!IsCUAS())
  1063. m_hIMCEdit = DisableIme( m_cEdit.m_hWnd );
  1064. m_hIMCFace = DisableIme( m_hWndFace );
  1065. m_hIMCSize = DisableIme( m_hWndSize );
  1066. }
  1067. //initial Caret Position
  1068. if ( m_bVertEdit )
  1069. {
  1070. CPoint pt( 0, 0 );
  1071. m_cEdit.SetCaretPos( pt );
  1072. m_cEdit.SetCaretPosition( FALSE, NULL, -1 );
  1073. }
  1074. m_cEdit.SetFocus();
  1075. return TRUE;
  1076. }
  1077. /******************************************************************************/
  1078. BOOL CTedit::PreCreateWindow( CREATESTRUCT& cs )
  1079. {
  1080. cs.dwExStyle |= WS_EX_TRANSPARENT;
  1081. return CWnd::PreCreateWindow( cs );
  1082. }
  1083. /******************************************************************************/
  1084. void CTedit::RefreshWindow( CRect* prect, BOOL bErase )
  1085. {
  1086. if (! m_bStarting)
  1087. {
  1088. UINT flags = RDW_INVALIDATE;
  1089. if (bErase)
  1090. flags |= RDW_ERASE;
  1091. if ( m_bVertEdit )
  1092. {
  1093. m_cEdit.SetFmtRect();
  1094. m_cEdit.Repaint();
  1095. }
  1096. else
  1097. m_cEdit.RedrawWindow( prect, NULL, flags );
  1098. }
  1099. }
  1100. /******************************************************************************/
  1101. void CTedit::SetTextColor( COLORREF crColor )
  1102. {
  1103. m_crFGColor = crColor;
  1104. RefreshWindow( NULL, FALSE );
  1105. }
  1106. /******************************************************************************/
  1107. void CTedit::SetBackColor( COLORREF crColor )
  1108. {
  1109. m_crBKColor = crColor;
  1110. if (! m_bBackgroundTransparent)
  1111. {
  1112. m_bBackgroundTransparent = TRUE; // just fake it out
  1113. SetTransparentMode( FALSE ); // to setup the background brush when in opaque mode
  1114. }
  1115. }
  1116. /******************************************************************************/
  1117. void CTedit::SetTransparentMode( BOOL bTransparent )
  1118. {
  1119. BOOL bRefresh = ((! m_bBackgroundTransparent && bTransparent)
  1120. || ( m_bBackgroundTransparent && ! bTransparent));
  1121. m_cEdit.m_bBackgroundTransparent = bTransparent;
  1122. m_bBackgroundTransparent = bTransparent;
  1123. if (m_bCleanupBKBrush)
  1124. {
  1125. m_hbrBkColor.DeleteObject();
  1126. m_bCleanupBKBrush = FALSE;
  1127. }
  1128. if (! m_bBackgroundTransparent)
  1129. {
  1130. m_hbrBkColor.CreateSolidBrush( m_crBKColor );
  1131. m_bCleanupBKBrush = TRUE;
  1132. }
  1133. if (bRefresh)
  1134. {
  1135. InvalidateRect( NULL );
  1136. UpdateWindow();
  1137. RefreshWindow();
  1138. }
  1139. }
  1140. /******************************************************************************/
  1141. void CTedit::Undo()
  1142. {
  1143. if ( m_bVertEdit )
  1144. m_cEdit.HideCaret();
  1145. switch(m_eLastAction)
  1146. {
  1147. case eEBOX_CHANGE:
  1148. m_cEdit.Undo();
  1149. break;
  1150. case eFONT_CHANGE:
  1151. ASSERT(m_pcTfont != NULL);
  1152. if (m_pcTfont != NULL)
  1153. {
  1154. m_pcTfont->Undo();
  1155. }
  1156. break;
  1157. case eSIZE_MOVE_CHANGE:
  1158. if (! m_cRectOldPos.IsRectEmpty())
  1159. MoveWindow( m_cRectOldPos );
  1160. break;
  1161. default:
  1162. break;
  1163. }
  1164. if ( m_bVertEdit )
  1165. {
  1166. m_cEdit.SetCaretShape();
  1167. m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
  1168. m_cEdit.ShowCaret();
  1169. }
  1170. }
  1171. /******************************************************************************/
  1172. void CTedit::ShowFontPalette(int nCmdShow)
  1173. {
  1174. ASSERT(m_pcTfont != NULL);
  1175. if (m_pcTfont != NULL)
  1176. {
  1177. theApp.m_bShowTextToolbar = ! theApp.m_bShowTextToolbar;
  1178. m_pcTfont->ShowWindow(nCmdShow);
  1179. }
  1180. }
  1181. /******************************************************************************/
  1182. BOOL CTedit::IsFontPaletteVisible(void)
  1183. {
  1184. BOOL bWindowVisible = FALSE;
  1185. ASSERT(m_pcTfont != NULL);
  1186. if (m_pcTfont != NULL)
  1187. {
  1188. bWindowVisible = m_pcTfont->IsWindowVisible();
  1189. }
  1190. return bWindowVisible;
  1191. }
  1192. /******************************************************************************/
  1193. void CTedit::ShowFontToolbar(BOOL bActivate)
  1194. {
  1195. // FEATURE: Remove ShowFontPalette after RTM
  1196. if (m_pcTfont == NULL)
  1197. {
  1198. return;
  1199. }
  1200. m_pcTfont->ShowWindow(bActivate ? SW_SHOW : SW_SHOWNOACTIVATE);
  1201. }
  1202. /******************************************************************************/
  1203. void CTedit::HideFontToolbar(void)
  1204. {
  1205. if (m_pcTfont == NULL)
  1206. {
  1207. return;
  1208. }
  1209. m_pcTfont->ShowWindow(SW_HIDE);
  1210. }
  1211. /******************************************************************************/
  1212. // Returns a Ptr to a discardable bitmap (CBitmap object) or NULL on error
  1213. void CTedit::GetBitmap( CDC* pDC, CRect* prectImg )
  1214. {
  1215. if (! m_bBackgroundTransparent)
  1216. pDC->FillRect( prectImg, &m_hbrBkColor );
  1217. m_cEdit.SetSel( -1, 0 );
  1218. if ( m_bVertEdit )
  1219. {
  1220. m_cEdit.SetFmtRect();
  1221. m_cEdit.UpdateWindow();
  1222. }
  1223. CPoint ptViewOrgOld = pDC->SetViewportOrg( prectImg->left, prectImg->top );
  1224. m_cEdit.SendMessage( WM_PAINT, (WPARAM)(pDC->m_hDC) );
  1225. pDC->SetViewportOrg( ptViewOrgOld );
  1226. pDC->SelectClipRgn( NULL );
  1227. }
  1228. /******************************************************************************/
  1229. void CTedit::PostNcDestroy()
  1230. {
  1231. // If m_pcTfont is destroyed by shutdown before CTedit,
  1232. // m_pcTfont will be null
  1233. if (m_pcTfont != NULL)
  1234. {
  1235. m_pcTfont->DestroyWindow();
  1236. m_pcTfont = NULL;
  1237. }
  1238. delete this;
  1239. }
  1240. /******************************************************************************/
  1241. CSize CTedit::GetDefaultMinSize( void )
  1242. {
  1243. CRect cRectClient;
  1244. int iWidth;
  1245. int iHeight;
  1246. // edit control takes up the whole client area of the ctedit
  1247. // object/window, so width of client of ctedit is same as widht of edit
  1248. // control window. Edit control window has no border.
  1249. GetClientRect( &cRectClient );
  1250. iWidth = cRectClient.Width();
  1251. iHeight = cRectClient.Height();
  1252. CDC* pDC = m_cEdit.GetDC();
  1253. CFont* pcFont = m_cEdit.GetFont();
  1254. if (pDC != NULL
  1255. && pcFont != NULL)
  1256. {
  1257. TEXTMETRIC tm;
  1258. CFont* pcFontOld = NULL;
  1259. pcFontOld = pDC->SelectObject( pcFont );
  1260. pDC->GetTextMetrics( &tm );
  1261. BOOL bUpdateSize = FALSE;
  1262. m_SizeMinimum.cx = tm.tmAveCharWidth * MIN_CHARS_DISPLAY_SIZE + CTracker::HANDLE_SIZE * 2;
  1263. m_SizeMinimum.cy = tm.tmHeight + CTracker::HANDLE_SIZE * 2;
  1264. if (m_SizeMinimum.cx > iWidth) // must be able to at least display MIN_CHARS_DISPLAY_SIZE
  1265. {
  1266. iWidth = m_SizeMinimum.cx;
  1267. bUpdateSize = TRUE;
  1268. }
  1269. if (m_SizeMinimum.cy > iHeight) // must be able to at least 1 char high
  1270. {
  1271. iHeight = m_SizeMinimum.cy;
  1272. bUpdateSize = TRUE;
  1273. }
  1274. if (bUpdateSize)
  1275. m_eLastAction = eNO_CHANGE; // don't want user to be able to undo this
  1276. if (pcFontOld != NULL)
  1277. {
  1278. pDC->SelectObject( pcFontOld );
  1279. }
  1280. }
  1281. if (pDC != NULL)
  1282. m_cEdit.ReleaseDC( pDC );
  1283. cRectClient.SetRect( 0, 0, iWidth - 1, iHeight - 1 );
  1284. ClientToScreen( &cRectClient );
  1285. m_pImgWnd->ScreenToClient( &cRectClient );
  1286. CRect rectDrawing = m_pImgWnd->GetDrawingRect();
  1287. if (cRectClient.right > rectDrawing.right)
  1288. iWidth -= (cRectClient.right - rectDrawing.right) - CTracker::HANDLE_SIZE;
  1289. if (cRectClient.bottom > rectDrawing.bottom)
  1290. iHeight -= (cRectClient.bottom - rectDrawing.bottom) - CTracker::HANDLE_SIZE;
  1291. m_SizeMinimum.cx = iWidth;
  1292. m_SizeMinimum.cy = iHeight;
  1293. return CSize( iWidth, iHeight );
  1294. }
  1295. /******************************************************************************/
  1296. void CTedit::OnAttrEditEnChange(void)
  1297. {
  1298. m_eLastAction = eEBOX_CHANGE;
  1299. if (m_bRefresh)
  1300. m_cEdit.UpdateWindow();
  1301. if ( m_bVertEdit )
  1302. {
  1303. m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
  1304. m_cEdit.UpdateWindow();
  1305. }
  1306. }
  1307. /******************************************************************************/
  1308. void CTedit::OnEnUpdate()
  1309. {
  1310. CPoint ptCaretPos = m_cEdit.GetCaretPos();
  1311. CPoint ptLastChar( (DWORD)m_cEdit.SendMessage( EM_POSFROMCHAR,
  1312. (WPARAM)(m_cEdit.GetWindowTextLength() - 1) ) );
  1313. CRect rect;
  1314. m_cEdit.GetClientRect( &rect );
  1315. rect.top = ptCaretPos.y;
  1316. rect.bottom = ptLastChar.y + m_iLineHeight;
  1317. m_cEdit.InvalidateRect( &rect, TRUE );
  1318. m_bChanged = TRUE;
  1319. }
  1320. /******************************************************************************/
  1321. void CTedit::OnEnMaxText()
  1322. {
  1323. if (m_bPasting)
  1324. {
  1325. if (!m_cEdit.m_bResizeOnly)
  1326. {
  1327. AfxMessageBox( IDS_UNABLE_TO_PASTE, MB_OK | MB_ICONEXCLAMATION );
  1328. }
  1329. return;
  1330. }
  1331. CFont* pfntEdit = m_cEdit.GetFont();
  1332. if (pfntEdit == NULL)
  1333. return;
  1334. CClientDC dc( &m_cEdit );
  1335. CFont* pfntOld = dc.SelectObject( pfntEdit );
  1336. TEXTMETRIC tm;
  1337. dc.GetTextMetrics( &tm );
  1338. CRect rectText;
  1339. CRect rectImg;
  1340. GetWindowRect( &rectText );
  1341. m_pImgWnd->ScreenToClient( &rectText );
  1342. POINT pt;
  1343. ::GetCaretPos (&pt);
  1344. //
  1345. // If the next character would extend past the end of the
  1346. // edit window, grow the window
  1347. if (!m_bVertEdit && m_cEdit.m_bResizeOnly &&
  1348. ((rectText.left + pt.x + 2*tm.tmMaxCharWidth < rectText.right)
  1349. || (rectText.top + pt.y + 2*tm.tmHeight < rectText.bottom)) )
  1350. {
  1351. return;
  1352. }
  1353. else if (m_bVertEdit && m_cEdit.m_bResizeOnly &&
  1354. ((pt.x - tm.tmMaxCharWidth > 0)
  1355. || (rectText.top + pt.y + 2*tm.tmHeight < rectText.bottom)) )
  1356. {
  1357. return;
  1358. }
  1359. m_pImgWnd->GetClientRect ( &rectImg );
  1360. if (m_cEdit.m_strResult.IsEmpty())
  1361. {
  1362. if (m_bVertEdit)
  1363. rectText.left -= tm.tmHeight;
  1364. else
  1365. rectText.bottom += tm.tmHeight;
  1366. }
  1367. else
  1368. {
  1369. CRect rectTmp = rectText;
  1370. int nLen = m_cEdit.m_strResult.GetLength();
  1371. if (m_bVertEdit)
  1372. rectText.left -= dc.DrawText(m_cEdit.m_strResult.GetBuffer(nLen),
  1373. nLen,&rectTmp,
  1374. DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
  1375. else
  1376. rectText.bottom += dc.DrawText(m_cEdit.m_strResult.GetBuffer(nLen),
  1377. nLen,&rectTmp,
  1378. DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
  1379. }
  1380. CRect rectDrawing = m_pImgWnd->GetDrawingRect();
  1381. if ( ((m_bVertEdit) && rectText.left>=rectDrawing.left && rectText.left >= rectImg.left) ||
  1382. ((!m_bVertEdit) && rectText.bottom<=rectDrawing.bottom && rectText.bottom<=rectImg.bottom) )
  1383. {
  1384. MoveWindow( &rectText );
  1385. m_cEdit.UpdateWindow();
  1386. if ( m_bVertEdit )
  1387. m_cEdit.UpdateInput();
  1388. if (!m_cEdit.m_bResizeOnly)
  1389. {
  1390. if (m_cEdit.m_strResult.IsEmpty())
  1391. {
  1392. #ifdef UNICODE
  1393. WCHAR ch[3];
  1394. ch[0] = (WCHAR)m_cEdit.m_uiLastChar[0];
  1395. ch[1] = L'\0';
  1396. #else
  1397. BYTE ch[3];
  1398. //
  1399. // Put lead and trail bytes in proper place for DBCS characters.
  1400. //
  1401. if (IsDBCSLeadByte (HIBYTE(LOWORD(m_cEdit.m_uiLastChar[0]))))
  1402. {
  1403. ch[0] = HIBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
  1404. ch[1] = LOBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
  1405. ch[2] = '\0';
  1406. }
  1407. else
  1408. {
  1409. ch[0] = LOBYTE(LOWORD(m_cEdit.m_uiLastChar[0]));
  1410. ch[1] = '\0';
  1411. }
  1412. #endif // UNICODE
  1413. if (ch[0] == VK_RETURN)
  1414. {
  1415. lstrcpy((LPTSTR)ch, TEXT("\r\n"));
  1416. }
  1417. m_cEdit.ReplaceSel((LPCTSTR) ch );
  1418. }
  1419. else
  1420. {
  1421. int nLen = m_cEdit.m_strResult.GetLength();
  1422. m_cEdit.ReplaceSel( m_cEdit.m_strResult.GetBuffer(nLen));
  1423. }
  1424. }
  1425. }
  1426. if (pfntOld)
  1427. dc.SelectObject( pfntOld );
  1428. }
  1429. /******************************************************************************/
  1430. void CTedit::OnAttrEditFontChange(void)
  1431. {
  1432. CClientDC editDC( &m_cEdit );
  1433. CFont* pcFont = m_cEdit.GetFont();
  1434. if (!pcFont)
  1435. {
  1436. return; // this happens when you "escape" from the font
  1437. // selection listbox
  1438. }
  1439. CFont* pFontOld = editDC.SelectObject( pcFont);
  1440. TEXTMETRIC tm;
  1441. editDC.GetTextMetrics( &tm );
  1442. m_iLineHeight = tm.tmHeight;
  1443. #ifdef _DEBUG
  1444. TRACE1( "New font line height %d.\n", m_iLineHeight );
  1445. #endif
  1446. //only DBCS associated font would enable IME
  1447. if ( !m_bStarting )
  1448. {
  1449. LOGFONT lf;
  1450. pcFont->GetObject( sizeof( LOGFONT ), &lf );
  1451. if ( IS_DBCS_CHARSET( lf.lfCharSet ) )
  1452. {
  1453. if (m_bAssocIMC)
  1454. {
  1455. m_bAssocIMC = FALSE;
  1456. if (!IsCUAS())
  1457. {
  1458. EnableIme( m_cEdit.m_hWnd, m_hIMCEdit );
  1459. m_hIMCEdit = NULL;
  1460. }
  1461. EnableIme( m_hWndFace, m_hIMCFace );
  1462. EnableIme( m_hWndSize, m_hIMCSize );
  1463. m_hIMCFace = NULL;
  1464. m_hIMCSize = NULL;
  1465. m_pcTfont->SetFocus();
  1466. }
  1467. }
  1468. else
  1469. {
  1470. if (!m_bAssocIMC)
  1471. {
  1472. m_bAssocIMC = TRUE;
  1473. if (!IsCUAS())
  1474. m_hIMCEdit = DisableIme( m_cEdit.m_hWnd );
  1475. m_hIMCFace = DisableIme( m_hWndFace );
  1476. m_hIMCSize = DisableIme( m_hWndSize );
  1477. m_pcTfont->SetFocus();
  1478. }
  1479. }
  1480. }
  1481. if (pFontOld != NULL)
  1482. editDC.SelectObject( pFontOld );
  1483. m_eLastAction = eFONT_CHANGE;
  1484. }
  1485. /******************************************************************************/
  1486. void CTedit::OnSize( UINT nType, int cx, int cy )
  1487. {
  1488. if (! m_bStarting)
  1489. ShowWindow( SW_HIDE );
  1490. // need to do this if transparent to force see through
  1491. m_cRectOldPos = m_cRectWindow;
  1492. GetWindowRect( &m_cRectWindow );
  1493. m_pImgWnd->ScreenToClient( m_cRectWindow );
  1494. m_eLastAction = eSIZE_MOVE_CHANGE;
  1495. // could be NULL when main window is created and child edit window
  1496. // has not been created yet.
  1497. if (m_cEdit.GetSafeHwnd() != NULL)
  1498. {
  1499. m_cEdit.MoveWindow( 0, 0, cx, cy );
  1500. m_cEdit.SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
  1501. }
  1502. InvalidateRect( NULL );
  1503. UpdateWindow();
  1504. if (m_bBackgroundTransparent)
  1505. {
  1506. RefreshWindow();
  1507. }
  1508. if (! m_bStarting)
  1509. ShowWindow( SW_SHOW );
  1510. if ( m_bVertEdit )
  1511. {
  1512. m_cEdit.SetFmtRect();
  1513. CPoint pt( -20000, -20000 );
  1514. m_cEdit.SetCaretPos( pt );
  1515. m_cEdit.SetCaretPosition( FALSE, NULL, -1 );
  1516. m_cEdit.Repaint();
  1517. }
  1518. }
  1519. /******************************************************************************/
  1520. void CTedit::OnMove( int x, int y )
  1521. {
  1522. // need to do this if transparent to force see through
  1523. m_cRectOldPos = m_cRectWindow;
  1524. GetWindowRect( &m_cRectWindow );
  1525. m_pImgWnd->ScreenToClient( m_cRectWindow );
  1526. if (m_cRectOldPos.Width() != m_cRectWindow.Width()
  1527. || m_cRectOldPos.Height() != m_cRectWindow.Height())
  1528. {
  1529. //reset back to previous, since new will be updated in onsize, due to
  1530. // size and move happening both (e.g. sizing either left or top side
  1531. // causes an onmove then an onsize
  1532. m_cRectWindow = m_cRectOldPos;
  1533. }
  1534. m_eLastAction = eSIZE_MOVE_CHANGE;
  1535. if (m_cEdit.GetSafeHwnd() != NULL)
  1536. {
  1537. m_cEdit.SetWindowPos( &wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
  1538. }
  1539. InvalidateRect( NULL );
  1540. UpdateWindow();
  1541. if (m_bBackgroundTransparent)
  1542. {
  1543. RefreshWindow();
  1544. }
  1545. }
  1546. /******************************************************************************/
  1547. LRESULT CTedit::OnMoving( WPARAM, LPARAM lprc )
  1548. {
  1549. LRESULT lResult = 0;
  1550. CRect rectEdit = *((LPRECT)lprc);
  1551. CRect rectImage = m_pImgWnd->GetDrawingRect();
  1552. m_pImgWnd->ClientToScreen( &rectImage );
  1553. int iX = 0;
  1554. int iY = 0;
  1555. if (rectEdit.left < rectImage.left)
  1556. iX = rectImage.left - rectEdit.left;
  1557. else
  1558. if (rectEdit.right > rectImage.right)
  1559. iX = -(rectEdit.right - rectImage.right);
  1560. if (rectEdit.top < rectImage.top)
  1561. iY = rectImage.top - rectEdit.top;
  1562. else
  1563. if (rectEdit.bottom > rectImage.bottom)
  1564. iY = -(rectEdit.bottom - rectImage.bottom);
  1565. if (iX || iY)
  1566. {
  1567. rectEdit.OffsetRect( iX, iY );
  1568. *((LPRECT)lprc) = rectEdit;
  1569. lResult = 1;
  1570. }
  1571. return lResult;
  1572. }
  1573. /******************************************************************************/
  1574. void CTedit::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI )
  1575. {
  1576. CRect rectImage = m_pImgWnd->GetDrawingRect();
  1577. CSize Size = rectImage.Size();
  1578. lpMMI->ptMaxSize.x = Size.cx;
  1579. lpMMI->ptMaxSize.y = Size.cy;
  1580. lpMMI->ptMaxPosition = rectImage.TopLeft();
  1581. lpMMI->ptMinTrackSize.x = m_SizeMinimum.cx;
  1582. lpMMI->ptMinTrackSize.y = m_SizeMinimum.cy;
  1583. CRect rectClient;
  1584. GetWindowRect( &rectClient );
  1585. m_pImgWnd->ScreenToClient( &rectClient );
  1586. switch (m_uiHitArea)
  1587. {
  1588. case HTTOP:
  1589. case HTLEFT:
  1590. case HTTOPLEFT:
  1591. break;
  1592. case HTRIGHT:
  1593. case HTTOPRIGHT:
  1594. case HTBOTTOMRIGHT:
  1595. lpMMI->ptMaxSize.x -= (rectClient.left - rectImage.left);
  1596. if (m_uiHitArea == HTBOTTOMRIGHT)
  1597. ; // fall thru and do the bottom
  1598. else
  1599. break;
  1600. case HTBOTTOMLEFT:
  1601. case HTBOTTOM:
  1602. lpMMI->ptMaxSize.y -= (rectClient.top - rectImage.top);
  1603. break;
  1604. }
  1605. lpMMI->ptMaxTrackSize = lpMMI->ptMaxSize;
  1606. }
  1607. /******************************************************************************/
  1608. HBRUSH CTedit::OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor )
  1609. {
  1610. HBRUSH hbrBack = NULL;
  1611. if (pWnd == &m_cEdit)
  1612. {
  1613. PBSelectPalette( pDC, theApp.m_pPalette, FALSE );
  1614. pDC->SetTextColor( m_crFGColor );
  1615. //set the background color and transparent mode
  1616. // if (m_bBackgroundTransparent)
  1617. // {
  1618. pDC->SetBkMode( TRANSPARENT );
  1619. hbrBack = (HBRUSH)::GetStockObject( NULL_BRUSH );
  1620. // }
  1621. // else
  1622. // {
  1623. // pDC->SetBkMode( OPAQUE );
  1624. // pDC->SetBkColor( m_crBKColor );
  1625. // hbrBack = (HBRUSH)m_hbrBkColor.GetSafeHandle();
  1626. // }
  1627. }
  1628. if (hbrBack == NULL)
  1629. return (HBRUSH)Default();
  1630. return hbrBack;
  1631. }
  1632. /******************************************************************************/
  1633. //void CTedit::OnLButtonDown(UINT nFlags, CPoint point )
  1634. // {
  1635. // SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
  1636. // SetFocus();
  1637. // CEdit::OnLButtonDown(nFlags, point);
  1638. // }
  1639. /******************************************************************************/
  1640. void CTedit::OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp )
  1641. {
  1642. /* Increase by an extra width height of the border*/
  1643. lpncsp->rgrc[0].left += CTracker::HANDLE_SIZE;
  1644. lpncsp->rgrc[0].top += CTracker::HANDLE_SIZE;
  1645. lpncsp->rgrc[0].right -= CTracker::HANDLE_SIZE;
  1646. lpncsp->rgrc[0].bottom -= CTracker::HANDLE_SIZE;
  1647. }
  1648. /******************************************************************************/
  1649. void CTedit::OnNcPaint()
  1650. {
  1651. CDC *pdcWindow = GetWindowDC();
  1652. ASSERT(pdcWindow != NULL);
  1653. if (pdcWindow != NULL)
  1654. {
  1655. CRgn rgnClipping;
  1656. CRect cWinRect;
  1657. int iWindowWidth;
  1658. int iWindowHeight;
  1659. GetWindowRect( &cWinRect );
  1660. iWindowWidth = cWinRect.Width();
  1661. iWindowHeight = cWinRect.Height();
  1662. CRect cBorderRect( 0, 0, iWindowWidth, iWindowHeight );
  1663. CTracker::DrawBorder ( pdcWindow, cBorderRect, CTracker::all );
  1664. CTracker::DrawHandles( pdcWindow, cBorderRect, CTracker::all );
  1665. ReleaseDC( pdcWindow );
  1666. }
  1667. }
  1668. /******************************************************************************/
  1669. UINT CTedit::OnNcHitTest( CPoint point )
  1670. {
  1671. CRect cClientRect;
  1672. UINT uiHitTestCode = HTCAPTION;
  1673. ScreenToClient( &point );
  1674. GetClientRect(&cClientRect);
  1675. //Test to see if the pt is in THE CLIENT AREA
  1676. if (cClientRect.PtInRect(point))
  1677. {
  1678. uiHitTestCode = HTCLIENT;
  1679. }
  1680. m_uiHitArea = HTNOWHERE;
  1681. switch (CTracker::HitTest( cClientRect, point, CTracker::nil ))
  1682. {
  1683. case CTracker::resizingTop:
  1684. m_uiHitArea = HTTOP;
  1685. break;
  1686. case CTracker::resizingLeft:
  1687. m_uiHitArea = HTLEFT;
  1688. break;
  1689. case CTracker::resizingRight:
  1690. m_uiHitArea = HTRIGHT;
  1691. break;
  1692. case CTracker::resizingBottom:
  1693. m_uiHitArea = HTBOTTOM;
  1694. break;
  1695. case CTracker::resizingTopLeft:
  1696. m_uiHitArea = HTTOPLEFT;
  1697. break;
  1698. case CTracker::resizingTopRight:
  1699. m_uiHitArea = HTTOPRIGHT;
  1700. break;
  1701. case CTracker::resizingBottomLeft:
  1702. m_uiHitArea = HTBOTTOMLEFT;
  1703. break;
  1704. case CTracker::resizingBottomRight:
  1705. m_uiHitArea = HTBOTTOMRIGHT;
  1706. break;
  1707. }
  1708. if (m_uiHitArea != HTNOWHERE)
  1709. uiHitTestCode = m_uiHitArea;
  1710. m_cEdit.SetHCursorShape();
  1711. return uiHitTestCode;
  1712. }
  1713. /******************************************************************************/
  1714. void CTedit::OnRButtonDown(UINT nFlags, CPoint point)
  1715. {
  1716. CMenu cMenuPopup;
  1717. CMenu *pcContextMenu;
  1718. CRect cRectClient;
  1719. BOOL bRC = cMenuPopup.LoadMenu( IDR_TEXT_POPUP );
  1720. ASSERT( bRC );
  1721. if (bRC)
  1722. {
  1723. GetClientRect( &cRectClient );
  1724. pcContextMenu = cMenuPopup.GetSubMenu( ID_EBOX_POPUPMENU_POS );
  1725. ASSERT( pcContextMenu != NULL );
  1726. if (pcContextMenu != NULL)
  1727. {
  1728. // update the check marks
  1729. OnUpdateTextPlain ( pcContextMenu );
  1730. OnUpdateTextBold ( pcContextMenu );
  1731. OnUpdateTextItalic ( pcContextMenu );
  1732. OnUpdateTextUnderline( pcContextMenu );
  1733. OnUpdateTextTexttool ( pcContextMenu );
  1734. ClientToScreen( &point );
  1735. ClientToScreen( &cRectClient );
  1736. // the frame actually has a clue about what items to enable...
  1737. CWnd *notify = GetParentFrame();
  1738. if( !notify )
  1739. notify = this; // oh well...
  1740. pcContextMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  1741. point.x, point.y, notify, &cRectClient );
  1742. }
  1743. }
  1744. }
  1745. /******************************************************************************/
  1746. void CTedit::OnTextPlain()
  1747. {
  1748. ASSERT( m_pcTfont != NULL );
  1749. if (m_pcTfont != NULL)
  1750. {
  1751. if (m_pcTfont->IsBoldOn())
  1752. {
  1753. m_pcTfont->OnBold();
  1754. }
  1755. if (m_pcTfont->IsItalicOn())
  1756. {
  1757. m_pcTfont->OnItalic();
  1758. }
  1759. if (m_pcTfont->IsUnderlineOn())
  1760. {
  1761. m_pcTfont->OnUnderline();
  1762. }
  1763. if (m_pcTfont->IsShadowOn())
  1764. {
  1765. m_pcTfont->OnShadow();
  1766. }
  1767. m_pcTfont->RefreshToolBar();
  1768. RefreshWindow();
  1769. }
  1770. }
  1771. /******************************************************************************/
  1772. void CTedit::OnTextBold()
  1773. {
  1774. ASSERT(m_pcTfont != NULL);
  1775. if (m_pcTfont != NULL)
  1776. {
  1777. m_pcTfont->OnBold();
  1778. m_pcTfont->RefreshToolBar();
  1779. RefreshWindow();
  1780. }
  1781. }
  1782. /******************************************************************************/
  1783. void CTedit::OnTextItalic()
  1784. {
  1785. ASSERT(m_pcTfont != NULL);
  1786. if (m_pcTfont != NULL)
  1787. {
  1788. m_pcTfont->OnItalic();
  1789. m_pcTfont->RefreshToolBar();
  1790. RefreshWindow();
  1791. }
  1792. }
  1793. /******************************************************************************/
  1794. void CTedit::OnTextUnderline()
  1795. {
  1796. ASSERT(m_pcTfont != NULL);
  1797. if (m_pcTfont != NULL)
  1798. {
  1799. m_pcTfont->OnUnderline();
  1800. m_pcTfont->RefreshToolBar();
  1801. RefreshWindow();
  1802. }
  1803. }
  1804. /******************************************************************************/
  1805. void CTedit::OnTextSelectfont()
  1806. {
  1807. if (m_pcTfont != NULL)
  1808. {
  1809. if (! IsFontPaletteVisible())
  1810. ShowFontPalette( SW_SHOW );
  1811. else
  1812. m_pcTfont->SetFocus();
  1813. }
  1814. }
  1815. /******************************************************************************/
  1816. void CTedit::OnTextSelectpointsize()
  1817. {
  1818. if (m_pcTfont != NULL)
  1819. {
  1820. if (! IsFontPaletteVisible())
  1821. ShowFontPalette( SW_SHOW );
  1822. else
  1823. m_pcTfont->SetFocus();
  1824. CWnd* pWnd = m_pcTfont->GetFontSizeControl();
  1825. if (pWnd != NULL)
  1826. {
  1827. pWnd->SetFocus();
  1828. }
  1829. }
  1830. }
  1831. /******************************************************************************/
  1832. void CTedit::OnEditCut()
  1833. {
  1834. if ( m_bVertEdit ) HideCaret();
  1835. m_cEdit.Cut();
  1836. RefreshWindow();
  1837. if ( m_bVertEdit )
  1838. {
  1839. m_cEdit.SetCaretShape();
  1840. ShowCaret();
  1841. }
  1842. }
  1843. /******************************************************************************/
  1844. void CTedit::OnEditCopy()
  1845. {
  1846. m_cEdit.Copy();
  1847. }
  1848. /******************************************************************************/
  1849. void CTedit::OnEditPaste()
  1850. {
  1851. m_bPasting = TRUE;
  1852. #ifdef _DEBUG
  1853. TRACE0( "OnEditPaste Start\n" );
  1854. #endif
  1855. m_cEdit.Paste();
  1856. #ifdef _DEBUG
  1857. TRACE0( "OnEditPaste End\n" );
  1858. #endif
  1859. m_bPasting = FALSE;
  1860. RefreshWindow();
  1861. }
  1862. /******************************************************************************/
  1863. void CTedit::OnTextDelete()
  1864. {
  1865. int iLength = m_cEdit.GetWindowTextLength();
  1866. int iStart = iLength;
  1867. int iEnd = iLength;
  1868. if ( m_bVertEdit ) m_cEdit.HideCaret();
  1869. m_cEdit.GetSel( iStart, iEnd );
  1870. if (iStart == iEnd)
  1871. {
  1872. if (iLength == iStart)
  1873. return;
  1874. CString strText;
  1875. m_cEdit.GetWindowText(strText);
  1876. if (!strText.IsEmpty() && (IsDBCSLeadByte((CHAR)strText[iStart])
  1877. || strText[iStart]==TEXT('\r')))
  1878. iEnd += 2;
  1879. else
  1880. iEnd += 1;
  1881. m_cEdit.SetSel( iStart, iEnd, TRUE );
  1882. }
  1883. m_cEdit.Clear();
  1884. if ( m_bVertEdit )
  1885. {
  1886. m_cEdit.SetCaretShape();
  1887. m_cEdit.SetCaretPosition( TRUE, NULL, -1 );
  1888. m_cEdit.ShowCaret();
  1889. m_cEdit.Repaint();
  1890. }
  1891. else
  1892. {
  1893. UpdateWindow();
  1894. RefreshWindow();
  1895. }
  1896. }
  1897. /******************************************************************************/
  1898. void CTedit::OnTextSelectall()
  1899. {
  1900. m_cEdit.SetSel( 0, -1, TRUE );
  1901. RefreshWindow();
  1902. }
  1903. /******************************************************************************/
  1904. void CTedit::OnTextUndo()
  1905. {
  1906. Undo();
  1907. RefreshWindow();
  1908. }
  1909. /******************************************************************************/
  1910. void CTedit::OnTextPlace()
  1911. {
  1912. CWnd* cwndParent = GetParent();
  1913. cwndParent->PostMessage( WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM( CTracker::HANDLE_SIZE + 1, CTracker::HANDLE_SIZE + 1 ) );
  1914. cwndParent->PostMessage( WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM( CTracker::HANDLE_SIZE + 1, CTracker::HANDLE_SIZE + 1 ) );
  1915. }
  1916. /******************************************************************************/
  1917. void CTedit::OnTextTexttool()
  1918. {
  1919. if (IsFontPaletteVisible())
  1920. {
  1921. ShowFontPalette( SW_HIDE );
  1922. }
  1923. else
  1924. {
  1925. ShowFontPalette( SW_SHOWNOACTIVATE );
  1926. }
  1927. }
  1928. /******************************************************************************/
  1929. void CTedit::OnUpdateTextPlain( CMenu *pcMenu )
  1930. {
  1931. ASSERT( m_pcTfont != NULL );
  1932. if (m_pcTfont != NULL)
  1933. {
  1934. if (! m_pcTfont->IsBoldOn()
  1935. && ! m_pcTfont->IsItalicOn()
  1936. && ! m_pcTfont->IsUnderlineOn()
  1937. && ! m_pcTfont->IsShadowOn())
  1938. {
  1939. pcMenu->CheckMenuItem(ID_TEXT_PLAIN, MF_BYCOMMAND | MF_CHECKED);
  1940. }
  1941. else
  1942. {
  1943. pcMenu->CheckMenuItem(ID_TEXT_PLAIN, MF_BYCOMMAND | MF_UNCHECKED);
  1944. }
  1945. }
  1946. }
  1947. /******************************************************************************/
  1948. void CTedit::OnUpdateTextBold(CMenu *pcMenu)
  1949. {
  1950. ASSERT(m_pcTfont != NULL);
  1951. if (m_pcTfont != NULL)
  1952. {
  1953. if (m_pcTfont->IsBoldOn())
  1954. {
  1955. pcMenu->CheckMenuItem(ID_TEXT_BOLD, MF_BYCOMMAND | MF_CHECKED);
  1956. }
  1957. else
  1958. {
  1959. pcMenu->CheckMenuItem(ID_TEXT_BOLD, MF_BYCOMMAND | MF_UNCHECKED);
  1960. }
  1961. }
  1962. }
  1963. /******************************************************************************/
  1964. void CTedit::OnUpdateTextItalic(CMenu *pcMenu)
  1965. {
  1966. ASSERT(m_pcTfont != NULL);
  1967. if (m_pcTfont != NULL)
  1968. {
  1969. if (m_pcTfont->IsItalicOn())
  1970. {
  1971. pcMenu->CheckMenuItem(ID_TEXT_ITALIC, MF_BYCOMMAND | MF_CHECKED);
  1972. }
  1973. else
  1974. {
  1975. pcMenu->CheckMenuItem(ID_TEXT_ITALIC, MF_BYCOMMAND | MF_UNCHECKED);
  1976. }
  1977. }
  1978. }
  1979. /******************************************************************************/
  1980. void CTedit::OnUpdateTextUnderline(CMenu *pcMenu)
  1981. {
  1982. ASSERT(m_pcTfont != NULL);
  1983. if (m_pcTfont != NULL)
  1984. {
  1985. if (m_pcTfont->IsUnderlineOn())
  1986. {
  1987. pcMenu->CheckMenuItem(ID_TEXT_UNDERLINE, MF_BYCOMMAND | MF_CHECKED);
  1988. }
  1989. else
  1990. {
  1991. pcMenu->CheckMenuItem(ID_TEXT_UNDERLINE, MF_BYCOMMAND | MF_UNCHECKED);
  1992. }
  1993. }
  1994. }
  1995. /******************************************************************************/
  1996. void CTedit::OnUpdateTextTexttool(CMenu *pcMenu)
  1997. {
  1998. if (IsFontPaletteVisible())
  1999. {
  2000. pcMenu->CheckMenuItem(ID_VIEW_TEXT_TOOLBAR, MF_BYCOMMAND | MF_CHECKED);
  2001. }
  2002. else
  2003. {
  2004. pcMenu->CheckMenuItem(ID_VIEW_TEXT_TOOLBAR, MF_BYCOMMAND | MF_UNCHECKED);
  2005. }
  2006. }
  2007. /******************************************************************************/
  2008. /******************************************************************************/
  2009. void CTedit::OnDestroy(void)
  2010. {
  2011. if ( m_cEdit.GetSafeHwnd() )
  2012. {
  2013. if ( m_cEdit.m_hOldCursor )
  2014. SetClassLongPtr( m_cEdit.m_hWnd, GCLP_HCURSOR, (LONG_PTR) m_cEdit.m_hOldCursor );
  2015. //restore original edit IMC
  2016. if (m_bAssocIMC)
  2017. {
  2018. m_bAssocIMC = FALSE;
  2019. EnableIme( m_cEdit.m_hWnd, m_hIMCEdit );
  2020. EnableIme( m_hWndFace, m_hIMCFace );
  2021. EnableIme( m_hWndSize, m_hIMCSize );
  2022. m_hIMCEdit = NULL;
  2023. m_hIMCFace = NULL;
  2024. m_hIMCSize = NULL;
  2025. }
  2026. }
  2027. Default();
  2028. return;
  2029. }
  2030. /******************************************************************************/
  2031. HIMC CTedit::DisableIme( HWND hWnd )
  2032. {
  2033. HIMC hIMC = NULL;
  2034. if ( (hWnd) && (::IsWindow( hWnd )) )
  2035. hIMC = ImmAssociateContext( hWnd, NULL );
  2036. return hIMC;
  2037. }
  2038. /******************************************************************************/
  2039. void CTedit::EnableIme( HWND hWnd, HIMC hIMC )
  2040. {
  2041. if ( (hWnd) && (::IsWindow( hWnd )) )
  2042. ImmAssociateContext( hWnd, hIMC );
  2043. }
  2044. /******************************************************************************/
  2045. //
  2046. // Tablet PC.
  2047. //
  2048. // Is CUAS (Cicero Unaware App Support) is on, we need to use hIMC even on
  2049. // Ansi Font. The string from English HW/Speech TIPs will be delivered
  2050. // through hIMC.
  2051. //
  2052. BOOL CTedit::IsCUAS()
  2053. {
  2054. BOOL bRet = FALSE;
  2055. typedef BOOL (*PFNCTFIMMISCICEROENABLED)(void);
  2056. static PFNCTFIMMISCICEROENABLED pfn = NULL;
  2057. if (!pfn)
  2058. {
  2059. HMODULE hMod = LoadLibrary(TEXT("imm32.dll"));
  2060. if (hMod)
  2061. {
  2062. pfn = (PFNCTFIMMISCICEROENABLED)GetProcAddress(hMod,
  2063. "CtfImmIsCiceroEnabled");
  2064. }
  2065. }
  2066. if (pfn)
  2067. bRet = pfn();
  2068. return bRet;
  2069. }
  2070. /******************************************************************************/