// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include <algorithm>

#include "xfa/src/foxitlib.h"
#include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
#include "xfa/src/fwl/src/core/include/fwl_appimp.h"
#include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_caretimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h"

// static
IFWL_Edit* IFWL_Edit::Create(const CFWL_WidgetImpProperties& properties,
                             IFWL_Widget* pOuter) {
  IFWL_Edit* pEdit = new IFWL_Edit;
  CFWL_EditImp* pEditImpl = new CFWL_EditImp(properties, pOuter);
  pEdit->SetImpl(pEditImpl);
  pEditImpl->SetInterface(pEdit);
  return pEdit;
}
// static
IFWL_Edit* IFWL_Edit::CreateComboEdit(
    const CFWL_WidgetImpProperties& properties,
    IFWL_Widget* pOuter) {
  IFWL_Edit* pEdit = new IFWL_Edit;
  CFWL_EditImp* pComboEditImpl = new CFWL_ComboEditImp(properties, pOuter);
  pEdit->SetImpl(pComboEditImpl);
  pComboEditImpl->SetInterface(pEdit);
  return pEdit;
}
IFWL_Edit::IFWL_Edit() {}
FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText);
}
int32_t IFWL_Edit::GetTextLength() const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength();
}
FWL_ERR IFWL_Edit::GetText(CFX_WideString& wsText,
                           int32_t nStart,
                           int32_t nCount) const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetText(wsText, nStart, nCount);
}
FWL_ERR IFWL_Edit::ClearText() {
  return static_cast<CFWL_EditImp*>(GetImpl())->ClearText();
}
int32_t IFWL_Edit::GetCaretPos() const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos();
}
int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore);
}
FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) {
  return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount);
}
int32_t IFWL_Edit::CountSelRanges() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges();
}
int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart);
}
FWL_ERR IFWL_Edit::ClearSelections() {
  return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections();
}
int32_t IFWL_Edit::GetLimit() {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit();
}
FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit);
}
FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias);
}
FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString& wsFormat) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetFormatString(wsFormat);
}
FWL_ERR IFWL_Edit::Insert(int32_t nStart,
                          const FX_WCHAR* lpText,
                          int32_t nLen) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Insert(nStart, lpText, nLen);
}
FWL_ERR IFWL_Edit::DeleteSelections() {
  return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections();
}
FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) {
  return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount);
}
FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace);
}
FWL_ERR IFWL_Edit::Replace(int32_t nStart,
                           int32_t nLen,
                           const CFX_WideStringC& wsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->Replace(nStart, nLen, wsReplace);
}
FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) {
  return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd);
}
FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy);
}
FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut);
}
FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste);
}
FX_BOOL IFWL_Edit::Delete() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Delete();
}
FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord);
}
FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord);
}
FX_BOOL IFWL_Edit::Undo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Undo();
}
FX_BOOL IFWL_Edit::Redo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Redo();
}
FX_BOOL IFWL_Edit::CanUndo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo();
}
FX_BOOL IFWL_Edit::CanRedo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo();
}
FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->SetTabWidth(fTabWidth, bEquidistant);
}
FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter);
}
FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax);
}
FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor);
}
FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize);
}
void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset);
}
FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf,
                                   CFX_ByteStringArray& sSuggest) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->GetSuggestWords(pointf, sSuggest);
}
FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf,
                                         const CFX_ByteStringC& bsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->ReplaceSpellCheckWord(pointf, bsReplace);
}
#define FWL_EDIT_Margin 3
CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties& properties,
                           IFWL_Widget* pOuter)
    : CFWL_WidgetImp(properties, pOuter),
      m_fVAlignOffset(0.0f),
      m_fScrollOffsetX(0.0f),
      m_fScrollOffsetY(0.0f),
      m_pEdtEngine(NULL),
      m_bLButtonDown(FALSE),
      m_nSelStart(0),
      m_nLimit(-1),
      m_fSpaceAbove(0),
      m_fSpaceBelow(0),
      m_fFontSize(0),
      m_bSetRange(FALSE),
      m_iMin(-1),
      m_iMax(0xFFFFFFF),
      m_backColor(0),
      m_updateBackColor(FALSE),
      m_iCurRecord(-1),
      m_iMaxRecord(128) {
  m_rtClient.Reset();
  m_rtEngine.Reset();
  m_rtStatic.Reset();
}
CFWL_EditImp::~CFWL_EditImp() {
  if (m_pEdtEngine) {
    m_pEdtEngine->Release();
    m_pEdtEngine = NULL;
  }
  ClearRecord();
}
FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const {
  wsClass = FWL_CLASS_Edit;
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_EditImp::GetClassID() const {
  return FWL_CLASSHASH_Edit;
}
FWL_ERR CFWL_EditImp::Initialize() {
  if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
    return FWL_ERR_Indefinite;
  if (!m_pDelegate) {
    m_pDelegate = new CFWL_EditImpDelegate(this);
  }
  InitCaret();
  if (!m_pEdtEngine) {
    InitEngine();
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Finalize() {
  if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
    ShowCaret(FALSE);
  }
  if (m_pHorzScrollBar) {
    m_pHorzScrollBar->Finalize();
  }
  if (m_pVertScrollBar) {
    m_pVertScrollBar->Finalize();
  }
  delete m_pDelegate;
  m_pDelegate = nullptr;
  return CFWL_WidgetImp::Finalize();
}
FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
  if (bAutoSize) {
    rect.Set(0, 0, 0, 0);
    if (m_pEdtEngine) {
      int32_t iTextLen = m_pEdtEngine->GetTextLength();
      if (iTextLen > 0) {
        CFX_WideString wsText;
        m_pEdtEngine->GetText(wsText, 0);
        CFX_SizeF sz = CalcTextSize(
            wsText, m_pProperties->m_pThemeProvider,
            m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
        rect.Set(0, 0, sz.x, sz.y);
      }
    }
    CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
  } else {
    rect = m_pProperties->m_rtWidget;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      if (IsShowScrollBar(TRUE)) {
        FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
        rect.width += *pfWidth;
        rect.width += FWL_EDIT_Margin;
      }
      if (IsShowScrollBar(FALSE)) {
        FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
        rect.height += *pfWidth;
        rect.height += FWL_EDIT_Margin;
      }
    }
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    ShowCaret(FALSE);
  }
  return CFWL_WidgetImp::SetStates(dwStates, bSet);
}
FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) {
  return CFWL_WidgetImp::SetWidgetRect(rect);
}
FWL_ERR CFWL_EditImp::Update() {
  if (IsLocked()) {
    return FWL_ERR_Indefinite;
  }
  if (!m_pProperties->m_pThemeProvider) {
    m_pProperties->m_pThemeProvider = GetAvailableTheme();
  }
  Layout();
  if (m_rtClient.IsEmpty()) {
    return FWL_ERR_Indefinite;
  }
  UpdateEditEngine();
  UpdateVAlignment();
  UpdateScroll();
  InitCaret();
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
    if (IsShowScrollBar(TRUE)) {
      CFX_RectF rect;
      m_pVertScrollBar->GetWidgetRect(rect);
      if (rect.Contains(fx, fy)) {
        return FWL_WGTHITTEST_VScrollBar;
      }
    }
    if (IsShowScrollBar(FALSE)) {
      CFX_RectF rect;
      m_pHorzScrollBar->GetWidgetRect(rect);
      if (rect.Contains(fx, fy)) {
        return FWL_WGTHITTEST_HScrollBar;
      }
    }
  }
  if (m_rtClient.Contains(fx, fy)) {
    return FWL_WGTHITTEST_Edit;
  }
  return FWL_WGTHITTEST_Unknown;
}
#define FX_EDIT_ISLATINWORD(u)                                     \
  (u == 0x2D || (u <= 0x005A && u >= 0x0041) ||                    \
   (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || \
   u == 0x0027)
static void AddSquigglyPath(CFX_Path& PathData,
                            FX_FLOAT fStartX,
                            FX_FLOAT fEndX,
                            FX_FLOAT fY,
                            FX_FLOAT fStep) {
  PathData.MoveTo(fStartX, fY);
  FX_FLOAT fx;
  int32_t i;
  for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
    PathData.LineTo(fx, fY + (i & 1) * fStep);
  }
}
void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData,
                                    int32_t nStart,
                                    int32_t nCount,
                                    FX_FLOAT fOffSetX,
                                    FX_FLOAT fOffSetY) {
  FX_FLOAT fStartX = 0.0f;
  FX_FLOAT fEndX = 0.0f;
  FX_FLOAT fY = 0.0f;
  FX_FLOAT fStep = 0.0f;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  CFX_RectFArray rectArray;
  CFX_RectF rectText;
  const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();
  FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() *
                    txtEdtParams->fFontSize / 1000;
  pPage->CalcRangeRectArray(nStart, nCount, rectArray);
  for (int i = 0; i < rectArray.GetSize(); i++) {
    rectText = rectArray.GetAt(i);
    fY = rectText.top + fAsent + fOffSetY;
    fStep = txtEdtParams->fFontSize / 16.0f;
    fStartX = rectText.left + fOffSetX;
    fEndX = fStartX + rectText.Width();
    AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
  }
}
int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) {
  return 0;
}
FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf,
                                      CFX_ByteStringArray& sSuggest) {
  int32_t nWordCount = 0;
  int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
  if (nWordCount < 1) {
    return FALSE;
  }
  CFX_WideString wsSpell;
  GetText(wsSpell, nWordStart, nWordCount);
  CFX_ByteString sLatinWord;
  for (int i = 0; i < nWordCount; i++) {
    if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
      break;
    }
    sLatinWord += (FX_CHAR)wsSpell[i];
  }
  if (sLatinWord.IsEmpty()) {
    return FALSE;
  }
  CFWL_EvtEdtCheckWord checkWordEvent;
  checkWordEvent.m_pSrcTarget = m_pInterface;
  checkWordEvent.bsWord = sLatinWord;
  checkWordEvent.bCheckWord = TRUE;
  DispatchEvent(&checkWordEvent);
  if (checkWordEvent.bCheckWord) {
    return FALSE;
  }
  CFWL_EvtEdtGetSuggestWords suggestWordsEvent;
  suggestWordsEvent.m_pSrcTarget = m_pInterface;
  suggestWordsEvent.bsWord = sLatinWord;
  suggestWordsEvent.bsArraySuggestWords = sSuggest;
  suggestWordsEvent.bSuggestWords = FALSE;
  DispatchEvent(&checkWordEvent);
  return suggestWordsEvent.bSuggestWords;
}
FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf,
                                            const CFX_ByteStringC& bsReplace) {
  int32_t nWordCount = 0;
  int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
  if (nWordCount < 1) {
    return FALSE;
  }
  CFX_WideString wsSpell;
  GetText(wsSpell, nWordStart, nWordCount);
  for (int i = 0; i < nWordCount; i++) {
    if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
      nWordCount = i;
      break;
    }
  }
  int32_t nDestLen = bsReplace.GetLength();
  CFX_WideString wsDest;
  FX_WCHAR* pBuffer = wsDest.GetBuffer(nDestLen);
  for (int32_t i = 0; i < nDestLen; i++) {
    pBuffer[i] = bsReplace[i];
  }
  wsDest.ReleaseBuffer(nDestLen);
  Replace(nWordStart, nWordCount, wsDest);
  return TRUE;
}
void CFWL_EditImp::DrawSpellCheck(CFX_Graphics* pGraphics,
                                  const CFX_Matrix* pMatrix) {
  pGraphics->SaveGraphState();
  if (pMatrix) {
    pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix));
  }
  FX_ARGB cr = 0xFFFF0000;
  CFX_Color crLine(cr);
  CFWL_EvtEdtCheckWord checkWordEvent;
  checkWordEvent.m_pSrcTarget = m_pInterface;
  CFX_ByteString sLatinWord;
  CFX_Path pathSpell;
  pathSpell.Create();
  int32_t nStart = 0;
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  CFX_WideString wsSpell;
  this->GetText(wsSpell);
  int32_t nContentLen = wsSpell.GetLength();
  for (int i = 0; i < nContentLen; i++) {
    if (FX_EDIT_ISLATINWORD(wsSpell[i])) {
      if (sLatinWord.IsEmpty()) {
        nStart = i;
      }
      sLatinWord += (FX_CHAR)wsSpell[i];
    } else {
      checkWordEvent.bsWord = sLatinWord;
      checkWordEvent.bCheckWord = TRUE;
      DispatchEvent(&checkWordEvent);
      if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
        AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
                         fOffSetY);
      }
      sLatinWord.Empty();
    }
  }
  checkWordEvent.bsWord = sLatinWord;
  checkWordEvent.bCheckWord = TRUE;
  DispatchEvent(&checkWordEvent);
  if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
    AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
                     fOffSetY);
  }
  if (!pathSpell.IsEmpty()) {
    CFX_RectF rtClip = m_rtEngine;
    CFX_Matrix mt;
    mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
    if (pMatrix) {
      pMatrix->TransformRect(rtClip);
      mt.Concat(*pMatrix);
    }
    pGraphics->SetClipRect(rtClip);
    pGraphics->SetStrokeColor(&crLine);
    pGraphics->SetLineWidth(0);
    pGraphics->StrokePath(&pathSpell, NULL);
  }
  pGraphics->RestoreGraphState();
}
FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics* pGraphics,
                                 const CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return FWL_ERR_Indefinite;
  if (!m_pProperties->m_pThemeProvider)
    return FWL_ERR_Indefinite;
  if (m_rtClient.IsEmpty()) {
    return FWL_ERR_Indefinite;
  }
  IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
  if (!m_pWidgetMgr->IsFormDisabled()) {
    DrawTextBk(pGraphics, pTheme, pMatrix);
  }
  if (m_pEdtEngine) {
    DrawContent(pGraphics, pTheme, pMatrix);
  }
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) &&
      !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) {
    DrawSpellCheck(pGraphics, pMatrix);
  }
  if (HasBorder()) {
    DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix);
  }
  if (HasEdge()) {
    DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
  if (!pThemeProvider)
    return FWL_ERR_Indefinite;
  if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetThemeProvider(pThemeProvider);
  }
  if (m_pVertScrollBar) {
    m_pVertScrollBar->SetThemeProvider(pThemeProvider);
  }
  if (m_pCaret) {
    m_pCaret->SetThemeProvider(pThemeProvider);
  }
  m_pProperties->m_pThemeProvider = pThemeProvider;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) {
  m_pEdtEngine->SetText(wsText);
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetTextLength() const {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetTextLength();
}
FWL_ERR CFWL_EditImp::GetText(CFX_WideString& wsText,
                              int32_t nStart,
                              int32_t nCount) const {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->GetText(wsText, nStart, nCount);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::ClearText() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->ClearText();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetCaretPos() const {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetCaretPos();
}
int32_t CFWL_EditImp::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->SetCaretPos(nIndex, bBefore);
}
FWL_ERR CFWL_EditImp::AddSelRange(int32_t nStart, int32_t nCount) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->AddSelRange(nStart, nCount);
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::CountSelRanges() {
  if (!m_pEdtEngine)
    return 0;
  return m_pEdtEngine->CountSelRanges();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetSelRange(int32_t nIndex, int32_t& nStart) {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetSelRange(nIndex, nStart);
}
FWL_ERR CFWL_EditImp::ClearSelections() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->ClearSelection();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetLimit() {
  return m_nLimit;
}
FWL_ERR CFWL_EditImp::SetLimit(int32_t nLimit) {
  m_nLimit = nLimit;
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->SetLimit(nLimit);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias) {
  if (!m_pEdtEngine)
    return FWL_ERR_Indefinite;
  m_pEdtEngine->SetAliasChar(wAlias);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetFormatString(const CFX_WideString& wsFormat) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->SetFormatBlock(0, wsFormat);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Insert(int32_t nStart,
                             const FX_WCHAR* lpText,
                             int32_t nLen) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return FWL_ERR_Indefinite;
  }
  m_pEdtEngine->Insert(nStart, lpText, nLen);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DeleteSelections() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  int32_t iCount = m_pEdtEngine->CountSelRanges();
  if (iCount > 0) {
    m_pEdtEngine->Delete(-1);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DeleteRange(int32_t nStart, int32_t nCount) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->DeleteRange(nStart, nCount);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC& wsReplace) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  int32_t iCount = m_pEdtEngine->CountSelRanges();
  for (int i = 0; i < iCount; i++) {
    int32_t nStart;
    int32_t nCount = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->Replace(nStart, nCount, wsReplace);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Replace(int32_t nStart,
                              int32_t nLen,
                              const CFX_WideStringC& wsReplace) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->Replace(nStart, nLen, wsReplace);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DoClipboard(int32_t iCmd) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return FWL_ERR_Succeeded;
  }
  IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
  if (!pNative)
    return FWL_ERR_Indefinite;
  IFWL_AdapterClipboardMgr* pClipBorder = pNative->GetClipboardMgr();
  if (!pClipBorder)
    return FWL_ERR_Indefinite;
  CFX_WideString wsText;
  switch (iCmd) {
    case 1: {
      int32_t nStart;
      int32_t nCount = m_pEdtEngine->GetSelRange(0, nStart);
      if (nCount < 1) {
        break;
      }
      m_pEdtEngine->GetText(wsText, nStart, nCount);
      pClipBorder->SetStringData(wsText);
      break;
    }
    case 2: {
      int32_t nStart;
      int32_t nCount = m_pEdtEngine->GetSelRange(0, nStart);
      if (nCount < 1) {
        break;
      }
      m_pEdtEngine->GetText(wsText, nStart, nCount);
      m_pEdtEngine->DeleteRange(nStart, nCount);
      m_pEdtEngine->ClearSelection();
      pClipBorder->SetStringData(wsText);
      break;
    }
    case 3: {
      pClipBorder->GetStringData(wsText);
      int32_t iLen = wsText.GetLength();
      if (iLen < 0) {
        break;
      }
      if (wsText[iLen] == L'\0') {
        if (iLen == 1) {
          break;
        }
        iLen--;
        wsText = wsText.Left(iLen);
      }
      int32_t nPos = m_pEdtEngine->GetCaretPos();
      m_pEdtEngine->Insert(nPos, wsText, iLen);
      break;
    }
    default: {}
  }
  return FWL_ERR_Succeeded;
}
FX_BOOL CFWL_EditImp::Copy(CFX_WideString& wsCopy) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount == 0) {
    return FALSE;
  }
  wsCopy.Empty();
  CFX_WideString wsTemp;
  int32_t nStart, nLength;
  for (int32_t i = 0; i < nCount; i++) {
    nLength = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->GetText(wsTemp, nStart, nLength);
    wsCopy += wsTemp;
    wsTemp.Empty();
  }
  return TRUE;
}
FX_BOOL CFWL_EditImp::Cut(CFX_WideString& wsCut) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount == 0) {
    return FALSE;
  }
  wsCut.Empty();
  CFX_WideString wsTemp;
  int32_t nStart, nLength;
  for (int32_t i = 0; i < nCount; i++) {
    nLength = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->GetText(wsTemp, nStart, nLength);
    wsCut += wsTemp;
    wsTemp.Empty();
  }
  m_pEdtEngine->Delete(0);
  return TRUE;
}
FX_BOOL CFWL_EditImp::Paste(const CFX_WideString& wsPaste) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCaret = m_pEdtEngine->GetCaretPos();
  int32_t iError =
      m_pEdtEngine->Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength());
  if (iError < 0) {
    ProcessInsertError(iError);
    return FALSE;
  }
  return TRUE;
}
FX_BOOL CFWL_EditImp::Delete() {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount < 1) {
    return FALSE;
  }
  m_pEdtEngine->Delete(0);
  return TRUE;
}
FX_BOOL CFWL_EditImp::Redo(const CFX_ByteStringC& bsRecord) {
  if (!m_pEdtEngine)
    return FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
    return TRUE;
  }
  return m_pEdtEngine->Redo(bsRecord);
}
FX_BOOL CFWL_EditImp::Undo(const CFX_ByteStringC& bsRecord) {
  if (!m_pEdtEngine)
    return FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
    return TRUE;
  }
  return m_pEdtEngine->Undo(bsRecord);
}
FX_BOOL CFWL_EditImp::Undo() {
  if (!CanUndo()) {
    return FALSE;
  }
  CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];
  return Undo(bsRecord);
}
FX_BOOL CFWL_EditImp::Redo() {
  if (!CanRedo()) {
    return FALSE;
  }
  CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];
  return Redo(bsRecord);
}
FX_BOOL CFWL_EditImp::CanUndo() {
  return m_iCurRecord >= 0;
}
FX_BOOL CFWL_EditImp::CanRedo() {
  return m_iCurRecord < m_RecordArr.GetSize() - 1;
}
FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  FDE_LPTXTEDTPARAMS pParams =
      (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams();
  pParams->fTabWidth = fTabWidth;
  pParams->bTabEquidistant = bEquidistant;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) {
  m_pOuter = pOuter;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetNumberRange(int32_t iMin, int32_t iMax) {
  m_iMin = iMin;
  m_iMax = iMax;
  m_bSetRange = TRUE;
  return FWL_ERR_Succeeded;
}
void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine* pEdit,
                                   int32_t nPage,
                                   FX_BOOL bVisible) {
  if (m_rtEngine.IsEmpty()) {
    return;
  }
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
    return;
  }
  FX_BOOL bRepaintContent = UpdateOffset();
  UpdateCaret();
  CFX_RectF rtInvalid;
  rtInvalid.Set(0, 0, 0, 0);
  FX_BOOL bRepaintScroll = FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
    IFWL_ScrollBar* pScroll = UpdateScroll();
    if (pScroll) {
      pScroll->GetWidgetRect(rtInvalid);
      bRepaintScroll = TRUE;
    }
  }
  if (bRepaintContent || bRepaintScroll) {
    if (bRepaintContent) {
      rtInvalid.Union(m_rtEngine);
    }
    Repaint(&rtInvalid);
  }
}
void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine* pEdit,
                                  FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) {
  FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes;
  if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) {
    UpdateVAlignment();
  }
  IFDE_TxtEdtPage* page = m_pEdtEngine->GetPage(0);
  FX_FLOAT fContentWidth = page->GetContentsBox().width;
  FX_FLOAT fContentHeight = page->GetContentsBox().height;
  CFX_RectF rtTemp;
  GetClientRect(rtTemp);
  FX_BOOL bHSelfAdaption =
      m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;
  FX_BOOL bVSelfAdaption =
      m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;
  FX_BOOL bNeedUpdate = FALSE;
  if (bHSelfAdaption || bVSelfAdaption) {
    CFWL_EvtEdtPreSelfAdaption evt;
    evt.m_pSrcTarget = m_pInterface;
    evt.bHSelfAdaption = TRUE;
    evt.bVSelfAdaption = TRUE;
    FX_FLOAT fWidth;
    FX_FLOAT fHight;
    fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;
    fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;
    evt.rtAfterChange.Set(0, 0, fWidth, fHight);
    DispatchEvent(&evt);
    if (!evt.bHSelfAdaption) {
      ModifyStylesEx(
          0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);
    }
    if (!evt.bVSelfAdaption) {
      ModifyStylesEx(
          0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);
    }
    bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) ||
                  (bVSelfAdaption && !evt.bVSelfAdaption);
  }
  FX_FLOAT fContentWidth1 = fContentWidth;
  FX_FLOAT fContentHeight1 = fContentHeight;
  if (bNeedUpdate) {
    UpdateEditParams();
    UpdateEditLayout();
    IFDE_TxtEdtPage* page1 = m_pEdtEngine->GetPage(0);
    fContentWidth1 = page1->GetContentsBox().width;
    fContentHeight1 = page1->GetContentsBox().height;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {
    rtTemp.width = std::max(m_pProperties->m_rtWidget.width, fContentWidth1);
    m_pProperties->m_rtWidget.width = fContentWidth1;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {
    rtTemp.height = std::max(m_pProperties->m_rtWidget.height, fContentHeight1);
    m_pProperties->m_rtWidget.height = fContentHeight1;
  }
  CFWL_EvtEdtTextChanged event;
  event.m_pSrcTarget = m_pInterface;
  event.nChangeType = ChangeInfo.nChangeType;
  event.wsInsert = ChangeInfo.wsInsert;
  event.wsDelete = ChangeInfo.wsDelete;
  event.wsPrevText = ChangeInfo.wsPrevText;
  DispatchEvent(&event);
  LayoutScrollBar();
  Repaint(&rtTemp);
}
void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) {
  CFX_RectF rtTemp;
  GetClientRect(rtTemp);
  Repaint(&rtTemp);
}
FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine* pEdit,
                                  int32_t nPageIndex,
                                  int32_t nPurpose) {
  IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
  IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
  if (!pPage)
    return FALSE;
  pPage->LoadPage();
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine* pEdit,
                                    int32_t nPageIndex,
                                    int32_t nPurpose) {
  IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
  IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
  if (!pPage)
    return FALSE;
  pPage->UnloadPage();
  return TRUE;
}

