cfwl_datetimepicker.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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 "xfa/fwl/cfwl_datetimepicker.h" 8 9#include <memory> 10#include <utility> 11 12#include "third_party/base/ptr_util.h" 13#include "xfa/fwl/cfwl_event.h" 14#include "xfa/fwl/cfwl_eventselectchanged.h" 15#include "xfa/fwl/cfwl_formproxy.h" 16#include "xfa/fwl/cfwl_messagemouse.h" 17#include "xfa/fwl/cfwl_messagesetfocus.h" 18#include "xfa/fwl/cfwl_notedriver.h" 19#include "xfa/fwl/cfwl_spinbutton.h" 20#include "xfa/fwl/cfwl_themebackground.h" 21#include "xfa/fwl/cfwl_widgetmgr.h" 22#include "xfa/fwl/ifwl_themeprovider.h" 23 24namespace { 25 26const int kDateTimePickerHeight = 20; 27 28} // namespace 29CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app) 30 : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), 31 m_iBtnState(1), 32 m_iYear(-1), 33 m_iMonth(-1), 34 m_iDay(-1), 35 m_bLBtnDown(false) { 36 m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; 37 38 auto monthProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); 39 monthProp->m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border; 40 monthProp->m_dwStates = FWL_WGTSTATE_Invisible; 41 monthProp->m_pParent = this; 42 monthProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; 43 m_pMonthCal.reset( 44 new CFWL_MonthCalendar(m_pOwnerApp, std::move(monthProp), this)); 45 46 m_pMonthCal->SetWidgetRect( 47 CFX_RectF(0, 0, m_pMonthCal->GetAutosizedWidgetRect().Size())); 48 49 auto editProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); 50 editProp->m_pParent = this; 51 editProp->m_pThemeProvider = m_pProperties->m_pThemeProvider; 52 53 m_pEdit = pdfium::MakeUnique<CFWL_DateTimeEdit>(m_pOwnerApp, 54 std::move(editProp), this); 55 RegisterEventTarget(m_pMonthCal.get()); 56 RegisterEventTarget(m_pEdit.get()); 57} 58 59CFWL_DateTimePicker::~CFWL_DateTimePicker() { 60 UnregisterEventTarget(); 61} 62 63FWL_Type CFWL_DateTimePicker::GetClassID() const { 64 return FWL_Type::DateTimePicker; 65} 66 67void CFWL_DateTimePicker::Update() { 68 if (m_pWidgetMgr->IsFormDisabled()) { 69 DisForm_Update(); 70 return; 71 } 72 if (m_iLock) 73 return; 74 if (!m_pProperties->m_pThemeProvider) 75 m_pProperties->m_pThemeProvider = GetAvailableTheme(); 76 77 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); 78 m_rtClient = GetClientRect(); 79 80 IFWL_ThemeProvider* theme = GetAvailableTheme(); 81 if (!theme) 82 return; 83 84 FX_FLOAT fBtn = theme->GetScrollBarWidth(); 85 m_rtBtn = CFX_RectF(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, 86 m_rtClient.height - 1); 87 88 CFX_RectF rtEdit(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, 89 m_rtClient.height); 90 m_pEdit->SetWidgetRect(rtEdit); 91 ResetEditAlignment(); 92 m_pEdit->Update(); 93 if (!(m_pMonthCal->GetThemeProvider())) 94 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); 95 96 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); 97 CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, 98 rtMonthCal.width, rtMonthCal.height); 99 m_pMonthCal->SetWidgetRect(rtPopUp); 100 m_pMonthCal->Update(); 101 return; 102} 103 104FWL_WidgetHit CFWL_DateTimePicker::HitTest(const CFX_PointF& point) { 105 if (m_pWidgetMgr->IsFormDisabled()) 106 return DisForm_HitTest(point); 107 if (m_rtClient.Contains(point)) 108 return FWL_WidgetHit::Client; 109 if (IsMonthCalendarVisible()) { 110 CFX_RectF rect = m_pMonthCal->GetWidgetRect(); 111 if (rect.Contains(point)) 112 return FWL_WidgetHit::Client; 113 } 114 return FWL_WidgetHit::Unknown; 115} 116 117void CFWL_DateTimePicker::DrawWidget(CFX_Graphics* pGraphics, 118 const CFX_Matrix* pMatrix) { 119 if (!pGraphics) 120 return; 121 if (!m_pProperties->m_pThemeProvider) 122 return; 123 124 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; 125 if (HasBorder()) 126 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); 127 if (!m_rtBtn.IsEmpty()) 128 DrawDropDownButton(pGraphics, pTheme, pMatrix); 129 if (m_pWidgetMgr->IsFormDisabled()) { 130 DisForm_DrawWidget(pGraphics, pMatrix); 131 return; 132 } 133} 134 135void CFWL_DateTimePicker::SetThemeProvider(IFWL_ThemeProvider* pTP) { 136 m_pProperties->m_pThemeProvider = pTP; 137 m_pMonthCal->SetThemeProvider(pTP); 138} 139 140void CFWL_DateTimePicker::GetCurSel(int32_t& iYear, 141 int32_t& iMonth, 142 int32_t& iDay) { 143 iYear = m_iYear; 144 iMonth = m_iMonth; 145 iDay = m_iDay; 146} 147 148void CFWL_DateTimePicker::SetCurSel(int32_t iYear, 149 int32_t iMonth, 150 int32_t iDay) { 151 if (iYear <= 0 || iYear >= 3000) 152 return; 153 if (iMonth <= 0 || iMonth >= 13) 154 return; 155 if (iDay <= 0 || iDay >= 32) 156 return; 157 158 m_iYear = iYear; 159 m_iMonth = iMonth; 160 m_iDay = iDay; 161 m_pMonthCal->SetSelect(iYear, iMonth, iDay); 162} 163 164void CFWL_DateTimePicker::SetEditText(const CFX_WideString& wsText) { 165 if (!m_pEdit) 166 return; 167 168 m_pEdit->SetText(wsText); 169 RepaintRect(m_rtClient); 170 171 CFWL_Event ev(CFWL_Event::Type::EditChanged); 172 DispatchEvent(&ev); 173} 174 175CFX_WideString CFWL_DateTimePicker::GetEditText() const { 176 return m_pEdit ? m_pEdit->GetText() : L""; 177} 178 179CFX_RectF CFWL_DateTimePicker::GetBBox() const { 180 if (m_pWidgetMgr->IsFormDisabled()) 181 return DisForm_GetBBox(); 182 183 CFX_RectF rect = m_pProperties->m_rtWidget; 184 if (!IsMonthCalendarVisible()) 185 return rect; 186 187 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); 188 rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top); 189 rect.Union(rtMonth); 190 return rect; 191} 192 193void CFWL_DateTimePicker::ModifyEditStylesEx(uint32_t dwStylesExAdded, 194 uint32_t dwStylesExRemoved) { 195 m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved); 196} 197 198void CFWL_DateTimePicker::DrawDropDownButton(CFX_Graphics* pGraphics, 199 IFWL_ThemeProvider* pTheme, 200 const CFX_Matrix* pMatrix) { 201 CFWL_ThemeBackground param; 202 param.m_pWidget = this; 203 param.m_iPart = CFWL_Part::DropDownButton; 204 param.m_dwStates = m_iBtnState; 205 param.m_pGraphics = pGraphics; 206 param.m_rtPart = m_rtBtn; 207 if (pMatrix) 208 param.m_matrix.Concat(*pMatrix); 209 pTheme->DrawBackground(¶m); 210} 211 212void CFWL_DateTimePicker::FormatDateString(int32_t iYear, 213 int32_t iMonth, 214 int32_t iDay, 215 CFX_WideString& wsText) { 216 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_ShortDateFormat) == 217 FWL_STYLEEXT_DTP_ShortDateFormat) { 218 wsText.Format(L"%d-%d-%d", iYear, iMonth, iDay); 219 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_LongDateFormat) == 220 FWL_STYLEEXT_DTP_LongDateFormat) { 221 wsText.Format(L"%d Year %d Month %d Day", iYear, iMonth, iDay); 222 } 223} 224 225void CFWL_DateTimePicker::ShowMonthCalendar(bool bActivate) { 226 if (m_pWidgetMgr->IsFormDisabled()) 227 return DisForm_ShowMonthCalendar(bActivate); 228 if (IsMonthCalendarVisible() == bActivate) 229 return; 230 if (!m_pForm) 231 InitProxyForm(); 232 233 if (!bActivate) { 234 m_pForm->EndDoModal(); 235 return; 236 } 237 238 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); 239 240 CFX_RectF rtAnchor(0, 0, m_pProperties->m_rtWidget.width, 241 m_pProperties->m_rtWidget.height); 242 GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth); 243 m_pForm->SetWidgetRect(rtMonth); 244 245 rtMonth.left = rtMonth.top = 0; 246 if (bActivate) 247 m_pMonthCal->RemoveStates(FWL_WGTSTATE_Invisible); 248 else 249 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible); 250 m_pMonthCal->SetWidgetRect(rtMonth); 251 m_pMonthCal->Update(); 252 m_pForm->DoModal(); 253} 254 255bool CFWL_DateTimePicker::IsMonthCalendarVisible() const { 256 if (m_pWidgetMgr->IsFormDisabled()) 257 return DisForm_IsMonthCalendarVisible(); 258 if (!m_pForm) 259 return false; 260 return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible); 261} 262 263void CFWL_DateTimePicker::ResetEditAlignment() { 264 if (!m_pEdit) 265 return; 266 267 uint32_t dwAdd = 0; 268 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditHAlignMask) { 269 case FWL_STYLEEXT_DTP_EditHCenter: { 270 dwAdd |= FWL_STYLEEXT_EDT_HCenter; 271 break; 272 } 273 case FWL_STYLEEXT_DTP_EditHFar: { 274 dwAdd |= FWL_STYLEEXT_EDT_HFar; 275 break; 276 } 277 default: { 278 dwAdd |= FWL_STYLEEXT_EDT_HNear; 279 break; 280 } 281 } 282 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditVAlignMask) { 283 case FWL_STYLEEXT_DTP_EditVCenter: { 284 dwAdd |= FWL_STYLEEXT_EDT_VCenter; 285 break; 286 } 287 case FWL_STYLEEXT_DTP_EditVFar: { 288 dwAdd |= FWL_STYLEEXT_EDT_VFar; 289 break; 290 } 291 default: { 292 dwAdd |= FWL_STYLEEXT_EDT_VNear; 293 break; 294 } 295 } 296 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_EditJustified) 297 dwAdd |= FWL_STYLEEXT_EDT_Justified; 298 299 m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask | 300 FWL_STYLEEXT_EDT_HAlignModeMask | 301 FWL_STYLEEXT_EDT_VAlignMask); 302} 303 304void CFWL_DateTimePicker::ProcessSelChanged(int32_t iYear, 305 int32_t iMonth, 306 int32_t iDay) { 307 m_iYear = iYear; 308 m_iMonth = iMonth; 309 m_iDay = iDay; 310 311 CFX_WideString wsText; 312 FormatDateString(m_iYear, m_iMonth, m_iDay, wsText); 313 m_pEdit->SetText(wsText); 314 m_pEdit->Update(); 315 RepaintRect(m_rtClient); 316 317 CFWL_EventSelectChanged ev(this); 318 ev.iYear = m_iYear; 319 ev.iMonth = m_iMonth; 320 ev.iDay = m_iDay; 321 DispatchEvent(&ev); 322} 323 324void CFWL_DateTimePicker::InitProxyForm() { 325 if (m_pForm) 326 return; 327 if (!m_pMonthCal) 328 return; 329 330 auto prop = pdfium::MakeUnique<CFWL_WidgetProperties>(); 331 prop->m_dwStyles = FWL_WGTSTYLE_Popup; 332 prop->m_dwStates = FWL_WGTSTATE_Invisible; 333 prop->m_pOwner = this; 334 335 m_pForm = pdfium::MakeUnique<CFWL_FormProxy>(m_pOwnerApp, std::move(prop), 336 m_pMonthCal.get()); 337 m_pMonthCal->SetParent(m_pForm.get()); 338} 339 340bool CFWL_DateTimePicker::DisForm_IsMonthCalendarVisible() const { 341 if (!m_pMonthCal) 342 return false; 343 return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible); 344} 345 346void CFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) { 347 if (IsMonthCalendarVisible() == bActivate) 348 return; 349 350 if (bActivate) { 351 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); 352 FX_FLOAT fPopupMin = rtMonthCal.height; 353 FX_FLOAT fPopupMax = rtMonthCal.height; 354 CFX_RectF rtAnchor(m_pProperties->m_rtWidget); 355 rtAnchor.width = rtMonthCal.width; 356 rtMonthCal.left = m_rtClient.left; 357 rtMonthCal.top = rtAnchor.Height(); 358 GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal); 359 m_pMonthCal->SetWidgetRect(rtMonthCal); 360 if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0) 361 m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay); 362 m_pMonthCal->Update(); 363 } 364 if (bActivate) 365 m_pMonthCal->RemoveStates(FWL_WGTSTATE_Invisible); 366 else 367 m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible); 368 369 if (bActivate) { 370 CFWL_MessageSetFocus msg(m_pEdit.get(), m_pMonthCal.get()); 371 m_pEdit->GetDelegate()->OnProcessMessage(&msg); 372 } 373 374 CFX_RectF rtInvalidate(0, 0, m_pProperties->m_rtWidget.width, 375 m_pProperties->m_rtWidget.height); 376 377 CFX_RectF rtCal = m_pMonthCal->GetWidgetRect(); 378 rtInvalidate.Union(rtCal); 379 rtInvalidate.Inflate(2, 2); 380 RepaintRect(rtInvalidate); 381} 382 383FWL_WidgetHit CFWL_DateTimePicker::DisForm_HitTest( 384 const CFX_PointF& point) const { 385 CFX_RectF rect(0, 0, m_pProperties->m_rtWidget.width, 386 m_pProperties->m_rtWidget.height); 387 if (rect.Contains(point)) 388 return FWL_WidgetHit::Edit; 389 if (DisForm_IsNeedShowButton()) 390 rect.width += m_fBtn; 391 if (rect.Contains(point)) 392 return FWL_WidgetHit::Client; 393 if (IsMonthCalendarVisible()) { 394 if (m_pMonthCal->GetWidgetRect().Contains(point)) 395 return FWL_WidgetHit::Client; 396 } 397 return FWL_WidgetHit::Unknown; 398} 399 400bool CFWL_DateTimePicker::DisForm_IsNeedShowButton() const { 401 return m_pProperties->m_dwStates & FWL_WGTSTATE_Focused || 402 m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused || 403 m_pEdit->GetStates() & FWL_WGTSTATE_Focused; 404} 405 406void CFWL_DateTimePicker::DisForm_Update() { 407 if (m_iLock) 408 return; 409 if (!m_pProperties->m_pThemeProvider) 410 m_pProperties->m_pThemeProvider = GetAvailableTheme(); 411 412 m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider); 413 m_rtClient = GetClientRect(); 414 m_pEdit->SetWidgetRect(m_rtClient); 415 ResetEditAlignment(); 416 m_pEdit->Update(); 417 418 if (!m_pMonthCal->GetThemeProvider()) 419 m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); 420 421 IFWL_ThemeProvider* theme = GetAvailableTheme(); 422 if (!theme) 423 return; 424 425 m_fBtn = theme->GetScrollBarWidth(); 426 CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); 427 CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, 428 rtMonthCal.width, rtMonthCal.height); 429 m_pMonthCal->SetWidgetRect(rtPopUp); 430 m_pMonthCal->Update(); 431} 432 433CFX_RectF CFWL_DateTimePicker::DisForm_GetBBox() const { 434 CFX_RectF rect = m_pProperties->m_rtWidget; 435 if (DisForm_IsNeedShowButton()) 436 rect.width += m_fBtn; 437 if (!IsMonthCalendarVisible()) 438 return rect; 439 440 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); 441 rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top); 442 rect.Union(rtMonth); 443 return rect; 444} 445 446void CFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, 447 const CFX_Matrix* pMatrix) { 448 if (!pGraphics) 449 return; 450 if (m_pEdit) { 451 CFX_RectF rtEdit = m_pEdit->GetWidgetRect(); 452 453 CFX_Matrix mt(1, 0, 0, 1, rtEdit.left, rtEdit.top); 454 if (pMatrix) 455 mt.Concat(*pMatrix); 456 m_pEdit->DrawWidget(pGraphics, &mt); 457 } 458 if (!IsMonthCalendarVisible()) 459 return; 460 461 CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); 462 CFX_Matrix mt(1, 0, 0, 1, rtMonth.left, rtMonth.top); 463 if (pMatrix) 464 mt.Concat(*pMatrix); 465 m_pMonthCal->DrawWidget(pGraphics, &mt); 466} 467 468void CFWL_DateTimePicker::OnProcessMessage(CFWL_Message* pMessage) { 469 if (!pMessage) 470 return; 471 472 switch (pMessage->GetType()) { 473 case CFWL_Message::Type::SetFocus: 474 OnFocusChanged(pMessage, true); 475 break; 476 case CFWL_Message::Type::KillFocus: 477 OnFocusChanged(pMessage, false); 478 break; 479 case CFWL_Message::Type::Mouse: { 480 CFWL_MessageMouse* pMouse = static_cast<CFWL_MessageMouse*>(pMessage); 481 switch (pMouse->m_dwCmd) { 482 case FWL_MouseCommand::LeftButtonDown: 483 OnLButtonDown(pMouse); 484 break; 485 case FWL_MouseCommand::LeftButtonUp: 486 OnLButtonUp(pMouse); 487 break; 488 case FWL_MouseCommand::Move: 489 OnMouseMove(pMouse); 490 break; 491 case FWL_MouseCommand::Leave: 492 OnMouseLeave(pMouse); 493 break; 494 default: 495 break; 496 } 497 break; 498 } 499 case CFWL_Message::Type::Key: { 500 if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { 501 m_pEdit->GetDelegate()->OnProcessMessage(pMessage); 502 return; 503 } 504 break; 505 } 506 default: 507 break; 508 } 509 510 CFWL_Widget::OnProcessMessage(pMessage); 511} 512 513void CFWL_DateTimePicker::OnDrawWidget(CFX_Graphics* pGraphics, 514 const CFX_Matrix* pMatrix) { 515 DrawWidget(pGraphics, pMatrix); 516} 517 518void CFWL_DateTimePicker::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { 519 if (!pMsg) 520 return; 521 if (m_pWidgetMgr->IsFormDisabled()) 522 return DisForm_OnFocusChanged(pMsg, bSet); 523 524 if (bSet) { 525 m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused); 526 RepaintRect(m_rtClient); 527 } else { 528 m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused); 529 RepaintRect(m_rtClient); 530 } 531 if (pMsg->m_pSrcTarget == m_pMonthCal.get() && IsMonthCalendarVisible()) { 532 ShowMonthCalendar(false); 533 } 534 RepaintRect(m_rtClient); 535} 536 537void CFWL_DateTimePicker::OnLButtonDown(CFWL_MessageMouse* pMsg) { 538 if (!pMsg) 539 return; 540 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) 541 SetFocus(true); 542 if (!m_rtBtn.Contains(pMsg->m_pos)) 543 return; 544 545 if (IsMonthCalendarVisible()) { 546 ShowMonthCalendar(false); 547 return; 548 } 549 ShowMonthCalendar(true); 550 551 m_bLBtnDown = true; 552 RepaintRect(m_rtClient); 553} 554 555void CFWL_DateTimePicker::OnLButtonUp(CFWL_MessageMouse* pMsg) { 556 if (!pMsg) 557 return; 558 559 m_bLBtnDown = false; 560 if (m_rtBtn.Contains(pMsg->m_pos)) 561 m_iBtnState = CFWL_PartState_Hovered; 562 else 563 m_iBtnState = CFWL_PartState_Normal; 564 RepaintRect(m_rtBtn); 565} 566 567void CFWL_DateTimePicker::OnMouseMove(CFWL_MessageMouse* pMsg) { 568 if (!m_rtBtn.Contains(pMsg->m_pos)) 569 m_iBtnState = CFWL_PartState_Normal; 570 RepaintRect(m_rtBtn); 571} 572 573void CFWL_DateTimePicker::OnMouseLeave(CFWL_MessageMouse* pMsg) { 574 if (!pMsg) 575 return; 576 m_iBtnState = CFWL_PartState_Normal; 577 RepaintRect(m_rtBtn); 578} 579 580void CFWL_DateTimePicker::DisForm_OnFocusChanged(CFWL_Message* pMsg, 581 bool bSet) { 582 CFX_RectF rtInvalidate(m_rtBtn); 583 if (bSet) { 584 m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; 585 if (m_pEdit && !(m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { 586 m_rtBtn = CFX_RectF(m_pProperties->m_rtWidget.width, 0, m_fBtn, 587 m_pProperties->m_rtWidget.height - 1); 588 } 589 rtInvalidate = m_rtBtn; 590 pMsg->m_pDstTarget = m_pEdit.get(); 591 m_pEdit->GetDelegate()->OnProcessMessage(pMsg); 592 } else { 593 m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; 594 m_rtBtn.Reset(); 595 596 if (DisForm_IsMonthCalendarVisible()) 597 ShowMonthCalendar(false); 598 if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { 599 pMsg->m_pSrcTarget = m_pEdit.get(); 600 m_pEdit->GetDelegate()->OnProcessMessage(pMsg); 601 } 602 } 603 rtInvalidate.Inflate(2, 2); 604 RepaintRect(rtInvalidate); 605} 606