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 "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h" 8 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h" 9 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h" 10 11 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001) 12 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) 13 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) 14 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb)) 15 16 PWL_FLOATRANGE::PWL_FLOATRANGE() { 17 Default(); 18 } 19 20 PWL_FLOATRANGE::PWL_FLOATRANGE(FX_FLOAT min, FX_FLOAT max) { 21 Set(min, max); 22 } 23 24 void PWL_FLOATRANGE::Default() { 25 fMin = 0; 26 fMax = 0; 27 } 28 29 void PWL_FLOATRANGE::Set(FX_FLOAT min, FX_FLOAT max) { 30 if (min > max) { 31 fMin = max; 32 fMax = min; 33 } else { 34 fMin = min; 35 fMax = max; 36 } 37 } 38 39 FX_BOOL PWL_FLOATRANGE::In(FX_FLOAT x) const { 40 return (IsFloatBigger(x, fMin) || IsFloatEqual(x, fMin)) && 41 (IsFloatSmaller(x, fMax) || IsFloatEqual(x, fMax)); 42 } 43 44 FX_FLOAT PWL_FLOATRANGE::GetWidth() const { 45 return fMax - fMin; 46 } 47 48 PWL_SCROLL_PRIVATEDATA::PWL_SCROLL_PRIVATEDATA() { 49 Default(); 50 } 51 52 void PWL_SCROLL_PRIVATEDATA::Default() { 53 ScrollRange.Default(); 54 fScrollPos = ScrollRange.fMin; 55 fClientWidth = 0; 56 fBigStep = 10; 57 fSmallStep = 1; 58 } 59 60 void PWL_SCROLL_PRIVATEDATA::SetScrollRange(FX_FLOAT min, FX_FLOAT max) { 61 ScrollRange.Set(min, max); 62 63 if (IsFloatSmaller(fScrollPos, ScrollRange.fMin)) 64 fScrollPos = ScrollRange.fMin; 65 if (IsFloatBigger(fScrollPos, ScrollRange.fMax)) 66 fScrollPos = ScrollRange.fMax; 67 } 68 69 void PWL_SCROLL_PRIVATEDATA::SetClientWidth(FX_FLOAT width) { 70 fClientWidth = width; 71 } 72 73 void PWL_SCROLL_PRIVATEDATA::SetSmallStep(FX_FLOAT step) { 74 fSmallStep = step; 75 } 76 77 void PWL_SCROLL_PRIVATEDATA::SetBigStep(FX_FLOAT step) { 78 fBigStep = step; 79 } 80 81 FX_BOOL PWL_SCROLL_PRIVATEDATA::SetPos(FX_FLOAT pos) { 82 if (ScrollRange.In(pos)) { 83 fScrollPos = pos; 84 return TRUE; 85 } 86 return FALSE; 87 } 88 89 void PWL_SCROLL_PRIVATEDATA::AddSmall() { 90 if (!SetPos(fScrollPos + fSmallStep)) 91 SetPos(ScrollRange.fMax); 92 } 93 94 void PWL_SCROLL_PRIVATEDATA::SubSmall() { 95 if (!SetPos(fScrollPos - fSmallStep)) 96 SetPos(ScrollRange.fMin); 97 } 98 99 void PWL_SCROLL_PRIVATEDATA::AddBig() { 100 if (!SetPos(fScrollPos + fBigStep)) 101 SetPos(ScrollRange.fMax); 102 } 103 104 void PWL_SCROLL_PRIVATEDATA::SubBig() { 105 if (!SetPos(fScrollPos - fBigStep)) 106 SetPos(ScrollRange.fMin); 107 } 108 109 CPWL_SBButton::CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType, 110 PWL_SBBUTTON_TYPE eButtonType) { 111 m_eScrollBarType = eScrollBarType; 112 m_eSBButtonType = eButtonType; 113 114 m_bMouseDown = FALSE; 115 } 116 117 CPWL_SBButton::~CPWL_SBButton() {} 118 119 CFX_ByteString CPWL_SBButton::GetClassName() const { 120 return "CPWL_SBButton"; 121 } 122 123 void CPWL_SBButton::OnCreate(PWL_CREATEPARAM& cp) { 124 cp.eCursorType = FXCT_ARROW; 125 } 126 127 void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { 128 CPWL_Wnd::GetThisAppearanceStream(sAppStream); 129 130 if (!IsVisible()) 131 return; 132 133 CFX_ByteTextBuf sButton; 134 135 CPDF_Rect rectWnd = GetWindowRect(); 136 137 if (rectWnd.IsEmpty()) 138 return; 139 140 sAppStream << "q\n"; 141 142 CPDF_Point ptCenter = GetCenterPoint(); 143 144 switch (m_eScrollBarType) { 145 case SBT_HSCROLL: 146 switch (m_eSBButtonType) { 147 case PSBT_MIN: { 148 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); 149 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, 150 ptCenter.y + PWL_TRIANGLE_HALFLEN); 151 CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, 152 ptCenter.y - PWL_TRIANGLE_HALFLEN); 153 154 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 155 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 156 sButton << "0 g\n"; 157 sButton << pt1.x << " " << pt1.y << " m\n"; 158 sButton << pt2.x << " " << pt2.y << " l\n"; 159 sButton << pt3.x << " " << pt3.y << " l\n"; 160 sButton << pt1.x << " " << pt1.y << " l f\n"; 161 162 sAppStream << sButton; 163 } 164 } break; 165 case PSBT_MAX: { 166 CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); 167 CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, 168 ptCenter.y + PWL_TRIANGLE_HALFLEN); 169 CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, 170 ptCenter.y - PWL_TRIANGLE_HALFLEN); 171 172 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 173 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 174 sButton << "0 g\n"; 175 sButton << pt1.x << " " << pt1.y << " m\n"; 176 sButton << pt2.x << " " << pt2.y << " l\n"; 177 sButton << pt3.x << " " << pt3.y << " l\n"; 178 sButton << pt1.x << " " << pt1.y << " l f\n"; 179 180 sAppStream << sButton; 181 } 182 } break; 183 default: 184 break; 185 } 186 break; 187 case SBT_VSCROLL: 188 switch (m_eSBButtonType) { 189 case PSBT_MIN: { 190 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, 191 ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); 192 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, 193 ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); 194 CPDF_Point pt3(ptCenter.x, ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); 195 196 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 197 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 198 sButton << "0 g\n"; 199 sButton << pt1.x << " " << pt1.y << " m\n"; 200 sButton << pt2.x << " " << pt2.y << " l\n"; 201 sButton << pt3.x << " " << pt3.y << " l\n"; 202 sButton << pt1.x << " " << pt1.y << " l f\n"; 203 204 sAppStream << sButton; 205 } 206 } break; 207 case PSBT_MAX: { 208 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, 209 ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); 210 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, 211 ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); 212 CPDF_Point pt3(ptCenter.x, ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); 213 214 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 215 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 216 sButton << "0 g\n"; 217 sButton << pt1.x << " " << pt1.y << " m\n"; 218 sButton << pt2.x << " " << pt2.y << " l\n"; 219 sButton << pt3.x << " " << pt3.y << " l\n"; 220 sButton << pt1.x << " " << pt1.y << " l f\n"; 221 222 sAppStream << sButton; 223 } 224 } break; 225 default: 226 break; 227 } 228 break; 229 default: 230 break; 231 } 232 233 sAppStream << "Q\n"; 234 } 235 236 void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, 237 CFX_Matrix* pUser2Device) { 238 if (!IsVisible()) 239 return; 240 241 CPDF_Rect rectWnd = GetWindowRect(); 242 if (rectWnd.IsEmpty()) 243 return; 244 245 CPDF_Point ptCenter = GetCenterPoint(); 246 int32_t nTransparancy = GetTransparency(); 247 248 switch (m_eScrollBarType) { 249 case SBT_HSCROLL: 250 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); 251 switch (m_eSBButtonType) { 252 case PSBT_MIN: { 253 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); 254 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, 255 ptCenter.y + PWL_TRIANGLE_HALFLEN); 256 CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, 257 ptCenter.y - PWL_TRIANGLE_HALFLEN); 258 259 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 260 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 261 CFX_PathData path; 262 263 path.SetPointCount(4); 264 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); 265 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); 266 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); 267 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); 268 269 pDevice->DrawPath(&path, pUser2Device, NULL, 270 CPWL_Utils::PWLColorToFXColor( 271 PWL_DEFAULT_BLACKCOLOR, nTransparancy), 272 0, FXFILL_ALTERNATE); 273 } 274 } break; 275 case PSBT_MAX: { 276 CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); 277 CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, 278 ptCenter.y + PWL_TRIANGLE_HALFLEN); 279 CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, 280 ptCenter.y - PWL_TRIANGLE_HALFLEN); 281 282 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && 283 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { 284 CFX_PathData path; 285 286 path.SetPointCount(4); 287 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); 288 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); 289 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); 290 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); 291 292 pDevice->DrawPath(&path, pUser2Device, NULL, 293 CPWL_Utils::PWLColorToFXColor( 294 PWL_DEFAULT_BLACKCOLOR, nTransparancy), 295 0, FXFILL_ALTERNATE); 296 } 297 } break; 298 default: 299 break; 300 } 301 break; 302 case SBT_VSCROLL: 303 switch (m_eSBButtonType) { 304 case PSBT_MIN: { 305 // draw border 306 CPDF_Rect rcDraw = rectWnd; 307 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 308 ArgbEncode(nTransparancy, 100, 100, 100), 309 0.0f); 310 311 // draw inner border 312 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); 313 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 314 ArgbEncode(nTransparancy, 255, 255, 255), 315 1.0f); 316 317 // draw background 318 319 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f); 320 321 if (IsEnabled()) 322 CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw, 323 nTransparancy, 80, 220); 324 else 325 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, 326 ArgbEncode(255, 255, 255, 255)); 327 328 // draw arrow 329 330 if (rectWnd.top - rectWnd.bottom > 6.0f) { 331 FX_FLOAT fX = rectWnd.left + 1.5f; 332 FX_FLOAT fY = rectWnd.bottom; 333 CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 4.0f), 334 CPDF_Point(fX + 2.5f, fY + 3.0f), 335 CPDF_Point(fX + 4.5f, fY + 5.0f), 336 CPDF_Point(fX + 6.5f, fY + 3.0f), 337 CPDF_Point(fX + 6.5f, fY + 4.0f), 338 CPDF_Point(fX + 4.5f, fY + 6.0f), 339 CPDF_Point(fX + 2.5f, fY + 4.0f)}; 340 341 if (IsEnabled()) 342 CPWL_Utils::DrawFillArea( 343 pDevice, pUser2Device, pts, 7, 344 ArgbEncode(nTransparancy, 255, 255, 255)); 345 else 346 CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7, 347 CPWL_Utils::PWLColorToFXColor( 348 PWL_DEFAULT_HEAVYGRAYCOLOR, 255)); 349 } 350 } break; 351 case PSBT_MAX: { 352 // draw border 353 CPDF_Rect rcDraw = rectWnd; 354 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 355 ArgbEncode(nTransparancy, 100, 100, 100), 356 0.0f); 357 358 // draw inner border 359 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); 360 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 361 ArgbEncode(nTransparancy, 255, 255, 255), 362 1.0f); 363 364 // draw background 365 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f); 366 if (IsEnabled()) 367 CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw, 368 nTransparancy, 80, 220); 369 else 370 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, 371 ArgbEncode(255, 255, 255, 255)); 372 373 // draw arrow 374 375 if (rectWnd.top - rectWnd.bottom > 6.0f) { 376 FX_FLOAT fX = rectWnd.left + 1.5f; 377 FX_FLOAT fY = rectWnd.bottom; 378 379 CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 5.0f), 380 CPDF_Point(fX + 2.5f, fY + 6.0f), 381 CPDF_Point(fX + 4.5f, fY + 4.0f), 382 CPDF_Point(fX + 6.5f, fY + 6.0f), 383 CPDF_Point(fX + 6.5f, fY + 5.0f), 384 CPDF_Point(fX + 4.5f, fY + 3.0f), 385 CPDF_Point(fX + 2.5f, fY + 5.0f)}; 386 387 if (IsEnabled()) 388 CPWL_Utils::DrawFillArea( 389 pDevice, pUser2Device, pts, 7, 390 ArgbEncode(nTransparancy, 255, 255, 255)); 391 else 392 CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7, 393 CPWL_Utils::PWLColorToFXColor( 394 PWL_DEFAULT_HEAVYGRAYCOLOR, 255)); 395 } 396 } break; 397 case PSBT_POS: { 398 // draw border 399 CPDF_Rect rcDraw = rectWnd; 400 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 401 ArgbEncode(nTransparancy, 100, 100, 100), 402 0.0f); 403 404 // draw inner border 405 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); 406 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, 407 ArgbEncode(nTransparancy, 255, 255, 255), 408 1.0f); 409 410 if (IsEnabled()) { 411 // draw shadow effect 412 413 CPDF_Point ptTop = CPDF_Point(rectWnd.left, rectWnd.top - 1.0f); 414 CPDF_Point ptBottom = 415 CPDF_Point(rectWnd.left, rectWnd.bottom + 1.0f); 416 417 ptTop.x += 1.5f; 418 ptBottom.x += 1.5f; 419 420 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 421 ArgbEncode(nTransparancy, 210, 210, 210), 422 1.0f); 423 424 ptTop.x += 1.0f; 425 ptBottom.x += 1.0f; 426 427 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 428 ArgbEncode(nTransparancy, 220, 220, 220), 429 1.0f); 430 431 ptTop.x += 1.0f; 432 ptBottom.x += 1.0f; 433 434 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 435 ArgbEncode(nTransparancy, 240, 240, 240), 436 1.0f); 437 438 ptTop.x += 1.0f; 439 ptBottom.x += 1.0f; 440 441 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 442 ArgbEncode(nTransparancy, 240, 240, 240), 443 1.0f); 444 445 ptTop.x += 1.0f; 446 ptBottom.x += 1.0f; 447 448 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 449 ArgbEncode(nTransparancy, 210, 210, 210), 450 1.0f); 451 452 ptTop.x += 1.0f; 453 ptBottom.x += 1.0f; 454 455 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 456 ArgbEncode(nTransparancy, 180, 180, 180), 457 1.0f); 458 459 ptTop.x += 1.0f; 460 ptBottom.x += 1.0f; 461 462 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 463 ArgbEncode(nTransparancy, 150, 150, 150), 464 1.0f); 465 466 ptTop.x += 1.0f; 467 ptBottom.x += 1.0f; 468 469 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 470 ArgbEncode(nTransparancy, 150, 150, 150), 471 1.0f); 472 473 ptTop.x += 1.0f; 474 ptBottom.x += 1.0f; 475 476 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 477 ArgbEncode(nTransparancy, 180, 180, 180), 478 1.0f); 479 480 ptTop.x += 1.0f; 481 ptBottom.x += 1.0f; 482 483 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, 484 ArgbEncode(nTransparancy, 210, 210, 210), 485 1.0f); 486 } else { 487 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, 488 ArgbEncode(255, 255, 255, 255)); 489 } 490 491 // draw friction 492 493 if (rectWnd.Height() > 8.0f) { 494 FX_COLORREF crStroke = ArgbEncode(nTransparancy, 120, 120, 120); 495 if (!IsEnabled()) 496 crStroke = CPWL_Utils::PWLColorToFXColor( 497 PWL_DEFAULT_HEAVYGRAYCOLOR, 255); 498 499 FX_FLOAT nFrictionWidth = 5.0f; 500 FX_FLOAT nFrictionHeight = 5.5f; 501 502 CPDF_Point ptLeft = 503 CPDF_Point(ptCenter.x - nFrictionWidth / 2.0f, 504 ptCenter.y - nFrictionHeight / 2.0f + 0.5f); 505 CPDF_Point ptRight = 506 CPDF_Point(ptCenter.x + nFrictionWidth / 2.0f, 507 ptCenter.y - nFrictionHeight / 2.0f + 0.5f); 508 509 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight, 510 crStroke, 1.0f); 511 512 ptLeft.y += 2.0f; 513 ptRight.y += 2.0f; 514 515 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight, 516 crStroke, 1.0f); 517 518 ptLeft.y += 2.0f; 519 ptRight.y += 2.0f; 520 521 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight, 522 crStroke, 1.0f); 523 } 524 } break; 525 default: 526 break; 527 } 528 break; 529 default: 530 break; 531 } 532 } 533 534 FX_BOOL CPWL_SBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) { 535 CPWL_Wnd::OnLButtonDown(point, nFlag); 536 537 if (CPWL_Wnd* pParent = GetParentWindow()) 538 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0, (intptr_t)&point); 539 540 m_bMouseDown = TRUE; 541 SetCapture(); 542 543 return TRUE; 544 } 545 546 FX_BOOL CPWL_SBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) { 547 CPWL_Wnd::OnLButtonUp(point, nFlag); 548 549 if (CPWL_Wnd* pParent = GetParentWindow()) 550 pParent->OnNotify(this, PNM_LBUTTONUP, 0, (intptr_t)&point); 551 552 m_bMouseDown = FALSE; 553 ReleaseCapture(); 554 555 return TRUE; 556 } 557 558 FX_BOOL CPWL_SBButton::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) { 559 CPWL_Wnd::OnMouseMove(point, nFlag); 560 561 if (CPWL_Wnd* pParent = GetParentWindow()) { 562 pParent->OnNotify(this, PNM_MOUSEMOVE, 0, (intptr_t)&point); 563 } 564 565 return TRUE; 566 } 567 568 CPWL_ScrollBar::CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType) 569 : m_sbType(sbType), 570 m_pMinButton(NULL), 571 m_pMaxButton(NULL), 572 m_pPosButton(NULL), 573 m_bMouseDown(FALSE), 574 m_bMinOrMax(FALSE), 575 m_bNotifyForever(TRUE) {} 576 577 CPWL_ScrollBar::~CPWL_ScrollBar() {} 578 579 CFX_ByteString CPWL_ScrollBar::GetClassName() const { 580 return "CPWL_ScrollBar"; 581 } 582 583 void CPWL_ScrollBar::OnCreate(PWL_CREATEPARAM& cp) { 584 cp.eCursorType = FXCT_ARROW; 585 } 586 587 void CPWL_ScrollBar::RePosChildWnd() { 588 CPDF_Rect rcClient = GetClientRect(); 589 CPDF_Rect rcMinButton, rcMaxButton; 590 FX_FLOAT fBWidth = 0; 591 592 switch (m_sbType) { 593 case SBT_HSCROLL: 594 if (rcClient.right - rcClient.left > 595 PWL_SCROLLBAR_BUTTON_WIDTH * 2 + PWL_SCROLLBAR_POSBUTTON_MINWIDTH + 596 2) { 597 rcMinButton = 598 CPDF_Rect(rcClient.left, rcClient.bottom, 599 rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH, rcClient.top); 600 rcMaxButton = CPDF_Rect(rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH, 601 rcClient.bottom, rcClient.right, rcClient.top); 602 } else { 603 fBWidth = (rcClient.right - rcClient.left - 604 PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) / 605 2; 606 607 if (fBWidth > 0) { 608 rcMinButton = CPDF_Rect(rcClient.left, rcClient.bottom, 609 rcClient.left + fBWidth, rcClient.top); 610 rcMaxButton = CPDF_Rect(rcClient.right - fBWidth, rcClient.bottom, 611 rcClient.right, rcClient.top); 612 } else { 613 SetVisible(FALSE); 614 } 615 } 616 break; 617 case SBT_VSCROLL: 618 if (IsFloatBigger(rcClient.top - rcClient.bottom, 619 PWL_SCROLLBAR_BUTTON_WIDTH * 2 + 620 PWL_SCROLLBAR_POSBUTTON_MINWIDTH + 2)) { 621 rcMinButton = 622 CPDF_Rect(rcClient.left, rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH, 623 rcClient.right, rcClient.top); 624 rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom, rcClient.right, 625 rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH); 626 } else { 627 fBWidth = (rcClient.top - rcClient.bottom - 628 PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) / 629 2; 630 631 if (IsFloatBigger(fBWidth, 0)) { 632 rcMinButton = CPDF_Rect(rcClient.left, rcClient.top - fBWidth, 633 rcClient.right, rcClient.top); 634 rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom, 635 rcClient.right, rcClient.bottom + fBWidth); 636 } else { 637 SetVisible(FALSE); 638 } 639 } 640 break; 641 } 642 643 if (m_pMinButton) 644 m_pMinButton->Move(rcMinButton, TRUE, FALSE); 645 if (m_pMaxButton) 646 m_pMaxButton->Move(rcMaxButton, TRUE, FALSE); 647 MovePosButton(FALSE); 648 } 649 650 void CPWL_ScrollBar::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { 651 CPDF_Rect rectWnd = GetWindowRect(); 652 653 if (IsVisible() && !rectWnd.IsEmpty()) { 654 CFX_ByteTextBuf sButton; 655 656 sButton << "q\n"; 657 sButton << "0 w\n" 658 << CPWL_Utils::GetColorAppStream(GetBackgroundColor(), TRUE); 659 sButton << rectWnd.left << " " << rectWnd.bottom << " " 660 << rectWnd.right - rectWnd.left << " " 661 << rectWnd.top - rectWnd.bottom << " re b Q\n"; 662 663 sAppStream << sButton; 664 } 665 } 666 667 void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice, 668 CFX_Matrix* pUser2Device) { 669 CPDF_Rect rectWnd = GetWindowRect(); 670 671 if (IsVisible() && !rectWnd.IsEmpty()) { 672 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rectWnd, 673 GetBackgroundColor(), GetTransparency()); 674 675 CPWL_Utils::DrawStrokeLine( 676 pDevice, pUser2Device, 677 CPDF_Point(rectWnd.left + 2.0f, rectWnd.top - 2.0f), 678 CPDF_Point(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f), 679 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f); 680 681 CPWL_Utils::DrawStrokeLine( 682 pDevice, pUser2Device, 683 CPDF_Point(rectWnd.right - 2.0f, rectWnd.top - 2.0f), 684 CPDF_Point(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f), 685 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f); 686 } 687 } 688 689 FX_BOOL CPWL_ScrollBar::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) { 690 CPWL_Wnd::OnLButtonDown(point, nFlag); 691 692 if (HasFlag(PWS_AUTOTRANSPARENT)) { 693 if (GetTransparency() != 255) { 694 SetTransparency(255); 695 InvalidateRect(); 696 } 697 } 698 699 CPDF_Rect rcMinArea, rcMaxArea; 700 701 if (m_pPosButton && m_pPosButton->IsVisible()) { 702 CPDF_Rect rcClient = GetClientRect(); 703 CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect(); 704 705 switch (m_sbType) { 706 case SBT_HSCROLL: 707 rcMinArea = CPDF_Rect(rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH, 708 rcClient.bottom, rcPosButton.left, rcClient.top); 709 rcMaxArea = CPDF_Rect(rcPosButton.right, rcClient.bottom, 710 rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH, 711 rcClient.top); 712 713 break; 714 case SBT_VSCROLL: 715 rcMinArea = CPDF_Rect(rcClient.left, rcPosButton.top, rcClient.right, 716 rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH); 717 rcMaxArea = CPDF_Rect(rcClient.left, 718 rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH, 719 rcClient.right, rcPosButton.bottom); 720 break; 721 } 722 723 rcMinArea.Normalize(); 724 rcMaxArea.Normalize(); 725 726 if (rcMinArea.Contains(point.x, point.y)) { 727 m_sData.SubBig(); 728 MovePosButton(TRUE); 729 NotifyScrollWindow(); 730 } 731 732 if (rcMaxArea.Contains(point.x, point.y)) { 733 m_sData.AddBig(); 734 MovePosButton(TRUE); 735 NotifyScrollWindow(); 736 } 737 } 738 739 return TRUE; 740 } 741 742 FX_BOOL CPWL_ScrollBar::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) { 743 CPWL_Wnd::OnLButtonUp(point, nFlag); 744 745 if (HasFlag(PWS_AUTOTRANSPARENT)) { 746 if (GetTransparency() != PWL_SCROLLBAR_TRANSPARANCY) { 747 SetTransparency(PWL_SCROLLBAR_TRANSPARANCY); 748 InvalidateRect(); 749 } 750 } 751 752 EndTimer(); 753 m_bMouseDown = FALSE; 754 755 return TRUE; 756 } 757 758 void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd, 759 FX_DWORD msg, 760 intptr_t wParam, 761 intptr_t lParam) { 762 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); 763 764 switch (msg) { 765 case PNM_LBUTTONDOWN: 766 if (pWnd == m_pMinButton) { 767 OnMinButtonLBDown(*(CPDF_Point*)lParam); 768 } 769 770 if (pWnd == m_pMaxButton) { 771 OnMaxButtonLBDown(*(CPDF_Point*)lParam); 772 } 773 774 if (pWnd == m_pPosButton) { 775 OnPosButtonLBDown(*(CPDF_Point*)lParam); 776 } 777 break; 778 case PNM_LBUTTONUP: 779 if (pWnd == m_pMinButton) { 780 OnMinButtonLBUp(*(CPDF_Point*)lParam); 781 } 782 783 if (pWnd == m_pMaxButton) { 784 OnMaxButtonLBUp(*(CPDF_Point*)lParam); 785 } 786 787 if (pWnd == m_pPosButton) { 788 OnPosButtonLBUp(*(CPDF_Point*)lParam); 789 } 790 break; 791 case PNM_MOUSEMOVE: 792 if (pWnd == m_pMinButton) { 793 OnMinButtonMouseMove(*(CPDF_Point*)lParam); 794 } 795 796 if (pWnd == m_pMaxButton) { 797 OnMaxButtonMouseMove(*(CPDF_Point*)lParam); 798 } 799 800 if (pWnd == m_pPosButton) { 801 OnPosButtonMouseMove(*(CPDF_Point*)lParam); 802 } 803 break; 804 case PNM_SETSCROLLINFO: { 805 if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) { 806 if (FXSYS_memcmp(&m_OriginInfo, pInfo, sizeof(PWL_SCROLL_INFO)) != 0) { 807 m_OriginInfo = *pInfo; 808 FX_FLOAT fMax = 809 pInfo->fContentMax - pInfo->fContentMin - pInfo->fPlateWidth; 810 fMax = fMax > 0.0f ? fMax : 0.0f; 811 SetScrollRange(0, fMax, pInfo->fPlateWidth); 812 SetScrollStep(pInfo->fBigStep, pInfo->fSmallStep); 813 } 814 } 815 } break; 816 case PNM_SETSCROLLPOS: { 817 FX_FLOAT fPos = *(FX_FLOAT*)lParam; 818 switch (m_sbType) { 819 case SBT_HSCROLL: 820 fPos = fPos - m_OriginInfo.fContentMin; 821 break; 822 case SBT_VSCROLL: 823 fPos = m_OriginInfo.fContentMax - fPos; 824 break; 825 } 826 SetScrollPos(fPos); 827 } break; 828 } 829 } 830 831 void CPWL_ScrollBar::CreateButtons(const PWL_CREATEPARAM& cp) { 832 PWL_CREATEPARAM scp = cp; 833 scp.pParentWnd = this; 834 scp.dwBorderWidth = 2; 835 scp.nBorderStyle = PBS_BEVELED; 836 837 scp.dwFlags = 838 PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP; 839 840 if (!m_pMinButton) { 841 m_pMinButton = new CPWL_SBButton(m_sbType, PSBT_MIN); 842 m_pMinButton->Create(scp); 843 } 844 845 if (!m_pMaxButton) { 846 m_pMaxButton = new CPWL_SBButton(m_sbType, PSBT_MAX); 847 m_pMaxButton->Create(scp); 848 } 849 850 if (!m_pPosButton) { 851 m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS); 852 m_pPosButton->SetVisible(FALSE); 853 m_pPosButton->Create(scp); 854 } 855 } 856 857 FX_FLOAT CPWL_ScrollBar::GetScrollBarWidth() const { 858 if (!IsVisible()) 859 return 0; 860 861 return PWL_SCROLLBAR_WIDTH; 862 } 863 864 void CPWL_ScrollBar::SetScrollRange(FX_FLOAT fMin, 865 FX_FLOAT fMax, 866 FX_FLOAT fClientWidth) { 867 if (m_pPosButton) { 868 m_sData.SetScrollRange(fMin, fMax); 869 m_sData.SetClientWidth(fClientWidth); 870 871 if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) { 872 m_pPosButton->SetVisible(FALSE); 873 } else { 874 m_pPosButton->SetVisible(TRUE); 875 MovePosButton(TRUE); 876 } 877 } 878 } 879 880 void CPWL_ScrollBar::SetScrollPos(FX_FLOAT fPos) { 881 FX_FLOAT fOldPos = m_sData.fScrollPos; 882 883 m_sData.SetPos(fPos); 884 885 if (!IsFloatEqual(m_sData.fScrollPos, fOldPos)) 886 MovePosButton(TRUE); 887 } 888 889 void CPWL_ScrollBar::SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep) { 890 m_sData.SetBigStep(fBigStep); 891 m_sData.SetSmallStep(fSmallStep); 892 } 893 894 void CPWL_ScrollBar::MovePosButton(FX_BOOL bRefresh) { 895 ASSERT(m_pMinButton); 896 ASSERT(m_pMaxButton); 897 898 if (m_pPosButton->IsVisible()) { 899 CPDF_Rect rcClient; 900 CPDF_Rect rcPosArea, rcPosButton; 901 902 rcClient = GetClientRect(); 903 rcPosArea = GetScrollArea(); 904 905 FX_FLOAT fLeft, fRight, fTop, fBottom; 906 907 switch (m_sbType) { 908 case SBT_HSCROLL: 909 fLeft = TrueToFace(m_sData.fScrollPos); 910 fRight = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth); 911 912 if (fRight - fLeft < PWL_SCROLLBAR_POSBUTTON_MINWIDTH) 913 fRight = fLeft + PWL_SCROLLBAR_POSBUTTON_MINWIDTH; 914 915 if (fRight > rcPosArea.right) { 916 fRight = rcPosArea.right; 917 fLeft = fRight - PWL_SCROLLBAR_POSBUTTON_MINWIDTH; 918 } 919 920 rcPosButton = CPDF_Rect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top); 921 922 break; 923 case SBT_VSCROLL: 924 fBottom = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth); 925 fTop = TrueToFace(m_sData.fScrollPos); 926 927 if (IsFloatSmaller(fTop - fBottom, PWL_SCROLLBAR_POSBUTTON_MINWIDTH)) 928 fBottom = fTop - PWL_SCROLLBAR_POSBUTTON_MINWIDTH; 929 930 if (IsFloatSmaller(fBottom, rcPosArea.bottom)) { 931 fBottom = rcPosArea.bottom; 932 fTop = fBottom + PWL_SCROLLBAR_POSBUTTON_MINWIDTH; 933 } 934 935 rcPosButton = CPDF_Rect(rcPosArea.left, fBottom, rcPosArea.right, fTop); 936 937 break; 938 } 939 940 m_pPosButton->Move(rcPosButton, TRUE, bRefresh); 941 } 942 } 943 944 void CPWL_ScrollBar::OnMinButtonLBDown(const CPDF_Point& point) { 945 m_sData.SubSmall(); 946 MovePosButton(TRUE); 947 NotifyScrollWindow(); 948 949 m_bMinOrMax = TRUE; 950 951 EndTimer(); 952 BeginTimer(100); 953 } 954 955 void CPWL_ScrollBar::OnMinButtonLBUp(const CPDF_Point& point) {} 956 957 void CPWL_ScrollBar::OnMinButtonMouseMove(const CPDF_Point& point) {} 958 959 void CPWL_ScrollBar::OnMaxButtonLBDown(const CPDF_Point& point) { 960 m_sData.AddSmall(); 961 MovePosButton(TRUE); 962 NotifyScrollWindow(); 963 964 m_bMinOrMax = FALSE; 965 966 EndTimer(); 967 BeginTimer(100); 968 } 969 970 void CPWL_ScrollBar::OnMaxButtonLBUp(const CPDF_Point& point) {} 971 972 void CPWL_ScrollBar::OnMaxButtonMouseMove(const CPDF_Point& point) {} 973 974 void CPWL_ScrollBar::OnPosButtonLBDown(const CPDF_Point& point) { 975 m_bMouseDown = TRUE; 976 977 if (m_pPosButton) { 978 CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect(); 979 980 switch (m_sbType) { 981 case SBT_HSCROLL: 982 m_nOldPos = point.x; 983 m_fOldPosButton = rcPosButton.left; 984 break; 985 case SBT_VSCROLL: 986 m_nOldPos = point.y; 987 m_fOldPosButton = rcPosButton.top; 988 break; 989 } 990 } 991 } 992 993 void CPWL_ScrollBar::OnPosButtonLBUp(const CPDF_Point& point) { 994 if (m_bMouseDown) { 995 if (!m_bNotifyForever) 996 NotifyScrollWindow(); 997 } 998 m_bMouseDown = FALSE; 999 } 1000 1001 void CPWL_ScrollBar::OnPosButtonMouseMove(const CPDF_Point& point) { 1002 FX_FLOAT fOldScrollPos = m_sData.fScrollPos; 1003 1004 FX_FLOAT fNewPos = 0; 1005 1006 switch (m_sbType) { 1007 case SBT_HSCROLL: 1008 if (FXSYS_fabs(point.x - m_nOldPos) < 1) 1009 return; 1010 fNewPos = FaceToTrue(m_fOldPosButton + point.x - m_nOldPos); 1011 break; 1012 case SBT_VSCROLL: 1013 if (FXSYS_fabs(point.y - m_nOldPos) < 1) 1014 return; 1015 fNewPos = FaceToTrue(m_fOldPosButton + point.y - m_nOldPos); 1016 break; 1017 } 1018 1019 if (m_bMouseDown) { 1020 switch (m_sbType) { 1021 case SBT_HSCROLL: 1022 1023 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) { 1024 fNewPos = m_sData.ScrollRange.fMin; 1025 } 1026 1027 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) { 1028 fNewPos = m_sData.ScrollRange.fMax; 1029 } 1030 1031 m_sData.SetPos(fNewPos); 1032 1033 break; 1034 case SBT_VSCROLL: 1035 1036 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) { 1037 fNewPos = m_sData.ScrollRange.fMin; 1038 } 1039 1040 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) { 1041 fNewPos = m_sData.ScrollRange.fMax; 1042 } 1043 1044 m_sData.SetPos(fNewPos); 1045 1046 break; 1047 } 1048 1049 if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) { 1050 MovePosButton(TRUE); 1051 1052 if (m_bNotifyForever) 1053 NotifyScrollWindow(); 1054 } 1055 } 1056 } 1057 1058 void CPWL_ScrollBar::NotifyScrollWindow() { 1059 if (CPWL_Wnd* pParent = GetParentWindow()) { 1060 FX_FLOAT fPos; 1061 switch (m_sbType) { 1062 case SBT_HSCROLL: 1063 fPos = m_OriginInfo.fContentMin + m_sData.fScrollPos; 1064 break; 1065 case SBT_VSCROLL: 1066 fPos = m_OriginInfo.fContentMax - m_sData.fScrollPos; 1067 break; 1068 } 1069 pParent->OnNotify(this, PNM_SCROLLWINDOW, (intptr_t)m_sbType, 1070 (intptr_t)&fPos); 1071 } 1072 } 1073 1074 CPDF_Rect CPWL_ScrollBar::GetScrollArea() const { 1075 CPDF_Rect rcClient = GetClientRect(); 1076 CPDF_Rect rcArea; 1077 1078 if (!m_pMinButton || !m_pMaxButton) 1079 return rcClient; 1080 1081 CPDF_Rect rcMin = m_pMinButton->GetWindowRect(); 1082 CPDF_Rect rcMax = m_pMaxButton->GetWindowRect(); 1083 1084 FX_FLOAT fMinWidth = rcMin.right - rcMin.left; 1085 FX_FLOAT fMinHeight = rcMin.top - rcMin.bottom; 1086 FX_FLOAT fMaxWidth = rcMax.right - rcMax.left; 1087 FX_FLOAT fMaxHeight = rcMax.top - rcMax.bottom; 1088 1089 switch (m_sbType) { 1090 case SBT_HSCROLL: 1091 if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) { 1092 rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom, 1093 rcClient.right - fMaxWidth - 1, rcClient.top); 1094 } else { 1095 rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom, 1096 rcClient.left + fMinWidth + 1, rcClient.top); 1097 } 1098 break; 1099 case SBT_VSCROLL: 1100 if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) { 1101 rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1, 1102 rcClient.right, rcClient.top - fMaxHeight - 1); 1103 } else { 1104 rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1, 1105 rcClient.right, rcClient.bottom + fMinHeight + 1); 1106 } 1107 break; 1108 } 1109 1110 rcArea.Normalize(); 1111 1112 return rcArea; 1113 } 1114 1115 FX_FLOAT CPWL_ScrollBar::TrueToFace(FX_FLOAT fTrue) { 1116 CPDF_Rect rcPosArea; 1117 rcPosArea = GetScrollArea(); 1118 1119 FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth; 1120 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth; 1121 1122 FX_FLOAT fFace = 0; 1123 1124 switch (m_sbType) { 1125 case SBT_HSCROLL: 1126 fFace = rcPosArea.left + 1127 fTrue * (rcPosArea.right - rcPosArea.left) / fFactWidth; 1128 break; 1129 case SBT_VSCROLL: 1130 fFace = rcPosArea.top - 1131 fTrue * (rcPosArea.top - rcPosArea.bottom) / fFactWidth; 1132 break; 1133 } 1134 1135 return fFace; 1136 } 1137 1138 FX_FLOAT CPWL_ScrollBar::FaceToTrue(FX_FLOAT fFace) { 1139 CPDF_Rect rcPosArea; 1140 rcPosArea = GetScrollArea(); 1141 1142 FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth; 1143 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth; 1144 1145 FX_FLOAT fTrue = 0; 1146 1147 switch (m_sbType) { 1148 case SBT_HSCROLL: 1149 fTrue = (fFace - rcPosArea.left) * fFactWidth / 1150 (rcPosArea.right - rcPosArea.left); 1151 break; 1152 case SBT_VSCROLL: 1153 fTrue = (rcPosArea.top - fFace) * fFactWidth / 1154 (rcPosArea.top - rcPosArea.bottom); 1155 break; 1156 } 1157 1158 return fTrue; 1159 } 1160 1161 void CPWL_ScrollBar::CreateChildWnd(const PWL_CREATEPARAM& cp) { 1162 CreateButtons(cp); 1163 } 1164 1165 void CPWL_ScrollBar::TimerProc() { 1166 PWL_SCROLL_PRIVATEDATA sTemp = m_sData; 1167 1168 if (m_bMinOrMax) 1169 m_sData.SubSmall(); 1170 else 1171 m_sData.AddSmall(); 1172 1173 if (FXSYS_memcmp(&m_sData, &sTemp, sizeof(PWL_SCROLL_PRIVATEDATA)) != 0) { 1174 MovePosButton(TRUE); 1175 NotifyScrollWindow(); 1176 } 1177 } 1178