Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fwl / src / basewidget / fwl_editimp.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../../foxitlib.h"\r
8 #include "../core/include/fwl_threadimp.h"\r
9 #include "../core/include/fwl_appimp.h"\r
10 #include "../core/include/fwl_targetimp.h"\r
11 #include "../core/include/fwl_noteimp.h"\r
12 #include "../core/include/fwl_widgetimp.h"\r
13 #include "../core/include/fwl_widgetmgrimp.h"\r
14 #include "include/fwl_scrollbarimp.h"\r
15 #include "include/fwl_editimp.h"\r
16 #include "include/fwl_caretimp.h"\r
17 IFWL_Edit* IFWL_Edit::Create()\r
18 {\r
19     return new IFWL_Edit;\r
20 }\r
21 IFWL_Edit::IFWL_Edit()\r
22 {\r
23     m_pData = NULL;\r
24 }\r
25 IFWL_Edit::~IFWL_Edit()\r
26 {\r
27     if (m_pData) {\r
28         delete (CFWL_EditImp*)m_pData;\r
29         m_pData = NULL;\r
30     }\r
31 }\r
32 FWL_ERR IFWL_Edit::Initialize(IFWL_Widget *pOuter)\r
33 {\r
34     m_pData = FX_NEW CFWL_EditImp(pOuter);\r
35     ((CFWL_EditImp*)m_pData)->SetInterface(this);\r
36     return ((CFWL_EditImp*)m_pData)->Initialize();\r
37 }\r
38 FWL_ERR IFWL_Edit::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)\r
39 {\r
40     m_pData = FX_NEW CFWL_EditImp(properties, pOuter);\r
41     ((CFWL_EditImp*)m_pData)->SetInterface(this);\r
42     return ((CFWL_EditImp*)m_pData)->Initialize();\r
43 }\r
44 FWL_ERR IFWL_Edit::SetText(const CFX_WideString &wsText)\r
45 {\r
46     return ((CFWL_EditImp*)m_pData)->SetText(wsText);\r
47 }\r
48 FX_INT32 IFWL_Edit::GetTextLength() const\r
49 {\r
50     return ((CFWL_EditImp*)m_pData)->GetTextLength();\r
51 }\r
52 FWL_ERR IFWL_Edit::GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const\r
53 {\r
54     return ((CFWL_EditImp*)m_pData)->GetText(wsText, nStart, nCount);\r
55 }\r
56 FWL_ERR IFWL_Edit::ClearText()\r
57 {\r
58     return ((CFWL_EditImp*)m_pData)->ClearText();\r
59 }\r
60 FX_INT32 IFWL_Edit::GetCaretPos() const\r
61 {\r
62     return ((CFWL_EditImp*)m_pData)->GetCaretPos();\r
63 }\r
64 FX_INT32 IFWL_Edit::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore)\r
65 {\r
66     return ((CFWL_EditImp*)m_pData)->SetCaretPos(nIndex, bBefore);\r
67 }\r
68 FWL_ERR IFWL_Edit::AddSelRange(FX_INT32 nStart, FX_INT32 nCount)\r
69 {\r
70     return ((CFWL_EditImp*)m_pData)->AddSelRange(nStart, nCount);\r
71 }\r
72 FX_INT32 IFWL_Edit::CountSelRanges()\r
73 {\r
74     return ((CFWL_EditImp*)m_pData)->CountSelRanges();\r
75 }\r
76 FX_INT32 IFWL_Edit::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)\r
77 {\r
78     return ((CFWL_EditImp*)m_pData)->GetSelRange(nIndex, nStart);\r
79 }\r
80 FWL_ERR IFWL_Edit::ClearSelections()\r
81 {\r
82     return ((CFWL_EditImp*)m_pData)->ClearSelections();\r
83 }\r
84 FX_INT32 IFWL_Edit::GetLimit()\r
85 {\r
86     return ((CFWL_EditImp*)m_pData)->GetLimit();\r
87 }\r
88 FWL_ERR IFWL_Edit::SetLimit(FX_INT32 nLimit)\r
89 {\r
90     return ((CFWL_EditImp*)m_pData)->SetLimit(nLimit);\r
91 }\r
92 FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias)\r
93 {\r
94     return ((CFWL_EditImp*)m_pData)->SetAliasChar(wAlias);\r
95 }\r
96 FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString &wsFormat)\r
97 {\r
98     return ((CFWL_EditImp*)m_pData)->SetFormatString(wsFormat);\r
99 }\r
100 FWL_ERR IFWL_Edit::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen)\r
101 {\r
102     return ((CFWL_EditImp*)m_pData)->Insert(nStart, lpText, nLen);\r
103 }\r
104 FWL_ERR IFWL_Edit::DeleteSelections()\r
105 {\r
106     return ((CFWL_EditImp*)m_pData)->DeleteSelections();\r
107 }\r
108 FWL_ERR IFWL_Edit::DeleteRange(FX_INT32 nStart, FX_INT32 nCount)\r
109 {\r
110     return ((CFWL_EditImp*)m_pData)->DeleteRange(nStart, nCount);\r
111 }\r
112 FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC &wsReplace)\r
113 {\r
114     return ((CFWL_EditImp*)m_pData)->ReplaceSelections(wsReplace);\r
115 }\r
116 FWL_ERR IFWL_Edit::Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace)\r
117 {\r
118     return ((CFWL_EditImp*)m_pData)->Replace(nStart, nLen, wsReplace);\r
119 }\r
120 FWL_ERR IFWL_Edit::DoClipboard(FX_INT32 iCmd)\r
121 {\r
122     return ((CFWL_EditImp*)m_pData)->DoClipboard(iCmd);\r
123 }\r
124 FX_BOOL IFWL_Edit::Copy(CFX_WideString &wsCopy)\r
125 {\r
126     return ((CFWL_EditImp*)m_pData)->Copy(wsCopy);\r
127 }\r
128 FX_BOOL IFWL_Edit::Cut(CFX_WideString &wsCut)\r
129 {\r
130     return ((CFWL_EditImp*)m_pData)->Cut(wsCut);\r
131 }\r
132 FX_BOOL IFWL_Edit::Paste(const CFX_WideString &wsPaste)\r
133 {\r
134     return ((CFWL_EditImp*)m_pData)->Paste(wsPaste);\r
135 }\r
136 FX_BOOL IFWL_Edit::Delete()\r
137 {\r
138     return ((CFWL_EditImp*)m_pData)->Delete();\r
139 }\r
140 FX_BOOL IFWL_Edit::Redo(FX_BSTR bsRecord)\r
141 {\r
142     return ((CFWL_EditImp*)m_pData)->Redo(bsRecord);\r
143 }\r
144 FX_BOOL IFWL_Edit::Undo(FX_BSTR bsRecord)\r
145 {\r
146     return ((CFWL_EditImp*)m_pData)->Undo(bsRecord);\r
147 }\r
148 FX_BOOL IFWL_Edit::Undo()\r
149 {\r
150     return ((CFWL_EditImp*)m_pData)->Undo();\r
151 }\r
152 FX_BOOL IFWL_Edit::Redo()\r
153 {\r
154     return ((CFWL_EditImp*)m_pData)->Redo();\r
155 }\r
156 FX_BOOL IFWL_Edit::CanUndo()\r
157 {\r
158     return ((CFWL_EditImp*)m_pData)->CanUndo();\r
159 }\r
160 FX_BOOL IFWL_Edit::CanRedo()\r
161 {\r
162     return ((CFWL_EditImp*)m_pData)->CanRedo();\r
163 }\r
164 FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)\r
165 {\r
166     return ((CFWL_EditImp*)m_pData)->SetTabWidth(fTabWidth, bEquidistant);\r
167 }\r
168 FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget *pOuter)\r
169 {\r
170     return ((CFWL_EditImp*)m_pData)->SetOuter(pOuter);\r
171 }\r
172 FWL_ERR IFWL_Edit::SetNumberRange(FX_INT32 iMin, FX_INT32 iMax)\r
173 {\r
174     return ((CFWL_EditImp*)m_pData)->SetNumberRange(iMin, iMax);\r
175 }\r
176 FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor)\r
177 {\r
178     return ((CFWL_EditImp*)m_pData)->SetBackgroundColor(dwColor);\r
179 }\r
180 FWL_ERR IFWL_Edit::SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize)\r
181 {\r
182     return ((CFWL_EditImp*)m_pData)->SetFont(wsFont, fSize);\r
183 }\r
184 void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset)\r
185 {\r
186     return ((CFWL_EditImp*)m_pData)->SetScrollOffset(fScrollOffset);\r
187 }\r
188 FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)\r
189 {\r
190     return ((CFWL_EditImp*)m_pData)->GetSuggestWords(pointf, sSuggest);\r
191 }\r
192 FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)\r
193 {\r
194     return ((CFWL_EditImp*)m_pData)->ReplaceSpellCheckWord(pointf, bsReplace);\r
195 }\r
196 #define FWL_EDIT_Margin 3\r
197 CFWL_EditImp::CFWL_EditImp(IFWL_Widget *pOuter )\r
198     : CFWL_WidgetImp(pOuter)\r
199     , m_fVAlignOffset(0.0f)\r
200     , m_fScrollOffsetX(0.0f)\r
201     , m_fScrollOffsetY(0.0f)\r
202     , m_pEdtEngine(NULL)\r
203     , m_bLButtonDown(FALSE)\r
204     , m_nSelStart(0)\r
205     , m_nLimit(-1)\r
206     , m_fFontSize(0)\r
207     , m_pVertScrollBar(NULL)\r
208     , m_pHorzScrollBar(NULL)\r
209     , m_pCaret(NULL)\r
210     , m_iMin(-1)\r
211     , m_iMax(0xFFFFFFF)\r
212     , m_bSetRange(FALSE)\r
213     , m_pTextField(NULL)\r
214     , m_backColor(0)\r
215     , m_updateBackColor(FALSE)\r
216     , m_iCurRecord(-1)\r
217     , m_iMaxRecord(128)\r
218     , m_fSpaceAbove(0)\r
219     , m_fSpaceBelow(0)\r
220 {\r
221     m_rtClient.Reset();\r
222     m_rtEngine.Reset();\r
223     m_rtStatic.Reset();\r
224 }\r
225 CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )\r
226     : CFWL_WidgetImp(properties, pOuter)\r
227     , m_fVAlignOffset(0.0f)\r
228     , m_fScrollOffsetX(0.0f)\r
229     , m_fScrollOffsetY(0.0f)\r
230     , m_pEdtEngine(NULL)\r
231     , m_bLButtonDown(FALSE)\r
232     , m_nSelStart(0)\r
233     , m_nLimit(-1)\r
234     , m_fFontSize(0)\r
235     , m_pVertScrollBar(NULL)\r
236     , m_pHorzScrollBar(NULL)\r
237     , m_pCaret(NULL)\r
238     , m_iMin(-1)\r
239     , m_iMax(0xFFFFFFF)\r
240     , m_bSetRange(FALSE)\r
241     , m_pTextField(NULL)\r
242     , m_backColor(0)\r
243     , m_updateBackColor(FALSE)\r
244     , m_iCurRecord(-1)\r
245     , m_iMaxRecord(128)\r
246     , m_fSpaceAbove(0)\r
247     , m_fSpaceBelow(0)\r
248 {\r
249     m_rtClient.Reset();\r
250     m_rtEngine.Reset();\r
251     m_rtStatic.Reset();\r
252 }\r
253 CFWL_EditImp::~CFWL_EditImp()\r
254 {\r
255     if (m_pEdtEngine) {\r
256         m_pEdtEngine->Release();\r
257         m_pEdtEngine = NULL;\r
258     }\r
259     if (m_pHorzScrollBar) {\r
260         m_pHorzScrollBar->Release();\r
261         m_pHorzScrollBar = NULL;\r
262     }\r
263     if (m_pVertScrollBar) {\r
264         m_pVertScrollBar->Release();\r
265         m_pVertScrollBar = NULL;\r
266     }\r
267     if (m_pCaret) {\r
268         m_pCaret->Release();\r
269         m_pCaret = NULL;\r
270     }\r
271     ClearRecord();\r
272 }\r
273 FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString &wsClass) const\r
274 {\r
275     wsClass = FWL_CLASS_Edit;\r
276     return FWL_ERR_Succeeded;\r
277 }\r
278 FX_DWORD CFWL_EditImp::GetClassID() const\r
279 {\r
280     return FWL_CLASSHASH_Edit;\r
281 }\r
282 FWL_ERR CFWL_EditImp::Initialize()\r
283 {\r
284     _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);\r
285     if (!m_pDelegate) {\r
286         m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_EditImpDelegate(this);\r
287     }\r
288     InitCaret();\r
289     if (!m_pEdtEngine) {\r
290         InitEngine();\r
291     }\r
292     return FWL_ERR_Succeeded;\r
293 }\r
294 FWL_ERR CFWL_EditImp::Finalize()\r
295 {\r
296     if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {\r
297         ShowCaret(FALSE);\r
298     }\r
299     if (m_pHorzScrollBar) {\r
300         m_pHorzScrollBar->Finalize();\r
301     }\r
302     if (m_pVertScrollBar) {\r
303         m_pVertScrollBar->Finalize();\r
304     }\r
305     if ( m_pDelegate) {\r
306         delete (CFWL_EditImpDelegate*)m_pDelegate;\r
307         m_pDelegate = NULL;\r
308     }\r
309     return CFWL_WidgetImp::Finalize();\r
310 }\r
311 FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )\r
312 {\r
313     if (bAutoSize) {\r
314         rect.Set(0, 0, 0, 0);\r
315         if (m_pEdtEngine) {\r
316             FX_INT32 iTextLen = m_pEdtEngine->GetTextLength();\r
317             if (iTextLen > 0) {\r
318                 CFX_WideString wsText;\r
319                 m_pEdtEngine->GetText(wsText, 0);\r
320                 CFX_SizeF sz = CalcTextSize(wsText,\r
321                                             m_pProperties->m_pThemeProvider,\r
322                                             m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);\r
323                 rect.Set(0, 0, sz.x, sz.y);\r
324             }\r
325         }\r
326         CFWL_WidgetImp::GetWidgetRect(rect, TRUE);\r
327     } else {\r
328         rect = m_pProperties->m_rtWidget;\r
329         if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
330             if (IsShowScrollBar(TRUE)) {\r
331                 FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);\r
332                 rect.width += *pfWidth;\r
333                 rect.width += FWL_EDIT_Margin;\r
334             }\r
335             if (IsShowScrollBar(FALSE)) {\r
336                 FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);\r
337                 rect.height += *pfWidth;\r
338                 rect.height += FWL_EDIT_Margin;\r
339             }\r
340         }\r
341     }\r
342     return FWL_ERR_Succeeded;\r
343 }\r
344 FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )\r
345 {\r
346     if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
347         ShowCaret(FALSE);\r
348     }\r
349     return CFWL_WidgetImp::SetStates(dwStates, bSet);\r
350 }\r
351 FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF &rect)\r
352 {\r
353     return      CFWL_WidgetImp::SetWidgetRect(rect);\r
354 }\r
355 FWL_ERR CFWL_EditImp::Update()\r
356 {\r
357     if (IsLocked()) {\r
358         return FWL_ERR_Indefinite;\r
359     }\r
360     if (!m_pProperties->m_pThemeProvider) {\r
361         m_pProperties->m_pThemeProvider = GetAvailableTheme();\r
362     }\r
363     Layout();\r
364     if (m_rtClient.IsEmpty()) {\r
365         return FWL_ERR_Indefinite;\r
366     }\r
367     UpdateEditEngine();\r
368     UpdateVAlignment();\r
369     UpdateScroll();\r
370     InitCaret();\r
371     return FWL_ERR_Succeeded;\r
372 }\r
373 FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)\r
374 {\r
375     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
376         if (IsShowScrollBar(TRUE)) {\r
377             CFX_RectF rect;\r
378             m_pVertScrollBar->GetWidgetRect(rect);\r
379             if (rect.Contains(fx, fy)) {\r
380                 return FWL_WGTHITTEST_VScrollBar;\r
381             }\r
382         }\r
383         if (IsShowScrollBar(FALSE)) {\r
384             CFX_RectF rect;\r
385             m_pHorzScrollBar->GetWidgetRect(rect);\r
386             if (rect.Contains(fx, fy)) {\r
387                 return FWL_WGTHITTEST_HScrollBar;\r
388             }\r
389         }\r
390     }\r
391     if (m_rtClient.Contains(fx, fy)) {\r
392         return FWL_WGTHITTEST_Edit;\r
393     }\r
394     return FWL_WGTHITTEST_Unknown;\r
395 }\r
396 #define FX_EDIT_ISLATINWORD(u)  (u == 0x2D || (u <= 0x005A && u >= 0x0041) || (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || u == 0x0027)\r
397 static void AddSquigglyPath(CFX_Path& PathData, FX_FLOAT fStartX, FX_FLOAT fEndX, FX_FLOAT fY, FX_FLOAT fStep)\r
398 {\r
399     PathData.MoveTo(fStartX, fY);\r
400     FX_FLOAT fx;\r
401     FX_INT32 i;\r
402     for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {\r
403         PathData.LineTo(fx, fY + (i & 1)*fStep);\r
404     }\r
405 }\r
406 void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData, FX_INT32 nStart, FX_INT32 nCount, FX_FLOAT fOffSetX, FX_FLOAT fOffSetY)\r
407 {\r
408     FX_FLOAT fStartX = 0.0f;\r
409     FX_FLOAT fEndX = 0.0f;\r
410     FX_FLOAT fY = 0.0f;\r
411     FX_FLOAT fStep = 0.0f;\r
412     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
413     CFX_RectFArray rectArray;\r
414     CFX_RectF rectText;\r
415     const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();\r
416     FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() * txtEdtParams->fFontSize / 1000;\r
417     pPage->CalcRangeRectArray(nStart, nCount, rectArray);\r
418     for (int i = 0; i < rectArray.GetSize(); i++) {\r
419         rectText = rectArray.GetAt(i);\r
420         fY = rectText.top + fAsent + fOffSetY;\r
421         fStep = txtEdtParams->fFontSize / 16.0f;\r
422         fStartX = rectText.left + fOffSetX;\r
423         fEndX = fStartX + rectText.Width();\r
424         AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);\r
425     }\r
426 }\r
427 FX_INT32 CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, FX_INT32& nCount)\r
428 {\r
429     return 0;\r
430 }\r
431 FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)\r
432 {\r
433     FX_INT32 nWordCount = 0;\r
434     FX_INT32 nWordStart = GetWordAtPoint(pointf, nWordCount);\r
435     if (nWordCount < 1) {\r
436         return FALSE;\r
437     }\r
438     CFX_WideString wsSpell;\r
439     GetText(wsSpell, nWordStart, nWordCount);\r
440     CFX_ByteString sLatinWord;\r
441     for (int i = 0; i < nWordCount; i++) {\r
442         if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {\r
443             break;\r
444         }\r
445         sLatinWord += (FX_CHAR)wsSpell[i];\r
446     }\r
447     if (sLatinWord.IsEmpty()) {\r
448         return FALSE;\r
449     }\r
450     CFWL_EvtEdtCheckWord checkWordEvent;\r
451     checkWordEvent.m_pSrcTarget = m_pInterface;\r
452     checkWordEvent.bsWord = sLatinWord;\r
453     checkWordEvent.bCheckWord = TRUE;\r
454     DispatchEvent(&checkWordEvent);\r
455     if (checkWordEvent.bCheckWord) {\r
456         return FALSE;\r
457     }\r
458     CFWL_EvtEdtGetSuggestWords suggestWordsEvent;\r
459     suggestWordsEvent.m_pSrcTarget = m_pInterface;\r
460     suggestWordsEvent.bsWord = sLatinWord;\r
461     suggestWordsEvent.bsArraySuggestWords = sSuggest;\r
462     suggestWordsEvent.bSuggestWords = FALSE;\r
463     DispatchEvent(&checkWordEvent);\r
464     return suggestWordsEvent.bSuggestWords;\r
465 }\r
466 FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)\r
467 {\r
468     FX_INT32 nWordCount = 0;\r
469     FX_INT32 nWordStart = GetWordAtPoint(pointf, nWordCount);\r
470     if (nWordCount < 1) {\r
471         return FALSE;\r
472     }\r
473     CFX_WideString wsSpell;\r
474     GetText(wsSpell, nWordStart, nWordCount);\r
475     for (int i = 0; i < nWordCount; i++) {\r
476         if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {\r
477             nWordCount = i;\r
478             break;\r
479         }\r
480     }\r
481     FX_INT32 nDestLen = bsReplace.GetLength();\r
482     CFX_WideString wsDest;\r
483     FX_LPWSTR pBuffer = wsDest.GetBuffer(nDestLen);\r
484     for (FX_INT32 i = 0; i < nDestLen; i++) {\r
485         pBuffer[i] = bsReplace[i];\r
486     }\r
487     wsDest.ReleaseBuffer(nDestLen);\r
488     Replace(nWordStart, nWordCount, wsDest);\r
489     return TRUE;\r
490 }\r
491 void CFWL_EditImp::DrawSpellCheck(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
492 {\r
493     pGraphics->SaveGraphState();\r
494     if (pMatrix) {\r
495         pGraphics->ConcatMatrix((CFX_Matrix*)pMatrix);\r
496     }\r
497     FX_ARGB cr = 0xFFFF0000;\r
498     CFX_Color crLine(cr);\r
499     FX_FLOAT fWidth = 1.0f;\r
500     CFWL_EvtEdtCheckWord checkWordEvent;\r
501     checkWordEvent.m_pSrcTarget = m_pInterface;\r
502     CFX_ByteString sLatinWord;\r
503     CFX_Path pathSpell;\r
504     pathSpell.Create();\r
505     FX_INT32 nStart = 0;\r
506     FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;\r
507     FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;\r
508     CFX_WideString wsSpell;\r
509     this->GetText(wsSpell);\r
510     FX_INT32 nContentLen = wsSpell.GetLength();\r
511     for (int i = 0; i < nContentLen; i++) {\r
512         if (FX_EDIT_ISLATINWORD(wsSpell[i])) {\r
513             if (sLatinWord.IsEmpty()) {\r
514                 nStart = i;\r
515             }\r
516             sLatinWord += (FX_CHAR)wsSpell[i];\r
517         } else {\r
518             checkWordEvent.bsWord = sLatinWord;\r
519             checkWordEvent.bCheckWord = TRUE;\r
520             DispatchEvent(&checkWordEvent);\r
521             if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {\r
522                 AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, fOffSetY);\r
523             }\r
524             sLatinWord.Empty();\r
525         }\r
526     }\r
527     checkWordEvent.bsWord = sLatinWord;\r
528     checkWordEvent.bCheckWord = TRUE;\r
529     DispatchEvent(&checkWordEvent);\r
530     if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {\r
531         AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, fOffSetY);\r
532     }\r
533     if (!pathSpell.IsEmpty()) {\r
534         CFX_RectF rtClip = m_rtEngine;\r
535         CFX_Matrix mt;\r
536         mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);\r
537         if (pMatrix) {\r
538             pMatrix->TransformRect(rtClip);\r
539             mt.Concat(*pMatrix);\r
540         }\r
541         pGraphics->SetClipRect(rtClip);\r
542         pGraphics->SetStrokeColor(&crLine);\r
543         pGraphics->SetLineWidth(0);\r
544         pGraphics->StrokePath(&pathSpell, NULL);\r
545     }\r
546     pGraphics->RestoreGraphState();\r
547 }\r
548 FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )\r
549 {\r
550     _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);\r
551     _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);\r
552     if (m_rtClient.IsEmpty()) {\r
553         return FWL_ERR_Indefinite;\r
554     }\r
555     IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;\r
556     if (!m_pWidgetMgr->IsFormDisabled()) {\r
557         DrawTextBk(pGraphics, pTheme, pMatrix);\r
558     }\r
559     if (m_pEdtEngine) {\r
560         DrawContent(pGraphics, pTheme, pMatrix);\r
561     }\r
562     if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) {\r
563         DrawSpellCheck(pGraphics, pMatrix);\r
564     }\r
565     if (HasBorder()) {\r
566         DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix);\r
567     }\r
568     if (HasEdge()) {\r
569         DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix);\r
570     }\r
571     return FWL_ERR_Succeeded;\r
572 }\r
573 FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)\r
574 {\r
575     _FWL_RETURN_VALUE_IF_FAIL(pThemeProvider, FWL_ERR_Indefinite);\r
576     if (m_pHorzScrollBar) {\r
577         m_pHorzScrollBar->SetThemeProvider(pThemeProvider);\r
578     }\r
579     if (m_pVertScrollBar) {\r
580         m_pVertScrollBar->SetThemeProvider(pThemeProvider);\r
581     }\r
582     if (m_pCaret) {\r
583         m_pCaret->SetThemeProvider(pThemeProvider);\r
584     }\r
585     m_pProperties->m_pThemeProvider = pThemeProvider;\r
586     return FWL_ERR_Succeeded;\r
587 }\r
588 FWL_ERR CFWL_EditImp::SetText(const CFX_WideString &wsText)\r
589 {\r
590     m_pEdtEngine->SetText(wsText);\r
591     return FWL_ERR_Succeeded;\r
592 }\r
593 FX_INT32 CFWL_EditImp::GetTextLength() const\r
594 {\r
595     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);\r
596     return m_pEdtEngine->GetTextLength();\r
597 }\r
598 FWL_ERR CFWL_EditImp::GetText(CFX_WideString &wsText, FX_INT32 nStart , FX_INT32 nCount ) const\r
599 {\r
600     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
601     m_pEdtEngine->GetText(wsText, nStart, nCount);\r
602     return FWL_ERR_Succeeded;\r
603 }\r
604 FWL_ERR CFWL_EditImp::ClearText()\r
605 {\r
606     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
607     m_pEdtEngine->ClearText();\r
608     return FWL_ERR_Succeeded;\r
609 }\r
610 FX_INT32 CFWL_EditImp::GetCaretPos() const\r
611 {\r
612     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);\r
613     return m_pEdtEngine->GetCaretPos();\r
614 }\r
615 FX_INT32 CFWL_EditImp::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore )\r
616 {\r
617     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);\r
618     return m_pEdtEngine->SetCaretPos(nIndex, bBefore);\r
619 }\r
620 FWL_ERR CFWL_EditImp::AddSelRange(FX_INT32 nStart, FX_INT32 nCount )\r
621 {\r
622     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
623     m_pEdtEngine->AddSelRange(nStart, nCount);\r
624     return FWL_ERR_Succeeded;\r
625 }\r
626 FX_INT32 CFWL_EditImp::CountSelRanges()\r
627 {\r
628     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, 0);\r
629     return m_pEdtEngine->CountSelRanges();\r
630     return FWL_ERR_Succeeded;\r
631 }\r
632 FX_INT32 CFWL_EditImp::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)\r
633 {\r
634     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);\r
635     return m_pEdtEngine->GetSelRange(nIndex, nStart);\r
636 }\r
637 FWL_ERR CFWL_EditImp::ClearSelections()\r
638 {\r
639     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
640     m_pEdtEngine->ClearSelection();\r
641     return FWL_ERR_Succeeded;\r
642 }\r
643 FX_INT32 CFWL_EditImp::GetLimit()\r
644 {\r
645     return m_nLimit;\r
646 }\r
647 FWL_ERR CFWL_EditImp::SetLimit(FX_INT32 nLimit)\r
648 {\r
649     m_nLimit = nLimit;\r
650     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
651     m_pEdtEngine->SetLimit(nLimit);\r
652     return FWL_ERR_Succeeded;\r
653 }\r
654 FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias)\r
655 {\r
656     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Indefinite);\r
657     m_pEdtEngine->SetAliasChar(wAlias);\r
658     return FWL_ERR_Succeeded;\r
659 }\r
660 FWL_ERR CFWL_EditImp::SetFormatString(const CFX_WideString &wsFormat)\r
661 {\r
662     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
663     m_pEdtEngine->SetFormatBlock(0, wsFormat);\r
664     return FWL_ERR_Succeeded;\r
665 }\r
666 FWL_ERR CFWL_EditImp::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen)\r
667 {\r
668     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
669     if (        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)\r
670             || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
671         return FWL_ERR_Indefinite;\r
672     }\r
673     m_pEdtEngine->Insert(nStart, lpText, nLen);\r
674     return FWL_ERR_Succeeded;\r
675 }\r
676 FWL_ERR CFWL_EditImp::DeleteSelections()\r
677 {\r
678     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
679     FX_INT32 iCount = m_pEdtEngine->CountSelRanges();\r
680     if (iCount > 0) {\r
681         m_pEdtEngine->Delete(-1);\r
682     }\r
683     return FWL_ERR_Succeeded;\r
684 }\r
685 FWL_ERR CFWL_EditImp::DeleteRange(FX_INT32 nStart, FX_INT32 nCount )\r
686 {\r
687     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
688     m_pEdtEngine->DeleteRange(nStart, nCount);\r
689     return FWL_ERR_Succeeded;\r
690 }\r
691 FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC &wsReplace)\r
692 {\r
693     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
694     FX_INT32 iCount = m_pEdtEngine->CountSelRanges();\r
695     for (int i = 0; i < iCount; i ++) {\r
696         FX_INT32 nStart;\r
697         FX_INT32 nCount = m_pEdtEngine->GetSelRange(i, nStart);\r
698         m_pEdtEngine->Replace(nStart, nCount, wsReplace);\r
699     }\r
700     return FWL_ERR_Succeeded;\r
701 }\r
702 FWL_ERR CFWL_EditImp::Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace)\r
703 {\r
704     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
705     m_pEdtEngine->Replace(nStart, nLen, wsReplace);\r
706     return FWL_ERR_Succeeded;\r
707 }\r
708 FWL_ERR CFWL_EditImp::DoClipboard(FX_INT32 iCmd)\r
709 {\r
710     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
711     if (        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)\r
712             ||  (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
713         return FWL_ERR_Succeeded;\r
714     }\r
715     IFWL_AdapterNative *pNative = FWL_GetAdapterNative();\r
716     _FWL_RETURN_VALUE_IF_FAIL(pNative, FWL_ERR_Indefinite);\r
717     IFWL_AdapterClipboardMgr *pClipBorder = pNative->GetClipboardMgr();\r
718     _FWL_RETURN_VALUE_IF_FAIL(pClipBorder, FWL_ERR_Indefinite);\r
719     CFX_WideString wsText;\r
720     switch(iCmd) {\r
721         case 1: {\r
722                 FX_INT32 nStart;\r
723                 FX_INT32 nCount = m_pEdtEngine->GetSelRange(0, nStart);\r
724                 if (nCount < 1) {\r
725                     break;\r
726                 }\r
727                 m_pEdtEngine->GetText(wsText, nStart, nCount);\r
728                 pClipBorder->SetStringData(wsText);\r
729                 break;\r
730             }\r
731         case 2: {\r
732                 FX_INT32 nStart;\r
733                 FX_INT32 nCount = m_pEdtEngine->GetSelRange(0, nStart);\r
734                 if (nCount < 1) {\r
735                     break;\r
736                 }\r
737                 m_pEdtEngine->GetText(wsText, nStart, nCount);\r
738                 m_pEdtEngine->DeleteRange(nStart, nCount);\r
739                 m_pEdtEngine->ClearSelection();\r
740                 pClipBorder->SetStringData(wsText);\r
741                 break;\r
742             }\r
743         case 3: {\r
744                 pClipBorder->GetStringData(wsText);\r
745                 FX_INT32 iLen = wsText.GetLength();\r
746                 if (iLen < 0) {\r
747                     break;\r
748                 }\r
749                 if (wsText[iLen] == L'\0') {\r
750                     if (iLen == 1) {\r
751                         break;\r
752                     }\r
753                     iLen --;\r
754                     wsText = wsText.Left(iLen);\r
755                 }\r
756                 FX_INT32 nPos = m_pEdtEngine->GetCaretPos();\r
757                 m_pEdtEngine->Insert(nPos, wsText, iLen);\r
758                 break;\r
759             }\r
760         default: {\r
761             }\r
762     }\r
763     return FWL_ERR_Succeeded;\r
764 }\r
765 FX_BOOL CFWL_EditImp::Copy(CFX_WideString &wsCopy)\r
766 {\r
767     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
768     FX_INT32 nCount = m_pEdtEngine->CountSelRanges();\r
769     if (nCount == 0) {\r
770         return FALSE;\r
771     }\r
772     wsCopy.Empty();\r
773     CFX_WideString wsTemp;\r
774     FX_INT32 nStart, nLength;\r
775     for (FX_INT32 i = 0; i < nCount; i ++) {\r
776         nLength = m_pEdtEngine->GetSelRange(i, nStart);\r
777         m_pEdtEngine->GetText(wsTemp, nStart, nLength);\r
778         wsCopy += wsTemp;\r
779         wsTemp.Empty();\r
780     }\r
781     return TRUE;\r
782 }\r
783 FX_BOOL CFWL_EditImp::Cut(CFX_WideString &wsCut)\r
784 {\r
785     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
786     FX_INT32 nCount = m_pEdtEngine->CountSelRanges();\r
787     if (nCount == 0) {\r
788         return FALSE;\r
789     }\r
790     wsCut.Empty();\r
791     CFX_WideString wsTemp;\r
792     FX_INT32 nStart, nLength;\r
793     for (FX_INT32 i = 0; i < nCount; i ++) {\r
794         nLength = m_pEdtEngine->GetSelRange(i, nStart);\r
795         m_pEdtEngine->GetText(wsTemp, nStart, nLength);\r
796         wsCut += wsTemp;\r
797         wsTemp.Empty();\r
798     }\r
799     m_pEdtEngine->Delete(0);\r
800     return TRUE;\r
801 }\r
802 FX_BOOL CFWL_EditImp::Paste(const CFX_WideString &wsPaste)\r
803 {\r
804     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
805     FX_INT32 nCaret = m_pEdtEngine->GetCaretPos();\r
806     FX_INT32 iError = m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(wsPaste), wsPaste.GetLength());\r
807     if (iError < 0) {\r
808         ProcessInsertError(iError);\r
809         return FALSE;\r
810     }\r
811     return TRUE;\r
812 }\r
813 FX_BOOL CFWL_EditImp::Delete()\r
814 {\r
815     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
816     FX_INT32 nCount = m_pEdtEngine->CountSelRanges();\r
817     if (nCount < 1) {\r
818         return FALSE;\r
819     }\r
820     m_pEdtEngine->Delete(0);\r
821     return TRUE;\r
822 }\r
823 FX_BOOL CFWL_EditImp::Redo(FX_BSTR bsRecord)\r
824 {\r
825     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
826     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {\r
827         return TRUE;\r
828     }\r
829     return m_pEdtEngine->Redo(bsRecord);\r
830 }\r
831 FX_BOOL CFWL_EditImp::Undo(FX_BSTR bsRecord)\r
832 {\r
833     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
834     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {\r
835         return TRUE;\r
836     }\r
837     return m_pEdtEngine->Undo(bsRecord);\r
838 }\r
839 FX_BOOL CFWL_EditImp::Undo()\r
840 {\r
841     if (!CanUndo()) {\r
842         return FALSE;\r
843     }\r
844     CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];\r
845     return Undo(bsRecord);\r
846 }\r
847 FX_BOOL CFWL_EditImp::Redo()\r
848 {\r
849     if (!CanRedo()) {\r
850         return FALSE;\r
851     }\r
852     CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];\r
853     return Redo(bsRecord);\r
854 }\r
855 FX_BOOL CFWL_EditImp::CanUndo()\r
856 {\r
857     return m_iCurRecord >= 0;\r
858 }\r
859 FX_BOOL CFWL_EditImp::CanRedo()\r
860 {\r
861     return m_iCurRecord < m_RecordArr.GetSize() - 1;\r
862 }\r
863 FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)\r
864 {\r
865     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);\r
866     FDE_LPTXTEDTPARAMS pParams = (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams();\r
867     pParams->fTabWidth = fTabWidth;\r
868     pParams->bTabEquidistant = bEquidistant;\r
869     return FWL_ERR_Succeeded;\r
870 }\r
871 FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget *pOuter)\r
872 {\r
873     m_pOuter = pOuter;\r
874     return FWL_ERR_Succeeded;\r
875 }\r
876 FWL_ERR CFWL_EditImp::SetNumberRange(FX_INT32 iMin, FX_INT32 iMax)\r
877 {\r
878     m_iMin = iMin;\r
879     m_iMax = iMax;\r
880     m_bSetRange = TRUE;\r
881     return FWL_ERR_Succeeded;\r
882 }\r
883 void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPage, FX_BOOL bVisible )\r
884 {\r
885     if (m_rtEngine.IsEmpty()) {\r
886         return;\r
887     }\r
888     if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {\r
889         return;\r
890     }\r
891     FX_BOOL bRepaintContent = UpdateOffset();\r
892     UpdateCaret();\r
893     CFX_RectF rtInvalid;\r
894     rtInvalid.Set(0, 0, 0, 0);\r
895     FX_BOOL bRepaintScroll = FALSE;\r
896     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {\r
897         IFWL_ScrollBar *pScroll = UpdateScroll();\r
898         if (pScroll) {\r
899             pScroll->GetWidgetRect(rtInvalid);\r
900             bRepaintScroll = TRUE;\r
901         }\r
902     }\r
903     if (bRepaintContent || bRepaintScroll) {\r
904         if (bRepaintContent) {\r
905             rtInvalid.Union(m_rtEngine);\r
906         }\r
907         Repaint(&rtInvalid);\r
908     }\r
909 }\r
910 void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine *pEdit, FDE_TXTEDT_TEXTCHANGE_INFO &ChangeInfo)\r
911 {\r
912     FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes;\r
913     if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) {\r
914         UpdateVAlignment();\r
915     }\r
916     IFDE_TxtEdtPage *page = m_pEdtEngine->GetPage(0);\r
917     FX_FLOAT fContentWidth = page->GetContentsBox().width;\r
918     FX_FLOAT fContentHeight = page->GetContentsBox().height;\r
919     CFX_RectF rtTemp;\r
920     GetClientRect(rtTemp);\r
921     FX_BOOL bHSelfAdaption = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;\r
922     FX_BOOL bVSelfAdaption = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;\r
923     FX_BOOL bNeedUpdate = FALSE;\r
924     if (bHSelfAdaption || bVSelfAdaption) {\r
925         CFWL_EvtEdtPreSelfAdaption evt;\r
926         evt.m_pSrcTarget = m_pInterface;\r
927         evt.bHSelfAdaption = TRUE;\r
928         evt.bVSelfAdaption = TRUE;\r
929         FX_FLOAT fWidth;\r
930         FX_FLOAT fHight;\r
931         fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;\r
932         fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;\r
933         evt.rtAfterChange.Set(0, 0, fWidth, fHight);\r
934         DispatchEvent(&evt);\r
935         if (!evt.bHSelfAdaption) {\r
936             ModifyStylesEx(0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);\r
937         }\r
938         if (!evt.bVSelfAdaption) {\r
939             ModifyStylesEx(0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);\r
940         }\r
941         bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) || (bVSelfAdaption && !evt.bVSelfAdaption);\r
942     }\r
943     FX_FLOAT fContentWidth1 = fContentWidth;\r
944     FX_FLOAT fContentHeight1 = fContentHeight;\r
945     if (bNeedUpdate) {\r
946         UpdateEditParams();\r
947         UpdateEditLayout();\r
948         IFDE_TxtEdtPage *page1 = m_pEdtEngine->GetPage(0);\r
949         fContentWidth1 = page1->GetContentsBox().width;\r
950         fContentHeight1 = page1->GetContentsBox().height;\r
951     }\r
952     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {\r
953         rtTemp.width = FX_MAX(m_pProperties->m_rtWidget.width, fContentWidth1);\r
954         m_pProperties->m_rtWidget.width = fContentWidth1;\r
955     }\r
956     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {\r
957         rtTemp.height = FX_MAX(m_pProperties->m_rtWidget.height, fContentHeight1);\r
958         m_pProperties->m_rtWidget.height = fContentHeight1;\r
959     }\r
960     CFWL_EvtEdtTextChanged event;\r
961     event.m_pSrcTarget = m_pInterface;\r
962     event.nChangeType = ChangeInfo.nChangeType;\r
963     event.wsInsert = ChangeInfo.wsInsert;\r
964     event.wsDelete = ChangeInfo.wsDelete;\r
965     event.wsPrevText = ChangeInfo.wsPrevText;\r
966     DispatchEvent(&event);\r
967     LayoutScrollBar();\r
968     Repaint(&rtTemp);\r
969 }\r
970 void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine *pEdit)\r
971 {\r
972     CFX_RectF rtTemp;\r
973     GetClientRect(rtTemp);\r
974     Repaint(&rtTemp);\r
975 }\r
976 FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose)\r
977 {\r
978     IFDE_TxtEdtEngine *pEdtEngine = m_pEdtEngine;\r
979     IFDE_TxtEdtPage *pPage = pEdtEngine->GetPage(nPageIndex);\r
980     _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);\r
981     pPage->LoadPage();\r
982     return TRUE;\r
983 }\r
984 FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose)\r
985 {\r
986     IFDE_TxtEdtEngine *pEdtEngine = m_pEdtEngine;\r
987     IFDE_TxtEdtPage *pPage = pEdtEngine->GetPage(nPageIndex);\r
988     _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);\r
989     pPage->UnloadPage();\r
990     return TRUE;\r
991 }\r
992 void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine *pEdit, FX_BSTR bsDoRecord)\r
993 {\r
994     AddDoRecord(bsDoRecord);\r
995     CFWL_WidgetImp *pSrcTarget = GetRootOuter();\r
996     if (!pSrcTarget) {\r
997         pSrcTarget = this;\r
998     }\r
999     CFWL_EvtEdtAddDoRecord evt;\r
1000     evt.m_pSrcTarget = m_pInterface;\r
1001     evt.m_wsDoRecord = bsDoRecord;\r
1002     m_pDelegate->OnProcessEvent(&evt);\r
1003 }\r
1004 FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, \\r
1005                                        const CFX_WideString &wsFieldText, FX_INT32 nCharIndex)\r
1006 {\r
1007     return TRUE;\r
1008 }\r
1009 FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex)\r
1010 {\r
1011     return TRUE;\r
1012 }\r
1013 FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, CFX_WideString &wsBlockText)\r
1014 {\r
1015     return FALSE;\r
1016 }\r
1017 FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine * pEdit, CFX_WideString &wsText)\r
1018 {\r
1019     IFWL_Widget *pDst = GetOuter();\r
1020     if (!pDst) {\r
1021         pDst = (IFWL_Widget*)this;\r
1022     }\r
1023     CFWL_EvtEdtValidate event;\r
1024     event.pDstWidget = pDst;\r
1025     event.m_pSrcTarget = m_pInterface;\r
1026     event.wsInsert = wsText;\r
1027     event.bValidate = TRUE;\r
1028     DispatchEvent(&event);\r
1029     return event.bValidate;\r
1030 }\r
1031 FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color)\r
1032 {\r
1033     m_backColor = color;\r
1034     m_updateBackColor = TRUE;\r
1035     return FWL_ERR_Succeeded;\r
1036 }\r
1037 FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize)\r
1038 {\r
1039     m_wsFont = wsFont;\r
1040     m_fFontSize = fSize;\r
1041     return FWL_ERR_Succeeded;\r
1042 }\r
1043 void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset)\r
1044 {\r
1045     m_fScrollOffsetY = fScrollOffset;\r
1046 }\r
1047 void CFWL_EditImp::DrawTextBk(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )\r
1048 {\r
1049     CFWL_ThemeBackground param;\r
1050     param.m_pWidget = m_pInterface;\r
1051     param.m_iPart = FWL_PART_EDT_Background;\r
1052     param.m_dwData = FWL_PARTDATA_EDT_Background;\r
1053     param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly ?\r
1054                        FWL_PARTSTATE_EDT_ReadOnly : FWL_PARTSTATE_EDT_Normal;\r
1055     FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled);\r
1056     if ( dwStates) {\r
1057         param.m_dwStates = FWL_PARTSTATE_EDT_Disable;\r
1058     }\r
1059     param.m_pGraphics = pGraphics;\r
1060     param.m_matrix = *pMatrix;\r
1061     param.m_rtPart = m_rtClient;\r
1062     pTheme->DrawBackground(&param);\r
1063     if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) {\r
1064         return;\r
1065     }\r
1066     CFX_RectF rtScorll;\r
1067     m_pHorzScrollBar->GetWidgetRect(rtScorll);\r
1068     FX_FLOAT fStaticWidth = rtScorll.height;\r
1069     CFX_RectF rtStatic;\r
1070     rtStatic.Set(m_rtClient.right() - rtScorll.height,\r
1071                  m_rtClient.bottom() - rtScorll.height,\r
1072                  rtScorll.height,\r
1073                  rtScorll.height);\r
1074     param.m_dwData = FWL_PARTDATA_EDT_StaticBackground;\r
1075     param.m_rtPart = rtStatic;\r
1076     pTheme->DrawBackground(&param);\r
1077 }\r
1078 void CFWL_EditImp::DrawContent(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )\r
1079 {\r
1080     _FWL_RETURN_IF_FAIL(m_pEdtEngine);\r
1081     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1082     _FWL_RETURN_IF_FAIL(pPage);\r
1083     pGraphics->SaveGraphState();\r
1084     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {\r
1085         pGraphics->SaveGraphState();\r
1086     }\r
1087     CFX_RectF rtClip = m_rtEngine;\r
1088     FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;\r
1089     FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;\r
1090     CFX_Matrix mt;\r
1091     mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);\r
1092     if (pMatrix) {\r
1093         pMatrix->TransformRect(rtClip);\r
1094         mt.Concat(*pMatrix);\r
1095     }\r
1096     FX_BOOL bShowSel = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) || (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);\r
1097     if (bShowSel) {\r
1098         IFWL_Widget *pForm = m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);\r
1099         if (pForm) {\r
1100             bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) != FWL_WGTSTATE_Deactivated;\r
1101         }\r
1102     }\r
1103     FX_INT32 nSelCount = m_pEdtEngine->CountSelRanges();\r
1104     if (bShowSel && nSelCount > 0) {\r
1105         FX_INT32 nPageCharStart = pPage->GetCharStart();\r
1106         FX_INT32 nPageCharCount = pPage->GetCharCount();\r
1107         FX_INT32 nPageCharEnd   = nPageCharStart + nPageCharCount - 1;\r
1108         FX_INT32 nCharCount;\r
1109         FX_INT32 nCharStart;\r
1110         CFX_RectFArray rectArr;\r
1111         FX_INT32 i = 0;\r
1112         for (i = 0; i < nSelCount; i ++) {\r
1113             nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart);\r
1114             FX_INT32 nCharEnd = nCharStart + nCharCount - 1;\r
1115             if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) {\r
1116                 continue;\r
1117             }\r
1118             FX_INT32 nBgn = FX_MAX(nCharStart, nPageCharStart);\r
1119             FX_INT32 nEnd = FX_MIN(nCharEnd, nPageCharEnd);\r
1120             pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, rectArr);\r
1121         }\r
1122         FX_INT32 nCount = rectArr.GetSize();\r
1123         CFX_Path path;\r
1124         path.Create();\r
1125         for (i = 0; i < nCount; i ++) {\r
1126             rectArr[i].left += fOffSetX;\r
1127             rectArr[i].top += fOffSetY;\r
1128             path.AddRectangle(rectArr[i].left,\r
1129                               rectArr[i].top,\r
1130                               rectArr[i].width,\r
1131                               rectArr[i].height);\r
1132         }\r
1133         pGraphics->SetClipRect(rtClip);\r
1134         CFWL_ThemeBackground param;\r
1135         param.m_pGraphics = pGraphics;\r
1136         param.m_matrix = *pMatrix;\r
1137         param.m_pWidget = m_pInterface;\r
1138         param.m_iPart = FWL_PART_EDT_Background;\r
1139         param.m_pPath = &path;\r
1140         pTheme->DrawBackground(&param);\r
1141     }\r
1142     CFX_RenderDevice *pRenderDev = pGraphics->GetRenderDevice();\r
1143     _FWL_RETURN_IF_FAIL(pRenderDev);\r
1144     IFDE_RenderDevice *pRenderDevice = IFDE_RenderDevice::Create(pRenderDev);\r
1145     _FWL_RETURN_IF_FAIL(pRenderDevice);\r
1146     IFDE_RenderContext *pRenderContext = IFDE_RenderContext::Create();\r
1147     _FWL_RETURN_IF_FAIL(pRenderContext);\r
1148     pRenderDevice->SetClipRect(rtClip);\r
1149     pRenderContext->StartRender(pRenderDevice, (IFDE_CanvasSet*)pPage, mt);\r
1150     pRenderContext->DoRender(NULL);\r
1151     pRenderContext->Release();\r
1152     pRenderDevice->Release();\r
1153     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {\r
1154         pGraphics->RestoreGraphState();\r
1155         CFX_Path path;\r
1156         path.Create();\r
1157         FX_INT32 iLimit = m_nLimit > 0 ? m_nLimit : 1;\r
1158         FX_FLOAT fStep = m_rtEngine.width / iLimit;\r
1159         FX_FLOAT fLeft = m_rtEngine.left + 1;\r
1160         for (FX_INT32 i = 1; i < iLimit; i++) {\r
1161             fLeft += fStep;\r
1162             path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom());\r
1163         }\r
1164         CFWL_ThemeBackground param;\r
1165         param.m_pGraphics = pGraphics;\r
1166         param.m_matrix = *pMatrix;\r
1167         param.m_pWidget = m_pInterface;\r
1168         param.m_iPart = FWL_PART_EDT_CombTextLine;\r
1169         param.m_pPath = &path;\r
1170         pTheme->DrawBackground(&param);\r
1171     }\r
1172     pGraphics->RestoreGraphState();\r
1173 }\r
1174 void CFWL_EditImp::UpdateEditEngine()\r
1175 {\r
1176     UpdateEditParams();\r
1177     UpdateEditLayout();\r
1178     if (m_nLimit > -1) {\r
1179         m_pEdtEngine->SetLimit(m_nLimit);\r
1180     }\r
1181 }\r
1182 void CFWL_EditImp::UpdateEditParams()\r
1183 {\r
1184     FDE_TXTEDTPARAMS params;\r
1185     params.nHorzScale = 100;\r
1186     params.fPlateWidth = m_rtEngine.width;\r
1187     params.fPlateHeight = m_rtEngine.height;\r
1188     if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) {\r
1189         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL;\r
1190     }\r
1191     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) {\r
1192         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical;\r
1193     }\r
1194     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) {\r
1195         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial;\r
1196     }\r
1197     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) {\r
1198         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve;\r
1199     }\r
1200     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) {\r
1201         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes;\r
1202     }\r
1203     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) {\r
1204         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab;\r
1205     }\r
1206     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {\r
1207         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText;\r
1208     }\r
1209     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) {\r
1210         params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight;\r
1211     }\r
1212     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) {\r
1213         params.dwMode |= FDE_TEXTEDITMODE_Validate;\r
1214     }\r
1215     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) {\r
1216         params.dwMode |= FDE_TEXTEDITMODE_Password;\r
1217     }\r
1218     switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) {\r
1219         case FWL_STYLEEXT_EDT_HNear: {\r
1220                 params.dwAlignment |= FDE_TEXTEDITALIGN_Left;\r
1221                 break;\r
1222             }\r
1223         case FWL_STYLEEXT_EDT_HCenter: {\r
1224                 params.dwAlignment |= FDE_TEXTEDITALIGN_Center;\r
1225                 break;\r
1226             }\r
1227         case FWL_STYLEEXT_EDT_HFar: {\r
1228                 params.dwAlignment |= FDE_TEXTEDITALIGN_Right;\r
1229                 break;\r
1230             }\r
1231         default: {\r
1232             }\r
1233     }\r
1234     switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) {\r
1235         case FWL_STYLEEXT_EDT_Justified: {\r
1236                 params.dwAlignment |= FDE_TEXTEDITALIGN_Justified;\r
1237                 break;\r
1238             }\r
1239         case FWL_STYLEEXT_EDT_Distributed: {\r
1240                 params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed;\r
1241                 break;\r
1242             }\r
1243         default: {\r
1244                 params.dwAlignment |= FDE_TEXTEDITALIGN_Normal;\r
1245             }\r
1246     }\r
1247     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {\r
1248         params.dwMode |= FDE_TEXTEDITMODE_MultiLines;\r
1249         if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {\r
1250             params.dwMode |= FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz;\r
1251         }\r
1252         if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) {\r
1253             params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert;\r
1254         } else {\r
1255             params.fPlateHeight = 0x00FFFFFF;\r
1256         }\r
1257     } else {\r
1258         if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {\r
1259             params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz;\r
1260         }\r
1261     }\r
1262     if (        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)\r
1263             ||  (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
1264         params.dwMode |= FDE_TEXTEDITMODE_ReadOnly;\r
1265     }\r
1266     FX_FLOAT *pFontSize = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_FontSize);\r
1267     _FWL_RETURN_IF_FAIL(pFontSize);\r
1268     m_fFontSize = *pFontSize;\r
1269     FX_DWORD *pFontColor = (FX_DWORD*)GetThemeCapacity(FWL_WGTCAPACITY_TextColor);\r
1270     _FWL_RETURN_IF_FAIL(pFontColor);\r
1271     params.dwFontColor = *pFontColor;\r
1272     FX_FLOAT *pLineHeight = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_LineHeight);\r
1273     _FWL_RETURN_IF_FAIL(pLineHeight);\r
1274     params.fLineSpace = *pLineHeight;\r
1275     IFX_Font *pFont = (IFX_Font*)GetThemeCapacity(FWL_WGTCAPACITY_Font);\r
1276     _FWL_RETURN_IF_FAIL(pFont);\r
1277     params.pFont                        = pFont;\r
1278     params.fFontSize            = m_fFontSize;\r
1279     params.nLineCount           = (FX_INT32)(params.fPlateHeight / params.fLineSpace);\r
1280     if (params.nLineCount <= 0) {\r
1281         params.nLineCount = 1;\r
1282     }\r
1283     params.fTabWidth            = params.fFontSize * 1;\r
1284     params.bTabEquidistant      = TRUE;\r
1285     params.wLineBreakChar       = L'\n';\r
1286     params.nCharRotation        = 0;\r
1287     params.pEventSink           = this;\r
1288     m_pEdtEngine->SetEditParams(params);\r
1289 }\r
1290 void CFWL_EditImp::UpdateEditLayout()\r
1291 {\r
1292     if (m_pEdtEngine->GetTextLength() <= 0) {\r
1293         m_pEdtEngine->SetTextByStream(NULL);\r
1294     }\r
1295     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1296     if (pPage) {\r
1297         pPage->UnloadPage();\r
1298         pPage = NULL;\r
1299     }\r
1300     m_pEdtEngine->StartLayout();\r
1301     m_pEdtEngine->DoLayout(NULL);\r
1302     m_pEdtEngine->EndLayout();\r
1303     pPage = m_pEdtEngine->GetPage(0);\r
1304     if (pPage) {\r
1305         pPage->LoadPage();\r
1306     }\r
1307 }\r
1308 FX_BOOL CFWL_EditImp::UpdateOffset()\r
1309 {\r
1310     CFX_RectF rtCaret;\r
1311     m_pEdtEngine->GetCaretRect(rtCaret);\r
1312     FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;\r
1313     FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;\r
1314     rtCaret.Offset(fOffSetX, fOffSetY);\r
1315     const CFX_RectF& rtEidt = m_rtEngine;\r
1316     if (rtEidt.Contains(rtCaret)) {\r
1317         IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1318         _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);\r
1319         CFX_RectF rtFDE = pPage->GetContentsBox();\r
1320         rtFDE.Offset(fOffSetX, fOffSetY);\r
1321         if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) {\r
1322             m_fScrollOffsetX += rtFDE.right() - rtEidt.right();\r
1323             if (m_fScrollOffsetX < 0) {\r
1324                 m_fScrollOffsetX = 0;\r
1325             }\r
1326         }\r
1327         if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) {\r
1328             m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom();\r
1329             if (m_fScrollOffsetY < 0) {\r
1330                 m_fScrollOffsetY = 0;\r
1331             }\r
1332         }\r
1333         return FALSE;\r
1334     } else {\r
1335         FX_FLOAT offsetX = 0.0;\r
1336         FX_FLOAT offsetY = 0.0;\r
1337         if (rtCaret.left < rtEidt.left) {\r
1338             offsetX = rtCaret.left - rtEidt.left;\r
1339         }\r
1340         if (rtCaret.right() > rtEidt.right()) {\r
1341             offsetX = rtCaret.right() - rtEidt.right();\r
1342         }\r
1343         if (rtCaret.top < rtEidt.top) {\r
1344             offsetY =  rtCaret.top - rtEidt.top;\r
1345         }\r
1346         if (rtCaret.bottom() > rtEidt.bottom()) {\r
1347             offsetY = rtCaret.bottom() - rtEidt.bottom();\r
1348         }\r
1349         if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) {\r
1350             m_fScrollOffsetX += offsetX;\r
1351         }\r
1352         if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) {\r
1353             m_fScrollOffsetY += offsetY;\r
1354         }\r
1355         if (m_fFontSize > m_rtEngine.height) {\r
1356             m_fScrollOffsetY = 0;\r
1357         }\r
1358         return TRUE;\r
1359     }\r
1360 }\r
1361 FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar *pScrollBar, FX_FLOAT fPosChanged)\r
1362 {\r
1363     if (pScrollBar == (IFWL_ScrollBar*)m_pHorzScrollBar) {\r
1364         m_fScrollOffsetX += fPosChanged;\r
1365     } else {\r
1366         m_fScrollOffsetY += fPosChanged;\r
1367     }\r
1368     return TRUE;\r
1369 }\r
1370 void CFWL_EditImp::UpdateVAlignment()\r
1371 {\r
1372     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1373     _FWL_RETURN_IF_FAIL(pPage);\r
1374     const CFX_RectF& rtFDE = pPage->GetContentsBox();\r
1375     FX_FLOAT fOffsetY = 0.0f;\r
1376     FX_FLOAT fSpaceAbove = 0.0f;\r
1377     FX_FLOAT fSpaceBelow = 0.0f;\r
1378     CFX_SizeF* pSpace = (CFX_SizeF*)GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow);\r
1379     if (pSpace) {\r
1380         fSpaceAbove = pSpace->x;\r
1381         fSpaceBelow = pSpace->y;\r
1382     }\r
1383     if (fSpaceAbove < 0.1f) {\r
1384         fSpaceAbove = 0;\r
1385     }\r
1386     if (fSpaceBelow < 0.1f) {\r
1387         fSpaceBelow = 0;\r
1388     }\r
1389     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) {\r
1390         fOffsetY = (m_rtEngine.height - rtFDE.height) / 2;\r
1391         if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 && fSpaceAbove < fSpaceBelow) {\r
1392             return;\r
1393         }\r
1394         fOffsetY += (fSpaceAbove - fSpaceBelow) / 2;\r
1395     } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) {\r
1396         fOffsetY = (m_rtEngine.height - rtFDE.height);\r
1397         fOffsetY -= fSpaceBelow;\r
1398     } else {\r
1399         fOffsetY += fSpaceAbove;\r
1400     }\r
1401     m_fVAlignOffset = fOffsetY;\r
1402     if (m_fVAlignOffset < 0) {\r
1403         m_fVAlignOffset = 0;\r
1404     }\r
1405 }\r
1406 void CFWL_EditImp::UpdateCaret()\r
1407 {\r
1408     CFX_RectF rtFDE;\r
1409     m_pEdtEngine->GetCaretRect(rtFDE);\r
1410     rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset);\r
1411     CFX_RectF rtCaret;\r
1412     rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height);\r
1413     CFX_RectF temp = rtCaret;\r
1414     CFX_RectF rtClient;\r
1415     GetClientRect(rtClient);\r
1416     rtCaret.Intersect(rtClient);\r
1417     if (rtCaret.left > rtClient.right()) {\r
1418         FX_FLOAT right = rtCaret.right();\r
1419         rtCaret.left = rtClient.right() - 1;\r
1420         rtCaret.width = right - rtCaret.left;\r
1421     }\r
1422     FX_BOOL bIntersect = !rtCaret.IsEmpty();\r
1423     FX_BOOL bShow = TRUE;\r
1424     FX_BOOL bShowWhole = FALSE;\r
1425     if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {\r
1426         bShow = FALSE;\r
1427     }\r
1428     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption && temp.right() > m_rtEngine.right()) {\r
1429         bShowWhole = TRUE;\r
1430     }\r
1431     if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption && temp.bottom() > m_rtEngine.bottom()) {\r
1432         bShowWhole = TRUE;\r
1433     } else {\r
1434         bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);\r
1435     }\r
1436     if (bShowWhole) {\r
1437         rtCaret = temp;\r
1438     }\r
1439     ShowCaret(bShow, &rtCaret);\r
1440 }\r
1441 IFWL_ScrollBar* CFWL_EditImp::UpdateScroll()\r
1442 {\r
1443     FX_BOOL bShowHorz = m_pHorzScrollBar && ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);\r
1444     FX_BOOL bShowVert = m_pVertScrollBar && ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);\r
1445     if (!bShowHorz && !bShowVert) {\r
1446         return NULL;\r
1447     }\r
1448     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1449     _FWL_RETURN_VALUE_IF_FAIL(pPage, NULL);\r
1450     const CFX_RectF &rtFDE = pPage->GetContentsBox();\r
1451     IFWL_ScrollBar *pRepaint = NULL;\r
1452     if (bShowHorz) {\r
1453         CFX_RectF rtScroll;\r
1454         m_pHorzScrollBar->GetWidgetRect(rtScroll);\r
1455         if (rtScroll.width < rtFDE.width) {\r
1456             m_pHorzScrollBar->LockUpdate();\r
1457             FX_FLOAT fRange = rtFDE.width - rtScroll.width;\r
1458             m_pHorzScrollBar->SetRange(0.0f, fRange);\r
1459             FX_FLOAT fPos = m_fScrollOffsetX;\r
1460             if (fPos < 0.0f) {\r
1461                 fPos = 0.0f;\r
1462             }\r
1463             if (fPos > fRange) {\r
1464                 fPos = fRange;\r
1465             }\r
1466             m_pHorzScrollBar->SetPos(fPos);\r
1467             m_pHorzScrollBar->SetTrackPos(fPos);\r
1468             m_pHorzScrollBar->SetPageSize(rtScroll.width);\r
1469             m_pHorzScrollBar->SetStepSize(rtScroll.width / 10);\r
1470             m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);\r
1471             m_pHorzScrollBar->UnlockUpdate();\r
1472             m_pHorzScrollBar->Update();\r
1473             pRepaint = (IFWL_ScrollBar*)m_pHorzScrollBar;\r
1474         } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {\r
1475             m_pHorzScrollBar->LockUpdate();\r
1476             m_pHorzScrollBar->SetRange(0, -1);\r
1477             m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);\r
1478             m_pHorzScrollBar->UnlockUpdate();\r
1479             m_pHorzScrollBar->Update();\r
1480             pRepaint = (IFWL_ScrollBar*)m_pHorzScrollBar;\r
1481         }\r
1482     }\r
1483     if (bShowVert) {\r
1484         CFX_RectF rtScroll;\r
1485         m_pVertScrollBar->GetWidgetRect(rtScroll);\r
1486         if (rtScroll.height < rtFDE.height) {\r
1487             m_pVertScrollBar->LockUpdate();\r
1488             FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace;\r
1489             FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;\r
1490             if (fRange < fStep) {\r
1491                 fRange = fStep;\r
1492             }\r
1493             m_pVertScrollBar->SetRange(0.0f, fRange);\r
1494             FX_FLOAT fPos = m_fScrollOffsetY;\r
1495             if (fPos < 0.0f) {\r
1496                 fPos = 0.0f;\r
1497             }\r
1498             if (fPos > fRange) {\r
1499                 fPos = fRange;\r
1500             }\r
1501             m_pVertScrollBar->SetPos(fPos);\r
1502             m_pVertScrollBar->SetTrackPos(fPos);\r
1503             m_pVertScrollBar->SetPageSize(rtScroll.height);\r
1504             m_pVertScrollBar->SetStepSize(fStep);\r
1505             m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);\r
1506             m_pVertScrollBar->UnlockUpdate();\r
1507             m_pVertScrollBar->Update();\r
1508             pRepaint = (IFWL_ScrollBar*)m_pVertScrollBar;\r
1509         } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {\r
1510             m_pVertScrollBar->LockUpdate();\r
1511             m_pVertScrollBar->SetRange(0, -1);\r
1512             m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);\r
1513             m_pVertScrollBar->UnlockUpdate();\r
1514             m_pVertScrollBar->Update();\r
1515             pRepaint = (IFWL_ScrollBar*)m_pVertScrollBar;\r
1516         }\r
1517     }\r
1518     return pRepaint;\r
1519 }\r
1520 FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert)\r
1521 {\r
1522     FX_BOOL bShow = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == FWL_WGTSTATE_Focused : TRUE;\r
1523     if (bVert) {\r
1524         return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) &&\r
1525                (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) && IsContentHeightOverflow();\r
1526     }\r
1527     return  bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);\r
1528 }\r
1529 FX_BOOL CFWL_EditImp::IsContentHeightOverflow()\r
1530 {\r
1531     _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);\r
1532     IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);\r
1533     _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);\r
1534     return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f;\r
1535 }\r
1536 FX_INT32 CFWL_EditImp::AddDoRecord(FX_BSTR bsDoRecord)\r
1537 {\r
1538     FX_INT32 nCount = m_RecordArr.GetSize();\r
1539     if (m_iCurRecord == nCount - 1) {\r
1540         if (nCount == m_iMaxRecord) {\r
1541             m_RecordArr.RemoveAt(0);\r
1542             m_iCurRecord --;\r
1543         }\r
1544     } else {\r
1545         for (FX_INT32 i = nCount - 1; i > m_iCurRecord; i --) {\r
1546             m_RecordArr.RemoveAt(i);\r
1547         }\r
1548     }\r
1549     m_RecordArr.Add(bsDoRecord);\r
1550     return m_iCurRecord = m_RecordArr.GetSize() - 1;\r
1551 }\r
1552 void CFWL_EditImp::Layout()\r
1553 {\r
1554     GetClientRect(m_rtClient);\r
1555     m_rtEngine = m_rtClient;\r
1556     FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);\r
1557     _FWL_RETURN_IF_FAIL(pfWidth);\r
1558     FX_FLOAT fWidth = *pfWidth;\r
1559     if (!m_pOuter) {\r
1560         CFX_RectF* pUIMargin = (CFX_RectF*)GetThemeCapacity(FWL_WGTCAPACITY_UIMargin);\r
1561         if (pUIMargin) {\r
1562             m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);\r
1563         }\r
1564     } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) {\r
1565         CFWL_ThemePart part;\r
1566         part.m_pWidget = m_pOuter;\r
1567         CFX_RectF* pUIMargin = (CFX_RectF*)m_pOuter->GetThemeProvider()->GetCapacity(&part, FWL_WGTCAPACITY_UIMargin);\r
1568         if (pUIMargin) {\r
1569             m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);\r
1570         }\r
1571     }\r
1572     FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);\r
1573     FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);\r
1574     if (bShowVertScrollbar) {\r
1575         InitScrollBar();\r
1576         CFX_RectF rtVertScr;\r
1577         if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
1578             rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin,\r
1579                           m_rtClient.top, fWidth, m_rtClient.height);\r
1580         } else {\r
1581             rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, m_rtClient.height);\r
1582             if (bShowHorzScrollbar) {\r
1583                 rtVertScr.height -= fWidth;\r
1584             }\r
1585             m_rtEngine.width -= fWidth;\r
1586         }\r
1587         m_pVertScrollBar->SetWidgetRect(rtVertScr);\r
1588         m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);\r
1589         m_pVertScrollBar->Update();\r
1590     } else if (m_pVertScrollBar) {\r
1591         m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);\r
1592     }\r
1593     if (bShowHorzScrollbar) {\r
1594         InitScrollBar(FALSE);\r
1595         CFX_RectF rtHoriScr;\r
1596         if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
1597             rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, m_rtClient.width, fWidth);\r
1598         } else {\r
1599             rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, m_rtClient.width, fWidth);\r
1600             if (bShowVertScrollbar) {\r
1601                 rtHoriScr.width -= fWidth;\r
1602             }\r
1603             m_rtEngine.height -= fWidth;\r
1604         }\r
1605         m_pHorzScrollBar->SetWidgetRect(rtHoriScr);\r
1606         m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);\r
1607         m_pHorzScrollBar->Update();\r
1608     } else if (m_pHorzScrollBar) {\r
1609         m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);\r
1610     }\r
1611 }\r
1612 void CFWL_EditImp::LayoutScrollBar()\r
1613 {\r
1614     if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) == 0) {\r
1615         return;\r
1616     }\r
1617     FX_FLOAT* pfWidth = NULL;\r
1618     FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);\r
1619     FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);\r
1620     if (bShowVertScrollbar) {\r
1621         if (!m_pVertScrollBar) {\r
1622             pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);\r
1623             FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;\r
1624             InitScrollBar();\r
1625             CFX_RectF rtVertScr;\r
1626             if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
1627                 rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin,\r
1628                               m_rtClient.top, fWidth, m_rtClient.height);\r
1629             } else {\r
1630                 rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, m_rtClient.height);\r
1631                 if (bShowHorzScrollbar) {\r
1632                     rtVertScr.height -= fWidth;\r
1633                 }\r
1634             }\r
1635             m_pVertScrollBar->SetWidgetRect(rtVertScr);\r
1636             m_pVertScrollBar->Update();\r
1637         }\r
1638         m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);\r
1639     } else if (m_pVertScrollBar) {\r
1640         m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);\r
1641     }\r
1642     if (bShowHorzScrollbar) {\r
1643         if (!m_pHorzScrollBar) {\r
1644             pfWidth = !pfWidth ? (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth) : pfWidth;\r
1645             FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;\r
1646             InitScrollBar(FALSE);\r
1647             CFX_RectF rtHoriScr;\r
1648             if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {\r
1649                 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, m_rtClient.width, fWidth);\r
1650             } else {\r
1651                 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, m_rtClient.width, fWidth);\r
1652                 if (bShowVertScrollbar) {\r
1653                     rtHoriScr.width -= (fWidth);\r
1654                 }\r
1655             }\r
1656             m_pHorzScrollBar->SetWidgetRect(rtHoriScr);\r
1657             m_pHorzScrollBar->Update();\r
1658         }\r
1659         m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);\r
1660     } else if (m_pHorzScrollBar) {\r
1661         m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);\r
1662     }\r
1663     if (bShowVertScrollbar || bShowHorzScrollbar) {\r
1664         UpdateScroll();\r
1665     }\r
1666 }\r
1667 void CFWL_EditImp::DeviceToEngine(CFX_PointF &pt)\r
1668 {\r
1669     pt.x += -m_rtEngine.left + m_fScrollOffsetX;\r
1670     pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY;\r
1671 }\r
1672 void CFWL_EditImp::InitScrollBar(FX_BOOL bVert )\r
1673 {\r
1674     if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {\r
1675         return;\r
1676     }\r
1677     CFWL_WidgetImpProperties prop;\r
1678     prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;\r
1679     prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible;\r
1680     prop.m_pParent = m_pInterface;\r
1681     prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;\r
1682     IFWL_ScrollBar *pScrollBar = IFWL_ScrollBar::Create();\r
1683     pScrollBar->Initialize(prop, m_pInterface);\r
1684     bVert ? (m_pVertScrollBar = pScrollBar) : (m_pHorzScrollBar = pScrollBar);\r
1685 }\r
1686 void CFWL_EditImp::InitEngine()\r
1687 {\r
1688     if (m_pEdtEngine) {\r
1689         return;\r
1690     }\r
1691     m_pEdtEngine = IFDE_TxtEdtEngine::Create();\r
1692 }\r
1693 extern  FX_BOOL FWL_ShowCaret(IFWL_Widget *pWidget, FX_BOOL bVisible, const CFX_RectF *pRtAnchor);\r
1694 void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF *pRect )\r
1695 {\r
1696     if (m_pCaret) {\r
1697         m_pCaret->ShowCaret(bVisible);\r
1698         if (bVisible && !pRect->IsEmpty()) {\r
1699             m_pCaret->SetWidgetRect(*pRect);\r
1700         }\r
1701         Repaint(&m_rtEngine);\r
1702     } else {\r
1703         IFWL_Widget *pOuter = (IFWL_Widget*)m_pInterface;\r
1704         if (bVisible) {\r
1705             pRect->Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);\r
1706         }\r
1707         while (pOuter->GetOuter()) {\r
1708             pOuter = pOuter->GetOuter();\r
1709             if (bVisible) {\r
1710                 CFX_RectF rtOuter;\r
1711                 pOuter->GetWidgetRect(rtOuter);\r
1712                 pRect->Offset(rtOuter.left, rtOuter.top);\r
1713             }\r
1714         }\r
1715         FWL_ShowCaret(pOuter, bVisible, pRect);\r
1716     }\r
1717 }\r
1718 FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum)\r
1719 {\r
1720     if (!m_pEdtEngine) {\r
1721         return FALSE;\r
1722     }\r
1723     if (!m_bSetRange) {\r
1724         return TRUE;\r
1725     }\r
1726     CFX_WideString wsOld, wsText;\r
1727     m_pEdtEngine->GetText(wsText, 0);\r
1728     if (wsText.IsEmpty()) {\r
1729         if (cNum == L'0') {\r
1730             return FALSE;\r
1731         }\r
1732         return TRUE;\r
1733     }\r
1734     FX_INT32 caretPos = m_pEdtEngine->GetCaretPos();\r
1735     FX_INT32 iSel =     CountSelRanges();\r
1736     if (iSel == 0) {\r
1737         if (cNum == L'0' && caretPos == 0) {\r
1738             return FALSE;\r
1739         }\r
1740         FX_INT32 nLen = wsText.GetLength();\r
1741         CFX_WideString l = wsText.Mid(0, caretPos);\r
1742         CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos);\r
1743         CFX_WideString wsNew = l + cNum + r;\r
1744         if (wsNew.GetInteger() <= m_iMax) {\r
1745             return TRUE;\r
1746         }\r
1747     } else {\r
1748         if (wsText.GetInteger() <= m_iMax) {\r
1749             return TRUE;\r
1750         }\r
1751     }\r
1752     return FALSE;\r
1753 }\r
1754 void CFWL_EditImp::InitCaret()\r
1755 {\r
1756     if (!m_pCaret) {\r
1757         if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) {\r
1758             m_pCaret = IFWL_Caret::Create();\r
1759             m_pCaret->Initialize(m_pInterface);\r
1760             m_pCaret->SetParent(m_pInterface);\r
1761             m_pCaret->SetStates(m_pProperties->m_dwStates);\r
1762         }\r
1763     } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) == 0) {\r
1764         m_pCaret->Release();\r
1765         m_pCaret = NULL;\r
1766     }\r
1767 }\r
1768 void CFWL_EditImp::ClearRecord()\r
1769 {\r
1770     m_iCurRecord = -1;\r
1771     m_RecordArr.RemoveAll();\r
1772 }\r
1773 void CFWL_EditImp::ProcessInsertError(FX_INT32 iError)\r
1774 {\r
1775     switch (iError) {\r
1776         case -2: {\r
1777                 CFWL_EvtEdtTextFull textFullEvent;\r
1778                 textFullEvent.m_pSrcTarget = m_pInterface;\r
1779                 DispatchEvent(&textFullEvent);\r
1780                 break;\r
1781             }\r
1782         default: {\r
1783             }\r
1784     }\r
1785 }\r
1786 CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp *pOwner)\r
1787     : m_pOwner(pOwner)\r
1788 {\r
1789 }\r
1790 FX_INT32 CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message *pMessage)\r
1791 {\r
1792     _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);\r
1793     FX_DWORD dwMsgCode = pMessage->GetClassID();\r
1794     FX_INT32 iRet = 1;\r
1795     switch (dwMsgCode) {\r
1796         case FWL_MSGHASH_Activate: {\r
1797                 DoActivate((CFWL_MsgActivate*)pMessage);\r
1798                 break;\r
1799             }\r
1800         case FWL_MSGHASH_Deactivate: {\r
1801                 DoDeactivate((CFWL_MsgDeactivate*)pMessage);\r
1802                 break;\r
1803             }\r
1804         case FWL_MSGHASH_SetFocus:\r
1805         case FWL_MSGHASH_KillFocus: {\r
1806                 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);\r
1807                 break;\r
1808             }\r
1809         case FWL_MSGHASH_Mouse: {\r
1810                 CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;\r
1811                 FX_DWORD dwCmd = pMsg->m_dwCmd;\r
1812                 switch(dwCmd) {\r
1813                     case FWL_MSGMOUSECMD_LButtonDown: {\r
1814                             OnLButtonDown(pMsg);\r
1815                             break;\r
1816                         }\r
1817                     case FWL_MSGMOUSECMD_LButtonUp: {\r
1818                             OnLButtonUp(pMsg);\r
1819                             break;\r
1820                         }\r
1821                     case FWL_MSGMOUSECMD_LButtonDblClk: {\r
1822                             OnButtonDblClk(pMsg);\r
1823                             break;\r
1824                         }\r
1825                     case FWL_MSGMOUSECMD_MouseMove: {\r
1826                             OnMouseMove(pMsg);\r
1827                             break;\r
1828                         }\r
1829                     case FWL_MSGMOUSECMD_RButtonDown: {\r
1830                             DoButtonDown(pMsg);\r
1831                             break;\r
1832                         }\r
1833                     default: {\r
1834                         }\r
1835                 }\r
1836                 break;\r
1837             }\r
1838         case FWL_MSGHASH_Key: {\r
1839                 CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;\r
1840                 FX_DWORD dwCmd = pKey->m_dwCmd;\r
1841                 if (dwCmd == FWL_MSGKEYCMD_KeyDown) {\r
1842                     OnKeyDown(pKey);\r
1843                 } else if (dwCmd == FWL_MSGKEYCMD_Char) {\r
1844                     OnChar(pKey);\r
1845                 }\r
1846                 break;\r
1847             }\r
1848         default: {\r
1849                 iRet = 0;\r
1850             }\r
1851     }\r
1852     CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);\r
1853     return iRet;\r
1854 }\r
1855 FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event *pEvent)\r
1856 {\r
1857     _FWL_RETURN_VALUE_IF_FAIL(pEvent, FWL_ERR_Indefinite);\r
1858     FX_DWORD dwHashCode = pEvent->GetClassID();\r
1859     if (dwHashCode != FWL_EVTHASH_Scroll) {\r
1860         return FWL_ERR_Succeeded;\r
1861     }\r
1862     IFWL_Widget *pSrcTarget = pEvent->m_pSrcTarget;\r
1863     if ((pSrcTarget == (IFWL_Widget*)m_pOwner->m_pVertScrollBar && m_pOwner->m_pVertScrollBar) || (pSrcTarget == (IFWL_Widget*)m_pOwner->m_pHorzScrollBar && m_pOwner->m_pHorzScrollBar)) {\r
1864         FX_DWORD dwScrollCode = ((CFWL_EvtScroll*)pEvent)->m_iScrollCode;\r
1865         FX_FLOAT fPos = ((CFWL_EvtScroll*)pEvent)->m_fPos;\r
1866         OnScroll((IFWL_ScrollBar*)pSrcTarget, dwScrollCode, fPos);\r
1867     }\r
1868     return FWL_ERR_Succeeded;\r
1869 }\r
1870 FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)\r
1871 {\r
1872     return m_pOwner->DrawWidget(pGraphics, pMatrix);\r
1873 }\r
1874 void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate *pMsg)\r
1875 {\r
1876     m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;\r
1877     m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1878 }\r
1879 void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate *pMsg)\r
1880 {\r
1881     m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;\r
1882     m_pOwner->Repaint(&m_pOwner->m_rtClient);\r
1883 }\r
1884 void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse *pMsg)\r
1885 {\r
1886     if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {\r
1887         m_pOwner->SetFocus(TRUE);\r
1888     }\r
1889     if (!m_pOwner->m_pEdtEngine) {\r
1890         m_pOwner->UpdateEditEngine();\r
1891     }\r
1892     IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);\r
1893     _FWL_RETURN_IF_FAIL(pPage);\r
1894     CFX_PointF pt;\r
1895     pt.Set(pMsg->m_fx, pMsg->m_fy);\r
1896     m_pOwner->DeviceToEngine(pt);\r
1897     FX_BOOL bBefore = TRUE;\r
1898     FX_INT32 nIndex = pPage->GetCharIndex(pt, bBefore);\r
1899     if (nIndex < 0) {\r
1900         nIndex = 0;\r
1901     }\r
1902     m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);\r
1903 }\r
1904 void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)\r
1905 {\r
1906     FX_DWORD dwStyleEx = m_pOwner->GetStylesEx();\r
1907     FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret;\r
1908     if (bSet) {\r
1909         m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;\r
1910         if (!m_pOwner->m_pEdtEngine) {\r
1911             m_pOwner->UpdateEditEngine();\r
1912         }\r
1913         m_pOwner->UpdateVAlignment();\r
1914         m_pOwner->UpdateOffset();\r
1915         m_pOwner->UpdateCaret();\r
1916     } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {\r
1917         m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;\r
1918         m_pOwner->ShowCaret(FALSE);\r
1919         if (m_pOwner->m_pEdtEngine && (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {\r
1920             FX_INT32 nSel = m_pOwner->CountSelRanges();\r
1921             if (nSel > 0) {\r
1922                 m_pOwner->ClearSelections();\r
1923                 bRepaint = TRUE;\r
1924             }\r
1925             m_pOwner->SetCaretPos(0);\r
1926             m_pOwner->UpdateOffset();\r
1927         }\r
1928         m_pOwner->ClearRecord();\r
1929     }\r
1930     m_pOwner->LayoutScrollBar();\r
1931     if (bRepaint) {\r
1932         CFX_RectF rtInvalidate;\r
1933         rtInvalidate.Set(0,\r
1934                          0,\r
1935                          m_pOwner->m_pProperties->m_rtWidget.width,\r
1936                          m_pOwner->m_pProperties->m_rtWidget.height);\r
1937         m_pOwner->Repaint(&rtInvalidate);\r
1938     }\r
1939 }\r
1940 void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)\r
1941 {\r
1942     DoCursor(pMsg);\r
1943     if(m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {\r
1944         return;\r
1945     }\r
1946     m_pOwner->m_bLButtonDown = TRUE;\r
1947     m_pOwner->SetGrab(TRUE);\r
1948     DoButtonDown(pMsg);\r
1949     FX_INT32 nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();\r
1950     FX_BOOL bRepaint = FALSE;\r
1951     FX_INT32 iCount = m_pOwner->m_pEdtEngine->CountSelRanges();\r
1952     if (iCount > 0) {\r
1953         m_pOwner->m_pEdtEngine->ClearSelection();\r
1954         bRepaint = TRUE;\r
1955     }\r
1956     FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;\r
1957     if (bShift && m_pOwner->m_nSelStart != nIndex) {\r
1958         FX_INT32 iStart = FX_MIN(m_pOwner->m_nSelStart, nIndex);\r
1959         FX_INT32 iEnd = FX_MAX(m_pOwner->m_nSelStart, nIndex);\r
1960         m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);\r
1961         bRepaint = TRUE;\r
1962     } else {\r
1963         m_pOwner->m_nSelStart = nIndex;\r
1964     }\r
1965     if (bRepaint) {\r
1966         m_pOwner->Repaint(&m_pOwner->m_rtEngine);\r
1967     }\r
1968 }\r
1969 void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)\r
1970 {\r
1971     DoCursor(pMsg);\r
1972     m_pOwner->m_bLButtonDown = FALSE;\r
1973     m_pOwner->SetGrab(FALSE);\r
1974 }\r
1975 void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse *pMsg)\r
1976 {\r
1977     _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);\r
1978     DoCursor(pMsg);\r
1979     IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);\r
1980     _FWL_RETURN_IF_FAIL(pPage);\r
1981     CFX_PointF pt;\r
1982     pt.Set(pMsg->m_fx, pMsg->m_fy);\r
1983     m_pOwner->DeviceToEngine(pt);\r
1984     FX_INT32 nCount = 0;\r
1985     FX_INT32 nIndex = pPage->SelectWord(pt, nCount);\r
1986     if (nIndex < 0) {\r
1987         return;\r
1988     }\r
1989     m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);\r
1990     m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);\r
1991     m_pOwner->Repaint(&m_pOwner->m_rtEngine);\r
1992 }\r
1993 void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)\r
1994 {\r
1995     _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);\r
1996     DoCursor(pMsg);\r
1997     if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {\r
1998         return;\r
1999     }\r
2000     IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);\r
2001     _FWL_RETURN_IF_FAIL(pPage);\r
2002     CFX_PointF pt;\r
2003     pt.Set(pMsg->m_fx, pMsg->m_fy);\r
2004     m_pOwner->DeviceToEngine(pt);\r
2005     FX_BOOL bBefore = TRUE;\r
2006     FX_INT32 nIndex = pPage->GetCharIndex(pt, bBefore);\r
2007     m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);\r
2008     nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();\r
2009     m_pOwner->m_pEdtEngine->ClearSelection();\r
2010     if (nIndex != m_pOwner->m_nSelStart) {\r
2011         FX_INT32 nLen = m_pOwner->m_pEdtEngine->GetTextLength();\r
2012         if (m_pOwner->m_nSelStart >= nLen) {\r
2013             m_pOwner->m_nSelStart = nLen;\r
2014         }\r
2015         m_pOwner->m_pEdtEngine->AddSelRange(FX_MIN(m_pOwner->m_nSelStart, nIndex), FXSYS_abs(nIndex - m_pOwner->m_nSelStart));\r
2016     }\r
2017 }\r
2018 void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)\r
2019 {\r
2020     _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);\r
2021     FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;\r
2022     FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;\r
2023     FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;\r
2024     FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;\r
2025     switch (dwKeyCode) {\r
2026         case FWL_VKEY_Left: {\r
2027                 MoveCaret = MC_Left;\r
2028                 break;\r
2029             }\r
2030         case FWL_VKEY_Right: {\r
2031                 MoveCaret = MC_Right;\r
2032                 break;\r
2033             }\r
2034         case FWL_VKEY_Up: {\r
2035                 MoveCaret = MC_Up;\r
2036                 break;\r
2037             }\r
2038         case FWL_VKEY_Down: {\r
2039                 MoveCaret = MC_Down;\r
2040                 break;\r
2041             }\r
2042         case FWL_VKEY_Home: {\r
2043                 if (bCtrl) {\r
2044                     MoveCaret = MC_Home;\r
2045                 } else {\r
2046                     MoveCaret = MC_LineStart;\r
2047                 }\r
2048                 break;\r
2049             }\r
2050         case FWL_VKEY_End: {\r
2051                 if (bCtrl) {\r
2052                     MoveCaret = MC_End;\r
2053                 } else {\r
2054                     MoveCaret = MC_LineEnd;\r
2055                 }\r
2056                 break;\r
2057             }\r
2058         case FWL_VKEY_Insert: {\r
2059                 break;\r
2060             }\r
2061         case FWL_VKEY_Delete: {\r
2062                 if (    (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)\r
2063                         ||      (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
2064                     break;\r
2065                 }\r
2066                 FX_INT32 nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();\r
2067 #if (_FX_OS_==_FX_MACOSX_)\r
2068                 m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);\r
2069 #else\r
2070                 m_pOwner->m_pEdtEngine->Delete(nCaret);\r
2071 #endif\r
2072                 break;\r
2073             }\r
2074         case FWL_VKEY_F2: {\r
2075                 break;\r
2076             }\r
2077         case FWL_VKEY_Tab: {\r
2078                 m_pOwner->DispatchKeyEvent(pMsg);\r
2079                 break;\r
2080             }\r
2081         default: {\r
2082 #if (_FX_OS_==_FX_MACOSX_)\r
2083                 if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)\r
2084 #else\r
2085                 if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)\r
2086 #endif\r
2087                 {\r
2088                     if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {\r
2089                         m_pOwner->DoClipboard(1);\r
2090                         return;\r
2091                     }\r
2092                     if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {\r
2093                         m_pOwner->DoClipboard(2);\r
2094                         return;\r
2095                     }\r
2096                     if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {\r
2097                         m_pOwner->DoClipboard(3);\r
2098                         return;\r
2099                     }\r
2100                 }\r
2101             }\r
2102     }\r
2103     if (MoveCaret != MC_MoveNone) {\r
2104         m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);\r
2105     }\r
2106 }\r
2107 void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey *pMsg)\r
2108 {\r
2109     if (        (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)\r
2110             ||  ( m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {\r
2111         return;\r
2112     }\r
2113     _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);\r
2114     FX_INT32 iError = 0;\r
2115     FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;\r
2116     FX_INT32 nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();\r
2117     switch (c) {\r
2118         case FWL_VKEY_Back: {\r
2119                 m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);\r
2120                 break;\r
2121             }\r
2122         case 0x0A: {\r
2123                 break;\r
2124             }\r
2125         case FWL_VKEY_Escape: {\r
2126                 break;\r
2127             }\r
2128         case FWL_VKEY_Tab: {\r
2129                 iError = m_pOwner->m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(L"\t"), 1);\r
2130                 break;\r
2131             }\r
2132         case FWL_VKEY_Return: {\r
2133                 if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_WantReturn) {\r
2134                     iError = m_pOwner->m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(L"\n"), 1);\r
2135                 }\r
2136                 break;\r
2137             }\r
2138         default: {\r
2139                 if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {\r
2140                     if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) {\r
2141                         if (((pMsg->m_dwKeyCode < FWL_VKEY_0) && (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) || pMsg->m_dwKeyCode > FWL_VKEY_9) {\r
2142                             break;\r
2143                         }\r
2144                         if (!m_pOwner->ValidateNumberChar(c)) {\r
2145                             break;\r
2146                         }\r
2147                     }\r
2148                 }\r
2149 #if (_FX_OS_==_FX_MACOSX_)\r
2150                 if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)\r
2151 #else\r
2152                 if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)\r
2153 #endif\r
2154                 {\r
2155                     break;\r
2156                 }\r
2157                 iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);\r
2158                 break;\r
2159             }\r
2160     }\r
2161     if (iError < 0) {\r
2162         m_pOwner->ProcessInsertError(iError);\r
2163     }\r
2164 }\r
2165 FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar *pScrollBar, FX_DWORD dwCode, FX_FLOAT fPos)\r
2166 {\r
2167     CFX_SizeF fs;\r
2168     pScrollBar->GetRange(fs.x, fs.y);\r
2169     FX_FLOAT iCurPos = pScrollBar->GetPos();\r
2170     FX_FLOAT fStep = pScrollBar->GetStepSize();\r
2171     switch (dwCode) {\r
2172         case FWL_SCBCODE_Min: {\r
2173                 fPos = fs.x;\r
2174                 break;\r
2175             }\r
2176         case FWL_SCBCODE_Max: {\r
2177                 fPos = fs.y;\r
2178                 break;\r
2179             }\r
2180         case FWL_SCBCODE_StepBackward: {\r
2181                 fPos -= fStep;\r
2182                 if (fPos < fs.x + fStep / 2) {\r
2183                     fPos = fs.x;\r
2184                 }\r
2185                 break;\r
2186             }\r
2187         case FWL_SCBCODE_StepForward: {\r
2188                 fPos += fStep;\r
2189                 if (fPos > fs.y - fStep / 2) {\r
2190                     fPos = fs.y;\r
2191                 }\r
2192                 break;\r
2193             }\r
2194         case FWL_SCBCODE_PageBackward: {\r
2195                 fPos -= pScrollBar->GetPageSize();\r
2196                 if (fPos < fs.x) {\r
2197                     fPos = fs.x;\r
2198                 }\r
2199                 break;\r
2200             }\r
2201         case FWL_SCBCODE_PageForward: {\r
2202                 fPos += pScrollBar->GetPageSize();\r
2203                 if (fPos > fs.y) {\r
2204                     fPos = fs.y;\r
2205                 }\r
2206                 break;\r
2207             }\r
2208         case FWL_SCBCODE_Pos:\r
2209         case FWL_SCBCODE_TrackPos: {\r
2210                 break;\r
2211             }\r
2212         case FWL_SCBCODE_EndScroll: {\r
2213                 return FALSE;\r
2214             }\r
2215         default: {\r
2216             }\r
2217     }\r
2218     if (iCurPos != fPos) {\r
2219         pScrollBar->SetPos(fPos);\r
2220         pScrollBar->SetTrackPos(fPos);\r
2221         m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);\r
2222         if (m_pOwner->m_pEdtEngine) {\r
2223             m_pOwner->UpdateCaret();\r
2224         }\r
2225         CFX_RectF rect;\r
2226         m_pOwner->GetWidgetRect(rect);\r
2227         CFX_RectF rtInvalidate;\r
2228         rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);\r
2229         m_pOwner->Repaint(&rtInvalidate);\r
2230     }\r
2231     return TRUE;\r
2232 }\r
2233 void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse *pMsg)\r
2234 {\r
2235     if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {\r
2236         IFWL_AdapterNative *pNative = FWL_GetAdapterNative();\r
2237         IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();\r
2238         if (NULL != pCursorMgr) {\r
2239             FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_InputBeam);\r
2240             pCursorMgr->SetCursor(hCursor);\r
2241             pCursorMgr->ShowCursor(TRUE);\r
2242         }\r
2243     }\r
2244 }\r