Remove CFX_ArrayTemplate, use unique_ptr in fpdfsdk/pdfwindow

Review-Url: https://codereview.chromium.org/2594153003
diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp
index ececa0b..aa77e9f 100644
--- a/fpdfsdk/fxedit/fxet_edit.cpp
+++ b/fpdfsdk/fxedit/fxet_edit.cpp
@@ -936,65 +936,60 @@
 }
 
 // static
-void CFX_Edit::GeneratePageObjects(
-    CPDF_PageObjectHolder* pObjectHolder,
-    CFX_Edit* pEdit,
-    const CFX_FloatPoint& ptOffset,
-    const CPVT_WordRange* pRange,
-    FX_COLORREF crText,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
+void CFX_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                   CFX_Edit* pEdit,
+                                   const CFX_FloatPoint& ptOffset,
+                                   const CPVT_WordRange* pRange,
+                                   FX_COLORREF crText,
+                                   std::vector<CPDF_TextObject*>* ObjArray) {
+  ObjArray->clear();
+
+  IPVT_FontMap* pFontMap = pEdit->GetFontMap();
+  if (!pFontMap)
+    return;
+
   FX_FLOAT fFontSize = pEdit->GetFontSize();
-
   int32_t nOldFontIndex = -1;
-
   CFX_ByteTextBuf sTextBuf;
+  CPVT_WordPlace oldplace;
   CFX_FloatPoint ptBT(0.0f, 0.0f);
-
-  ObjArray.RemoveAll();
-
   CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
-  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
-    if (pRange)
-      pIterator->SetAt(pRange->BeginPos);
-    else
-      pIterator->SetAt(0);
+  if (pRange)
+    pIterator->SetAt(pRange->BeginPos);
+  else
+    pIterator->SetAt(0);
 
-    CPVT_WordPlace oldplace;
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (pRange && place.WordCmp(pRange->EndPos) > 0)
+      break;
 
-    while (pIterator->NextWord()) {
-      CPVT_WordPlace place = pIterator->GetAt();
-      if (pRange && place.WordCmp(pRange->EndPos) > 0)
-        break;
+    CPVT_Word word;
+    if (!pIterator->GetWord(word))
+      continue;
 
-      CPVT_Word word;
-      if (pIterator->GetWord(word)) {
-        if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
-          if (sTextBuf.GetLength() > 0) {
-            ObjArray.Add(AddTextObjToPageObjects(
-                pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
-                fFontSize, 0.0f, 100,
-                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                sTextBuf.MakeString()));
+    if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
+      if (sTextBuf.GetLength() > 0) {
+        ObjArray->push_back(AddTextObjToPageObjects(
+            pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
+            fFontSize, 0.0f, 100,
+            CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+            sTextBuf.MakeString()));
 
-            sTextBuf.Clear();
-          }
-
-          ptBT = word.ptWord;
-          nOldFontIndex = word.nFontIndex;
-        }
-
-        sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
-                        .AsStringC();
-        oldplace = place;
+        sTextBuf.Clear();
       }
+      ptBT = word.ptWord;
+      nOldFontIndex = word.nFontIndex;
     }
-
-    if (sTextBuf.GetLength() > 0) {
-      ObjArray.Add(AddTextObjToPageObjects(
-          pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
-          0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-          sTextBuf.MakeString()));
-    }
+    sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
+                    .AsStringC();
+    oldplace = place;
+  }
+  if (sTextBuf.GetLength() > 0) {
+    ObjArray->push_back(AddTextObjToPageObjects(
+        pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
+        0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+        sTextBuf.MakeString()));
   }
 }
 
diff --git a/fpdfsdk/fxedit/fxet_edit.h b/fpdfsdk/fxedit/fxet_edit.h
index 1c3e955..2ab27d3 100644
--- a/fpdfsdk/fxedit/fxet_edit.h
+++ b/fpdfsdk/fxedit/fxet_edit.h
@@ -8,6 +8,7 @@
 #define FPDFSDK_FXEDIT_FXET_EDIT_H_
 
 #include <memory>
+#include <vector>
 
 #include "core/fpdfdoc/cpvt_secprops.h"
 #include "core/fpdfdoc/cpvt_wordprops.h"
