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