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_Utils.h"
     10 #include "../../include/pdfwindow/PWL_ScrollBar.h"
     11 
     12 /* -------------------------- CPWL_Timer -------------------------- */
     13 
     14 static CFX_MapPtrTemplate<FX_INT32, CPWL_Timer*>	g_TimeMap;
     15 
     16 CPWL_Timer::CPWL_Timer(CPWL_TimerHandler* pAttached, IFX_SystemHandler* pSystemHandler) :
     17 	m_pAttached(pAttached),
     18 	m_nTimerID(0),
     19 	m_pSystemHandler(pSystemHandler)
     20 {
     21 	ASSERT(m_pAttached != NULL);
     22 	ASSERT(m_pSystemHandler != NULL);
     23 }
     24 
     25 CPWL_Timer::~CPWL_Timer()
     26 {
     27 	KillPWLTimer();
     28 }
     29 
     30 FX_INT32 CPWL_Timer::SetPWLTimer(FX_INT32 nElapse)
     31 {
     32 	if (m_nTimerID != 0) KillPWLTimer();
     33 	m_nTimerID = m_pSystemHandler->SetTimer(nElapse, TimerProc);
     34 	g_TimeMap.SetAt(m_nTimerID, this);
     35 	return m_nTimerID;
     36 }
     37 
     38 void CPWL_Timer::KillPWLTimer()
     39 {
     40 	if (m_nTimerID != 0)
     41 	{
     42 		m_pSystemHandler->KillTimer(m_nTimerID);
     43 		g_TimeMap.RemoveKey(m_nTimerID);
     44 		m_nTimerID = 0;
     45 	}
     46 }
     47 
     48 void CPWL_Timer::TimerProc(FX_INT32 idEvent)
     49 {
     50 	CPWL_Timer* pTimer = NULL;
     51 	if (g_TimeMap.Lookup(idEvent, pTimer))
     52 	{
     53 		if (pTimer)
     54 		{
     55 			if (pTimer->m_pAttached)
     56 				pTimer->m_pAttached->TimerProc();
     57 		}
     58 	}
     59 }
     60 
     61 /* -------------------------- CPWL_TimerHandler -------------------------- */
     62 
     63 CPWL_TimerHandler::CPWL_TimerHandler() : m_pTimer(NULL)
     64 {
     65 }
     66 
     67 CPWL_TimerHandler::~CPWL_TimerHandler()
     68 {
     69 	if (m_pTimer) delete m_pTimer;
     70 }
     71 
     72 void CPWL_TimerHandler::BeginTimer(FX_INT32 nElapse)
     73 {
     74 	if (!m_pTimer)
     75 		m_pTimer = new CPWL_Timer(this, GetSystemHandler());
     76 
     77 	if (m_pTimer)
     78 		m_pTimer->SetPWLTimer(nElapse);
     79 }
     80 
     81 void CPWL_TimerHandler::EndTimer()
     82 {
     83 	if (m_pTimer)
     84 		m_pTimer->KillPWLTimer();
     85 }
     86 
     87 void CPWL_TimerHandler::TimerProc()
     88 {
     89 }
     90 
     91 /* --------------------------- CPWL_MsgControl ---------------------------- */
     92 
     93 class CPWL_MsgControl
     94 {
     95 	friend class CPWL_Wnd;
     96 
     97 public:
     98 	CPWL_MsgControl(CPWL_Wnd * pWnd)
     99 	{
    100 //		PWL_TRACE("new CPWL_MsgControl\n");
    101 		m_pCreatedWnd = pWnd;
    102 		Default();
    103 	}
    104 
    105 	~CPWL_MsgControl()
    106 	{
    107 //		PWL_TRACE("~CPWL_MsgControl\n");
    108 		Default();
    109 	}
    110 
    111 	void Default()
    112 	{
    113 		m_aMousePath.RemoveAll();
    114 		m_aKeyboardPath.RemoveAll();
    115 		m_pMainMouseWnd = NULL;
    116 		m_pMainKeyboardWnd = NULL;
    117 	}
    118 
    119 	FX_BOOL IsWndCreated(const CPWL_Wnd * pWnd) const
    120 	{
    121 		return m_pCreatedWnd == pWnd;
    122 	}
    123 
    124 	FX_BOOL IsMainCaptureMouse(const CPWL_Wnd * pWnd) const
    125 	{
    126 		return pWnd == m_pMainMouseWnd;
    127 	}
    128 
    129 	FX_BOOL IsWndCaptureMouse(const CPWL_Wnd * pWnd) const
    130 	{
    131 		if (pWnd)
    132 			for( FX_INT32 i=0,sz=m_aMousePath.GetSize(); i<sz; i++)
    133 				if (m_aMousePath.GetAt(i) == pWnd)
    134 					return TRUE;
    135 
    136 		return FALSE;
    137 	}
    138 
    139 	FX_BOOL IsMainCaptureKeyboard(const CPWL_Wnd * pWnd) const
    140 	{
    141 		return pWnd == m_pMainKeyboardWnd;
    142 	}
    143 
    144 
    145 	FX_BOOL IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const
    146 	{
    147 		if (pWnd)
    148 			for( FX_INT32 i=0,sz=m_aKeyboardPath.GetSize(); i<sz; i++)
    149 				if (m_aKeyboardPath.GetAt(i) == pWnd)
    150 					return TRUE;
    151 
    152 		return FALSE;
    153 	}
    154 
    155 	void SetFocus(CPWL_Wnd * pWnd)
    156 	{
    157 		m_aKeyboardPath.RemoveAll();
    158 
    159 		if (pWnd)
    160 		{
    161 			m_pMainKeyboardWnd = pWnd;
    162 
    163 			CPWL_Wnd * pParent = pWnd;
    164 			while (pParent)
    165 			{
    166 				m_aKeyboardPath.Add(pParent);
    167 				pParent = pParent->GetParentWindow();
    168 			}
    169 
    170 			pWnd->OnSetFocus();
    171 		}
    172 	}
    173 
    174 	void KillFocus()
    175 	{
    176 		if (m_aKeyboardPath.GetSize() > 0)
    177 			if (CPWL_Wnd* pWnd = m_aKeyboardPath.GetAt(0))
    178 				pWnd->OnKillFocus();
    179 
    180 		m_pMainKeyboardWnd = NULL;
    181 		m_aKeyboardPath.RemoveAll();
    182 	}
    183 
    184 	void SetCapture(CPWL_Wnd * pWnd)
    185 	{
    186 		m_aMousePath.RemoveAll();
    187 
    188 		if (pWnd)
    189 		{
    190 			m_pMainMouseWnd = pWnd;
    191 
    192 			CPWL_Wnd * pParent = pWnd;
    193 			while (pParent)
    194 			{
    195 				m_aMousePath.Add(pParent);
    196 				pParent = pParent->GetParentWindow();
    197 			}
    198 		}
    199 	}
    200 
    201 	void ReleaseCapture()
    202 	{
    203 		m_pMainMouseWnd = NULL;
    204 		m_aMousePath.RemoveAll();
    205 	}
    206 
    207 private:
    208 	CFX_ArrayTemplate<CPWL_Wnd*>	m_aMousePath;
    209 	CFX_ArrayTemplate<CPWL_Wnd*>	m_aKeyboardPath;
    210 	CPWL_Wnd*						m_pCreatedWnd;
    211 	CPWL_Wnd*						m_pMainMouseWnd;
    212 	CPWL_Wnd*						m_pMainKeyboardWnd;
    213 };
    214 
    215 /* --------------------------- CPWL_Wnd ---------------------------- */
    216 
    217 CPWL_Wnd::CPWL_Wnd() :
    218 	m_pVScrollBar(NULL),
    219 	m_rcWindow(),
    220 	m_rcClip(),
    221 	m_bCreated(FALSE),
    222 	m_bVisible(FALSE),
    223 	m_bNotifying(FALSE),
    224 	m_bEnabled(TRUE)
    225 {
    226 }
    227 
    228 CPWL_Wnd::~CPWL_Wnd()
    229 {
    230 	ASSERT(m_bCreated == FALSE);
    231 }
    232 
    233 CFX_ByteString CPWL_Wnd::GetClassName() const
    234 {
    235 	return "CPWL_Wnd";
    236 }
    237 
    238 void CPWL_Wnd::Create(const PWL_CREATEPARAM & cp)
    239 {
    240 	if (!IsValid())
    241 	{
    242 		m_sPrivateParam = cp;
    243 
    244 		OnCreate(m_sPrivateParam);
    245 
    246 		m_sPrivateParam.rcRectWnd.Normalize();
    247 		m_rcWindow = m_sPrivateParam.rcRectWnd;
    248 		m_rcClip = CPWL_Utils::InflateRect(m_rcWindow,1.0f);
    249 
    250 		CreateMsgControl();
    251 
    252 		if (m_sPrivateParam.pParentWnd)
    253 			m_sPrivateParam.pParentWnd->OnNotify(this, PNM_ADDCHILD);
    254 
    255 		PWL_CREATEPARAM ccp = m_sPrivateParam;
    256 
    257 		ccp.dwFlags &= 0xFFFF0000L; //remove sub styles
    258 		ccp.mtChild = CPDF_Matrix(1,0,0,1,0,0);
    259 
    260 		CreateScrollBar(ccp);
    261 		CreateChildWnd(ccp);
    262 
    263 		m_bVisible = HasFlag(PWS_VISIBLE);
    264 
    265 		OnCreated();
    266 
    267 		RePosChildWnd();
    268 		m_bCreated = TRUE;
    269 	}
    270 }
    271 
    272 void CPWL_Wnd::OnCreate(PWL_CREATEPARAM & cp)
    273 {
    274 }
    275 
    276 void CPWL_Wnd::OnCreated()
    277 {
    278 }
    279 
    280 void CPWL_Wnd::OnDestroy()
    281 {
    282 }
    283 
    284 void CPWL_Wnd::Destroy()
    285 {
    286 	KillFocus();
    287 
    288 	OnDestroy();
    289 
    290 	if (m_bCreated)
    291 	{
    292 		for (FX_INT32 i = m_aChildren.GetSize()-1; i >= 0; i --)
    293 		{
    294 			if (CPWL_Wnd * pChild = m_aChildren[i])
    295 			{
    296 				pChild->Destroy();
    297 				delete pChild;
    298 				pChild = NULL;
    299 			}
    300 		}
    301 
    302 		if (m_sPrivateParam.pParentWnd)
    303 			m_sPrivateParam.pParentWnd->OnNotify(this, PNM_REMOVECHILD);
    304 		m_bCreated = FALSE;
    305 	}
    306 
    307 	DestroyMsgControl();
    308 
    309 	FXSYS_memset(&m_sPrivateParam, 0, sizeof(PWL_CREATEPARAM));
    310 	m_aChildren.RemoveAll();
    311 	m_pVScrollBar = NULL;
    312 }
    313 
    314 void CPWL_Wnd::Move(const CPDF_Rect & rcNew, FX_BOOL bReset,FX_BOOL bRefresh)
    315 {
    316 	if (IsValid())
    317 	{
    318 		CPDF_Rect rcOld = this->GetWindowRect();
    319 
    320 		m_rcWindow = rcNew;
    321 		m_rcWindow.Normalize();
    322 		//m_rcClip = CPWL_Utils::InflateRect(m_rcWindow,1.0f); //for special caret
    323 
    324 		if (rcOld.left != rcNew.left || rcOld.right != rcNew.right ||
    325 			rcOld.top != rcNew.top || rcOld.bottom != rcNew.bottom)
    326 		{
    327 			if (bReset)
    328 			{
    329 				RePosChildWnd();
    330 			}
    331 
    332 		}
    333 		if (bRefresh)
    334 		{
    335 			InvalidateRectMove(rcOld,rcNew);
    336 		}
    337 
    338 		m_sPrivateParam.rcRectWnd = m_rcWindow;
    339 	}
    340 }
    341 
    342 void  CPWL_Wnd::InvalidateRectMove(const CPDF_Rect & rcOld, const CPDF_Rect & rcNew)
    343 {
    344 	CPDF_Rect rcUnion = rcOld;
    345 	rcUnion.Union(rcNew);
    346 
    347 	InvalidateRect(&rcUnion);
    348 
    349 	/*
    350 	CPDF_Rect SubArray[4];
    351 
    352 	rcOld.Substract4(rcNew,SubArray);
    353 	for (FX_INT32 i=0;i<4;i++)
    354 	{
    355 		if (SubArray[i].left == 0 &&
    356 			SubArray[i].right == 0 &&
    357 			SubArray[i].top == 0 &&
    358 			SubArray[i].bottom == 0)continue;
    359 
    360 		InvalidateRect(&CPWL_Utils::InflateRect(SubArray[i],2));
    361 	}
    362 
    363 	rcNew.Substract4(rcOld,SubArray);
    364 	for (FX_INT32 j=0;j<4;j++)
    365 	{
    366 		if (SubArray[j].left == 0 &&
    367 			SubArray[j].right == 0 &&
    368 			SubArray[j].top == 0 &&
    369 			SubArray[j].bottom == 0)continue;
    370 
    371 		InvalidateRect(&CPWL_Utils::InflateRect(SubArray[j],2));
    372 	}
    373 	*/
    374 }
    375 
    376 void CPWL_Wnd::GetAppearanceStream(CFX_ByteString & sAppStream)
    377 {
    378 	if (IsValid())
    379 	{
    380 		CFX_ByteTextBuf sTextBuf;
    381 		GetAppearanceStream(sTextBuf);
    382 		sAppStream += sTextBuf.GetByteString();
    383 	}
    384 }
    385 
    386 void CPWL_Wnd::GetAppearanceStream(CFX_ByteTextBuf & sAppStream)
    387 {
    388 	if (IsValid() && IsVisible())
    389 	{
    390 		GetThisAppearanceStream(sAppStream);
    391 		GetChildAppearanceStream(sAppStream);
    392 	}
    393 }
    394 
    395 //if don't set,Get default apperance stream
    396 void CPWL_Wnd::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
    397 {
    398 	CPDF_Rect rectWnd = GetWindowRect();
    399 	if (!rectWnd.IsEmpty())
    400 	{
    401 		CFX_ByteTextBuf sThis;
    402 
    403 		if (HasFlag(PWS_BACKGROUND))
    404 			sThis << CPWL_Utils::GetRectFillAppStream(rectWnd,this->GetBackgroundColor());
    405 
    406 		if (HasFlag(PWS_BORDER))
    407 			sThis << CPWL_Utils::GetBorderAppStream(rectWnd,
    408 									(FX_FLOAT)GetBorderWidth(),
    409 									GetBorderColor(),
    410 									this->GetBorderLeftTopColor(this->GetBorderStyle()),
    411 									this->GetBorderRightBottomColor(this->GetBorderStyle()),
    412 									this->GetBorderStyle(),
    413 									this->GetBorderDash());
    414 
    415 		sAppStream << sThis;
    416 	}
    417 }
    418 
    419 void CPWL_Wnd::GetChildAppearanceStream(CFX_ByteTextBuf & sAppStream)
    420 {
    421 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    422 	{
    423 		if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
    424 		{
    425 			pChild->GetAppearanceStream(sAppStream);
    426 		}
    427 	}
    428 }
    429 
    430 void CPWL_Wnd::DrawAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
    431 {
    432 	if (IsValid() && IsVisible())
    433 	{
    434 		DrawThisAppearance(pDevice,pUser2Device);
    435 		DrawChildAppearance(pDevice,pUser2Device);
    436 	}
    437 }
    438 
    439 void CPWL_Wnd::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
    440 {
    441 	CPDF_Rect rectWnd = GetWindowRect();
    442 	if (!rectWnd.IsEmpty())
    443 	{
    444 		if (HasFlag(PWS_BACKGROUND))
    445 		{
    446 			CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rectWnd,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
    447 			CPWL_Utils::DrawFillRect(pDevice,pUser2Device,rcClient,this->GetBackgroundColor(),GetTransparency());
    448 		}
    449 
    450 		if (HasFlag(PWS_BORDER))
    451 			CPWL_Utils::DrawBorder(pDevice,
    452 								pUser2Device,
    453 								rectWnd,
    454 								(FX_FLOAT)GetBorderWidth(),
    455 								GetBorderColor(),
    456 								this->GetBorderLeftTopColor(this->GetBorderStyle()),
    457 								this->GetBorderRightBottomColor(this->GetBorderStyle()),
    458 								this->GetBorderStyle(),
    459 								this->GetBorderDash(),
    460 								GetTransparency());
    461 	}
    462 }
    463 
    464 void CPWL_Wnd::DrawChildAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
    465 {
    466 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    467 	{
    468 		if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
    469 		{
    470 			CPDF_Matrix mt = pChild->GetChildMatrix();
    471 			if (mt.IsIdentity())
    472 			{
    473 				pChild->DrawAppearance(pDevice,pUser2Device);
    474 			}
    475 			else
    476 			{
    477 				mt.Concat(*pUser2Device);
    478 				pChild->DrawAppearance(pDevice,&mt);
    479 			}
    480 		}
    481 	}
    482 }
    483 
    484 void CPWL_Wnd::InvalidateRect(CPDF_Rect* pRect)
    485 {
    486 	if (IsValid())
    487 	{
    488 		CPDF_Rect rcRefresh = pRect ? *pRect : GetWindowRect();
    489 
    490 		if (!HasFlag(PWS_NOREFRESHCLIP))
    491 		{
    492 			CPDF_Rect rcClip = GetClipRect();
    493 			if (!rcClip.IsEmpty())
    494 			{
    495 				rcRefresh.Intersect(rcClip);
    496 			}
    497 		}
    498 
    499 		FX_RECT rcWin = PWLtoWnd(rcRefresh);
    500 		rcWin.left -= PWL_INVALIDATE_INFLATE;
    501 		rcWin.top -= PWL_INVALIDATE_INFLATE;
    502 		rcWin.right += PWL_INVALIDATE_INFLATE;
    503 		rcWin.bottom += PWL_INVALIDATE_INFLATE;
    504 
    505 		if (IFX_SystemHandler* pSH = GetSystemHandler())
    506 		{
    507 			if (FX_HWND hWnd = GetAttachedHWnd())
    508 			{
    509 				pSH->InvalidateRect(hWnd, rcWin);
    510 			}
    511 		}
    512 	}
    513 }
    514 
    515 #define PWL_IMPLEMENT_KEY_METHOD(key_method_name)\
    516 FX_BOOL CPWL_Wnd::key_method_name(FX_WORD nChar, FX_DWORD nFlag)\
    517 {\
    518 	if (IsValid() && IsVisible() && IsEnabled())\
    519 	{\
    520 		if (IsWndCaptureKeyboard(this))\
    521 		{\
    522 			for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
    523 			{\
    524 				if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
    525 				{\
    526 					if (IsWndCaptureKeyboard(pChild))\
    527 					{\
    528 						return pChild->key_method_name(nChar,nFlag);\
    529 					}\
    530 				}\
    531 			}\
    532 		}\
    533 	}\
    534 	return FALSE;\
    535 }
    536 
    537 #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name)\
    538 FX_BOOL CPWL_Wnd::mouse_method_name(const CPDF_Point & point, FX_DWORD nFlag)\
    539 {\
    540 	if (IsValid() && IsVisible() && IsEnabled())\
    541 	{\
    542 		if (IsWndCaptureMouse(this))\
    543 		{\
    544 			for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
    545 			{\
    546 				if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
    547 				{\
    548 					if (IsWndCaptureMouse(pChild))\
    549 					{\
    550 						return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\
    551 					}\
    552 				}\
    553 			}\
    554 			SetCursor();\
    555 		}\
    556 		else\
    557 		{\
    558 			for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)\
    559 			{\
    560 				if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))\
    561 				{\
    562 					if (pChild->WndHitTest(pChild->ParentToChild(point)))\
    563 					{\
    564 						return pChild->mouse_method_name(pChild->ParentToChild(point),nFlag);\
    565 					}\
    566 				}\
    567 			}\
    568 			if (this->WndHitTest(point))\
    569 				SetCursor();\
    570 		}\
    571 	}\
    572 	return FALSE;\
    573 }
    574 
    575 PWL_IMPLEMENT_KEY_METHOD(OnKeyDown)
    576 PWL_IMPLEMENT_KEY_METHOD(OnKeyUp)
    577 PWL_IMPLEMENT_KEY_METHOD(OnChar)
    578 
    579 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk)
    580 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown)
    581 PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp)
    582 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk)
    583 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown)
    584 PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp)
    585 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDblClk)
    586 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown)
    587 PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp)
    588 PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove)
    589 
    590 FX_BOOL	CPWL_Wnd::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag)
    591 {
    592 	if (IsValid() && IsVisible() && IsEnabled())
    593 	{
    594 		SetCursor();
    595 		if (IsWndCaptureKeyboard(this))
    596 		{
    597 			for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    598 			{
    599 				if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
    600 				{
    601 					if (IsWndCaptureKeyboard(pChild))
    602 					{
    603 						return pChild->OnMouseWheel(zDelta,pChild->ParentToChild(point), nFlag);
    604 					}
    605 				}
    606 			}
    607 		}
    608 	}
    609 	return FALSE;
    610 }
    611 
    612 void CPWL_Wnd::AddChild(CPWL_Wnd * pWnd)
    613 {
    614 	m_aChildren.Add(pWnd);
    615 }
    616 
    617 void CPWL_Wnd::RemoveChild(CPWL_Wnd * pWnd)
    618 {
    619 	for (FX_INT32 i = m_aChildren.GetSize()-1; i >= 0; i --)
    620 	{
    621 		if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
    622 		{
    623 			if (pChild == pWnd)
    624 			{
    625 				m_aChildren.RemoveAt(i);
    626 				break;
    627 			}
    628 		}
    629 	}
    630 }
    631 
    632 void CPWL_Wnd::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam)
    633 {
    634 	switch (msg)
    635 	{
    636 	case PNM_ADDCHILD:
    637 		this->AddChild(pWnd);
    638 		break;
    639 	case PNM_REMOVECHILD:
    640 		this->RemoveChild(pWnd);
    641 		break;
    642 	default:
    643 		break;
    644 	}
    645 }
    646 
    647 FX_BOOL CPWL_Wnd::IsValid() const
    648 {
    649 	return m_bCreated;
    650 }
    651 
    652 PWL_CREATEPARAM CPWL_Wnd::GetCreationParam() const
    653 {
    654 	return m_sPrivateParam;
    655 }
    656 
    657 CPWL_Wnd* CPWL_Wnd::GetParentWindow() const
    658 {
    659 	return m_sPrivateParam.pParentWnd;
    660 }
    661 
    662 CPDF_Rect CPWL_Wnd::GetOriginWindowRect() const
    663 {
    664 	return m_sPrivateParam.rcRectWnd;
    665 }
    666 
    667 CPDF_Rect CPWL_Wnd::GetWindowRect() const
    668 {
    669 	return m_rcWindow;
    670 }
    671 
    672 CPDF_Rect CPWL_Wnd::GetClientRect() const
    673 {
    674 	CPDF_Rect rcWindow = GetWindowRect();
    675 	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
    676 
    677 	if (CPWL_ScrollBar * pVSB = this->GetVScrollBar())
    678 		rcClient.right -= pVSB->GetScrollBarWidth();
    679 
    680 	rcClient.Normalize();
    681 
    682 	if (rcWindow.Contains(rcClient))
    683 		return rcClient;
    684 	else
    685 		return CPDF_Rect();
    686 }
    687 
    688 CPDF_Point CPWL_Wnd::GetCenterPoint() const
    689 {
    690 	CPDF_Rect rcClient = GetClientRect();
    691 
    692 	return CPDF_Point((rcClient.left + rcClient.right) * 0.5f,
    693 		(rcClient.top + rcClient.bottom) * 0.5f);
    694 }
    695 
    696 CPDF_Rect CPWL_Wnd::GetClientCenterSquare() const
    697 {
    698 	return CPWL_Utils::GetCenterSquare(GetClientRect());
    699 }
    700 
    701 CPDF_Rect CPWL_Wnd::GetWindowCenterSquare() const
    702 {
    703 	return CPWL_Utils::GetCenterSquare(CPWL_Utils::DeflateRect(GetWindowRect(),0.1f));
    704 }
    705 
    706 FX_BOOL CPWL_Wnd::HasFlag(FX_DWORD dwFlags) const
    707 {
    708 	return (m_sPrivateParam.dwFlags & dwFlags) != 0;
    709 }
    710 
    711 void CPWL_Wnd::RemoveFlag(FX_DWORD dwFlags)
    712 {
    713 	m_sPrivateParam.dwFlags &= ~dwFlags;
    714 }
    715 
    716 void CPWL_Wnd::AddFlag(FX_DWORD dwFlags)
    717 {
    718 	m_sPrivateParam.dwFlags |= dwFlags;
    719 }
    720 
    721 CPWL_Color CPWL_Wnd::GetBackgroundColor() const
    722 {
    723 	return m_sPrivateParam.sBackgroundColor;
    724 }
    725 
    726 void CPWL_Wnd::SetBackgroundColor(const CPWL_Color & color)
    727 {
    728 	m_sPrivateParam.sBackgroundColor = color;
    729 }
    730 
    731 void CPWL_Wnd::SetTextColor(const CPWL_Color & color)
    732 {
    733 	m_sPrivateParam.sTextColor = color;
    734 }
    735 
    736 void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color & color)
    737 {
    738 	m_sPrivateParam.sTextStrokeColor = color;
    739 }
    740 
    741 CPWL_Color CPWL_Wnd::GetTextColor() const
    742 {
    743 	return m_sPrivateParam.sTextColor;
    744 }
    745 
    746 CPWL_Color CPWL_Wnd::GetTextStrokeColor() const
    747 {
    748 	return m_sPrivateParam.sTextStrokeColor;
    749 }
    750 
    751 FX_INT32 CPWL_Wnd::GetBorderStyle() const
    752 {
    753 	return m_sPrivateParam.nBorderStyle;
    754 }
    755 
    756 void CPWL_Wnd::SetBorderStyle(FX_INT32 nBorderStyle)
    757 {
    758 	if (HasFlag(PWS_BORDER))
    759 		m_sPrivateParam.nBorderStyle = nBorderStyle;
    760 }
    761 
    762 FX_INT32 CPWL_Wnd::GetBorderWidth() const
    763 {
    764 	if (HasFlag(PWS_BORDER))
    765 		return m_sPrivateParam.dwBorderWidth;
    766 
    767 	return 0;
    768 }
    769 
    770 FX_INT32 CPWL_Wnd::GetInnerBorderWidth() const
    771 {
    772 	/*
    773 	switch (GetBorderStyle())
    774 	{
    775 	case PBS_BEVELED:
    776 	case PBS_INSET:
    777 		return GetBorderWidth() / 2;
    778 	}
    779 	*/
    780 	return 0;
    781 }
    782 
    783 void CPWL_Wnd::SetBorderWidth(FX_INT32 nBorderWidth)
    784 {
    785 	if (HasFlag(PWS_BORDER))
    786 		m_sPrivateParam.dwBorderWidth = nBorderWidth;
    787 }
    788 
    789 CPWL_Color CPWL_Wnd::GetBorderColor() const
    790 {
    791 	if (HasFlag(PWS_BORDER))
    792 		return m_sPrivateParam.sBorderColor;
    793 
    794 	return CPWL_Color();
    795 }
    796 
    797 void CPWL_Wnd::SetBorderColor(const CPWL_Color & color)
    798 {
    799 	if (HasFlag(PWS_BORDER))
    800 		m_sPrivateParam.sBorderColor = color;
    801 }
    802 
    803 CPWL_Dash CPWL_Wnd::GetBorderDash() const
    804 {
    805 	return m_sPrivateParam.sDash;
    806 }
    807 
    808 void* CPWL_Wnd::GetAttachedData() const
    809 {
    810 	return m_sPrivateParam.pAttachedData;
    811 }
    812 
    813 void CPWL_Wnd::SetBorderDash(const CPWL_Dash & sDash)
    814 {
    815 	if (HasFlag(PWS_BORDER))
    816 		m_sPrivateParam.sDash = sDash;
    817 }
    818 
    819 CPWL_ScrollBar* CPWL_Wnd::GetVScrollBar() const
    820 {
    821 	if (HasFlag(PWS_VSCROLL))
    822 		return m_pVScrollBar;
    823 
    824 	return NULL;
    825 }
    826 
    827 void CPWL_Wnd::CreateScrollBar(const PWL_CREATEPARAM & cp)
    828 {
    829 	CreateVScrollBar(cp);
    830 }
    831 
    832 void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM & cp)
    833 {
    834 	if (!m_pVScrollBar && HasFlag(PWS_VSCROLL))
    835 	{
    836 		PWL_CREATEPARAM scp = cp;
    837 
    838 		//flags
    839 		scp.dwFlags = PWS_CHILD| PWS_BACKGROUND | PWS_AUTOTRANSPARENT | PWS_NOREFRESHCLIP;
    840 
    841 		scp.pParentWnd = this;
    842 		scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR;
    843 		scp.eCursorType = FXCT_ARROW;
    844 		scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY;
    845 
    846 		if ((m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL)))
    847 			m_pVScrollBar->Create(scp);
    848 	}
    849 }
    850 
    851 void CPWL_Wnd::SetCapture()
    852 {
    853 	if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
    854 		pMsgCtrl->SetCapture(this);
    855 }
    856 
    857 void CPWL_Wnd::ReleaseCapture()
    858 {
    859 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    860 		if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
    861 			pChild->ReleaseCapture();
    862 
    863 	if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
    864 		pMsgCtrl->ReleaseCapture();
    865 }
    866 
    867 void CPWL_Wnd::SetFocus()
    868 {
    869 	if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
    870 	{
    871 		if (!pMsgCtrl->IsMainCaptureKeyboard(this))
    872 			pMsgCtrl->KillFocus();
    873 		pMsgCtrl->SetFocus(this);
    874 	}
    875 }
    876 
    877 void CPWL_Wnd::KillFocus()
    878 {
    879 	if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
    880 	{
    881 		if (pMsgCtrl->IsWndCaptureKeyboard(this))
    882 			pMsgCtrl->KillFocus();
    883 	}
    884 }
    885 
    886 void CPWL_Wnd::OnSetFocus()
    887 {
    888 }
    889 
    890 void CPWL_Wnd::OnKillFocus()
    891 {
    892 }
    893 
    894 FX_BOOL	CPWL_Wnd::WndHitTest(const CPDF_Point & point) const
    895 {
    896 	return IsValid() && IsVisible() && GetWindowRect().Contains(point.x,point.y);
    897 }
    898 
    899 FX_BOOL CPWL_Wnd::ClientHitTest(const CPDF_Point & point) const
    900 {
    901 	return IsValid() && IsVisible() && GetClientRect().Contains(point.x,point.y);
    902 }
    903 
    904 const CPWL_Wnd * CPWL_Wnd::GetRootWnd() const
    905 {
    906 	if (m_sPrivateParam.pParentWnd)
    907 		return m_sPrivateParam.pParentWnd->GetRootWnd();
    908 	else
    909 		return this;
    910 }
    911 
    912 void CPWL_Wnd::SetVisible(FX_BOOL bVisible)
    913 {
    914 	if (IsValid())
    915 	{
    916 		for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    917 		{
    918 			if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
    919 			{
    920 				pChild->SetVisible(bVisible);
    921 			}
    922 		}
    923 
    924 		if (bVisible != m_bVisible)
    925 		{
    926 			m_bVisible = bVisible;
    927 			RePosChildWnd();
    928 			InvalidateRect();
    929 		}
    930 	}
    931 }
    932 
    933 void CPWL_Wnd::SetClipRect(const CPDF_Rect & rect)
    934 {
    935 	m_rcClip = rect;
    936 	m_rcClip.Normalize();
    937 }
    938 
    939 CPDF_Rect CPWL_Wnd::GetClipRect() const
    940 {
    941 	return m_rcClip;
    942 }
    943 
    944 FX_BOOL	CPWL_Wnd::IsReadOnly() const
    945 {
    946 	return HasFlag(PWS_READONLY);
    947 }
    948 
    949 void CPWL_Wnd::RePosChildWnd()
    950 {
    951 	CPDF_Rect rcContent = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
    952 
    953 	CPWL_ScrollBar * pVSB = this->GetVScrollBar();
    954 
    955 	CPDF_Rect rcVScroll = CPDF_Rect(rcContent.right - PWL_SCROLLBAR_WIDTH,
    956 							rcContent.bottom,
    957 							rcContent.right-1.0f,
    958 							rcContent.top);
    959 
    960 	if (pVSB) pVSB->Move(rcVScroll,TRUE,FALSE);
    961 }
    962 
    963 void CPWL_Wnd::CreateChildWnd(const PWL_CREATEPARAM & cp)
    964 {
    965 }
    966 
    967 void CPWL_Wnd::SetCursor()
    968 {
    969 	if (IsValid())
    970 	{
    971 		if (IFX_SystemHandler* pSH = GetSystemHandler())
    972 		{
    973 			FX_INT32 nCursorType = this->GetCreationParam().eCursorType;
    974 			pSH->SetCursor(nCursorType);
    975 		}
    976 	}
    977 }
    978 
    979 void CPWL_Wnd::CreateMsgControl()
    980 {
    981 	if (!m_sPrivateParam.pMsgControl)
    982 		m_sPrivateParam.pMsgControl = new CPWL_MsgControl(this);
    983 }
    984 
    985 void CPWL_Wnd::DestroyMsgControl()
    986 {
    987 	if (CPWL_MsgControl* pMsgControl = GetMsgControl())
    988 		if (pMsgControl->IsWndCreated(this))
    989 			delete pMsgControl;
    990 }
    991 
    992 CPWL_MsgControl* CPWL_Wnd::GetMsgControl() const
    993 {
    994 	return m_sPrivateParam.pMsgControl;
    995 }
    996 
    997 FX_BOOL CPWL_Wnd::IsCaptureMouse() const
    998 {
    999 	return IsWndCaptureMouse(this);
   1000 }
   1001 
   1002 FX_BOOL CPWL_Wnd::IsWndCaptureMouse(const CPWL_Wnd * pWnd) const
   1003 {
   1004 	if (CPWL_MsgControl * pCtrl = GetMsgControl())
   1005 		return pCtrl->IsWndCaptureMouse(pWnd);
   1006 
   1007 	return FALSE;
   1008 }
   1009 
   1010 FX_BOOL CPWL_Wnd::IsWndCaptureKeyboard(const CPWL_Wnd * pWnd) const
   1011 {
   1012 	if (CPWL_MsgControl * pCtrl = GetMsgControl())
   1013 		return pCtrl->IsWndCaptureKeyboard(pWnd);
   1014 
   1015 	return FALSE;
   1016 }
   1017 
   1018 FX_BOOL CPWL_Wnd::IsFocused() const
   1019 {
   1020 	if (CPWL_MsgControl * pCtrl = GetMsgControl())
   1021 		return pCtrl->IsMainCaptureKeyboard(this);
   1022 
   1023 	return FALSE;
   1024 }
   1025 
   1026 CPDF_Rect CPWL_Wnd::GetFocusRect() const
   1027 {
   1028 	return CPWL_Utils::InflateRect(this->GetWindowRect(),1);
   1029 }
   1030 
   1031 FX_FLOAT CPWL_Wnd::GetFontSize() const
   1032 {
   1033 	return this->m_sPrivateParam.fFontSize;
   1034 }
   1035 
   1036 void CPWL_Wnd::SetFontSize(FX_FLOAT fFontSize)
   1037 {
   1038 	this->m_sPrivateParam.fFontSize = fFontSize;
   1039 }
   1040 
   1041 IFX_SystemHandler* CPWL_Wnd::GetSystemHandler() const
   1042 {
   1043 	return m_sPrivateParam.pSystemHandler;
   1044 }
   1045 
   1046 IPWL_FocusHandler* CPWL_Wnd::GetFocusHandler() const
   1047 {
   1048 	return m_sPrivateParam.pFocusHandler;
   1049 }
   1050 
   1051 IPWL_Provider* CPWL_Wnd::GetProvider() const
   1052 {
   1053 	return m_sPrivateParam.pProvider;
   1054 }
   1055 
   1056 IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const
   1057 {
   1058 	return m_sPrivateParam.pFontMap;
   1059 }
   1060 
   1061 CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(FX_INT32 nBorderStyle) const
   1062 {
   1063 	CPWL_Color color;
   1064 
   1065 	switch (nBorderStyle)
   1066 	{
   1067 		case PBS_SOLID:
   1068 			break;
   1069 		case PBS_DASH:
   1070 			break;
   1071 		case PBS_BEVELED:
   1072 			color = CPWL_Color(COLORTYPE_GRAY,1);
   1073 			break;
   1074 		case PBS_INSET:
   1075 			color = CPWL_Color(COLORTYPE_GRAY,0.5f);
   1076 			break;
   1077 		case PBS_UNDERLINED:
   1078 			break;
   1079 	}
   1080 
   1081 	return color;
   1082 }
   1083 
   1084 CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(FX_INT32 nBorderStyle) const
   1085 {
   1086 	CPWL_Color color;
   1087 
   1088 	switch (nBorderStyle)
   1089 	{
   1090 		case PBS_SOLID:
   1091 			break;
   1092 		case PBS_DASH:
   1093 			break;
   1094 		case PBS_BEVELED:
   1095 			color = CPWL_Utils::DevideColor(GetBackgroundColor(),2);
   1096 			break;
   1097 		case PBS_INSET:
   1098 			color = CPWL_Color(COLORTYPE_GRAY,0.75f);
   1099 			break;
   1100 		case PBS_UNDERLINED:
   1101 			break;
   1102 	}
   1103 
   1104 	return color;
   1105 }
   1106 
   1107 /* ----------------------------------------------------------------- */
   1108 
   1109 FX_INT32 CPWL_Wnd::GetTransparency()
   1110 {
   1111 	return m_sPrivateParam.nTransparency;
   1112 }
   1113 
   1114 void CPWL_Wnd::SetTransparency(FX_INT32 nTransparency)
   1115 {
   1116 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
   1117 	{
   1118 		if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
   1119 		{
   1120 			pChild->SetTransparency(nTransparency);
   1121 		}
   1122 	}
   1123 
   1124 	m_sPrivateParam.nTransparency = nTransparency;
   1125 }
   1126 
   1127 CPDF_Matrix	CPWL_Wnd::GetWindowMatrix() const
   1128 {
   1129 	CPDF_Matrix mt = this->GetChildToRoot();
   1130 
   1131 	if (IPWL_Provider* pProvider = GetProvider())
   1132 	{
   1133 		mt.Concat(pProvider->GetWindowMatrix(GetAttachedData()));
   1134 		return mt;
   1135 	}
   1136 
   1137 /*
   1138 	if (CReader_App* pApp = CPWL_Module::GetReaderApp())
   1139 		if (CReader_Document* pDocument = pApp->GetCurrentDocument())
   1140 			if (CReader_DocView* pDocView = pDocument->GetCurrentDocView())
   1141 			{
   1142 				CPDF_Matrix mtPageView;
   1143 				pDocView->GetCurrentMatrix(mtPageView);
   1144 				mt.Concat(mtPageView);
   1145 				return mt;
   1146 			}
   1147 
   1148 */
   1149 
   1150 	return mt;
   1151 }
   1152 
   1153 void CPWL_Wnd::PWLtoWnd(const CPDF_Point& point, FX_INT32& x, FX_INT32& y) const
   1154 {
   1155 	CPDF_Matrix mt = GetWindowMatrix();
   1156 	CPDF_Point pt = point;
   1157 	mt.Transform(pt.x,pt.y);
   1158 	x = (FX_INT32)(pt.x+0.5);
   1159 	y = (FX_INT32)(pt.y+0.5);
   1160 }
   1161 
   1162 FX_RECT CPWL_Wnd::PWLtoWnd(const CPDF_Rect & rect) const
   1163 {
   1164 	CPDF_Rect rcTemp = rect;
   1165 	CPDF_Matrix mt = GetWindowMatrix();
   1166 	mt.TransformRect(rcTemp);
   1167 	return FX_RECT((FX_INT32)(rcTemp.left+0.5), (FX_INT32)(rcTemp.bottom+0.5), (FX_INT32)(rcTemp.right+0.5), (FX_INT32)(rcTemp.top+0.5));
   1168 }
   1169 
   1170 FX_HWND CPWL_Wnd::GetAttachedHWnd() const
   1171 {
   1172 	return m_sPrivateParam.hAttachedWnd;
   1173 }
   1174 
   1175 CPDF_Point CPWL_Wnd::ChildToParent(const CPDF_Point& point) const
   1176 {
   1177 	CPDF_Matrix mt = GetChildMatrix();
   1178 	if (mt.IsIdentity())
   1179 		return point;
   1180 	else
   1181 	{
   1182 		CPDF_Point pt = point;
   1183 		mt.Transform(pt.x,pt.y);
   1184 		return pt;
   1185 	}
   1186 }
   1187 
   1188 CPDF_Rect CPWL_Wnd::ChildToParent(const CPDF_Rect& rect) const
   1189 {
   1190 	CPDF_Matrix mt = GetChildMatrix();
   1191 	if (mt.IsIdentity())
   1192 		return rect;
   1193 	else
   1194 	{
   1195 		CPDF_Rect rc = rect;
   1196 		mt.TransformRect(rc);
   1197 		return rc;
   1198 	}
   1199 }
   1200 
   1201 CPDF_Point CPWL_Wnd::ParentToChild(const CPDF_Point& point) const
   1202 {
   1203 	CPDF_Matrix mt = GetChildMatrix();
   1204 	if (mt.IsIdentity())
   1205 		return point;
   1206 	else
   1207 	{
   1208 		mt.SetReverse(mt);
   1209 		CPDF_Point pt = point;
   1210 		mt.Transform(pt.x,pt.y);
   1211 		return pt;
   1212 	}
   1213 }
   1214 
   1215 CPDF_Rect CPWL_Wnd::ParentToChild(const CPDF_Rect& rect) const
   1216 {
   1217 	CPDF_Matrix mt = GetChildMatrix();
   1218 	if (mt.IsIdentity())
   1219 		return rect;
   1220 	else
   1221 	{
   1222 		mt.SetReverse(mt);
   1223 		CPDF_Rect rc = rect;
   1224 		mt.TransformRect(rc);
   1225 		return rc;
   1226 	}
   1227 }
   1228 
   1229 CPDF_Matrix CPWL_Wnd::GetChildToRoot() const
   1230 {
   1231 	CPDF_Matrix mt(1,0,0,1,0,0);
   1232 
   1233 	if (HasFlag(PWS_CHILD))
   1234 	{
   1235 		const CPWL_Wnd* pParent = this;
   1236 		while (pParent)
   1237 		{
   1238 			mt.Concat(pParent->GetChildMatrix());
   1239 			pParent = pParent->GetParentWindow();
   1240 		}
   1241 	}
   1242 
   1243 	return mt;
   1244 }
   1245 
   1246 CPDF_Matrix CPWL_Wnd::GetChildMatrix() const
   1247 {
   1248 	if (HasFlag(PWS_CHILD))
   1249 		return m_sPrivateParam.mtChild;
   1250 
   1251 	return CPDF_Matrix(1,0,0,1,0,0);
   1252 }
   1253 
   1254 void CPWL_Wnd::SetChildMatrix(const CPDF_Matrix& mt)
   1255 {
   1256 	m_sPrivateParam.mtChild = mt;
   1257 }
   1258 
   1259 const CPWL_Wnd*	CPWL_Wnd::GetFocused() const
   1260 {
   1261 	if (CPWL_MsgControl * pMsgCtrl = GetMsgControl())
   1262 	{
   1263 		return pMsgCtrl->m_pMainKeyboardWnd;
   1264 	}
   1265 
   1266 	return NULL;
   1267 }
   1268 
   1269 void CPWL_Wnd::EnableWindow(FX_BOOL bEnable)
   1270 {
   1271 	if (m_bEnabled != bEnable)
   1272 	{
   1273 		for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
   1274 		{
   1275 			if (CPWL_Wnd* pChild = m_aChildren.GetAt(i))
   1276 			{
   1277 				pChild->EnableWindow(bEnable);
   1278 			}
   1279 		}
   1280 
   1281 		this->m_bEnabled = bEnable;
   1282 
   1283 		if (bEnable)
   1284 			this->OnEnabled();
   1285 		else
   1286 			this->OnDisabled();
   1287 	}
   1288 }
   1289 
   1290 FX_BOOL CPWL_Wnd::IsEnabled()
   1291 {
   1292 	return m_bEnabled;
   1293 }
   1294 
   1295 void CPWL_Wnd::OnEnabled()
   1296 {
   1297 }
   1298 
   1299 void CPWL_Wnd::OnDisabled()
   1300 {
   1301 }
   1302 
   1303 FX_BOOL CPWL_Wnd::IsCTRLpressed(FX_DWORD nFlag) const
   1304 {
   1305 	if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
   1306 	{
   1307 		return pSystemHandler->IsCTRLKeyDown(nFlag);
   1308 	}
   1309 
   1310 	return FALSE;
   1311 }
   1312 
   1313 FX_BOOL	CPWL_Wnd::IsSHIFTpressed(FX_DWORD nFlag) const
   1314 {
   1315 	if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
   1316 	{
   1317 		return pSystemHandler->IsSHIFTKeyDown(nFlag);
   1318 	}
   1319 
   1320 	return FALSE;
   1321 }
   1322 
   1323 FX_BOOL	CPWL_Wnd::IsALTpressed(FX_DWORD nFlag) const
   1324 {
   1325 	if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
   1326 	{
   1327 		return pSystemHandler->IsALTKeyDown(nFlag);
   1328 	}
   1329 
   1330 	return FALSE;
   1331 }
   1332 
   1333 FX_BOOL	CPWL_Wnd::IsINSERTpressed(FX_DWORD nFlag) const
   1334 {
   1335 	if (IFX_SystemHandler* pSystemHandler = GetSystemHandler())
   1336 	{
   1337 		return pSystemHandler->IsINSERTKeyDown(nFlag);
   1338 	}
   1339 
   1340 	return FALSE;
   1341 }
   1342 
   1343