@@ -335,13 +336,12 @@
                        const CPVT_WordRange* pRange,
                        CFX_SystemHandler* pSystemHandler,
                        CFFL_FormFiller* pFFLData);
-  static void GeneratePageObjects(
-      CPDF_PageObjectHolder* pObjectHolder,
-      CFX_Edit* pEdit,
-      const CFX_FloatPoint& ptOffset,
-      const CPVT_WordRange* pRange,
-      FX_COLORREF crText,
-      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
+  static void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                  CFX_Edit* pEdit,
+                                  const CFX_FloatPoint& ptOffset,
+                                  const CPVT_WordRange* pRange,
+                                  FX_COLORREF crText,
+                                  std::vector<CPDF_TextObject*>* ObjArray);
 
   CFX_Edit();
   ~CFX_Edit();
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp
index 153e9ab..bb8ec91 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp
@@ -875,10 +875,9 @@
   return range;
 }
 
-void CPWL_Edit::GeneratePageObjects(
-    CPDF_PageObjectHolder* pObjectHolder,
-    const CFX_FloatPoint& ptOffset,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
+void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                    const CFX_FloatPoint& ptOffset,
+                                    std::vector<CPDF_TextObject*>* ObjArray) {
   CFX_Edit::GeneratePageObjects(
       pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
@@ -887,9 +886,9 @@
 
 void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                                     const CFX_FloatPoint& ptOffset) {
-  CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
+  std::vector<CPDF_TextObject*> ObjArray;
   CFX_Edit::GeneratePageObjects(
       pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
-      ObjArray);
+      &ObjArray);
 }
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.h b/fpdfsdk/pdfwindow/PWL_Edit.h
index 3832236..801dedd 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.h
+++ b/fpdfsdk/pdfwindow/PWL_Edit.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_PDFWINDOW_PWL_EDIT_H_
 #define FPDFSDK_PDFWINDOW_PWL_EDIT_H_
 
+#include <vector>
+
 #include "core/fxcrt/fx_basic.h"
 #include "fpdfsdk/fxedit/fx_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
@@ -105,7 +107,7 @@
 
   void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                            const CFX_FloatPoint& ptOffset,
-                           CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
+                           std::vector<CPDF_TextObject*>* ObjArray);
   void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                            const CFX_FloatPoint& ptOffset);
 
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.cpp b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
index 15fbbee..9a2962c 100644
--- a/fpdfsdk/pdfwindow/PWL_FontMap.cpp
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/pdfwindow/PWL_FontMap.h"
 
+#include <utility>
+
 #include "core/fpdfapi/cpdf_modulemgr.h"
 #include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fpdfapi/font/cpdf_fontencoding.h"
@@ -14,6 +16,7 @@
 #include "core/fpdfdoc/ipvt_fontmap.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/stl_util.h"
 
 namespace {
 
@@ -57,32 +60,26 @@
 }
 
 CPDF_Font* CPWL_FontMap::GetPDFFont(int32_t nFontIndex) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-      return pData->pFont;
-    }
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
+      return m_Data[nFontIndex]->pFont;
   }
-
   return nullptr;
 }
 
 CFX_ByteString CPWL_FontMap::GetPDFFontAlias(int32_t nFontIndex) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) {
-      return pData->sFontName;
-    }
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
+      return m_Data[nFontIndex]->sFontName;
   }
-
-  return "";
+  return CFX_ByteString();
 }
 
 bool CPWL_FontMap::KnowWord(int32_t nFontIndex, uint16_t word) {
-  if (nFontIndex >= 0 && nFontIndex < m_aData.GetSize()) {
-    if (m_aData.GetAt(nFontIndex)) {
+  if (nFontIndex >= 0 && nFontIndex < pdfium::CollectionSize<int32_t>(m_Data)) {
+    if (m_Data[nFontIndex])
       return CharCodeFromUnicode(nFontIndex, word) >= 0;
-    }
   }
-
   return false;
 }
 
@@ -119,11 +116,11 @@
 }
 
 int32_t CPWL_FontMap::CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) {
-  CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex);
-  if (!pData)
+  if (nFontIndex < 0 || nFontIndex >= pdfium::CollectionSize<int32_t>(m_Data))
     return -1;
 
