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