void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine* pEdit,
                                  const CFX_ByteStringC& bsDoRecord) {
  AddDoRecord(bsDoRecord);
}

FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine* pEdit,
                                       int32_t nBlockIndex,
                                       int32_t nFieldIndex,
                                       const CFX_WideString& wsFieldText,
                                       int32_t nCharIndex) {
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit,
                                       int32_t nBlockIndex) {
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit,
                                            int32_t nBlockIndex,
                                            CFX_WideString& wsBlockText) {
  return FALSE;
}
FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine* pEdit,
                                  CFX_WideString& wsText) {
  IFWL_Widget* pDst = GetOuter();
  if (!pDst) {
    pDst = m_pInterface;
  }
  CFWL_EvtEdtValidate event;
  event.pDstWidget = pDst;
  event.m_pSrcTarget = m_pInterface;
  event.wsInsert = wsText;
  event.bValidate = TRUE;
  DispatchEvent(&event);
  return event.bValidate;
}
FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) {
  m_backColor = color;
  m_updateBackColor = TRUE;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
  m_wsFont = wsFont;
  m_fFontSize = fSize;
  return FWL_ERR_Succeeded;
}
void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) {
  m_fScrollOffsetY = fScrollOffset;
}
void CFWL_EditImp::DrawTextBk(CFX_Graphics* pGraphics,
                              IFWL_ThemeProvider* pTheme,
                              const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground param;
  param.m_pWidget = m_pInterface;
  param.m_iPart = FWL_PART_EDT_Background;
  param.m_dwData = FWL_PARTDATA_EDT_Background;
  param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly
                         ? FWL_PARTSTATE_EDT_ReadOnly
                         : FWL_PARTSTATE_EDT_Normal;
  FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled);
  if (dwStates) {
    param.m_dwStates = FWL_PARTSTATE_EDT_Disable;
  }
  param.m_pGraphics = pGraphics;
  param.m_matrix = *pMatrix;
  param.m_rtPart = m_rtClient;
  pTheme->DrawBackground(&param);
  if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) {
    return;
  }
  CFX_RectF rtScorll;
  m_pHorzScrollBar->GetWidgetRect(rtScorll);
  CFX_RectF rtStatic;
  rtStatic.Set(m_rtClient.right() - rtScorll.height,
               m_rtClient.bottom() - rtScorll.height, rtScorll.height,
               rtScorll.height);
  param.m_dwData = FWL_PARTDATA_EDT_StaticBackground;
  param.m_rtPart = rtStatic;
  pTheme->DrawBackground(&param);
}
void CFWL_EditImp::DrawContent(CFX_Graphics* pGraphics,
                               IFWL_ThemeProvider* pTheme,
                               const CFX_Matrix* pMatrix) {
  if (!m_pEdtEngine)
    return;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  pGraphics->SaveGraphState();
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    pGraphics->SaveGraphState();
  }
  CFX_RectF rtClip = m_rtEngine;
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  CFX_Matrix mt;
  mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
  if (pMatrix) {
    pMatrix->TransformRect(rtClip);
    mt.Concat(*pMatrix);
  }
  FX_BOOL bShowSel =
      (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
  if (bShowSel) {
    IFWL_Widget* pForm =
        m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
    if (pForm) {
      bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) !=
                 FWL_WGTSTATE_Deactivated;
    }
  }
  int32_t nSelCount = m_pEdtEngine->CountSelRanges();
  if (bShowSel && nSelCount > 0) {
    int32_t nPageCharStart = pPage->GetCharStart();
    int32_t nPageCharCount = pPage->GetCharCount();
    int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1;
    int32_t nCharCount;
    int32_t nCharStart;
    CFX_RectFArray rectArr;
    int32_t i = 0;
    for (i = 0; i < nSelCount; i++) {
      nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart);
      int32_t nCharEnd = nCharStart + nCharCount - 1;
      if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) {
        continue;
      }
      int32_t nBgn = std::max(nCharStart, nPageCharStart);
      int32_t nEnd = std::min(nCharEnd, nPageCharEnd);
      pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1,
                                rectArr);
    }
    int32_t nCount = rectArr.GetSize();
    CFX_Path path;
    path.Create();
    for (i = 0; i < nCount; i++) {
      rectArr[i].left += fOffSetX;
      rectArr[i].top += fOffSetY;
      path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width,
                        rectArr[i].height);
    }
    pGraphics->SetClipRect(rtClip);
    CFWL_ThemeBackground param;
    param.m_pGraphics = pGraphics;
    param.m_matrix = *pMatrix;
    param.m_pWidget = m_pInterface;
    param.m_iPart = FWL_PART_EDT_Background;
    param.m_pPath = &path;
    pTheme->DrawBackground(&param);
  }
  CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice();
  if (!pRenderDev)
    return;
  IFDE_RenderDevice* pRenderDevice = IFDE_RenderDevice::Create(pRenderDev);
  if (!pRenderDevice)
    return;
  IFDE_RenderContext* pRenderContext = IFDE_RenderContext::Create();
  if (!pRenderContext)
    return;
  pRenderDevice->SetClipRect(rtClip);
  pRenderContext->StartRender(pRenderDevice, pPage, mt);
  pRenderContext->DoRender(NULL);
  pRenderContext->Release();
  pRenderDevice->Release();
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    pGraphics->RestoreGraphState();
    CFX_Path path;
    path.Create();
    int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1;
    FX_FLOAT fStep = m_rtEngine.width / iLimit;
    FX_FLOAT fLeft = m_rtEngine.left + 1;
    for (int32_t i = 1; i < iLimit; i++) {
      fLeft += fStep;
      path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom());
    }
    CFWL_ThemeBackground param;
    param.m_pGraphics = pGraphics;
    param.m_matrix = *pMatrix;
    param.m_pWidget = m_pInterface;
    param.m_iPart = FWL_PART_EDT_CombTextLine;
    param.m_pPath = &path;
    pTheme->DrawBackground(&param);
  }
  pGraphics->RestoreGraphState();
}
void CFWL_EditImp::UpdateEditEngine() {
  UpdateEditParams();
  UpdateEditLayout();
  if (m_nLimit > -1) {
    m_pEdtEngine->SetLimit(m_nLimit);
  }
}
void CFWL_EditImp::UpdateEditParams() {
  FDE_TXTEDTPARAMS params;
  params.nHorzScale = 100;
  params.fPlateWidth = m_rtEngine.width;
  params.fPlateHeight = m_rtEngine.height;
  if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) {
    params.dwMode |= FDE_TEXTEDITMODE_Validate;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) {
    params.dwMode |= FDE_TEXTEDITMODE_Password;
  }
  switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) {
    case FWL_STYLEEXT_EDT_HNear: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Left;
      break;
    }
    case FWL_STYLEEXT_EDT_HCenter: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Center;
      break;
    }
    case FWL_STYLEEXT_EDT_HFar: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Right;
      break;
    }
    default: {}
  }
  switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) {
    case FWL_STYLEEXT_EDT_Justified: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Justified;
      break;
    }
    case FWL_STYLEEXT_EDT_Distributed: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed;
      break;
    }
    default: { params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; }
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
    params.dwMode |= FDE_TEXTEDITMODE_MultiLines;
    if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 &&
        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
      params.dwMode |=
          FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz;
    }
    if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 &&
        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) {
      params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert;
    } else {
      params.fPlateHeight = 0x00FFFFFF;
    }
  } else {
    if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
      params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz;
    }
  }
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    params.dwMode |= FDE_TEXTEDITMODE_ReadOnly;
  }
  FX_FLOAT* pFontSize =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FontSize));
  if (!pFontSize)
    return;
  m_fFontSize = *pFontSize;
  FX_DWORD* pFontColor =
      static_cast<FX_DWORD*>(GetThemeCapacity(FWL_WGTCAPACITY_TextColor));
  if (!pFontColor)
    return;
  params.dwFontColor = *pFontColor;
  FX_FLOAT* pLineHeight =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_LineHeight));
  if (!pLineHeight)
    return;
  params.fLineSpace = *pLineHeight;
  IFX_Font* pFont =
      static_cast<IFX_Font*>(GetThemeCapacity(FWL_WGTCAPACITY_Font));
  if (!pFont)
    return;
  params.pFont = pFont;
  params.fFontSize = m_fFontSize;
  params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace);
  if (params.nLineCount <= 0) {
    params.nLineCount = 1;
  }
  params.fTabWidth = params.fFontSize * 1;
  params.bTabEquidistant = TRUE;
  params.wLineBreakChar = L'\n';
  params.nCharRotation = 0;
  params.pEventSink = this;
  m_pEdtEngine->SetEditParams(params);
}
void CFWL_EditImp::UpdateEditLayout() {
  if (m_pEdtEngine->GetTextLength() <= 0) {
    m_pEdtEngine->SetTextByStream(NULL);
  }
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (pPage) {
    pPage->UnloadPage();
    pPage = NULL;
  }
  m_pEdtEngine->StartLayout();
  m_pEdtEngine->DoLayout(NULL);
  m_pEdtEngine->EndLayout();
  pPage = m_pEdtEngine->GetPage(0);
  if (pPage) {
    pPage->LoadPage();
  }
}
FX_BOOL CFWL_EditImp::UpdateOffset() {
  CFX_RectF rtCaret;
  m_pEdtEngine->GetCaretRect(rtCaret);
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  rtCaret.Offset(fOffSetX, fOffSetY);
  const CFX_RectF& rtEidt = m_rtEngine;
  if (rtEidt.Contains(rtCaret)) {
    IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
    if (!pPage)
      return FALSE;
    CFX_RectF rtFDE = pPage->GetContentsBox();
    rtFDE.Offset(fOffSetX, fOffSetY);
    if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) {
      m_fScrollOffsetX += rtFDE.right() - rtEidt.right();
      if (m_fScrollOffsetX < 0) {
        m_fScrollOffsetX = 0;
      }
    }
    if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) {
      m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom();
      if (m_fScrollOffsetY < 0) {
        m_fScrollOffsetY = 0;
      }
    }
    return FALSE;
  } else {
    FX_FLOAT offsetX = 0.0;
    FX_FLOAT offsetY = 0.0;
    if (rtCaret.left < rtEidt.left) {
      offsetX = rtCaret.left - rtEidt.left;
    }
    if (rtCaret.right() > rtEidt.right()) {
      offsetX = rtCaret.right() - rtEidt.right();
    }
    if (rtCaret.top < rtEidt.top) {
      offsetY = rtCaret.top - rtEidt.top;
    }
    if (rtCaret.bottom() > rtEidt.bottom()) {
      offsetY = rtCaret.bottom() - rtEidt.bottom();
    }
    if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) {
      m_fScrollOffsetX += offsetX;
    }
    if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) {
      m_fScrollOffsetY += offsetY;
    }
    if (m_fFontSize > m_rtEngine.height) {
      m_fScrollOffsetY = 0;
    }
    return TRUE;
  }
}
FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar* pScrollBar,
                                   FX_FLOAT fPosChanged) {
  if (pScrollBar == m_pHorzScrollBar.get()) {
    m_fScrollOffsetX += fPosChanged;
  } else {
    m_fScrollOffsetY += fPosChanged;
  }
  return TRUE;
}
void CFWL_EditImp::UpdateVAlignment() {
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  const CFX_RectF& rtFDE = pPage->GetContentsBox();
  FX_FLOAT fOffsetY = 0.0f;
  FX_FLOAT fSpaceAbove = 0.0f;
  FX_FLOAT fSpaceBelow = 0.0f;
  CFX_SizeF* pSpace = static_cast<CFX_SizeF*>(
      GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow));
  if (pSpace) {
    fSpaceAbove = pSpace->x;
    fSpaceBelow = pSpace->y;
  }
  if (fSpaceAbove < 0.1f) {
    fSpaceAbove = 0;
  }
  if (fSpaceBelow < 0.1f) {
    fSpaceBelow = 0;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) {
    fOffsetY = (m_rtEngine.height - rtFDE.height) / 2;
    if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 &&
        fSpaceAbove < fSpaceBelow) {
      return;
    }
    fOffsetY += (fSpaceAbove - fSpaceBelow) / 2;
  } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) {
    fOffsetY = (m_rtEngine.height - rtFDE.height);
    fOffsetY -= fSpaceBelow;
  } else {
    fOffsetY += fSpaceAbove;
  }
  m_fVAlignOffset = fOffsetY;
  if (m_fVAlignOffset < 0) {
    m_fVAlignOffset = 0;
  }
}
void CFWL_EditImp::UpdateCaret() {
  CFX_RectF rtFDE;
  m_pEdtEngine->GetCaretRect(rtFDE);
  rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX,
               m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset);
  CFX_RectF rtCaret;
  rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height);
  CFX_RectF temp = rtCaret;
  CFX_RectF rtClient;
  GetClientRect(rtClient);
  rtCaret.Intersect(rtClient);
  if (rtCaret.left > rtClient.right()) {
    FX_FLOAT right = rtCaret.right();
    rtCaret.left = rtClient.right() - 1;
    rtCaret.width = right - rtCaret.left;
  }
  FX_BOOL bIntersect = !rtCaret.IsEmpty();
  FX_BOOL bShow = TRUE;
  FX_BOOL bShowWhole = FALSE;
  if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {
    bShow = FALSE;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption &&
      temp.right() > m_rtEngine.right()) {
    bShowWhole = TRUE;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption &&
      temp.bottom() > m_rtEngine.bottom()) {
    bShowWhole = TRUE;
  } else {
    bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);
  }
  if (bShowWhole) {
    rtCaret = temp;
  }
  ShowCaret(bShow, &rtCaret);
}
IFWL_ScrollBar* CFWL_EditImp::UpdateScroll() {
  FX_BOOL bShowHorz =
      m_pHorzScrollBar &&
      ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
  FX_BOOL bShowVert =
      m_pVertScrollBar &&
      ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
  if (!bShowHorz && !bShowVert) {
    return NULL;
  }
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return NULL;
  const CFX_RectF& rtFDE = pPage->GetContentsBox();
  IFWL_ScrollBar* pRepaint = NULL;
  if (bShowHorz) {
    CFX_RectF rtScroll;
    m_pHorzScrollBar->GetWidgetRect(rtScroll);
    if (rtScroll.width < rtFDE.width) {
      m_pHorzScrollBar->LockUpdate();
      FX_FLOAT fRange = rtFDE.width - rtScroll.width;
      m_pHorzScrollBar->SetRange(0.0f, fRange);
      FX_FLOAT fPos = m_fScrollOffsetX;
      if (fPos < 0.0f) {
        fPos = 0.0f;
      }
      if (fPos > fRange) {
        fPos = fRange;
      }
      m_pHorzScrollBar->SetPos(fPos);
      m_pHorzScrollBar->SetTrackPos(fPos);
      m_pHorzScrollBar->SetPageSize(rtScroll.width);
      m_pHorzScrollBar->SetStepSize(rtScroll.width / 10);
      m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
      m_pHorzScrollBar->UnlockUpdate();
      m_pHorzScrollBar->Update();
      pRepaint = m_pHorzScrollBar.get();
    } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
      m_pHorzScrollBar->LockUpdate();
      m_pHorzScrollBar->SetRange(0, -1);
      m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
      m_pHorzScrollBar->UnlockUpdate();
      m_pHorzScrollBar->Update();
      pRepaint = m_pHorzScrollBar.get();
    }
  }
  if (bShowVert) {
    CFX_RectF rtScroll;
    m_pVertScrollBar->GetWidgetRect(rtScroll);
    if (rtScroll.height < rtFDE.height) {
      m_pVertScrollBar->LockUpdate();
      FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace;
      FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;
      if (fRange < fStep) {
        fRange = fStep;
      }
      m_pVertScrollBar->SetRange(0.0f, fRange);
      FX_FLOAT fPos = m_fScrollOffsetY;
      if (fPos < 0.0f) {
        fPos = 0.0f;
      }
      if (fPos > fRange) {
        fPos = fRange;
      }
      m_pVertScrollBar->SetPos(fPos);
      m_pVertScrollBar->SetTrackPos(fPos);
      m_pVertScrollBar->SetPageSize(rtScroll.height);
      m_pVertScrollBar->SetStepSize(fStep);
      m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
      m_pVertScrollBar->UnlockUpdate();
      m_pVertScrollBar->Update();
      pRepaint = m_pVertScrollBar.get();
    } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
      m_pVertScrollBar->LockUpdate();
      m_pVertScrollBar->SetRange(0, -1);
      m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
      m_pVertScrollBar->UnlockUpdate();
      m_pVertScrollBar->Update();
      pRepaint = m_pVertScrollBar.get();
    }
  }
  return pRepaint;
}
FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert) {
  FX_BOOL bShow =
      (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus)
          ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) ==
                FWL_WGTSTATE_Focused
          : TRUE;
  if (bVert) {
    return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) &&
           (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) &&
           IsContentHeightOverflow();
  }
  return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) &&
         (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
}
FX_BOOL CFWL_EditImp::IsContentHeightOverflow() {
  if (!m_pEdtEngine)
    return FALSE;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return FALSE;
  return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f;
}
int32_t CFWL_EditImp::AddDoRecord(const CFX_ByteStringC& bsDoRecord) {
  int32_t nCount = m_RecordArr.GetSize();
  if (m_iCurRecord == nCount - 1) {
    if (nCount == m_iMaxRecord) {
      m_RecordArr.RemoveAt(0);
      m_iCurRecord--;
    }
  } else {
    for (int32_t i = nCount - 1; i > m_iCurRecord; i--) {
      m_RecordArr.RemoveAt(i);
    }
  }
  m_RecordArr.Add(bsDoRecord);
  return m_iCurRecord = m_RecordArr.GetSize() - 1;
}
void CFWL_EditImp::Layout() {
  GetClientRect(m_rtClient);
  m_rtEngine = m_rtClient;
  FX_FLOAT* pfWidth =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
  if (!pfWidth)
    return;
  FX_FLOAT fWidth = *pfWidth;
  if (!m_pOuter) {
    CFX_RectF* pUIMargin =
        static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin));
    if (pUIMargin) {
      m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
                         pUIMargin->height);
    }
  } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) {
    CFWL_ThemePart part;
    part.m_pWidget = m_pOuter;
    CFX_RectF* pUIMargin =
        static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity(
            &part, FWL_WGTCAPACITY_UIMargin));
    if (pUIMargin) {
      m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
                         pUIMargin->height);
    }
  }
  FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
  FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
  if (bShowVertScrollbar) {
    InitScrollBar();
    CFX_RectF rtVertScr;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
                    fWidth, m_rtClient.height);
    } else {
      rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
                    m_rtClient.height);
      if (bShowHorzScrollbar) {
        rtVertScr.height -= fWidth;
      }
      m_rtEngine.width -= fWidth;
    }
    m_pVertScrollBar->SetWidgetRect(rtVertScr);
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
    m_pVertScrollBar->Update();
  } else if (m_pVertScrollBar) {
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowHorzScrollbar) {
    InitScrollBar(FALSE);
    CFX_RectF rtHoriScr;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
                    m_rtClient.width, fWidth);
    } else {
      rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
                    m_rtClient.width, fWidth);
      if (bShowVertScrollbar) {
        rtHoriScr.width -= fWidth;
      }
      m_rtEngine.height -= fWidth;
    }
    m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
    m_pHorzScrollBar->Update();
  } else if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
}
void CFWL_EditImp::LayoutScrollBar() {
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) ==
      0) {
    return;
  }
  FX_FLOAT* pfWidth = NULL;
  FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
  FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
  if (bShowVertScrollbar) {
    if (!m_pVertScrollBar) {
      pfWidth = static_cast<FX_FLOAT*>(
          GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
      FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
      InitScrollBar();
      CFX_RectF rtVertScr;
      if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
        rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
                      fWidth, m_rtClient.height);
      } else {
        rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
                      m_rtClient.height);
        if (bShowHorzScrollbar) {
          rtVertScr.height -= fWidth;
        }
      }
      m_pVertScrollBar->SetWidgetRect(rtVertScr);
      m_pVertScrollBar->Update();
    }
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
  } else if (m_pVertScrollBar) {
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowHorzScrollbar) {
    if (!m_pHorzScrollBar) {
      if (!pfWidth) {
        pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
      }
      FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
      InitScrollBar(FALSE);
      CFX_RectF rtHoriScr;
      if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
        rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
                      m_rtClient.width, fWidth);
      } else {
        rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
                      m_rtClient.width, fWidth);
        if (bShowVertScrollbar) {
          rtHoriScr.width -= (fWidth);
        }
      }
      m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
      m_pHorzScrollBar->Update();
    }
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
  } else if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowVertScrollbar || bShowHorzScrollbar) {
    UpdateScroll();
  }
}
void CFWL_EditImp::DeviceToEngine(CFX_PointF& pt) {
  pt.x += -m_rtEngine.left + m_fScrollOffsetX;
  pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY;
}
void CFWL_EditImp::InitScrollBar(FX_BOOL bVert) {
  if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
    return;
  }
  CFWL_WidgetImpProperties prop;
  prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;
  prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible;
  prop.m_pParent = m_pInterface;
  prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
  IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, m_pInterface);
  pScrollBar->Initialize();
  (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar);
}
void CFWL_EditImp::InitEngine() {
  if (m_pEdtEngine) {
    return;
  }
  m_pEdtEngine = IFDE_TxtEdtEngine::Create();
}
extern FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
                             FX_BOOL bVisible,
                             const CFX_RectF* pRtAnchor);