-  if (!pData->pFont)
+  CPWL_FontMap_Data* pData = m_Data[nFontIndex].get();
+  if (!pData || !pData->pFont)
     return -1;
 
   if (pData->pFont->IsUnicodeCompatible())
@@ -133,40 +130,25 @@
 }
 
 CFX_ByteString CPWL_FontMap::GetNativeFontName(int32_t nCharset) {
-  // searching native font is slow, so we must save time
-  for (int32_t i = 0, sz = m_aNativeFont.GetSize(); i < sz; i++) {
-    if (CPWL_FontMap_Native* pData = m_aNativeFont.GetAt(i)) {
-      if (pData->nCharset == nCharset)
-        return pData->sFontName;
-    }
+  for (const auto& pData : m_NativeFont) {
+    if (pData && pData->nCharset == nCharset)
+      return pData->sFontName;
   }
 
   CFX_ByteString sNew = GetNativeFont(nCharset);
+  if (sNew.IsEmpty())
+    return CFX_ByteString();
 
-  if (!sNew.IsEmpty()) {
-    CPWL_FontMap_Native* pNewData = new CPWL_FontMap_Native;
-    pNewData->nCharset = nCharset;
-    pNewData->sFontName = sNew;
-
-    m_aNativeFont.Add(pNewData);
-  }
-
+  auto pNewData = pdfium::MakeUnique<CPWL_FontMap_Native>();
+  pNewData->nCharset = nCharset;
+  pNewData->sFontName = sNew;
+  m_NativeFont.push_back(std::move(pNewData));
   return sNew;
 }
 
 void CPWL_FontMap::Empty() {
-  {
-    for (int32_t i = 0, sz = m_aData.GetSize(); i < sz; i++)
-      delete m_aData.GetAt(i);
-
-    m_aData.RemoveAll();
-  }
-  {
-    for (int32_t i = 0, sz = m_aNativeFont.GetSize(); i < sz; i++)
-      delete m_aNativeFont.GetAt(i);
-
-    m_aNativeFont.RemoveAll();
-  }
+  m_Data.clear();
+  m_NativeFont.clear();
 }
 
 void CPWL_FontMap::Initialize() {
@@ -184,15 +166,15 @@
 
 int32_t CPWL_FontMap::FindFont(const CFX_ByteString& sFontName,
                                int32_t nCharset) {
-  for (int32_t i = 0, sz = m_aData.GetSize(); i < sz; i++) {
-    if (CPWL_FontMap_Data* pData = m_aData.GetAt(i)) {
-      if (nCharset == FXFONT_DEFAULT_CHARSET || nCharset == pData->nCharset) {
-        if (sFontName.IsEmpty() || pData->sFontName == sFontName)
-          return i;
-      }
+  int32_t i = 0;
+  for (const auto& pData : m_Data) {
+    if (pData &&
+        (nCharset == FXFONT_DEFAULT_CHARSET || nCharset == pData->nCharset) &&
+        (sFontName.IsEmpty() || pData->sFontName == sFontName)) {
+      return i;
     }
+    ++i;
   }
-
   return -1;
 }
 
@@ -225,14 +207,12 @@
 int32_t CPWL_FontMap::AddFontData(CPDF_Font* pFont,
                                   const CFX_ByteString& sFontAlias,
                                   int32_t nCharset) {
-  CPWL_FontMap_Data* pNewData = new CPWL_FontMap_Data;
+  auto pNewData = pdfium::MakeUnique<CPWL_FontMap_Data>();
   pNewData->pFont = pFont;
   pNewData->sFontName = sFontAlias;
   pNewData->nCharset = nCharset;
-
-  m_aData.Add(pNewData);
-
-  return m_aData.GetSize() - 1;
+  m_Data.push_back(std::move(pNewData));
+  return pdfium::CollectionSize<int32_t>(m_Data) - 1;
 }
 
 void CPWL_FontMap::AddedFont(CPDF_Font* pFont,
@@ -243,10 +223,9 @@
     nCharset = GetNativeCharset();
 
   CFX_ByteString sFontName = GetDefaultFontByCharset(nCharset);
-  if (m_pSystemHandler->FindNativeTrueTypeFont(sFontName))
-    return sFontName;
+  if (!m_pSystemHandler->FindNativeTrueTypeFont(sFontName))
+    return CFX_ByteString();
 
-  sFontName.clear();
   return sFontName;
 }
 
@@ -305,11 +284,10 @@
 }
 
 const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(int32_t nIndex) const {
-  if (nIndex >= 0 && nIndex < m_aData.GetSize()) {
-    return m_aData.GetAt(nIndex);
-  }
+  if (nIndex < 0 || nIndex >= pdfium::CollectionSize<int32_t>(m_Data))
+    return nullptr;
 
-  return nullptr;
+  return m_Data[nIndex].get();
 }
 
 int32_t CPWL_FontMap::GetNativeCharset() {
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.h b/fpdfsdk/pdfwindow/PWL_FontMap.h
index 47ef193..c14fcd7 100644
--- a/fpdfsdk/pdfwindow/PWL_FontMap.h
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.h
@@ -8,6 +8,7 @@
 #define FPDFSDK_PDFWINDOW_PWL_FONTMAP_H_
 
 #include <memory>
+#include <vector>
 
 #include "core/fpdfdoc/ipvt_fontmap.h"
 #include "core/fxge/fx_font.h"
@@ -70,8 +71,8 @@
                                  int32_t nCharset);
   CFX_ByteString EncodeFontAlias(const CFX_ByteString& sFontName);
 
-  CFX_ArrayTemplate<CPWL_FontMap_Data*> m_aData;
-  CFX_ArrayTemplate<CPWL_FontMap_Native*> m_aNativeFont;
+  std::vector<std::unique_ptr<CPWL_FontMap_Data>> m_Data;
+  std::vector<std::unique_ptr<CPWL_FontMap_Native>> m_NativeFont;
 
  private:
   int32_t FindFont(const CFX_ByteString& sFontName,
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.cpp b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
index 78a4363..c9dc89c 100644
--- a/fpdfsdk/pdfwindow/PWL_Wnd.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
@@ -270,27 +270,23 @@
 
 void CPWL_Wnd::Destroy() {
   KillFocus();
-
   OnDestroy();
-
   if (m_bCreated) {
-    for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
-      if (CPWL_Wnd* pChild = m_aChildren[i]) {
+    for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
+      if (CPWL_Wnd* pChild = *it) {
+        *it = nullptr;
         pChild->Destroy();
         delete pChild;
-        pChild = nullptr;
       }
     }
-
     if (m_sPrivateParam.pParentWnd)
       m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
+
     m_bCreated = false;
   }
-
   DestroyMsgControl();
-
   FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM));
-  m_aChildren.RemoveAll();
+  m_Children.clear();
   m_pVScrollBar = nullptr;
 }
 
@@ -352,10 +348,9 @@
 }
 
 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
+  for (CPWL_Wnd* pChild : m_Children) {
+    if (pChild)
       pChild->GetAppearanceStream(sAppStream);
-    }
   }
 }
 
