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