• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/pwl/cpwl_combo_box.h"
8 
9 #include <algorithm>
10 #include <sstream>
11 #include <utility>
12 
13 #include "core/fxge/cfx_pathdata.h"
14 #include "core/fxge/cfx_renderdevice.h"
15 #include "fpdfsdk/pwl/cpwl_edit.h"
16 #include "fpdfsdk/pwl/cpwl_edit_ctrl.h"
17 #include "fpdfsdk/pwl/cpwl_list_box.h"
18 #include "fpdfsdk/pwl/cpwl_list_impl.h"
19 #include "fpdfsdk/pwl/cpwl_wnd.h"
20 #include "public/fpdf_fwlevent.h"
21 #include "third_party/base/ptr_util.h"
22 
23 namespace {
24 
25 constexpr float kComboBoxDefaultFontSize = 12.0f;
26 constexpr float kComboBoxTriangleHalfLength = 3.0f;
27 constexpr int kDefaultButtonWidth = 13;
28 
29 }  // namespace
30 
CPWL_CBListBox(const CreateParams & cp,std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)31 CPWL_CBListBox::CPWL_CBListBox(
32     const CreateParams& cp,
33     std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
34     : CPWL_ListBox(cp, std::move(pAttachedData)) {}
35 
36 CPWL_CBListBox::~CPWL_CBListBox() = default;
37 
OnLButtonUp(const CFX_PointF & point,uint32_t nFlag)38 bool CPWL_CBListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
39   CPWL_Wnd::OnLButtonUp(point, nFlag);
40 
41   if (!m_bMouseDown)
42     return true;
43 
44   ReleaseCapture();
45   m_bMouseDown = false;
46 
47   if (!ClientHitTest(point))
48     return true;
49   if (CPWL_Wnd* pParent = GetParentWindow())
50     pParent->NotifyLButtonUp(this, point);
51 
52   return !OnNotifySelectionChanged(false, nFlag);
53 }
54 
IsMovementKey(uint16_t nChar) const55 bool CPWL_CBListBox::IsMovementKey(uint16_t nChar) const {
56   switch (nChar) {
57     case FWL_VKEY_Up:
58     case FWL_VKEY_Down:
59     case FWL_VKEY_Home:
60     case FWL_VKEY_Left:
61     case FWL_VKEY_End:
62     case FWL_VKEY_Right:
63       return true;
64     default:
65       return false;
66   }
67 }
68 
OnMovementKeyDown(uint16_t nChar,uint32_t nFlag)69 bool CPWL_CBListBox::OnMovementKeyDown(uint16_t nChar, uint32_t nFlag) {
70   ASSERT(IsMovementKey(nChar));
71 
72   switch (nChar) {
73     case FWL_VKEY_Up:
74       m_pList->OnVK_UP(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
75       break;
76     case FWL_VKEY_Down:
77       m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
78       break;
79     case FWL_VKEY_Home:
80       m_pList->OnVK_HOME(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
81       break;
82     case FWL_VKEY_Left:
83       m_pList->OnVK_LEFT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
84       break;
85     case FWL_VKEY_End:
86       m_pList->OnVK_END(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
87       break;
88     case FWL_VKEY_Right:
89       m_pList->OnVK_RIGHT(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
90       break;
91   }
92   return OnNotifySelectionChanged(true, nFlag);
93 }
94 
IsChar(uint16_t nChar,uint32_t nFlag) const95 bool CPWL_CBListBox::IsChar(uint16_t nChar, uint32_t nFlag) const {
96   return m_pList->OnChar(nChar, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
97 }
98 
OnCharNotify(uint16_t nChar,uint32_t nFlag)99 bool CPWL_CBListBox::OnCharNotify(uint16_t nChar, uint32_t nFlag) {
100   if (auto* pComboBox = static_cast<CPWL_ComboBox*>(GetParentWindow()))
101     pComboBox->SetSelectText();
102 
103   return OnNotifySelectionChanged(true, nFlag);
104 }
105 
CPWL_CBButton(const CreateParams & cp,std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)106 CPWL_CBButton::CPWL_CBButton(
107     const CreateParams& cp,
108     std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
109     : CPWL_Wnd(cp, std::move(pAttachedData)) {}
110 
111 CPWL_CBButton::~CPWL_CBButton() = default;
112 
DrawThisAppearance(CFX_RenderDevice * pDevice,const CFX_Matrix & mtUser2Device)113 void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
114                                        const CFX_Matrix& mtUser2Device) {
115   CPWL_Wnd::DrawThisAppearance(pDevice, mtUser2Device);
116 
117   CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect();
118   if (!IsVisible() || rectWnd.IsEmpty())
119     return;
120 
121   CFX_PointF ptCenter = GetCenterPoint();
122 
123   static constexpr float kComboBoxTriangleQuarterLength =
124       kComboBoxTriangleHalfLength * 0.5;
125   CFX_PointF pt1(ptCenter.x - kComboBoxTriangleHalfLength,
126                  ptCenter.y + kComboBoxTriangleQuarterLength);
127   CFX_PointF pt2(ptCenter.x + kComboBoxTriangleHalfLength,
128                  ptCenter.y + kComboBoxTriangleQuarterLength);
129   CFX_PointF pt3(ptCenter.x, ptCenter.y - kComboBoxTriangleQuarterLength);
130 
131   if (IsFloatBigger(rectWnd.right - rectWnd.left,
132                     kComboBoxTriangleHalfLength * 2) &&
133       IsFloatBigger(rectWnd.top - rectWnd.bottom,
134                     kComboBoxTriangleHalfLength)) {
135     CFX_PathData path;
136     path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false);
137     path.AppendPoint(pt2, FXPT_TYPE::LineTo, false);
138     path.AppendPoint(pt3, FXPT_TYPE::LineTo, false);
139     path.AppendPoint(pt1, FXPT_TYPE::LineTo, false);
140 
141     pDevice->DrawPath(&path, &mtUser2Device, nullptr,
142                       PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0,
143                       FXFILL_ALTERNATE);
144   }
145 }
146 
OnLButtonDown(const CFX_PointF & point,uint32_t nFlag)147 bool CPWL_CBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
148   CPWL_Wnd::OnLButtonDown(point, nFlag);
149 
150   SetCapture();
151   if (CPWL_Wnd* pParent = GetParentWindow())
152     pParent->NotifyLButtonDown(this, point);
153 
154   return true;
155 }
156 
OnLButtonUp(const CFX_PointF & point,uint32_t nFlag)157 bool CPWL_CBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
158   CPWL_Wnd::OnLButtonUp(point, nFlag);
159 
160   ReleaseCapture();
161   return true;
162 }
163 
CPWL_ComboBox(const CreateParams & cp,std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)164 CPWL_ComboBox::CPWL_ComboBox(
165     const CreateParams& cp,
166     std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
167     : CPWL_Wnd(cp, std::move(pAttachedData)) {
168   GetCreationParams()->dwFlags &= ~PWS_HSCROLL;
169   GetCreationParams()->dwFlags &= ~PWS_VSCROLL;
170 }
171 
172 CPWL_ComboBox::~CPWL_ComboBox() = default;
173 
OnDestroy()174 void CPWL_ComboBox::OnDestroy() {
175   // Until cleanup takes place in the virtual destructor for CPWL_Wnd
176   // subclasses, implement the virtual OnDestroy method that does the
177   // cleanup first, then invokes the superclass OnDestroy ... gee,
178   // like a dtor would.
179   m_pList.Release();
180   m_pButton.Release();
181   m_pEdit.Release();
182   CPWL_Wnd::OnDestroy();
183 }
184 
SetFocus()185 void CPWL_ComboBox::SetFocus() {
186   if (m_pEdit)
187     m_pEdit->SetFocus();
188 }
189 
KillFocus()190 void CPWL_ComboBox::KillFocus() {
191   if (!SetPopup(false))
192     return;
193 
194   CPWL_Wnd::KillFocus();
195 }
196 
GetSelectedText()197 WideString CPWL_ComboBox::GetSelectedText() {
198   if (m_pEdit)
199     return m_pEdit->GetSelectedText();
200 
201   return WideString();
202 }
203 
ReplaceSelection(const WideString & text)204 void CPWL_ComboBox::ReplaceSelection(const WideString& text) {
205   if (m_pEdit)
206     m_pEdit->ReplaceSelection(text);
207 }
208 
CanUndo()209 bool CPWL_ComboBox::CanUndo() {
210   return m_pEdit && m_pEdit->CanUndo();
211 }
212 
CanRedo()213 bool CPWL_ComboBox::CanRedo() {
214   return m_pEdit && m_pEdit->CanRedo();
215 }
216 
Undo()217 bool CPWL_ComboBox::Undo() {
218   return m_pEdit && m_pEdit->Undo();
219 }
220 
Redo()221 bool CPWL_ComboBox::Redo() {
222   return m_pEdit && m_pEdit->Redo();
223 }
224 
GetText()225 WideString CPWL_ComboBox::GetText() {
226   return m_pEdit ? m_pEdit->GetText() : WideString();
227 }
228 
SetText(const WideString & text)229 void CPWL_ComboBox::SetText(const WideString& text) {
230   if (m_pEdit)
231     m_pEdit->SetText(text);
232 }
233 
AddString(const WideString & str)234 void CPWL_ComboBox::AddString(const WideString& str) {
235   if (m_pList)
236     m_pList->AddString(str);
237 }
238 
GetSelect() const239 int32_t CPWL_ComboBox::GetSelect() const {
240   return m_nSelectItem;
241 }
242 
SetSelect(int32_t nItemIndex)243 void CPWL_ComboBox::SetSelect(int32_t nItemIndex) {
244   if (m_pList)
245     m_pList->Select(nItemIndex);
246 
247   m_pEdit->SetText(m_pList->GetText());
248   m_nSelectItem = nItemIndex;
249 }
250 
SetEditSelection(int32_t nStartChar,int32_t nEndChar)251 void CPWL_ComboBox::SetEditSelection(int32_t nStartChar, int32_t nEndChar) {
252   if (m_pEdit)
253     m_pEdit->SetSelection(nStartChar, nEndChar);
254 }
255 
GetEditSelection(int32_t & nStartChar,int32_t & nEndChar) const256 void CPWL_ComboBox::GetEditSelection(int32_t& nStartChar,
257                                      int32_t& nEndChar) const {
258   nStartChar = -1;
259   nEndChar = -1;
260 
261   if (m_pEdit)
262     m_pEdit->GetSelection(nStartChar, nEndChar);
263 }
264 
ClearSelection()265 void CPWL_ComboBox::ClearSelection() {
266   if (m_pEdit)
267     m_pEdit->ClearSelection();
268 }
269 
CreateChildWnd(const CreateParams & cp)270 void CPWL_ComboBox::CreateChildWnd(const CreateParams& cp) {
271   CreateEdit(cp);
272   CreateButton(cp);
273   CreateListBox(cp);
274 }
275 
CreateEdit(const CreateParams & cp)276 void CPWL_ComboBox::CreateEdit(const CreateParams& cp) {
277   if (m_pEdit)
278     return;
279 
280   CreateParams ecp = cp;
281   ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PES_CENTER |
282                 PES_AUTOSCROLL | PES_UNDO;
283 
284   if (HasFlag(PWS_AUTOFONTSIZE))
285     ecp.dwFlags |= PWS_AUTOFONTSIZE;
286 
287   if (!HasFlag(PCBS_ALLOWCUSTOMTEXT))
288     ecp.dwFlags |= PWS_READONLY;
289 
290   ecp.rcRectWnd = CFX_FloatRect();
291   ecp.dwBorderWidth = 0;
292   ecp.nBorderStyle = BorderStyle::SOLID;
293 
294   auto pEdit = pdfium::MakeUnique<CPWL_Edit>(ecp, CloneAttachedData());
295   m_pEdit = pEdit.get();
296   m_pEdit->AttachFFLData(m_pFormFiller.Get());
297   AddChild(std::move(pEdit));
298   m_pEdit->Realize();
299 }
300 
CreateButton(const CreateParams & cp)301 void CPWL_ComboBox::CreateButton(const CreateParams& cp) {
302   if (m_pButton)
303     return;
304 
305   CreateParams bcp = cp;
306   bcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND;
307   bcp.sBackgroundColor = CFX_Color(CFX_Color::kRGB, 220.0f / 255.0f,
308                                    220.0f / 255.0f, 220.0f / 255.0f);
309   bcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
310   bcp.dwBorderWidth = 2;
311   bcp.nBorderStyle = BorderStyle::BEVELED;
312   bcp.eCursorType = FXCT_ARROW;
313 
314   auto pButton = pdfium::MakeUnique<CPWL_CBButton>(bcp, CloneAttachedData());
315   m_pButton = pButton.get();
316   AddChild(std::move(pButton));
317   m_pButton->Realize();
318 }
319 
CreateListBox(const CreateParams & cp)320 void CPWL_ComboBox::CreateListBox(const CreateParams& cp) {
321   if (m_pList)
322     return;
323 
324   CreateParams lcp = cp;
325   lcp.dwFlags =
326       PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PLBS_HOVERSEL | PWS_VSCROLL;
327   lcp.nBorderStyle = BorderStyle::SOLID;
328   lcp.dwBorderWidth = 1;
329   lcp.eCursorType = FXCT_ARROW;
330   lcp.rcRectWnd = CFX_FloatRect();
331 
332   lcp.fFontSize =
333       (cp.dwFlags & PWS_AUTOFONTSIZE) ? kComboBoxDefaultFontSize : cp.fFontSize;
334 
335   if (cp.sBorderColor.nColorType == CFX_Color::kTransparent)
336     lcp.sBorderColor = PWL_DEFAULT_BLACKCOLOR;
337 
338   if (cp.sBackgroundColor.nColorType == CFX_Color::kTransparent)
339     lcp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
340 
341   auto pList = pdfium::MakeUnique<CPWL_CBListBox>(lcp, CloneAttachedData());
342   m_pList = pList.get();
343   m_pList->AttachFFLData(m_pFormFiller.Get());
344   AddChild(std::move(pList));
345   m_pList->Realize();
346 }
347 
RePosChildWnd()348 bool CPWL_ComboBox::RePosChildWnd() {
349   ObservedPtr<CPWL_ComboBox> thisObserved(this);
350   const CFX_FloatRect rcClient = GetClientRect();
351   if (m_bPopup) {
352     const float fOldWindowHeight = m_rcOldWindow.Height();
353     const float fOldClientHeight = fOldWindowHeight - GetBorderWidth() * 2;
354 
355     CFX_FloatRect rcList = CPWL_Wnd::GetWindowRect();
356     CFX_FloatRect rcButton = rcClient;
357     rcButton.left =
358         std::max(rcButton.right - kDefaultButtonWidth, rcClient.left);
359     CFX_FloatRect rcEdit = rcClient;
360     rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
361     if (m_bBottom) {
362       rcButton.bottom = rcButton.top - fOldClientHeight;
363       rcEdit.bottom = rcEdit.top - fOldClientHeight;
364       rcList.top -= fOldWindowHeight;
365     } else {
366       rcButton.top = rcButton.bottom + fOldClientHeight;
367       rcEdit.top = rcEdit.bottom + fOldClientHeight;
368       rcList.bottom += fOldWindowHeight;
369     }
370 
371     if (m_pButton) {
372       m_pButton->Move(rcButton, true, false);
373       if (!thisObserved)
374         return false;
375     }
376 
377     if (m_pEdit) {
378       m_pEdit->Move(rcEdit, true, false);
379       if (!thisObserved)
380         return false;
381     }
382 
383     if (m_pList) {
384       if (!m_pList->SetVisible(true) || !thisObserved)
385         return false;
386 
387       if (!m_pList->Move(rcList, true, false) || !thisObserved)
388         return false;
389 
390       m_pList->ScrollToListItem(m_nSelectItem);
391       if (!thisObserved)
392         return false;
393     }
394     return true;
395   }
396 
397   CFX_FloatRect rcButton = rcClient;
398   rcButton.left = std::max(rcButton.right - kDefaultButtonWidth, rcClient.left);
399 
400   if (m_pButton) {
401     m_pButton->Move(rcButton, true, false);
402     if (!thisObserved)
403       return false;
404   }
405 
406   CFX_FloatRect rcEdit = rcClient;
407   rcEdit.right = std::max(rcButton.left - 1.0f, rcEdit.left);
408 
409   if (m_pEdit) {
410     m_pEdit->Move(rcEdit, true, false);
411     if (!thisObserved)
412       return false;
413   }
414 
415   if (m_pList) {
416     m_pList->SetVisible(false);
417     if (!thisObserved)
418       return false;
419   }
420 
421   return true;
422 }
423 
SelectAll()424 void CPWL_ComboBox::SelectAll() {
425   if (m_pEdit && HasFlag(PCBS_ALLOWCUSTOMTEXT))
426     m_pEdit->SelectAll();
427 }
428 
GetFocusRect() const429 CFX_FloatRect CPWL_ComboBox::GetFocusRect() const {
430   return CFX_FloatRect();
431 }
432 
SetPopup(bool bPopup)433 bool CPWL_ComboBox::SetPopup(bool bPopup) {
434   if (!m_pList)
435     return true;
436   if (bPopup == m_bPopup)
437     return true;
438   float fListHeight = m_pList->GetContentRect().Height();
439   if (!IsFloatBigger(fListHeight, 0.0f))
440     return true;
441 
442   if (!bPopup) {
443     m_bPopup = bPopup;
444     return Move(m_rcOldWindow, true, true);
445   }
446 
447   if (!m_pFillerNotify)
448     return true;
449 
450   ObservedPtr<CPWL_ComboBox> thisObserved(this);
451   if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), 0))
452     return !!thisObserved;
453   if (!thisObserved)
454     return false;
455 
456   float fBorderWidth = m_pList->GetBorderWidth() * 2;
457   float fPopupMin = 0.0f;
458   if (m_pList->GetCount() > 3)
459     fPopupMin = m_pList->GetFirstHeight() * 3 + fBorderWidth;
460   float fPopupMax = fListHeight + fBorderWidth;
461 
462   bool bBottom;
463   float fPopupRet;
464   m_pFillerNotify->QueryWherePopup(GetAttachedData(), fPopupMin, fPopupMax,
465                                    &bBottom, &fPopupRet);
466   if (!IsFloatBigger(fPopupRet, 0.0f))
467     return true;
468 
469   m_rcOldWindow = CPWL_Wnd::GetWindowRect();
470   m_bPopup = bPopup;
471   m_bBottom = bBottom;
472 
473   CFX_FloatRect rcWindow = m_rcOldWindow;
474   if (bBottom)
475     rcWindow.bottom -= fPopupRet;
476   else
477     rcWindow.top += fPopupRet;
478 
479   if (!Move(rcWindow, true, true))
480     return false;
481 
482   m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), 0);
483   return !!thisObserved;
484 }
485 
OnKeyDown(uint16_t nChar,uint32_t nFlag)486 bool CPWL_ComboBox::OnKeyDown(uint16_t nChar, uint32_t nFlag) {
487   if (!m_pList)
488     return false;
489   if (!m_pEdit)
490     return false;
491 
492   m_nSelectItem = -1;
493 
494   switch (nChar) {
495     case FWL_VKEY_Up:
496       if (m_pList->GetCurSel() > 0) {
497         if (m_pFillerNotify) {
498           if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
499             return false;
500           if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
501             return false;
502         }
503         if (m_pList->IsMovementKey(nChar)) {
504           if (m_pList->OnMovementKeyDown(nChar, nFlag))
505             return false;
506           SetSelectText();
507         }
508       }
509       return true;
510     case FWL_VKEY_Down:
511       if (m_pList->GetCurSel() < m_pList->GetCount() - 1) {
512         if (m_pFillerNotify) {
513           if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
514             return false;
515           if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
516             return false;
517         }
518         if (m_pList->IsMovementKey(nChar)) {
519           if (m_pList->OnMovementKeyDown(nChar, nFlag))
520             return false;
521           SetSelectText();
522         }
523       }
524       return true;
525   }
526 
527   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
528     return m_pEdit->OnKeyDown(nChar, nFlag);
529 
530   return false;
531 }
532 
OnChar(uint16_t nChar,uint32_t nFlag)533 bool CPWL_ComboBox::OnChar(uint16_t nChar, uint32_t nFlag) {
534   if (!m_pList)
535     return false;
536 
537   if (!m_pEdit)
538     return false;
539 
540   m_nSelectItem = -1;
541   if (HasFlag(PCBS_ALLOWCUSTOMTEXT))
542     return m_pEdit->OnChar(nChar, nFlag);
543 
544   if (m_pFillerNotify) {
545     if (m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), nFlag))
546       return false;
547     if (m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), nFlag))
548       return false;
549   }
550   if (!m_pList->IsChar(nChar, nFlag))
551     return false;
552   return m_pList->OnCharNotify(nChar, nFlag);
553 }
554 
NotifyLButtonDown(CPWL_Wnd * child,const CFX_PointF & pos)555 void CPWL_ComboBox::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
556   if (child == m_pButton) {
557     SetPopup(!m_bPopup);
558     // Note, |this| may no longer be viable at this point. If more work needs to
559     // be done, check the return value of SetPopup().
560   }
561 }
562 
NotifyLButtonUp(CPWL_Wnd * child,const CFX_PointF & pos)563 void CPWL_ComboBox::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
564   if (!m_pEdit || !m_pList || child != m_pList)
565     return;
566 
567   SetSelectText();
568   SelectAll();
569   m_pEdit->SetFocus();
570   SetPopup(false);
571   // Note, |this| may no longer be viable at this point. If more work needs to
572   // be done, check the return value of SetPopup().
573 }
574 
IsPopup() const575 bool CPWL_ComboBox::IsPopup() const {
576   return m_bPopup;
577 }
578 
SetSelectText()579 void CPWL_ComboBox::SetSelectText() {
580   m_pEdit->SelectAll();
581   m_pEdit->ReplaceSelection(m_pList->GetText());
582   m_pEdit->SelectAll();
583   m_nSelectItem = m_pList->GetCurSel();
584 }
585 
SetFillerNotify(IPWL_Filler_Notify * pNotify)586 void CPWL_ComboBox::SetFillerNotify(IPWL_Filler_Notify* pNotify) {
587   m_pFillerNotify = pNotify;
588 
589   if (m_pEdit)
590     m_pEdit->SetFillerNotify(pNotify);
591 
592   if (m_pList)
593     m_pList->SetFillerNotify(pNotify);
594 }
595