@@ -389,15 +384,16 @@
 
 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice,
                                    CFX_Matrix* pUser2Device) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      CFX_Matrix mt = pChild->GetChildMatrix();
-      if (mt.IsIdentity()) {
-        pChild->DrawAppearance(pDevice, pUser2Device);
-      } else {
-        mt.Concat(*pUser2Device);
-        pChild->DrawAppearance(pDevice, &mt);
-      }
+  for (CPWL_Wnd* pChild : m_Children) {
+    if (!pChild)
+      continue;
+
+    CFX_Matrix mt = pChild->GetChildMatrix();
+    if (mt.IsIdentity()) {
+      pChild->DrawAppearance(pDevice, pUser2Device);
+    } else {
+      mt.Concat(*pUser2Device);
+      pChild->DrawAppearance(pDevice, &mt);
     }
   }
 }
@@ -426,55 +422,48 @@
   }
 }
 
-#define PWL_IMPLEMENT_KEY_METHOD(key_method_name)                      \
-  bool CPWL_Wnd::key_method_name(uint16_t nChar, uint32_t nFlag) {     \
-    if (IsValid() && IsVisible() && IsEnabled()) {                     \
-      if (IsWndCaptureKeyboard(this)) {                                \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {               \
-            if (IsWndCaptureKeyboard(pChild)) {                        \
-              return pChild->key_method_name(nChar, nFlag);            \
-            }                                                          \
-          }                                                            \
-        }                                                              \
-      }                                                                \
-    }                                                                  \
-    return false;                                                      \
-  }
-
-#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)                        \
-  bool CPWL_Wnd::mouse_method_name(const CFX_FloatPoint& point,              \
-                                   uint32_t nFlag) {                         \
-    if (IsValid() && IsVisible() && IsEnabled()) {                           \
-      if (IsWndCaptureMouse(this)) {                                         \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {       \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {                     \
-            if (IsWndCaptureMouse(pChild)) {                                 \
-              return pChild->mouse_method_name(pChild->ParentToChild(point), \
-                                               nFlag);                       \
-            }                                                                \
-          }                                                                  \
-        }                                                                    \
-        SetCursor();                                                         \
-      } else {                                                               \
-        for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {       \
-          if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {                     \
-            if (pChild->WndHitTest(pChild->ParentToChild(point))) {          \
-              return pChild->mouse_method_name(pChild->ParentToChild(point), \
-                                               nFlag);                       \
-            }                                                                \
-          }                                                                  \
-        }                                                                    \
-        if (WndHitTest(point))                                               \
-          SetCursor();                                                       \
-      }                                                                      \
-    }                                                                        \
-    return false;                                                            \
+#define PWL_IMPLEMENT_KEY_METHOD(key_method_name)                  \
+  bool CPWL_Wnd::key_method_name(uint16_t nChar, uint32_t nFlag) { \
+    if (!IsValid() || !IsVisible() || !IsEnabled())                \
+      return false;                                                \
+    if (!IsWndCaptureKeyboard(this))                               \
+      return false;                                                \
+    for (const auto& pChild : m_Children) {                        \
+      if (pChild && IsWndCaptureKeyboard(pChild))                  \
+        return pChild->key_method_name(nChar, nFlag);              \
+    }                                                              \
+    return false;                                                  \
   }
 
 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
 PWL_IMPLEMENT_KEY_METHOD(OnChar)
+#undef PWL_IMPLEMENT_KEY_METHOD
+
+#define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)                          \
+  bool CPWL_Wnd::mouse_method_name(const CFX_FloatPoint& point,                \
+                                   uint32_t nFlag) {                           \
+    if (!IsValid() || !IsVisible() || !IsEnabled())                            \
+      return false;                                                            \
+    if (IsWndCaptureMouse(this)) {                                             \
+      for (const auto& pChild : m_Children) {                                  \
+        if (pChild && IsWndCaptureMouse(pChild)) {                             \
+          return pChild->mouse_method_name(pChild->ParentToChild(point),       \
+                                           nFlag);                             \
+        }                                                                      \
+      }                                                                        \
+      SetCursor();                                                             \
+      return false;                                                            \
+    }                                                                          \
+    for (const auto& pChild : m_Children) {                                    \
+      if (pChild && pChild->WndHitTest(pChild->ParentToChild(point))) {        \
+        return pChild->mouse_method_name(pChild->ParentToChild(point), nFlag); \
+      }                                                                        \
+    }                                                                          \
+    if (WndHitTest(point))                                                     \
+      SetCursor();                                                             \
+    return false;                                                              \
+  }
 
 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
@@ -485,37 +474,34 @@
 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
+#undef PWL_IMPLEMENT_MOUSE_METHOD
 
 bool CPWL_Wnd::OnMouseWheel(short zDelta,
                             const CFX_FloatPoint& point,
                             uint32_t nFlag) {
-  if (IsValid() && IsVisible() && IsEnabled()) {
-    SetCursor();
-    if (IsWndCaptureKeyboard(this)) {
-      for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-        if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-          if (IsWndCaptureKeyboard(pChild)) {
-            return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point),
-                                        nFlag);
-          }
-        }
-      }
-    }
+  if (!IsValid() || !IsVisible() || !IsEnabled())
+    return false;
+
+  SetCursor();
+  if (!IsWndCaptureKeyboard(this))
+    return false;
+
+  for (const auto& pChild : m_Children) {
+    if (pChild && IsWndCaptureKeyboard(pChild))
+      return pChild->OnMouseWheel(zDelta, pChild->ParentToChild(point), nFlag);
   }
   return false;
 }
 
 void CPWL_Wnd::AddChild(CPWL_Wnd* pWnd) {
-  m_aChildren.Add(pWnd);
+  m_Children.push_back(pWnd);
 }
 
 void CPWL_Wnd::RemoveChild(CPWL_Wnd* pWnd) {
-  for (int32_t i = m_aChildren.GetSize() - 1; i >= 0; i--) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-      if (pChild == pWnd) {
-        m_aChildren.RemoveAt(i);
-        break;
-      }
+  for (auto it = m_Children.rbegin(); it != m_Children.rend(); ++it) {
+    if (*it && *it == pWnd) {
+      m_Children.erase(std::next(it).base());
+      break;
     }
   }
 }
