Home | History | Annotate | Download | only in pdfwindow
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../include/pdfwindow/PDFWindow.h"
      8 #include "../../include/pdfwindow/PWL_Wnd.h"
      9 #include "../../include/pdfwindow/PWL_EditCtrl.h"
     10 #include "../../include/pdfwindow/PWL_ScrollBar.h"
     11 #include "../../include/pdfwindow/PWL_Utils.h"
     12 #include "../../include/pdfwindow/PWL_Caret.h"
     13 #include "../../include/pdfwindow/PWL_FontMap.h"
     14 
     15 #define IsFloatZero(f)						((f) < 0.0001 && (f) > -0.0001)
     16 #define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
     17 #define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
     18 #define IsFloatEqual(fa,fb)					IsFloatZero((fa)-(fb))
     19 
     20 /* ---------------------------- CPWL_EditCtrl ------------------------------ */
     21 
     22 CPWL_EditCtrl::CPWL_EditCtrl() :
     23 	m_pEdit(NULL),
     24 	m_pEditCaret(NULL),
     25 	m_bMouseDown(FALSE),
     26 	m_pEditNotify(NULL),
     27 	m_nCharSet(DEFAULT_CHARSET),
     28 	m_nCodePage(0)
     29 {
     30 	m_pEdit = IFX_Edit::NewEdit();
     31 	ASSERT(m_pEdit != NULL);
     32 }
     33 
     34 CPWL_EditCtrl::~CPWL_EditCtrl()
     35 {
     36 	IFX_Edit::DelEdit(m_pEdit);
     37 }
     38 
     39 void CPWL_EditCtrl::OnCreate(PWL_CREATEPARAM & cp)
     40 {
     41 	cp.eCursorType = FXCT_VBEAM;
     42 }
     43 
     44 void CPWL_EditCtrl::OnCreated()
     45 {
     46 	SetFontSize(this->GetCreationParam().fFontSize);
     47 
     48 	m_pEdit->SetFontMap(this->GetFontMap());
     49 	m_pEdit->SetNotify(this);
     50 	m_pEdit->Initialize();
     51 }
     52 
     53 FX_BOOL CPWL_EditCtrl::IsWndHorV()
     54 {
     55 	CPDF_Matrix mt = GetWindowMatrix();
     56 	CPDF_Point point1(0,1);
     57 	CPDF_Point point2(1,1);
     58 
     59 	mt.Transform(point1.x, point1.y);
     60 	mt.Transform(point2.x, point2.y);
     61 
     62 	return point2.y == point1.y;
     63 }
     64 
     65 void CPWL_EditCtrl::SetCursor()
     66 {
     67 	if (IsValid())
     68 	{
     69 		if (IFX_SystemHandler* pSH = GetSystemHandler())
     70 		{
     71 			if (IsWndHorV())
     72 				pSH->SetCursor(FXCT_VBEAM);
     73 			else
     74 				pSH->SetCursor(FXCT_HBEAM);
     75 		}
     76 	}
     77 }
     78 
     79 void CPWL_EditCtrl::RePosChildWnd()
     80 {
     81 	m_pEdit->SetPlateRect(GetClientRect());
     82 }
     83 
     84 void CPWL_EditCtrl::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam)
     85 {
     86 	CPWL_Wnd::OnNotify(pWnd,msg,wParam,lParam);
     87 
     88 	switch (msg)
     89 	{
     90 		case PNM_SETSCROLLINFO:
     91 			switch (wParam)
     92 			{
     93 				case SBT_VSCROLL:
     94 					if (CPWL_Wnd * pChild = GetVScrollBar())
     95 					{
     96 						pChild->OnNotify(pWnd,PNM_SETSCROLLINFO,wParam,lParam);
     97 					}
     98 					break;
     99 			}
    100 			break;
    101 		case PNM_SETSCROLLPOS:
    102 			switch (wParam)
    103 			{
    104 				case SBT_VSCROLL:
    105 					if (CPWL_Wnd * pChild = GetVScrollBar())
    106 					{
    107 						pChild->OnNotify(pWnd,PNM_SETSCROLLPOS,wParam,lParam);
    108 					}
    109 					break;
    110 			}
    111 			break;
    112 		case PNM_SCROLLWINDOW:
    113 			{
    114 				FX_FLOAT fPos = *(FX_FLOAT*)lParam;
    115 				switch (wParam)
    116 				{
    117 					case SBT_VSCROLL:
    118 						m_pEdit->SetScrollPos(CPDF_Point(m_pEdit->GetScrollPos().x,fPos));
    119 						break;
    120 				}
    121 			}
    122 			break;
    123 		case PNM_SETCARETINFO:
    124 			{
    125 				if (PWL_CARET_INFO * pCaretInfo = (PWL_CARET_INFO *)wParam)
    126 				{
    127 					this->SetCaret(pCaretInfo->bVisible,
    128 						pCaretInfo->ptHead,
    129 						pCaretInfo->ptFoot);
    130 				}
    131 			}
    132 			break;
    133 	}
    134 }
    135 
    136 void CPWL_EditCtrl::CreateChildWnd(const PWL_CREATEPARAM & cp)
    137 {
    138 	if (!IsReadOnly())
    139 		CreateEditCaret(cp);
    140 }
    141 
    142 void CPWL_EditCtrl::CreateEditCaret(const PWL_CREATEPARAM & cp)
    143 {
    144 	if (!m_pEditCaret)
    145 	{
    146 		m_pEditCaret = new CPWL_Caret;
    147 		m_pEditCaret->SetInvalidRect(GetClientRect());
    148 
    149 		PWL_CREATEPARAM	ecp = cp;
    150 		ecp.pParentWnd = this;
    151 		ecp.dwFlags = PWS_CHILD | PWS_NOREFRESHCLIP;
    152 		ecp.dwBorderWidth = 0;
    153 		ecp.nBorderStyle = PBS_SOLID;
    154 		ecp.rcRectWnd = CPDF_Rect(0,0,0,0);
    155 
    156 		m_pEditCaret->Create(ecp);
    157 	}
    158 }
    159 
    160 void CPWL_EditCtrl::SetFontSize(FX_FLOAT fFontSize)
    161 {
    162 	m_pEdit->SetFontSize(fFontSize);
    163 }
    164 
    165 FX_FLOAT CPWL_EditCtrl::GetFontSize() const
    166 {
    167 	return m_pEdit->GetFontSize();
    168 }
    169 
    170 FX_BOOL CPWL_EditCtrl::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
    171 {
    172 	if (m_bMouseDown) return TRUE;
    173 
    174 	FX_BOOL bRet = CPWL_Wnd::OnKeyDown(nChar,nFlag);
    175 
    176 	//FILTER
    177 	switch (nChar)
    178 	{
    179 	default:
    180 		return FALSE;
    181 	case FWL_VKEY_Delete:
    182 	case FWL_VKEY_Up:
    183 	case FWL_VKEY_Down:
    184 	case FWL_VKEY_Left:
    185 	case FWL_VKEY_Right:
    186 	case FWL_VKEY_Home:
    187 	case FWL_VKEY_End:
    188 	case FWL_VKEY_Insert:
    189 	case 'C':
    190 	case 'V':
    191 	case 'X':
    192 	case 'A':
    193 	case 'Z':
    194 	case 'c':
    195 	case 'v':
    196 	case 'x':
    197 	case 'a':
    198 	case 'z':
    199 		break;
    200 	}
    201 
    202 	if (nChar == FWL_VKEY_Delete)
    203 	{
    204 		if (m_pEdit->IsSelected())
    205 			nChar = FWL_VKEY_Unknown;
    206 	}
    207 
    208 	switch (nChar)
    209 	{
    210 		case FWL_VKEY_Delete:
    211 			Delete();
    212 			return TRUE;
    213 		case FWL_VKEY_Insert:
    214 			if (IsSHIFTpressed(nFlag))
    215 				PasteText();
    216 			return TRUE;
    217 		case FWL_VKEY_Up:
    218 			m_pEdit->OnVK_UP(IsSHIFTpressed(nFlag),FALSE);
    219 			return TRUE;
    220 		case FWL_VKEY_Down:
    221 			m_pEdit->OnVK_DOWN(IsSHIFTpressed(nFlag),FALSE);
    222 			return TRUE;
    223 		case FWL_VKEY_Left:
    224 			m_pEdit->OnVK_LEFT(IsSHIFTpressed(nFlag),FALSE);
    225 			return TRUE;
    226 		case FWL_VKEY_Right:
    227 			m_pEdit->OnVK_RIGHT(IsSHIFTpressed(nFlag),FALSE);
    228 			return TRUE;
    229 		case FWL_VKEY_Home:
    230 			m_pEdit->OnVK_HOME(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
    231 			return TRUE;
    232 		case FWL_VKEY_End:
    233 			m_pEdit->OnVK_END(IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
    234 			return TRUE;
    235 		case FWL_VKEY_Unknown:
    236 			if (!IsSHIFTpressed(nFlag))
    237 				Clear();
    238 			else
    239 				CutText();
    240 			return TRUE;
    241 		default:
    242 			break;
    243 	}
    244 
    245 	return bRet;
    246 }
    247 
    248 FX_BOOL CPWL_EditCtrl::OnChar(FX_WORD nChar, FX_DWORD nFlag)
    249 {
    250 	if (m_bMouseDown) return TRUE;
    251 
    252 	CPWL_Wnd::OnChar(nChar,nFlag);
    253 
    254 	//FILTER
    255 	switch (nChar)
    256 	{
    257 		case 0x0A:
    258 		case 0x1B:
    259 			return FALSE;
    260 		default:
    261 			break;
    262 	}
    263 
    264 	FX_BOOL bCtrl = IsCTRLpressed(nFlag);
    265 	FX_BOOL bAlt = IsALTpressed(nFlag);
    266 	FX_BOOL bShift = IsSHIFTpressed(nFlag);
    267 
    268 	FX_WORD word = nChar;
    269 
    270 	if (bCtrl && !bAlt)
    271 	{
    272 		switch (nChar)
    273 		{
    274 			case 'C' - 'A' + 1:
    275 				this->CopyText();
    276 				return TRUE;
    277 			case 'V' - 'A' + 1:
    278 				this->PasteText();
    279 				return TRUE;
    280 			case 'X' - 'A' + 1:
    281 				this->CutText();
    282 				return TRUE;
    283 			case 'A' - 'A' + 1:
    284 				this->SelectAll();
    285 				return TRUE;
    286 			case 'Z' - 'A' + 1:
    287 				if (bShift)
    288 					Redo();
    289 				else
    290 					Undo();
    291 				return TRUE;
    292 			default:
    293 				if (nChar < 32)
    294 					return FALSE;
    295 		}
    296 	}
    297 
    298 	if (IsReadOnly()) return TRUE;
    299 
    300 	if (m_pEdit->IsSelected() && word ==  FWL_VKEY_Back)
    301 		word = FWL_VKEY_Unknown;
    302 
    303 	Clear();
    304 
    305 	switch (word)
    306 	{
    307 	case FWL_VKEY_Back:
    308 		Backspace();
    309 		break;
    310 	case FWL_VKEY_Return:
    311 		InsertReturn();
    312 		break;
    313 	case FWL_VKEY_Unknown:
    314 		break;
    315 	default:
    316 		if (IsINSERTpressed(nFlag))
    317 			Delete();
    318 		InsertWord(word, this->GetCharSet());
    319 		break;
    320 	}
    321 
    322 	return TRUE;
    323 }
    324 
    325 FX_BOOL CPWL_EditCtrl::OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag)
    326 {
    327 	CPWL_Wnd::OnLButtonDown(point,nFlag);
    328 
    329 	if (ClientHitTest(point))
    330 	{
    331 		if (m_bMouseDown)
    332 			this->InvalidateRect();
    333 
    334 		m_bMouseDown = TRUE;
    335 		SetCapture();
    336 
    337 		m_pEdit->OnMouseDown(point,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
    338 	}
    339 
    340 	return TRUE;
    341 }
    342 
    343 FX_BOOL CPWL_EditCtrl::OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag)
    344 {
    345 	CPWL_Wnd::OnLButtonUp(point,nFlag);
    346 
    347 	if (m_bMouseDown)
    348 	{
    349 		//can receive keybord message
    350 		if (ClientHitTest(point) && !this->IsFocused())
    351 			SetFocus();
    352 
    353 		ReleaseCapture();
    354 		m_bMouseDown = FALSE;
    355 	}
    356 
    357 	return TRUE;
    358 }
    359 
    360 FX_BOOL CPWL_EditCtrl::OnMouseMove(const CPDF_Point & point, FX_DWORD nFlag)
    361 {
    362 	CPWL_Wnd::OnMouseMove(point,nFlag);
    363 
    364 	if (m_bMouseDown)
    365 		m_pEdit->OnMouseMove(point,FALSE,FALSE);
    366 
    367 	return TRUE;
    368 }
    369 
    370 CPDF_Rect CPWL_EditCtrl::GetContentRect() const
    371 {
    372 	return m_pEdit->GetContentRect();
    373 }
    374 
    375 void CPWL_EditCtrl::SetEditCaret(FX_BOOL bVisible)
    376 {
    377 	CPDF_Point ptHead(0,0),ptFoot(0,0);
    378 
    379 	if (bVisible)
    380 	{
    381 		GetCaretInfo(ptHead,ptFoot);
    382 	}
    383 
    384 	CPVT_WordPlace wpTemp = m_pEdit->GetCaretWordPlace();
    385 	this->IOnSetCaret(bVisible,ptHead,ptFoot,wpTemp);
    386 }
    387 
    388 void CPWL_EditCtrl::GetCaretInfo(CPDF_Point & ptHead, CPDF_Point & ptFoot) const
    389 {
    390 	if (IFX_Edit_Iterator * pIterator = m_pEdit->GetIterator())
    391 	{
    392 		pIterator->SetAt(m_pEdit->GetCaret());
    393 		CPVT_Word word;
    394 		CPVT_Line line;
    395 		if (pIterator->GetWord(word))
    396 		{
    397 			ptHead.x = word.ptWord.x + word.fWidth;
    398 			ptHead.y = word.ptWord.y + word.fAscent;
    399 			ptFoot.x = word.ptWord.x + word.fWidth;
    400 			ptFoot.y = word.ptWord.y + word.fDescent;
    401 		}
    402 		else if (pIterator->GetLine(line))
    403 		{
    404 			ptHead.x = line.ptLine.x;
    405 			ptHead.y = line.ptLine.y + line.fLineAscent;
    406 			ptFoot.x = line.ptLine.x;
    407 			ptFoot.y = line.ptLine.y + line.fLineDescent;
    408 		}
    409 	}
    410 }
    411 
    412 void CPWL_EditCtrl::GetCaretPos(FX_INT32& x, FX_INT32& y) const
    413 {
    414 	CPDF_Point ptHead(0,0), ptFoot(0,0);
    415 
    416 	GetCaretInfo(ptHead,ptFoot);
    417 
    418 	PWLtoWnd(ptHead, x, y);
    419 }
    420 
    421 void CPWL_EditCtrl::SetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPDF_Point & ptFoot)
    422 {
    423 	if (m_pEditCaret)
    424 	{
    425 		if (!IsFocused() || m_pEdit->IsSelected())
    426 			bVisible = FALSE;
    427 
    428 		m_pEditCaret->SetCaret(bVisible, ptHead, ptFoot);
    429 	}
    430 }
    431 
    432 FX_BOOL	CPWL_EditCtrl::IsModified() const
    433 {
    434 	return m_pEdit->IsModified();
    435 }
    436 
    437 CFX_WideString CPWL_EditCtrl::GetText() const
    438 {
    439 	return m_pEdit->GetText();
    440 }
    441 
    442 void CPWL_EditCtrl::SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar)
    443 {
    444 	m_pEdit->SetSel(nStartChar, nEndChar);
    445 }
    446 
    447 void CPWL_EditCtrl::GetSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar ) const
    448 {
    449 	m_pEdit->GetSel(nStartChar, nEndChar);
    450 }
    451 
    452 void CPWL_EditCtrl::Clear()
    453 {
    454 	if (!IsReadOnly())
    455 		m_pEdit->Clear();
    456 }
    457 
    458 void CPWL_EditCtrl::SelectAll()
    459 {
    460 	m_pEdit->SelectAll();
    461 }
    462 
    463 void CPWL_EditCtrl::Paint()
    464 {
    465 	if (m_pEdit)
    466 		m_pEdit->Paint();
    467 }
    468 
    469 void CPWL_EditCtrl::EnableRefresh(FX_BOOL bRefresh)
    470 {
    471 	if (m_pEdit)
    472 		m_pEdit->EnableRefresh(bRefresh);
    473 }
    474 
    475 FX_INT32 CPWL_EditCtrl::GetCaret() const
    476 {
    477 	if (m_pEdit)
    478 		return m_pEdit->GetCaret();
    479 
    480 	return -1;
    481 }
    482 
    483 void CPWL_EditCtrl::SetCaret(FX_INT32 nPos)
    484 {
    485 	if (m_pEdit)
    486 		m_pEdit->SetCaret(nPos);
    487 }
    488 
    489 FX_INT32 CPWL_EditCtrl::GetTotalWords() const
    490 {
    491 	if (m_pEdit)
    492 		return m_pEdit->GetTotalWords();
    493 
    494 	return 0;
    495 }
    496 
    497 void CPWL_EditCtrl::SetScrollPos(const CPDF_Point& point)
    498 {
    499 	if (m_pEdit)
    500 		m_pEdit->SetScrollPos(point);
    501 }
    502 
    503 CPDF_Point CPWL_EditCtrl::GetScrollPos() const
    504 {
    505 	if (m_pEdit)
    506 		return m_pEdit->GetScrollPos();
    507 
    508 	return CPDF_Point(0.0f, 0.0f);
    509 }
    510 
    511 CPDF_Font * CPWL_EditCtrl::GetCaretFont() const
    512 {
    513 	FX_INT32 nFontIndex = 0;
    514 
    515 	if (IFX_Edit_Iterator * pIterator = m_pEdit->GetIterator())
    516 	{
    517 		pIterator->SetAt(m_pEdit->GetCaret());
    518 		CPVT_Word word;
    519 		CPVT_Section section;
    520 		if (pIterator->GetWord(word))
    521 		{
    522 			nFontIndex = word.nFontIndex;
    523 		}
    524 		else if (HasFlag(PES_RICH))
    525 		{
    526 			if (pIterator->GetSection(section))
    527 			{
    528 				nFontIndex = section.WordProps.nFontIndex;
    529 			}
    530 		}
    531 	}
    532 
    533 	if (IFX_Edit_FontMap * pFontMap = GetFontMap())
    534 		return pFontMap->GetPDFFont(nFontIndex);
    535 	else
    536 		return NULL;
    537 }
    538 
    539 FX_FLOAT CPWL_EditCtrl::GetCaretFontSize() const
    540 {
    541 	FX_FLOAT fFontSize = GetFontSize();
    542 
    543 	if (IFX_Edit_Iterator * pIterator = m_pEdit->GetIterator())
    544 	{
    545 		pIterator->SetAt(m_pEdit->GetCaret());
    546 		CPVT_Word word;
    547 		CPVT_Section section;
    548 		if (pIterator->GetWord(word))
    549 		{
    550 			fFontSize = word.fFontSize;
    551 		}
    552 		else if (HasFlag(PES_RICH))
    553 		{
    554 			if (pIterator->GetSection(section))
    555 			{
    556 				fFontSize = section.WordProps.fFontSize;
    557 			}
    558 		}
    559 	}
    560 
    561 	return fFontSize;
    562 }
    563 
    564 void CPWL_EditCtrl::SetText(FX_LPCWSTR csText)
    565 {
    566 	m_pEdit->SetText(csText);
    567 }
    568 
    569 void CPWL_EditCtrl::CopyText()
    570 {
    571 }
    572 
    573 void CPWL_EditCtrl::PasteText()
    574 {
    575 }
    576 
    577 void CPWL_EditCtrl::CutText()
    578 {
    579 }
    580 
    581 void CPWL_EditCtrl::ShowVScrollBar(FX_BOOL bShow)
    582 {
    583 }
    584 
    585 void CPWL_EditCtrl::InsertText(FX_LPCWSTR csText)
    586 {
    587 	if (!IsReadOnly())
    588 		m_pEdit->InsertText(csText);
    589 }
    590 
    591 void CPWL_EditCtrl::InsertWord(FX_WORD word, FX_INT32 nCharset)
    592 {
    593 	if (!IsReadOnly())
    594 		m_pEdit->InsertWord(word, nCharset);
    595 }
    596 
    597 void CPWL_EditCtrl::InsertReturn()
    598 {
    599 	if (!IsReadOnly())
    600 		m_pEdit->InsertReturn();
    601 }
    602 
    603 void CPWL_EditCtrl::Delete()
    604 {
    605 	if (!IsReadOnly())
    606 		m_pEdit->Delete();
    607 }
    608 
    609 void CPWL_EditCtrl::Backspace()
    610 {
    611 	if (!IsReadOnly())
    612 		m_pEdit->Backspace();
    613 }
    614 
    615 FX_BOOL	CPWL_EditCtrl::CanUndo() const
    616 {
    617 	return !IsReadOnly() && m_pEdit->CanUndo();
    618 }
    619 
    620 FX_BOOL	CPWL_EditCtrl::CanRedo() const
    621 {
    622 	return !IsReadOnly() && m_pEdit->CanRedo();
    623 }
    624 
    625 void CPWL_EditCtrl::Redo()
    626 {
    627 	if (CanRedo())
    628 		m_pEdit->Redo();
    629 }
    630 
    631 void CPWL_EditCtrl::Undo()
    632 {
    633 	if (CanUndo())
    634 		m_pEdit->Undo();
    635 }
    636 
    637 void CPWL_EditCtrl::IOnSetScrollInfoY(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax,
    638 												FX_FLOAT fContentMin, FX_FLOAT fContentMax,
    639 												FX_FLOAT fSmallStep, FX_FLOAT fBigStep)
    640 {
    641 	PWL_SCROLL_INFO Info;
    642 
    643 	Info.fPlateWidth = fPlateMax - fPlateMin;
    644 	Info.fContentMin = fContentMin;
    645 	Info.fContentMax = fContentMax;
    646 	Info.fSmallStep = fSmallStep;
    647 	Info.fBigStep = fBigStep;
    648 
    649 	this->OnNotify(this,PNM_SETSCROLLINFO,SBT_VSCROLL,(FX_INTPTR)&Info);
    650 
    651 //	PWL_TRACE("set scroll info:%f\n",fContentMax - fContentMin);
    652 
    653 	if (IsFloatBigger(Info.fPlateWidth,Info.fContentMax-Info.fContentMin)
    654 		|| IsFloatEqual(Info.fPlateWidth,Info.fContentMax-Info.fContentMin))
    655 	{
    656 		this->ShowVScrollBar(FALSE);
    657 	}
    658 	else
    659 	{
    660 		this->ShowVScrollBar(TRUE);
    661 	}
    662 }
    663 
    664 void CPWL_EditCtrl::IOnSetScrollPosY(FX_FLOAT fy)
    665 {
    666 //	PWL_TRACE("set scroll position:%f\n",fy);
    667 	this->OnNotify(this,PNM_SETSCROLLPOS,SBT_VSCROLL,(FX_INTPTR)&fy);
    668 }
    669 
    670 void CPWL_EditCtrl::IOnSetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPDF_Point & ptFoot, const CPVT_WordPlace& place)
    671 {
    672 	PWL_CARET_INFO cInfo;
    673 	cInfo.bVisible = bVisible;
    674 	cInfo.ptHead = ptHead;
    675 	cInfo.ptFoot = ptFoot;
    676 
    677 	this->OnNotify(this,PNM_SETCARETINFO,(FX_INTPTR)&cInfo,(FX_INTPTR)NULL);
    678 }
    679 
    680 void CPWL_EditCtrl::IOnCaretChange(const CPVT_SecProps & secProps, const CPVT_WordProps & wordProps)
    681 {
    682 }
    683 
    684 void CPWL_EditCtrl::IOnContentChange(const CPDF_Rect& rcContent)
    685 {
    686 	if (this->IsValid())
    687 	{
    688 		if (m_pEditNotify)
    689 		{
    690 			m_pEditNotify->OnContentChange(rcContent);
    691 		}
    692 	}
    693 }
    694 
    695 void CPWL_EditCtrl::IOnInvalidateRect(CPDF_Rect * pRect)
    696 {
    697 	this->InvalidateRect(pRect);
    698 }
    699 
    700 FX_INT32 CPWL_EditCtrl::GetCharSet() const
    701 {
    702 	if (m_nCharSet < 0)
    703 		return DEFAULT_CHARSET;
    704 	else
    705 		return m_nCharSet;
    706 }
    707 
    708 void CPWL_EditCtrl::GetTextRange(const CPDF_Rect& rect, FX_INT32 & nStartChar, FX_INT32 & nEndChar) const
    709 {
    710 	nStartChar = m_pEdit->WordPlaceToWordIndex(m_pEdit->SearchWordPlace(CPDF_Point(rect.left, rect.top)));
    711 	nEndChar = m_pEdit->WordPlaceToWordIndex(m_pEdit->SearchWordPlace(CPDF_Point(rect.right, rect.bottom)));
    712 }
    713 
    714 CFX_WideString CPWL_EditCtrl::GetText(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const
    715 {
    716 	CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStartChar);
    717 	CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEndChar);
    718 	return m_pEdit->GetRangeText(CPVT_WordRange(wpStart, wpEnd));
    719 }
    720 
    721 void	CPWL_EditCtrl::SetReadyToInput()
    722 {
    723 	if (m_bMouseDown)
    724 	{
    725 		ReleaseCapture();
    726 		m_bMouseDown = FALSE;
    727 	}
    728 }
    729