void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF* pRect) {
  if (m_pCaret) {
    m_pCaret->ShowCaret(bVisible);
    if (bVisible && !pRect->IsEmpty()) {
      m_pCaret->SetWidgetRect(*pRect);
    }
    Repaint(&m_rtEngine);
  } else {
    IFWL_Widget* pOuter = m_pInterface;
    if (bVisible) {
      pRect->Offset(m_pProperties->m_rtWidget.left,
                    m_pProperties->m_rtWidget.top);
    }
    while (pOuter->GetOuter()) {
      pOuter = pOuter->GetOuter();
      if (bVisible) {
        CFX_RectF rtOuter;
        pOuter->GetWidgetRect(rtOuter);
        pRect->Offset(rtOuter.left, rtOuter.top);
      }
    }
    FWL_ShowCaret(pOuter, bVisible, pRect);
  }
}
FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum) {
  if (!m_pEdtEngine) {
    return FALSE;
  }
  if (!m_bSetRange) {
    return TRUE;
  }
  CFX_WideString wsOld, wsText;
  m_pEdtEngine->GetText(wsText, 0);
  if (wsText.IsEmpty()) {
    if (cNum == L'0') {
      return FALSE;
    }
    return TRUE;
  }
  int32_t caretPos = m_pEdtEngine->GetCaretPos();
  int32_t iSel = CountSelRanges();
  if (iSel == 0) {
    if (cNum == L'0' && caretPos == 0) {
      return FALSE;
    }
    int32_t nLen = wsText.GetLength();
    CFX_WideString l = wsText.Mid(0, caretPos);
    CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos);
    CFX_WideString wsNew = l + cNum + r;
    if (wsNew.GetInteger() <= m_iMax) {
      return TRUE;
    }
  } else {
    if (wsText.GetInteger() <= m_iMax) {
      return TRUE;
    }
  }
  return FALSE;
}
void CFWL_EditImp::InitCaret() {
  if (!m_pCaret) {
    if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) {
      CFWL_WidgetImpProperties prop;
      m_pCaret.reset(IFWL_Caret::Create(prop, m_pInterface));
      m_pCaret->Initialize();
      m_pCaret->SetParent(m_pInterface);
      m_pCaret->SetStates(m_pProperties->m_dwStates);
    }
  } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) ==
             0) {
    m_pCaret.reset();
  }
}
void CFWL_EditImp::ClearRecord() {
  m_iCurRecord = -1;
  m_RecordArr.RemoveAll();
}
void CFWL_EditImp::ProcessInsertError(int32_t iError) {
  switch (iError) {
    case -2: {
      CFWL_EvtEdtTextFull textFullEvent;
      textFullEvent.m_pSrcTarget = m_pInterface;
      DispatchEvent(&textFullEvent);
      break;
    }
    default: {}
  }
}
CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner)
    : m_pOwner(pOwner) {}