@@ -675,10 +661,10 @@
 }
 
 void CPWL_Wnd::ReleaseCapture() {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++)
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
+  for (const auto& pChild : m_Children) {
+    if (pChild)
       pChild->ReleaseCapture();
-
+  }
   if (CPWL_MsgControl* pMsgCtrl = GetMsgControl())
     pMsgCtrl->ReleaseCapture();
 }
@@ -718,18 +704,17 @@
 }
 
 void CPWL_Wnd::SetVisible(bool bVisible) {
-  if (IsValid()) {
-    for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        pChild->SetVisible(bVisible);
-      }
-    }
+  if (!IsValid())
+    return;
 
-    if (bVisible != m_bVisible) {
-      m_bVisible = bVisible;
-      RePosChildWnd();
-      InvalidateRect();
-    }
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->SetVisible(bVisible);
+  }
+  if (bVisible != m_bVisible) {
+    m_bVisible = bVisible;
+    RePosChildWnd();
+    InvalidateRect();
   }
 }
 
@@ -866,22 +851,17 @@
 }
 
 void CPWL_Wnd::SetTransparency(int32_t nTransparency) {
-  for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-    if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
+  for (const auto& pChild : m_Children) {
+    if (pChild)
       pChild->SetTransparency(nTransparency);
-    }
   }
