Home | History | Annotate | Download | only in pdfwindow
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "fpdfsdk/include/pdfwindow/PWL_ComboBox.h"
      8 
      9 #include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
     10 #include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
     11 #include "fpdfsdk/include/pdfwindow/PWL_ListBox.h"
     12 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
     13 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
     14 #include "public/fpdf_fwlevent.h"
     15 
     16 #define PWLCB_DEFAULTFONTSIZE 12.0f
     17 
     18 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
     19 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
     20 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
     21 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
     22 
     23 FX_BOOL CPWL_CBListBox::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
     24   CPWL_Wnd::OnLButtonUp(point, nFlag);
     25 
     26   if (m_bMouseDown) {
     27     ReleaseCapture();
     28     m_bMouseDown = FALSE;
     29 
     30     if (ClientHitTest(point)) {
     31       if (CPWL_Wnd* pParent = GetParentWindow()) {
     32         pParent->OnNotify(this, PNM_LBUTTONUP, 0,
     33                           PWL_MAKEDWORD(point.x, point.y));
     34       }
     35 
     36       FX_BOOL bExit = FALSE;
     37       OnNotifySelChanged(FALSE, bExit, nFlag);
     38       if (bExit)
     39         return FALSE;
     40     }
     41   }
     42 
     43   return TRUE;
     44 }
     45 
     46 FX_BOOL CPWL_CBListBox::OnKeyDownWithExit(FX_WORD nChar,
     47                                           FX_BOOL& bExit,
     48                                           FX_DWORD nFlag) {
     49   if (!m_pList)
     50     return FALSE;
     51 
     52   switch (nChar) {
     53     default:
     54       return FALSE;
     55     case FWL_VKEY_Up:
     56     case FWL_VKEY_Down:
     57     case FWL_VKEY_Home:
     58     case FWL_VKEY_Left:
     59     case FWL_VKEY_End:
     60     case FWL_VKEY_Right:
     61       break;
     62   }
     63 
     64   switch (nChar) {
     65     case FWL_VKEY_Up:
     66       m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     67       break;
     68     case FWL_VKEY_Down:
     69       m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     70       break;
     71     case FWL_VKEY_Home:
     72       m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     73       break;
     74     case FWL_VKEY_Left:
     75       m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     76       break;
     77     case FWL_VKEY_End:
     78       m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     79       break;
     80     case FWL_VKEY_Right:
     81       m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
     82       break;
     83     case FWL_VKEY_Delete:
     84       break;
     85   }
     86 
     87   OnNotifySelChanged(TRUE, bExit, nFlag);
     88 
     89   return TRUE;
     90 }
     91 
     92 FX_BOOL CPWL_CBListBox::OnCharWithExit(FX_WORD nChar,
     93                                        FX_BOOL& bExit,
     94                                        FX_DWORD nFlag) {
     95   if (!m_pList)
     96     return FALSE;
     97 
     98   if (!m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)))
     99     return FALSE;
    100 
    101   if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetParentWindow()) {
    102     pComboBox->SetSelectText();
    103   }
    104 
    105   OnNotifySelChanged(TRUE, bExit, nFlag);
    106 
    107   return TRUE;
    108 }
    109 
    110 void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
    111   CPWL_Wnd::GetThisAppearanceStream(sAppStream);
    112 
    113   CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
    114 
    115   if (IsVisible() && !rectWnd.IsEmpty()) {
    116     CFX_ByteTextBuf sButton;
    117 
    118     CPDF_Point ptCenter = GetCenterPoint();
    119 
    120     CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
    121                    ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    122     CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
    123                    ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    124     CPDF_Point pt3(ptCenter.x,
    125                    ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    126 
    127     if (IsFloatBigger(rectWnd.right - rectWnd.left,
    128                       PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
    129         IsFloatBigger(rectWnd.top - rectWnd.bottom,
    130                       PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
    131       sButton << "0 g\n";
    132       sButton << pt1.x << " " << pt1.y << " m\n";
    133       sButton << pt2.x << " " << pt2.y << " l\n";
    134       sButton << pt3.x << " " << pt3.y << " l\n";
    135       sButton << pt1.x << " " << pt1.y << " l f\n";
    136 
    137       sAppStream << "q\n" << sButton << "Q\n";
    138     }
    139   }
    140 }
    141 
    142 void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
    143                                        CFX_Matrix* pUser2Device) {
    144   CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
    145 
    146   CPDF_Rect rectWnd = CPWL_Wnd::GetWindowRect();
    147 
    148   if (IsVisible() && !rectWnd.IsEmpty()) {
    149     CPDF_Point ptCenter = GetCenterPoint();
    150 
    151     CPDF_Point pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN,
    152                    ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    153     CPDF_Point pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN,
    154                    ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    155     CPDF_Point pt3(ptCenter.x,
    156                    ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f);
    157 
    158     if (IsFloatBigger(rectWnd.right - rectWnd.left,
    159                       PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) &&
    160         IsFloatBigger(rectWnd.top - rectWnd.bottom,
    161                       PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
    162       CFX_PathData path;
    163 
    164       path.SetPointCount(4);
    165       path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
    166       path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
    167       path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
    168       path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
    169 
    170       pDevice->DrawPath(&path, pUser2Device, NULL,
    171                         CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
    172                                                       GetTransparency()),
    173                         0, FXFILL_ALTERNATE);
    174     }
    175   }
    176 }
    177 
    178 FX_BOOL CPWL_CBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
    179   CPWL_Wnd::OnLButtonDown(point, nFlag);
    180 
    181   SetCapture();
    182 
    183   if (CPWL_Wnd* pParent = GetParentWindow()) {
    184     pParent->OnNotify(this, PNM_LBUTTONDOWN, 0,
    185                       PWL_MAKEDWORD(point.x, point.y));
    186   }
    187 
    188   return TRUE;
    189 }
    190 
    191 FX_BOOL CPWL_CBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
    192   CPWL_Wnd::OnLButtonUp(point, nFlag);
    193 
    194   ReleaseCapture();
    195 
    196   return TRUE;
    197 }
    198 
    199 CPWL_ComboBox::CPWL_ComboBox()
    200     : m_pEdit(NULL),
    201       m_pButton(NULL),
    202       m_pList(NULL),
    203       m_bPopup(FALSE),
    204       m_nPopupWhere(0),
    205       m_nSelectItem(-1),
    206       m_pFillerNotify(NULL) {}
    207 
    208 CFX_ByteString CPWL_ComboBox::GetClassName() const {
    209   return "CPWL_ComboBox";
    210 }
    211 
    212 void CPWL_ComboBox::OnCreate(PWL_CREATEPARAM& cp) {
    213   cp.dwFlags &= ~PWS_HSCROLL;
    214   cp.dwFlags &= ~PWS_VSCROLL;
    215 }
    216 
    217 void CPWL_ComboBox::SetFocus() {
    218   if (m_pEdit)
    219     m_pEdit->SetFocus();
    220 }
    221 
    222 void CPWL_ComboBox::KillFocus() {
    223   SetPopup(FALSE);
    224   CPWL_Wnd::KillFocus();
    225 }
    226 
    227 CFX_WideString CPWL_ComboBox::GetText() const {
    228   if (m_pEdit) {
    229     return m_pEdit->GetText();
    230   }
    231   return CFX_WideString();
    232 }
    233 
    234 void CPWL_ComboBox::SetText(const FX_WCHAR* text) {
    235   if (m_pEdit)
    236     m_pEdit->SetText(text);
    237 }
    238 
    239 void CPWL_ComboBox::AddString(const FX_WCHAR* string) {
    240   if (m_pList)
    241     m_pList->AddString(string);
    242 }
    243 
    244 int32_t CPWL_ComboBox::GetSelect() const {
    245   return m_nSelectItem;
    246 }
    247 
    248 void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
    249   if (m_pList)
    250     m_pList->Select(nItemIndex);
    251 
    252   m_pEdit->SetText(m_pList->GetText().c_str());
    253 
    254   m_nSelectItem = nItemIndex;
    255 }
    256 
    257 void CPWL_ComboBox::SetEditSel(int32_t nStartChar, int32_t nEndChar) {
    258   if (m_pEdit) {
    259     m_pEdit->SetSel(nStartChar, nEndChar);
    260   }
    261 }
    262 
    263 void CPWL_ComboBox::GetEditSel(int32_t& nStartChar, int32_t& nEndChar) const {
    264   nStartChar = -1;
    265   nEndChar = -1;
    266 
    267   if (m_pEdit) {
    268     m_pEdit->GetSel(nStartChar, nEndChar);
    269   }
    270 }
    271 
    272 void CPWL_ComboBox::Clear() {
    273   if (m_pEdit) {
    274     m_pEdit->Clear();
    275   }
    276 }
    277 
    278 void CPWL_ComboBox::CreateChildWnd(const PWL_CREATEPARAM& cp) {
    279   CreateEdit(cp);
    280   CreateButton(cp);
    281   CreateListBox(cp);
    282 }
    283 
    284 void CPWL_ComboBox::CreateEdit(const PWL_CREATEPARAM& cp) {
    285   if (!m_pEdit) {
    286     m_pEdit = new CPWL_CBEdit;
    287     m_pEdit->AttachFFLData(m_pFormFiller);
    288 
    289     PWL_CREATEPARAM ecp = cp;
    290     ecp.pParentWnd = this;
    291     ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
    292                   PES_AUTOSCROLL | PES_UNDO;
    293 
    294     if (HasFlag(PWS_AUTOFONTSIZE))
    295       ecp.dwFlags |= PWS_AUTOFONTSIZE;
    296 
    297     if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
    298       ecp.dwFlags |= PWS_READONLY;
    299 
    300     ecp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
    301     ecp.dwBorderWidth = 0;
    302     ecp.nBorderStyle = PBS_SOLID;
    303 
    304     m_pEdit->Create(ecp);
    305   }
    306 }
    307 
    308 void CPWL_ComboBox::CreateButton(const PWL_CREATEPARAM& cp) {
    309   if (!m_pButton) {
    310     m_pButton = new CPWL_CBButton;
    311 
    312     PWL_CREATEPARAM bcp = cp;
    313     bcp.pParentWnd = this;
    314     bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
    315     bcp.sBackgroundColor = PWL_SCROLLBAR_BKCOLOR;
    316     bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
    317     bcp.dwBorderWidth = 2;
    318     bcp.nBorderStyle = PBS_BEVELED;
    319     bcp.eCursorType = FXCT_ARROW;
    320 
    321     m_pButton->Create(bcp);
    322   }
    323 }
    324 
    325 void CPWL_ComboBox::CreateListBox(const PWL_CREATEPARAM& cp) {
    326   if (!m_pList) {
    327     m_pList = new CPWL_CBListBox;
    328     m_pList->AttachFFLData(m_pFormFiller);
    329     PWL_CREATEPARAM lcp = cp;
    330     lcp.pParentWnd = this;
    331     lcp.dwFlags =
    332         PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
    333     lcp.nBorderStyle = PBS_SOLID;
    334     lcp.dwBorderWidth = 1;
    335     lcp.eCursorType = FXCT_ARROW;
    336     lcp.rcRectWnd = CPDF_Rect(0, 0, 0, 0);
    337 
    338     if (cp.dwFlags & PWS_AUTOFONTSIZE)
    339       lcp.fFontSize = PWLCB_DEFAULTFONTSIZE;
    340     else
    341       lcp.fFontSize = cp.fFontSize;
    342 
    343     if (cp.sBorderColor.nColorType == COLORTYPE_TRANSPARENT)
    344       lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
    345 
    346     if (cp.sBackgroundColor.nColorType == COLORTYPE_TRANSPARENT)
    347       lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
    348 
    349     m_pList->Create(lcp);
    350   }
    351 }
    352 
    353 void CPWL_ComboBox::RePosChildWnd() {
    354   CPDF_Rect rcClient = GetClientRect();
    355 
    356   if (m_bPopup) {
    357     CPDF_Rect rclient = GetClientRect();
    358     CPDF_Rect rcButton = rclient;
    359     CPDF_Rect rcEdit = rcClient;
    360     CPDF_Rect rcList = CPWL_Wnd::GetWindowRect();
    361 
    362     FX_FLOAT fOldWindowHeight = m_rcOldWindow.Height();
    363     FX_FLOAT fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
    364 
    365     switch (m_nPopupWhere) {
    366       case 0:
    367         rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
    368 
    369         if (rcButton.left < rclient.left)
    370           rcButton.left = rclient.left;
    371 
    372         rcButton.bottom = rcButton.top - fOldClientHeight;
    373 
    374         rcEdit.right = rcButton.left - 1.0f;
    375 
    376         if (rcEdit.left < rclient.left)
    377           rcEdit.left = rclient.left;
    378 
    379         if (rcEdit.right < rcEdit.left)
    380           rcEdit.right = rcEdit.left;
    381 
    382         rcEdit.bottom = rcEdit.top - fOldClientHeight;
    383 
    384         rcList.top -= fOldWindowHeight;
    385 
    386         break;
    387       case 1:
    388         rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
    389 
    390         if (rcButton.left < rclient.left)
    391           rcButton.left = rclient.left;
    392 
    393         rcButton.top = rcButton.bottom + fOldClientHeight;
    394 
    395         rcEdit.right = rcButton.left - 1.0f;
    396 
    397         if (rcEdit.left < rclient.left)
    398           rcEdit.left = rclient.left;
    399 
    400         if (rcEdit.right < rcEdit.left)
    401           rcEdit.right = rcEdit.left;
    402 
    403         rcEdit.top = rcEdit.bottom + fOldClientHeight;
    404 
    405         rcList.bottom += fOldWindowHeight;
    406 
    407         break;
    408     }
    409 
    410     if (m_pButton)
    411       m_pButton->Move(rcButton, TRUE, FALSE);
    412 
    413     if (m_pEdit)
    414       m_pEdit->Move(rcEdit, TRUE, FALSE);
    415 
    416     if (m_pList) {
    417       m_pList->SetVisible(TRUE);
    418       m_pList->Move(rcList, TRUE, FALSE);
    419       m_pList->ScrollToListItem(m_nSelectItem);
    420     }
    421   } else {
    422     CPDF_Rect rcButton = rcClient;
    423 
    424     rcButton.left = rcButton.right - PWL_COMBOBOX_BUTTON_WIDTH;
    425 
    426     if (rcButton.left < rcClient.left)
    427       rcButton.left = rcClient.left;
    428 
    429     if (m_pButton)
    430       m_pButton->Move(rcButton, TRUE, FALSE);
    431 
    432     CPDF_Rect rcEdit = rcClient;
    433     rcEdit.right = rcButton.left - 1.0f;
    434 
    435     if (rcEdit.left < rcClient.left)
    436       rcEdit.left = rcClient.left;
    437 
    438     if (rcEdit.right < rcEdit.left)
    439       rcEdit.right = rcEdit.left;
    440 
    441     if (m_pEdit)
    442       m_pEdit->Move(rcEdit, TRUE, FALSE);
    443 
    444     if (m_pList)
    445       m_pList->SetVisible(FALSE);
    446   }
    447 }
    448 
    449 void CPWL_ComboBox::SelectAll() {
    450   if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
    451     m_pEdit->SelectAll();
    452 }
    453 
    454 CPDF_Rect CPWL_ComboBox::GetFocusRect() const {
    455   return CPDF_Rect();
    456 }
    457 
    458 void CPWL_ComboBox::SetPopup(FX_BOOL bPopup) {
    459   if (!m_pList)
    460     return;
    461   if (bPopup == m_bPopup)
    462     return;
    463   FX_FLOAT fListHeight = m_pList->GetContentRect().Height();
    464   if (!IsFloatBigger(fListHeight, 0.0f))
    465     return;
    466 
    467   if (bPopup) {
    468     if (m_pFillerNotify) {
    469 #ifdef PDF_ENABLE_XFA
    470       FX_BOOL bExit = FALSE;
    471       m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
    472       if (bExit)
    473         return;
    474 #endif  // PDF_ENABLE_XFA
    475       int32_t nWhere = 0;
    476       FX_FLOAT fPopupRet = 0.0f;
    477       FX_FLOAT fPopupMin = 0.0f;
    478       if (m_pList->GetCount() > 3)
    479         fPopupMin =
    480             m_pList->GetFirstHeight() * 3 + m_pList->GetBorderWidth() * 2;
    481       FX_FLOAT fPopupMax = fListHeight + m_pList->GetBorderWidth() * 2;
    482       m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
    483                                        nWhere, fPopupRet);
    484 
    485       if (IsFloatBigger(fPopupRet, 0.0f)) {
    486         m_bPopup = bPopup;
    487 
    488         CPDF_Rect rcWindow = CPWL_Wnd::GetWindowRect();
    489         m_rcOldWindow = rcWindow;
    490         switch (nWhere) {
    491           default:
    492           case 0:
    493             rcWindow.bottom -= fPopupRet;
    494             break;
    495           case 1:
    496             rcWindow.top += fPopupRet;
    497             break;
    498         }
    499 
    500         m_nPopupWhere = nWhere;
    501         Move(rcWindow, TRUE, TRUE);
    502 #ifdef PDF_ENABLE_XFA
    503         bExit = FALSE;
    504         m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
    505         if (bExit)
    506           return;
    507 #endif  // PDF_ENABLE_XFA
    508       }
    509     }
    510   } else {
    511     m_bPopup = bPopup;
    512     Move(m_rcOldWindow, TRUE, TRUE);
    513   }
    514 }
    515 
    516 FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
    517   if (!m_pList)
    518     return FALSE;
    519   if (!m_pEdit)
    520     return FALSE;
    521 
    522   m_nSelectItem = -1;
    523 
    524   switch (nChar) {
    525     case FWL_VKEY_Up:
    526       if (m_pList->GetCurSel() > 0) {
    527         FX_BOOL bExit = FALSE;
    528 #ifdef PDF_ENABLE_XFA
    529         if (m_pFillerNotify) {
    530           m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
    531           if (bExit)
    532             return FALSE;
    533           bExit = FALSE;
    534           m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
    535           if (bExit)
    536             return FALSE;
    537         }
    538 #endif  // PDF_ENABLE_XFA
    539         if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
    540           if (bExit)
    541             return FALSE;
    542           SetSelectText();
    543         }
    544       }
    545       return TRUE;
    546     case FWL_VKEY_Down:
    547       if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
    548         FX_BOOL bExit = FALSE;
    549 #ifdef PDF_ENABLE_XFA
    550         if (m_pFillerNotify) {
    551           m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
    552           if (bExit)
    553             return FALSE;
    554           bExit = FALSE;
    555           m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
    556           if (bExit)
    557             return FALSE;
    558         }
    559 #endif  // PDF_ENABLE_XFA
    560         if (m_pList->OnKeyDownWithExit(nChar, bExit, nFlag)) {
    561           if (bExit)
    562             return FALSE;
    563           SetSelectText();
    564         }
    565       }
    566       return TRUE;
    567   }
    568 
    569   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
    570     return m_pEdit->OnKeyDown(nChar, nFlag);
    571 
    572   return FALSE;
    573 }
    574 
    575 FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
    576   if (!m_pList)
    577     return FALSE;
    578 
    579   if (!m_pEdit)
    580     return FALSE;
    581 
    582   m_nSelectItem = -1;
    583   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
    584     return m_pEdit->OnChar(nChar, nFlag);
    585 
    586   FX_BOOL bExit = FALSE;
    587 #ifdef PDF_ENABLE_XFA
    588   if (m_pFillerNotify) {
    589     m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
    590     if (bExit)
    591       return FALSE;
    592 
    593     m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
    594     if (bExit)
    595       return FALSE;
    596   }
    597 #endif  // PDF_ENABLE_XFA
    598   return m_pList->OnCharWithExit(nChar, bExit, nFlag) ? bExit : FALSE;
    599 }
    600 
    601 void CPWL_ComboBox::OnNotify(CPWL_Wnd* pWnd,
    602                              FX_DWORD msg,
    603                              intptr_t wParam,
    604                              intptr_t lParam) {
    605   switch (msg) {
    606     case PNM_LBUTTONDOWN:
    607       if (pWnd == m_pButton) {
    608         SetPopup(!m_bPopup);
    609         return;
    610       }
    611       break;
    612     case PNM_LBUTTONUP:
    613       if (m_pEdit && m_pList) {
    614         if (pWnd == m_pList) {
    615           SetSelectText();
    616           SelectAll();
    617           m_pEdit->SetFocus();
    618           SetPopup(FALSE);
    619           return;
    620         }
    621       }
    622   }
    623 
    624   CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
    625 }
    626 
    627 FX_BOOL CPWL_ComboBox::IsPopup() const {
    628   return m_bPopup;
    629 }
    630 
    631 void CPWL_ComboBox::SetSelectText() {
    632   CFX_WideString swText = m_pList->GetText();
    633   m_pEdit->SelectAll();
    634   m_pEdit->ReplaceSel(m_pList->GetText().c_str());
    635   m_pEdit->SelectAll();
    636 
    637   m_nSelectItem = m_pList->GetCurSel();
    638 }
    639 
    640 void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
    641   m_pFillerNotify = pNotify;
    642 
    643   if (m_pEdit)
    644     m_pEdit->SetFillerNotify(pNotify);
    645 
    646   if (m_pList)
    647     m_pList->SetFillerNotify(pNotify);
    648 }
    649