int32_t CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return 0;
  FX_DWORD dwMsgCode = pMessage->GetClassID();
  int32_t iRet = 1;
  switch (dwMsgCode) {
    case FWL_MSGHASH_Activate: {
      DoActivate(static_cast<CFWL_MsgActivate*>(pMessage));
      break;
    }
    case FWL_MSGHASH_Deactivate: {
      DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage));
      break;
    }
    case FWL_MSGHASH_SetFocus:
    case FWL_MSGHASH_KillFocus: {
      OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
      break;
    }
    case FWL_MSGHASH_Mouse: {
      CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
      FX_DWORD dwCmd = pMsg->m_dwCmd;
      switch (dwCmd) {
        case FWL_MSGMOUSECMD_LButtonDown: {
          OnLButtonDown(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonUp: {
          OnLButtonUp(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonDblClk: {
          OnButtonDblClk(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_MouseMove: {
          OnMouseMove(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_RButtonDown: {
          DoButtonDown(pMsg);
          break;
        }
        default: {}
      }
      break;
    }
    case FWL_MSGHASH_Key: {
      CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
      FX_DWORD dwCmd = pKey->m_dwCmd;
      if (dwCmd == FWL_MSGKEYCMD_KeyDown) {
        OnKeyDown(pKey);
      } else if (dwCmd == FWL_MSGKEYCMD_Char) {
        OnChar(pKey);
      }
      break;
    }
    default: { iRet = 0; }
  }
  CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
  return iRet;
}
FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
  if (!pEvent)
    return FWL_ERR_Indefinite;
  FX_DWORD dwHashCode = pEvent->GetClassID();
  if (dwHashCode != FWL_EVTHASH_Scroll) {
    return FWL_ERR_Succeeded;
  }
  IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
  if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() &&
       m_pOwner->m_pVertScrollBar) ||
      (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() &&
       m_pOwner->m_pHorzScrollBar)) {
    CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
    OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget),
             pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
                                           const CFX_Matrix* pMatrix) {
  return m_pOwner->DrawWidget(pGraphics, pMatrix);
}
void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate* pMsg) {
  m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;
  m_pOwner->Repaint(&m_pOwner->m_rtClient);
}
void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate* pMsg) {
  m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;
  m_pOwner->Repaint(&m_pOwner->m_rtClient);
}
void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse* pMsg) {
  if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
    m_pOwner->SetFocus(TRUE);
  }
  if (!m_pOwner->m_pEdtEngine) {
    m_pOwner->UpdateEditEngine();
  }
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  FX_BOOL bBefore = TRUE;
  int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
  if (nIndex < 0) {
    nIndex = 0;
  }
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
}
void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) {
  FX_DWORD dwStyleEx = m_pOwner->GetStylesEx();
  FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret;
  if (bSet) {
    m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
    if (!m_pOwner->m_pEdtEngine) {
      m_pOwner->UpdateEditEngine();
    }
    m_pOwner->UpdateVAlignment();
    m_pOwner->UpdateOffset();
    m_pOwner->UpdateCaret();
  } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
    m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
    m_pOwner->ShowCaret(FALSE);
    if (m_pOwner->m_pEdtEngine &&
        (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {
      int32_t nSel = m_pOwner->CountSelRanges();
      if (nSel > 0) {
        m_pOwner->ClearSelections();
        bRepaint = TRUE;
      }
      m_pOwner->SetCaretPos(0);
      m_pOwner->UpdateOffset();
    }
    m_pOwner->ClearRecord();
  }
  m_pOwner->LayoutScrollBar();
  if (bRepaint) {
    CFX_RectF rtInvalidate;
    rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
                     m_pOwner->m_pProperties->m_rtWidget.height);
    m_pOwner->Repaint(&rtInvalidate);
  }
}
void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
  DoCursor(pMsg);
  if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
    return;
  }
  m_pOwner->m_bLButtonDown = TRUE;
  m_pOwner->SetGrab(TRUE);
  DoButtonDown(pMsg);
  int32_t nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
  FX_BOOL bRepaint = FALSE;
  int32_t iCount = m_pOwner->m_pEdtEngine->CountSelRanges();
  if (iCount > 0) {
    m_pOwner->m_pEdtEngine->ClearSelection();
    bRepaint = TRUE;
  }
  FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
  if (bShift && m_pOwner->m_nSelStart != nIndex) {
    int32_t iStart = std::min(m_pOwner->m_nSelStart, nIndex);
    int32_t iEnd = std::max(m_pOwner->m_nSelStart, nIndex);
    m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);
    bRepaint = TRUE;
  } else {
    m_pOwner->m_nSelStart = nIndex;
  }
  if (bRepaint) {
    m_pOwner->Repaint(&m_pOwner->m_rtEngine);
  }
}
void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
  DoCursor(pMsg);
  m_pOwner->m_bLButtonDown = FALSE;
  m_pOwner->SetGrab(FALSE);
}
void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  DoCursor(pMsg);
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  int32_t nCount = 0;
  int32_t nIndex = pPage->SelectWord(pt, nCount);
  if (nIndex < 0) {
    return;
  }
  m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);
  m_pOwner->Repaint(&m_pOwner->m_rtEngine);
}
void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  DoCursor(pMsg);
  if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {
    return;
  }
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  FX_BOOL bBefore = TRUE;
  int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
  nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
  m_pOwner->m_pEdtEngine->ClearSelection();
  if (nIndex != m_pOwner->m_nSelStart) {
    int32_t nLen = m_pOwner->m_pEdtEngine->GetTextLength();
    if (m_pOwner->m_nSelStart >= nLen) {
      m_pOwner->m_nSelStart = nLen;
    }
    m_pOwner->m_pEdtEngine->AddSelRange(
        std::min(m_pOwner->m_nSelStart, nIndex),
        FXSYS_abs(nIndex - m_pOwner->m_nSelStart));
  }
}
void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;
  FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
  FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
  FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
  switch (dwKeyCode) {
    case FWL_VKEY_Left: {
      MoveCaret = MC_Left;
      break;
    }
    case FWL_VKEY_Right: {
      MoveCaret = MC_Right;
      break;
    }
    case FWL_VKEY_Up: {
      MoveCaret = MC_Up;
      break;
    }
    case FWL_VKEY_Down: {
      MoveCaret = MC_Down;
      break;
    }
    case FWL_VKEY_Home: {
      if (bCtrl) {
        MoveCaret = MC_Home;
      } else {
        MoveCaret = MC_LineStart;
      }
      break;
    }
    case FWL_VKEY_End: {
      if (bCtrl) {
        MoveCaret = MC_End;
      } else {
        MoveCaret = MC_LineEnd;
      }
      break;
    }
    case FWL_VKEY_Insert: {
      break;
    }
    case FWL_VKEY_Delete: {
      if ((m_pOwner->m_pProperties->m_dwStyleExes &
           FWL_STYLEEXT_EDT_ReadOnly) ||
          (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
        break;
      }
      int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
#if (_FX_OS_ == _FX_MACOSX_)
      m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
#else
      m_pOwner->m_pEdtEngine->Delete(nCaret);
#endif
      break;
    }
    case FWL_VKEY_F2: {
      break;
    }
    case FWL_VKEY_Tab: {
      m_pOwner->DispatchKeyEvent(pMsg);
      break;
    }
    default: {
#if (_FX_OS_ == _FX_MACOSX_)
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
#else
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
#endif
      {
        if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {
          m_pOwner->DoClipboard(1);
          return;
        }
        if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {
          m_pOwner->DoClipboard(2);
          return;
        }
        if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {
          m_pOwner->DoClipboard(3);
          return;
        }
      }
    }
  }
  if (MoveCaret != MC_MoveNone) {
    m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);
  }
}
void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey* pMsg) {
  if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return;
  }
  if (!m_pOwner->m_pEdtEngine)
    return;
  int32_t iError = 0;
  FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;
  int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
  switch (c) {
    case FWL_VKEY_Back: {
      m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
      break;
    }
    case 0x0A: {
      break;
    }
    case FWL_VKEY_Escape: {
      break;
    }
    case FWL_VKEY_Tab: {
      iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\t", 1);
      break;
    }
    case FWL_VKEY_Return: {
      if (m_pOwner->m_pProperties->m_dwStyleExes &
          FWL_STYLEEXT_EDT_WantReturn) {
        iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\n", 1);
      }
      break;
    }
    default: {
      if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
        if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) {
          if (((pMsg->m_dwKeyCode < FWL_VKEY_0) &&
               (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) ||
              pMsg->m_dwKeyCode > FWL_VKEY_9) {
            break;
          }
          if (!m_pOwner->ValidateNumberChar(c)) {
            break;
          }
        }
      }
#if (_FX_OS_ == _FX_MACOSX_)
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
#else
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
#endif
      {
        break;
      }
      iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);
      break;
    }
  }
  if (iError < 0) {
    m_pOwner->ProcessInsertError(iError);
  }
}
FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar,
                                       FX_DWORD dwCode,
                                       FX_FLOAT fPos) {
  CFX_SizeF fs;
  pScrollBar->GetRange(fs.x, fs.y);
  FX_FLOAT iCurPos = pScrollBar->GetPos();
  FX_FLOAT fStep = pScrollBar->GetStepSize();
  switch (dwCode) {
    case FWL_SCBCODE_Min: {
      fPos = fs.x;
      break;
    }
    case FWL_SCBCODE_Max: {
      fPos = fs.y;
      break;
    }
    case FWL_SCBCODE_StepBackward: {
      fPos -= fStep;
      if (fPos < fs.x + fStep / 2) {
        fPos = fs.x;
      }
      break;
    }
    case FWL_SCBCODE_StepForward: {
      fPos += fStep;
      if (fPos > fs.y - fStep / 2) {
        fPos = fs.y;
      }
      break;
    }
    case FWL_SCBCODE_PageBackward: {
      fPos -= pScrollBar->GetPageSize();
      if (fPos < fs.x) {
        fPos = fs.x;
      }
      break;
    }
    case FWL_SCBCODE_PageForward: {
      fPos += pScrollBar->GetPageSize();
      if (fPos > fs.y) {
        fPos = fs.y;
      }
      break;
    }
    case FWL_SCBCODE_Pos:
    case FWL_SCBCODE_TrackPos: {
      break;
    }
    case FWL_SCBCODE_EndScroll: {
      return FALSE;
    }
    default: {}
  }
  if (iCurPos != fPos) {
    pScrollBar->SetPos(fPos);
    pScrollBar->SetTrackPos(fPos);
    m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);
    if (m_pOwner->m_pEdtEngine) {
      m_pOwner->UpdateCaret();
    }
    CFX_RectF rect;
    m_pOwner->GetWidgetRect(rect);
    CFX_RectF rtInvalidate;
    rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);
    m_pOwner->Repaint(&rtInvalidate);
  }
  return TRUE;
}
void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {
  if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
    IFWL_AdapterNative* pNative = FWL_GetAdapterNative();
    IFWL_AdapterCursorMgr* pCursorMgr = pNative->GetCursorMgr();
    if (NULL != pCursorMgr) {
      FWL_HCURSOR hCursor =
          pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_InputBeam);
      pCursorMgr->SetCursor(hCursor);
      pCursorMgr->ShowCursor(TRUE);
    }
  }
}