-
   m_sPrivateParam.nTransparency = nTransparency;
 }
 
 CFX_Matrix CPWL_Wnd::GetWindowMatrix() const {
   CFX_Matrix mt = GetChildToRoot();
-
-  if (IPWL_Provider* pProvider = GetProvider()) {
+  if (IPWL_Provider* pProvider = GetProvider())
     mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
-    return mt;
-  }
 
   return mt;
 }
@@ -982,28 +962,23 @@
 }
 
 const CPWL_Wnd* CPWL_Wnd::GetFocused() const {
-  if (CPWL_MsgControl* pMsgCtrl = GetMsgControl()) {
-    return pMsgCtrl->m_pMainKeyboardWnd;
-  }
-
-  return nullptr;
+  CPWL_MsgControl* pMsgCtrl = GetMsgControl();
+  return pMsgCtrl ? pMsgCtrl->m_pMainKeyboardWnd : nullptr;
 }
 
 void CPWL_Wnd::EnableWindow(bool bEnable) {
-  if (m_bEnabled != bEnable) {
-    for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
-      if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
-        pChild->EnableWindow(bEnable);
-      }
-    }
+  if (m_bEnabled == bEnable)
+    return;
 
-    m_bEnabled = bEnable;
-
-    if (bEnable)
-      OnEnabled();
-    else
-      OnDisabled();
+  for (const auto& pChild : m_Children) {
+    if (pChild)
+      pChild->EnableWindow(bEnable);
   }
+  m_bEnabled = bEnable;
+  if (bEnable)
+    OnEnabled();
+  else
+    OnDisabled();
 }
 
 bool CPWL_Wnd::IsEnabled() {
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.h b/fpdfsdk/pdfwindow/PWL_Wnd.h
index bba14f2..ce3d58c 100644
--- a/fpdfsdk/pdfwindow/PWL_Wnd.h
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.h
@@ -413,16 +413,13 @@
   CPWL_MsgControl* GetMsgControl() const;
 
  protected:
-  CFX_ArrayTemplate<CPWL_Wnd*> m_aChildren;
+  std::vector<CPWL_Wnd*> m_Children;
 
  private:
   PWL_CREATEPARAM m_sPrivateParam;
-
   CPWL_ScrollBar* m_pVScrollBar;
-
   CFX_FloatRect m_rcWindow;
   CFX_FloatRect m_rcClip;
-
   bool m_bCreated;
   bool m_bVisible;
   bool m_bNotifying;