Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1224 lines
29 KiB

  1. //
  2. // PAGE.CPP
  3. // WB Page Handling
  4. //
  5. // Copyright Microsoft 1998-
  6. //
  7. // PRECOMP
  8. #include "precomp.h"
  9. //
  10. //
  11. // Function: GetData
  12. //
  13. // Purpose: Get a pointer to the external representation of a graphic
  14. //
  15. //
  16. PWB_GRAPHIC PG_GetData
  17. (
  18. WB_PAGE_HANDLE hPage,
  19. WB_GRAPHIC_HANDLE hGraphic
  20. )
  21. {
  22. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetData");
  23. // Get the pointer from the core
  24. PWB_GRAPHIC pHeader = NULL;
  25. UINT uiReturn = g_pwbCore->WBP_GraphicGet(hPage, hGraphic, &pHeader);
  26. if (uiReturn != 0)
  27. {
  28. // Throw an exception
  29. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  30. }
  31. return pHeader;
  32. }
  33. //
  34. //
  35. // Function: AllocateGraphic
  36. //
  37. // Purpose: Allocate memory for a graphic
  38. //
  39. //
  40. PWB_GRAPHIC PG_AllocateGraphic
  41. (
  42. WB_PAGE_HANDLE hPage,
  43. DWORD length
  44. )
  45. {
  46. MLZ_EntryOut(ZONE_FUNCTION, "PG_AllocateGraphic");
  47. // Release the object (function never fails)
  48. PWB_GRAPHIC pHeader = NULL;
  49. UINT uiReturn = g_pwbCore->WBP_GraphicAllocate(hPage, length, &pHeader);
  50. if (uiReturn != 0)
  51. {
  52. // Throw exception
  53. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  54. }
  55. return pHeader;
  56. }
  57. //
  58. //
  59. // Function: First (crect)
  60. //
  61. // Purpose: Return the first object in the page (bottommost Z-order)
  62. // that intersects the bounding rectangle
  63. //
  64. //
  65. //CHANGED BY RAND - for object hit check
  66. DCWbGraphic* PG_First
  67. (
  68. WB_PAGE_HANDLE hPage,
  69. WB_GRAPHIC_HANDLE * phGraphic,
  70. LPCRECT pRectUpdate,
  71. BOOL bCheckReallyHit
  72. )
  73. {
  74. UINT uiReturn = 0;
  75. BOOL empty = TRUE;
  76. PWB_GRAPHIC pHeader = NULL;
  77. DCWbGraphic* pGraphic = NULL;
  78. RECT rc;
  79. MLZ_EntryOut(ZONE_FUNCTION, "PG_First");
  80. uiReturn = g_pwbCore->WBP_GraphicHandle(hPage, NULL, FIRST, phGraphic);
  81. if (uiReturn == WB_RC_NO_SUCH_GRAPHIC)
  82. {
  83. return(pGraphic);
  84. }
  85. if (uiReturn != 0)
  86. {
  87. // Throw an exception
  88. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  89. return NULL;
  90. }
  91. if (pRectUpdate == NULL)
  92. {
  93. // Read the graphic
  94. // We have got what we want
  95. TRACE_MSG(("Got the object we want"));
  96. pGraphic = DCWbGraphic::ConstructGraphic(hPage, *phGraphic);
  97. }
  98. else
  99. {
  100. pHeader = PG_GetData(hPage, *phGraphic);
  101. if(pHeader == NULL)
  102. {
  103. return NULL;
  104. }
  105. rc.left = pHeader->rectBounds.left;
  106. rc.top = pHeader->rectBounds.top;
  107. rc.right = pHeader->rectBounds.right;
  108. rc.bottom = pHeader->rectBounds.bottom;
  109. empty = !::IntersectRect(&rc, &rc, pRectUpdate);
  110. g_pwbCore->WBP_GraphicRelease(hPage, *phGraphic, pHeader);
  111. if (empty)
  112. {
  113. TRACE_MSG(("First object not needed - go to next"));
  114. pGraphic = PG_Next(hPage, phGraphic, pRectUpdate, bCheckReallyHit);
  115. }
  116. else
  117. {
  118. pGraphic = DCWbGraphic::ConstructGraphic(hPage, *phGraphic);
  119. if( bCheckReallyHit && (pGraphic != NULL) )
  120. {
  121. // do a real object hit test since we
  122. // know its bounding rect has hit
  123. if( !pGraphic->CheckReallyHit( pRectUpdate ) )
  124. {
  125. delete pGraphic;
  126. pGraphic = PG_Next(hPage, phGraphic, pRectUpdate, TRUE); // look again
  127. }
  128. }
  129. }
  130. }
  131. return(pGraphic);
  132. }
  133. //
  134. //
  135. // Function: Next
  136. //
  137. // Purpose: Return the next graphic in the page (going up through the
  138. // Z-order). GetFirst must have been called before this
  139. // member.
  140. //
  141. DCWbGraphic* PG_Next
  142. (
  143. WB_PAGE_HANDLE hPage,
  144. WB_GRAPHIC_HANDLE * phGraphic,
  145. LPCRECT pRectUpdate,
  146. BOOL bCheckReallyHit
  147. )
  148. {
  149. UINT uiReturn = 0;
  150. BOOL empty = TRUE;
  151. PWB_GRAPHIC pHeader = NULL;
  152. DCWbGraphic* pGraphic = NULL;
  153. RECT rc;
  154. MLZ_EntryOut(ZONE_FUNCTION, "PG_Next");
  155. while (uiReturn == 0)
  156. {
  157. uiReturn = g_pwbCore->WBP_GraphicHandle(hPage, *phGraphic,
  158. AFTER, phGraphic);
  159. if (uiReturn == WB_RC_NO_SUCH_GRAPHIC)
  160. {
  161. return(pGraphic);
  162. }
  163. else if (uiReturn != 0)
  164. {
  165. // Throw an exception
  166. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  167. return NULL;
  168. }
  169. if (pRectUpdate == NULL)
  170. {
  171. // Read the graphic
  172. // We have got what we want
  173. TRACE_MSG(("Got the object we want"));
  174. pGraphic = DCWbGraphic::ConstructGraphic(hPage, *phGraphic);
  175. break;
  176. }
  177. else
  178. {
  179. pHeader = PG_GetData(hPage, *phGraphic);
  180. rc.left = pHeader->rectBounds.left;
  181. rc.top = pHeader->rectBounds.top;
  182. rc.right = pHeader->rectBounds.right;
  183. rc.bottom = pHeader->rectBounds.bottom;
  184. empty = !::IntersectRect(&rc, &rc, pRectUpdate);
  185. g_pwbCore->WBP_GraphicRelease(hPage, *phGraphic, pHeader);
  186. if (!empty)
  187. {
  188. TRACE_MSG(("Found the one we want - breaking out"));
  189. pGraphic = DCWbGraphic::ConstructGraphic(hPage, *phGraphic);
  190. if( bCheckReallyHit && (pGraphic != NULL) )
  191. {
  192. // do a real object hit test since we
  193. // know its bounding rect has hit
  194. if( pGraphic->CheckReallyHit( pRectUpdate ) )
  195. break;
  196. else
  197. {
  198. delete pGraphic; // look again
  199. pGraphic = NULL;
  200. }
  201. }
  202. else
  203. break; // found it
  204. }
  205. }
  206. }
  207. return(pGraphic);
  208. }
  209. //
  210. //
  211. // Function: After
  212. //
  213. // Purpose: Return the graphic after the specified graphic (going up
  214. // through the Z-order).
  215. //
  216. //
  217. DCWbGraphic* PG_After
  218. (
  219. WB_PAGE_HANDLE hPage,
  220. const DCWbGraphic& graphic
  221. )
  222. {
  223. MLZ_EntryOut(ZONE_FUNCTION, "PG_After");
  224. WB_GRAPHIC_HANDLE hGraphic;
  225. UINT uiReturn = g_pwbCore->WBP_GraphicHandle(hPage, graphic.Handle(),
  226. AFTER, &hGraphic);
  227. if (uiReturn == WB_RC_NO_SUCH_GRAPHIC)
  228. {
  229. return(NULL);
  230. }
  231. if (uiReturn != 0)
  232. {
  233. // Throw an exception
  234. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  235. return NULL;
  236. }
  237. // Read the graphic
  238. return(DCWbGraphic::ConstructGraphic(hPage, hGraphic));
  239. }
  240. //
  241. //
  242. // Function: Before
  243. //
  244. // Purpose: Return the graphic before the specified graphic (going down
  245. // through the Z-order).
  246. //
  247. //
  248. DCWbGraphic* PG_Before
  249. (
  250. WB_PAGE_HANDLE hPage,
  251. const DCWbGraphic& graphic
  252. )
  253. {
  254. MLZ_EntryOut(ZONE_FUNCTION, "PG_Before");
  255. WB_GRAPHIC_HANDLE hGraphic;
  256. UINT uiReturn = g_pwbCore->WBP_GraphicHandle(hPage, graphic.Handle(),
  257. BEFORE, &hGraphic);
  258. if (uiReturn == WB_RC_NO_SUCH_GRAPHIC)
  259. {
  260. return(NULL);
  261. }
  262. if (uiReturn != 0)
  263. {
  264. // Throw an exception
  265. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  266. return NULL;
  267. }
  268. // Read the graphic
  269. return(DCWbGraphic::ConstructGraphic(hPage, hGraphic));
  270. }
  271. //
  272. //
  273. // Function: FirstPointer
  274. //
  275. // Purpose: Return the first remote pointer object that is currently
  276. // active on this page.
  277. //
  278. //
  279. DCWbGraphicPointer* PG_FirstPointer
  280. (
  281. WB_PAGE_HANDLE hPage,
  282. POM_OBJECT * ppUserNext
  283. )
  284. {
  285. MLZ_EntryOut(ZONE_FUNCTION, "PG_FirstPointer");
  286. // Get the handle of the first user
  287. g_pwbCore->WBP_PersonHandleFirst(ppUserNext);
  288. // Return the next pointer that is active on this page
  289. return PG_LookForPointer(hPage, *ppUserNext);
  290. }
  291. //
  292. //
  293. // Function: LocalPointer
  294. //
  295. // Purpose: Return the local user's pointer, if it is active on this
  296. // page.
  297. //
  298. //
  299. DCWbGraphicPointer* PG_LocalPointer
  300. (
  301. WB_PAGE_HANDLE hPage
  302. )
  303. {
  304. MLZ_EntryOut(ZONE_FUNCTION, "PG_LocalPointer");
  305. DCWbGraphicPointer* pResult = NULL;
  306. // Get the local user
  307. POM_OBJECT hUser;
  308. g_pwbCore->WBP_PersonHandleLocal(&hUser);
  309. WbUser* pUser = WB_GetUser(hUser);
  310. // Check whether the pointer is active, and is on this page
  311. if ((pUser != NULL) &&
  312. (pUser->IsUsingPointer()) &&
  313. (pUser->PointerPage() == hPage))
  314. {
  315. pResult = pUser->GetPointer();
  316. }
  317. // Return the next pointer that is active on this page
  318. return pResult;
  319. }
  320. //
  321. //
  322. // Function: NextPointer
  323. //
  324. // Purpose: Return the next pointer in use.
  325. // FirstPointer must have been called before this member.
  326. //
  327. //
  328. DCWbGraphicPointer* PG_NextPointer
  329. (
  330. WB_PAGE_HANDLE hPage,
  331. POM_OBJECT * ppUserNext
  332. )
  333. {
  334. MLZ_EntryOut(ZONE_FUNCTION, "PG_NextPointer");
  335. DCWbGraphicPointer* pPointer;
  336. // Go forward one from the current user
  337. UINT uiReturn = g_pwbCore->WBP_PersonHandleNext(*ppUserNext, ppUserNext);
  338. if (uiReturn == 0)
  339. {
  340. pPointer = PG_LookForPointer(hPage, *ppUserNext);
  341. }
  342. else
  343. {
  344. if (uiReturn != WB_RC_NO_SUCH_PERSON)
  345. {
  346. ERROR_OUT(("Error getting next user handle"));
  347. }
  348. pPointer = NULL;
  349. }
  350. return(pPointer);
  351. }
  352. //
  353. //
  354. // Function: NextPointer
  355. //
  356. // Purpose: Return the next pointer in use.
  357. //
  358. //
  359. DCWbGraphicPointer* PG_NextPointer
  360. (
  361. WB_PAGE_HANDLE hPage,
  362. const DCWbGraphicPointer* pStartPointer
  363. )
  364. {
  365. MLZ_EntryOut(ZONE_FUNCTION, "PG_NextPointer");
  366. DCWbGraphicPointer* pPointer;
  367. // Go forward one from passed pointer
  368. POM_OBJECT hUser;
  369. UINT uiReturn = g_pwbCore->WBP_PersonHandleNext((pStartPointer->GetUser())->Handle(),
  370. &hUser);
  371. if (uiReturn == 0)
  372. {
  373. pPointer = PG_LookForPointer(hPage, hUser);
  374. }
  375. else
  376. {
  377. if (uiReturn != WB_RC_NO_SUCH_PERSON)
  378. {
  379. ERROR_OUT(("Error from WBP_PersonHandleNext"));
  380. }
  381. pPointer = NULL;
  382. }
  383. return(pPointer);
  384. }
  385. //
  386. //
  387. // Function: LookForPointer
  388. //
  389. // Purpose: Look for the first pointer active on this page, starting
  390. // the serach with the user whose handle is passed in.
  391. //
  392. //
  393. DCWbGraphicPointer* PG_LookForPointer
  394. (
  395. WB_PAGE_HANDLE hPage,
  396. POM_OBJECT hUser
  397. )
  398. {
  399. MLZ_EntryOut(ZONE_FUNCTION, "PG_LookForPointer");
  400. DCWbGraphicPointer* pPointer = NULL;
  401. WbUser* pUser;
  402. UINT result = 0;
  403. // Scan the users (starting with the one passed in)
  404. for (;;)
  405. {
  406. // Check if the user has an active pointer on this page
  407. pUser = WB_GetUser(hUser);
  408. if ((pUser != NULL) &&
  409. (pUser->IsUsingPointer()) &&
  410. (pUser->PointerPage() == hPage))
  411. {
  412. pPointer = pUser->GetPointer();
  413. break;
  414. }
  415. // Get the next user
  416. result = g_pwbCore->WBP_PersonHandleNext(hUser, &hUser);
  417. if (result != 0)
  418. {
  419. if (result != WB_RC_NO_SUCH_PERSON)
  420. {
  421. ERROR_OUT(("Error from WBP_PersonHandleNext"));
  422. }
  423. break;
  424. }
  425. }
  426. return(pPointer);
  427. }
  428. //
  429. //
  430. // Function: GraphicUpdate
  431. //
  432. // Purpose: Update an existing graphic
  433. //
  434. //
  435. void PG_GraphicUpdate
  436. (
  437. WB_PAGE_HANDLE hPage,
  438. WB_GRAPHIC_HANDLE * phGraphic,
  439. PWB_GRAPHIC pHeader
  440. )
  441. {
  442. MLZ_EntryOut(ZONE_FUNCTION, "PG_GraphicUpdate");
  443. UINT uiReturn = g_pwbCore->WBP_GraphicUpdateRequest(hPage,
  444. *phGraphic, pHeader);
  445. if (uiReturn != 0)
  446. {
  447. if( uiReturn == OM_RC_OBJECT_DELETED )
  448. {
  449. // somebody nuked our object, try to put it back (bug 4416)
  450. g_pwbCore->WBP_GraphicAddLast(hPage, pHeader, phGraphic);
  451. }
  452. // Throw exception - exception code will special case
  453. // OM_RC_OBJECT_DELETED and cancel drawing
  454. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  455. return;
  456. }
  457. }
  458. //
  459. //
  460. // Function: GraphicReplace
  461. //
  462. // Purpose: Replace an existing graphic
  463. //
  464. //
  465. void PG_GraphicReplace
  466. (
  467. WB_PAGE_HANDLE hPage,
  468. WB_GRAPHIC_HANDLE * phGraphic,
  469. PWB_GRAPHIC pHeader
  470. )
  471. {
  472. MLZ_EntryOut(ZONE_FUNCTION, "PG_GraphicReplace");
  473. UINT uiReturn = g_pwbCore->WBP_GraphicReplaceRequest(hPage,
  474. *phGraphic, pHeader);
  475. if (uiReturn != 0)
  476. {
  477. if (uiReturn == OM_RC_OBJECT_DELETED)
  478. {
  479. // somebody nuked our object, try to put it back (bug 4416)
  480. g_pwbCore->WBP_GraphicAddLast(hPage, pHeader, phGraphic);
  481. }
  482. // Throw exception - exception code will special case
  483. // OM_RC_OBJECT_DELETED and cancel drawing
  484. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  485. return;
  486. }
  487. }
  488. //
  489. //
  490. // Function: Clear
  491. //
  492. // Purpose: Delete all graphics on the page
  493. //
  494. //
  495. void PG_Clear
  496. (
  497. WB_PAGE_HANDLE hPage
  498. )
  499. {
  500. UINT uiReturn = g_pwbCore->WBP_PageClear(hPage);
  501. if (uiReturn != 0)
  502. {
  503. // Throw exception
  504. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  505. return;
  506. }
  507. }
  508. //
  509. //
  510. // Function: Delete
  511. //
  512. // Purpose: Delete the specified graphic
  513. //
  514. //
  515. void PG_GraphicDelete
  516. (
  517. WB_PAGE_HANDLE hPage,
  518. const DCWbGraphic& graphic
  519. )
  520. {
  521. MLZ_EntryOut(ZONE_FUNCTION, "PG_GraphicDelete");
  522. UINT uiReturn = g_pwbCore->WBP_GraphicDeleteRequest(hPage, graphic.Handle());
  523. if (uiReturn != 0)
  524. {
  525. // Throw exception
  526. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  527. return;
  528. }
  529. }
  530. //
  531. //
  532. // Function: SelectLast
  533. //
  534. // Purpose: Select the last object whose bounding rectangle contains
  535. // the point specified.
  536. //
  537. //
  538. DCWbGraphic* PG_SelectLast
  539. (
  540. WB_PAGE_HANDLE hPage,
  541. POINT point
  542. )
  543. {
  544. RECT rectHit;
  545. DCWbGraphic* pGraphic = NULL;
  546. DCWbGraphic* pGraphicPrev = NULL;
  547. WB_GRAPHIC_HANDLE hGraphic;
  548. UINT uiReturn = g_pwbCore->WBP_GraphicSelect(hPage, point, NULL, LAST,
  549. &hGraphic);
  550. if (uiReturn == WB_RC_NO_SUCH_GRAPHIC)
  551. {
  552. return(pGraphic);
  553. }
  554. if (uiReturn != 0)
  555. {
  556. // Throw exception
  557. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  558. return NULL;
  559. }
  560. // Get the graphic
  561. pGraphic = DCWbGraphic::ConstructGraphic(hPage, hGraphic);
  562. // Check to see if its really hit
  563. if (pGraphic != NULL)
  564. {
  565. MAKE_HIT_RECT(rectHit, point);
  566. if (!pGraphic->CheckReallyHit( &rectHit ))
  567. {
  568. // have to look some more
  569. pGraphicPrev = PG_SelectPrevious(hPage, *pGraphic, point );
  570. if( pGraphic != pGraphicPrev )
  571. {
  572. delete pGraphic;
  573. pGraphic = pGraphicPrev;
  574. }
  575. }
  576. }
  577. return(pGraphic);
  578. }
  579. //
  580. //
  581. // Function: SelectPrevious
  582. //
  583. // Purpose: Select the previous object whose bounding rectangle contains
  584. // the point specified.
  585. //
  586. //
  587. DCWbGraphic* PG_SelectPrevious
  588. (
  589. WB_PAGE_HANDLE hPage,
  590. const DCWbGraphic& graphic,
  591. POINT point
  592. )
  593. {
  594. RECT rectHit;
  595. DCWbGraphic* pGraphic = NULL;
  596. WB_GRAPHIC_HANDLE hGraphic;
  597. WB_GRAPHIC_HANDLE hGraphicPrev;
  598. MLZ_EntryOut(ZONE_FUNCTION, "PG_SelectPrevious");
  599. MAKE_HIT_RECT(rectHit, point );
  600. hGraphic = graphic.Handle();
  601. while ( (g_pwbCore->WBP_GraphicSelect(hPage, point,
  602. hGraphic, BEFORE, &hGraphicPrev ))
  603. != WB_RC_NO_SUCH_GRAPHIC )
  604. {
  605. // Get the graphic
  606. pGraphic = DCWbGraphic::ConstructGraphic(hPage, hGraphicPrev);
  607. if( pGraphic == NULL )
  608. break;
  609. if( pGraphic->CheckReallyHit( &rectHit ) )
  610. break;
  611. hGraphic = hGraphicPrev;
  612. delete pGraphic;
  613. pGraphic = NULL;
  614. }
  615. return(pGraphic);
  616. }
  617. //
  618. //
  619. // Function: IsTopmost
  620. //
  621. // Purpose: Return TRUE if the specified graphic is topmost on the page
  622. //
  623. //
  624. BOOL PG_IsTopmost
  625. (
  626. WB_PAGE_HANDLE hPage,
  627. const DCWbGraphic* pGraphic
  628. )
  629. {
  630. MLZ_EntryOut(ZONE_FUNCTION, "PG_IsTopmost");
  631. WB_GRAPHIC_HANDLE hGraphic;
  632. UINT uiReturn = g_pwbCore->WBP_GraphicHandle(hPage, NULL, LAST, &hGraphic);
  633. if (uiReturn != 0)
  634. {
  635. // Throw an exception
  636. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  637. return FALSE;
  638. }
  639. return (pGraphic->Handle() == hGraphic);
  640. }
  641. //
  642. //
  643. // Function: Draw
  644. //
  645. // Purpose: Draw the contents of the page into the specified device
  646. // context.
  647. //
  648. //
  649. void PG_Draw
  650. (
  651. WB_PAGE_HANDLE hPage,
  652. HDC hDC,
  653. BOOL thumbNail
  654. )
  655. {
  656. WB_GRAPHIC_HANDLE hStart;
  657. MLZ_EntryOut(ZONE_FUNCTION, "PG_Draw");
  658. //
  659. // Draw the graphic objects
  660. //
  661. DCWbGraphic* pGraphic = PG_First(hPage, &hStart);
  662. while (pGraphic != NULL)
  663. {
  664. pGraphic->Draw(hDC, thumbNail);
  665. // Release the current graphic
  666. delete pGraphic;
  667. // Get the next one
  668. pGraphic = PG_Next(hPage, &hStart);
  669. }
  670. }
  671. //CHANGED BY RAND
  672. #define WB_MIN_PRINT_MARGIN_SIZE (30)
  673. //
  674. //
  675. // Function: Print
  676. //
  677. // Purpose: Print the contents of the page to the specified printer. The
  678. // contents are scaled to "best fit" on the page. i.e. the
  679. // largest scaling factor that preserves the aspect ratio of
  680. // the page is used.
  681. //
  682. //
  683. void PG_Print
  684. (
  685. WB_PAGE_HANDLE hPage,
  686. HDC hdc,
  687. LPCRECT lprcPrint
  688. )
  689. {
  690. int pageWidth;
  691. int pageHeight;
  692. int areaHeight;
  693. int areaWidth;
  694. int areaAspectRatio;
  695. int pageAspectRatio;
  696. int nPhysOffsetX;
  697. int nPhysOffsetY;
  698. int nPhysWidth;
  699. int nPhysHeight;
  700. int nVOffsetX;
  701. int nVOffsetY;
  702. // get physical printer params
  703. nPhysOffsetX = GetDeviceCaps(hdc, PHYSICALOFFSETX );
  704. nPhysOffsetY = GetDeviceCaps(hdc, PHYSICALOFFSETY );
  705. nPhysWidth = GetDeviceCaps(hdc, PHYSICALWIDTH );
  706. nPhysHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT );
  707. // calc correct printer area (allow for bugs in some drivers...)
  708. if( nPhysOffsetX <= 0 )
  709. {
  710. nPhysOffsetX = WB_MIN_PRINT_MARGIN_SIZE;
  711. nVOffsetX = nPhysOffsetX;
  712. }
  713. else
  714. nVOffsetX = 0;
  715. if( nPhysOffsetY <= 0 )
  716. {
  717. nPhysOffsetY = WB_MIN_PRINT_MARGIN_SIZE;
  718. nVOffsetY = nPhysOffsetY;
  719. }
  720. else
  721. nVOffsetY = 0;
  722. // get and adjust printer page area
  723. pageWidth = GetDeviceCaps(hdc, HORZRES );
  724. pageHeight = GetDeviceCaps(hdc, VERTRES );
  725. if( pageWidth >= (nPhysWidth - nPhysOffsetX) )
  726. {
  727. // HORZRES is lying to us, compensate
  728. pageWidth = nPhysWidth - 2*nPhysOffsetX;
  729. }
  730. if( pageHeight >= (nPhysHeight - nPhysOffsetY) )
  731. {
  732. // VERTRES is lying to us, compensate
  733. pageHeight = nPhysHeight - 2*nPhysOffsetY;
  734. }
  735. // adjust printer area to get max fit for Whiteboard page
  736. areaWidth = lprcPrint->right - lprcPrint->left;
  737. areaHeight = lprcPrint->bottom - lprcPrint->top;
  738. areaAspectRatio = ((100 * areaHeight + (areaWidth/2))/(areaWidth));
  739. pageAspectRatio = ((100 * pageHeight + (pageWidth/2))/(pageWidth));
  740. if (areaAspectRatio < pageAspectRatio)
  741. pageHeight = ((pageWidth * areaHeight + (areaWidth/2))/areaWidth);
  742. else
  743. if (areaAspectRatio > pageAspectRatio)
  744. pageWidth = ((pageHeight * areaWidth + (areaHeight/2))/areaHeight);
  745. // set up xforms
  746. ::SetMapMode(hdc, MM_ANISOTROPIC );
  747. ::SetWindowExtEx(hdc, areaWidth, areaHeight,NULL );
  748. ::SetWindowOrgEx(hdc, 0,0, NULL );
  749. ::SetViewportExtEx(hdc, pageWidth, pageHeight, NULL );
  750. ::SetViewportOrgEx(hdc, nVOffsetX, nVOffsetY, NULL );
  751. // draw the page
  752. PG_Draw(hPage, hdc);
  753. }
  754. //
  755. //
  756. // Function: AreaInUse
  757. //
  758. // Purpose: Return the bounding rectangle of all graphics on the page
  759. //
  760. //
  761. void PG_GetAreaInUse
  762. (
  763. WB_PAGE_HANDLE hPage,
  764. LPRECT lprcArea
  765. )
  766. {
  767. WB_GRAPHIC_HANDLE hStart;
  768. RECT rcBounds;
  769. MLZ_EntryOut(ZONE_FUNCTION, "PG_AreaInUse");
  770. ::SetRectEmpty(lprcArea);
  771. // Union together the rects of all the graphics
  772. DCWbGraphic* pGraphic = PG_First(hPage, &hStart);
  773. while (pGraphic != NULL)
  774. {
  775. pGraphic->GetBoundsRect(&rcBounds);
  776. ::UnionRect(lprcArea, lprcArea, &rcBounds);
  777. // Release the current graphic
  778. delete pGraphic;
  779. // Get the next one
  780. pGraphic = PG_Next(hPage, &hStart);
  781. }
  782. }
  783. //
  784. //
  785. // Function: PG_InitializePalettes
  786. //
  787. // Purpose: Create palettes for display and print (if necessary)
  788. //
  789. //
  790. void PG_InitializePalettes(void)
  791. {
  792. MLZ_EntryOut(ZONE_FUNCTION, "PG_InitializePalettes");
  793. // If the palettes are not yet initialized - initialize them now
  794. if (!g_bPalettesInitialized)
  795. {
  796. ASSERT(!g_hRainbowPaletteDisplay);
  797. // Get the number of colors supported by the screen
  798. // We only need an info DC for this, not a full DC
  799. HDC hdc;
  800. hdc = ::CreateIC("DISPLAY", NULL, NULL, NULL);
  801. if (!hdc)
  802. {
  803. return;
  804. }
  805. // Determine whether the device supports palettes
  806. int iBitsPixel = ::GetDeviceCaps(hdc, BITSPIXEL);
  807. int iPlanes = ::GetDeviceCaps(hdc, PLANES);
  808. int iNumColors = iBitsPixel * iPlanes;
  809. ::DeleteDC(hdc);
  810. // If we need the palette, create it.
  811. // We only need the palette on a 8bpp machine. Anything less (4bpp)
  812. // and there will be no palette, anything more is a pure color display.
  813. if ((iNumColors == 8) &&
  814. (g_hRainbowPaletteDisplay = CreateColorPalette()))
  815. {
  816. // Show that we want to use the palette
  817. g_bUsePalettes = TRUE;
  818. }
  819. else
  820. {
  821. g_bUsePalettes = FALSE;
  822. }
  823. // Show that we have now initialized the palette information
  824. g_bPalettesInitialized = TRUE;
  825. }
  826. }
  827. //
  828. //
  829. // Function: PG_GetPalette
  830. //
  831. // Purpose: Return the palette for use with this page.
  832. // This object is temporary and should not be stored.
  833. //
  834. //
  835. HPALETTE PG_GetPalette(void)
  836. {
  837. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetPalette");
  838. // If the palettes are not yet initialized - initialize them now
  839. PG_InitializePalettes();
  840. if (g_bUsePalettes)
  841. {
  842. // If we are using a non-default palette, set the return value
  843. return(g_hRainbowPaletteDisplay);
  844. }
  845. else
  846. {
  847. return(NULL);
  848. }
  849. }
  850. void PG_ReinitPalettes(void)
  851. {
  852. MLZ_EntryOut(ZONE_FUNCTION, "PG_ReinitPalettes");
  853. if (g_hRainbowPaletteDisplay)
  854. {
  855. if (g_pDraw->m_hDCCached)
  856. {
  857. // Select out the rainbow palette so we can delete it
  858. ::SelectPalette(g_pDraw->m_hDCCached, (HPALETTE)::GetStockObject(DEFAULT_PALETTE), TRUE);
  859. }
  860. ::DeletePalette(g_hRainbowPaletteDisplay);
  861. g_hRainbowPaletteDisplay = NULL;
  862. }
  863. g_bPalettesInitialized = FALSE;
  864. PG_InitializePalettes();
  865. }
  866. //
  867. //
  868. // Function : PG_GetObscuringRect
  869. //
  870. // Purpose : Return the intersection of a graphic and any objects which
  871. // obscure it
  872. //
  873. //
  874. void PG_GetObscuringRect
  875. (
  876. WB_PAGE_HANDLE hPage,
  877. DCWbGraphic* pGraphic,
  878. LPRECT lprcObscuring
  879. )
  880. {
  881. DCWbGraphic* pNextGraphic;
  882. RECT rc;
  883. RECT rcBounds;
  884. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetObscuringRect");
  885. ::SetRectEmpty(lprcObscuring);
  886. pGraphic->GetBoundsRect(&rcBounds);
  887. // Loop through all the objects which are above the given one in the
  888. // Z-order, checking to see if they overlap the given object
  889. pNextGraphic = pGraphic;
  890. while (pNextGraphic = PG_After(hPage, *pNextGraphic))
  891. {
  892. // Get the bounding rectangle of the next object
  893. pNextGraphic->GetBoundsRect(&rc);
  894. // Check the intersection of the rectangles
  895. ::IntersectRect(&rc, &rc, &rcBounds);
  896. // Add the intersection to the obscuring rectangle
  897. ::UnionRect(lprcObscuring, lprcObscuring, &rc);
  898. }
  899. // check text editbox if its up - bug 2185
  900. if (g_pMain->m_drawingArea.TextEditActive())
  901. {
  902. g_pMain->m_drawingArea.GetTextEditBoundsRect(&rc);
  903. ::IntersectRect(&rc, &rc, &rcBounds);
  904. ::UnionRect(lprcObscuring, lprcObscuring, &rc);
  905. }
  906. }
  907. //
  908. // ZGreaterGraphic()
  909. //
  910. // Determines which handle, hLastGraphic or hTestGraphic, is first in the
  911. // ZOrder (greater and consequently "underneath" the other graphic). If
  912. // hTestGraphic is NULL then the first graphic is returned.
  913. //
  914. WB_GRAPHIC_HANDLE PG_ZGreaterGraphic
  915. (
  916. WB_PAGE_HANDLE hPage,
  917. WB_GRAPHIC_HANDLE hLastGraphic,
  918. WB_GRAPHIC_HANDLE hTestGraphic
  919. )
  920. {
  921. MLZ_EntryOut(ZONE_FUNCTION, "PG_ZGreaterGraphic");
  922. WB_GRAPHIC_HANDLE hGraphic;
  923. WB_GRAPHIC_HANDLE hCurrentGraphic;
  924. if (g_pwbCore->WBP_GraphicHandle(hPage, NULL, FIRST, &hGraphic) != 0)
  925. return(NULL);
  926. if (hTestGraphic == NULL)
  927. return(hGraphic);
  928. if (hLastGraphic == NULL)
  929. return(hTestGraphic);
  930. // search for which one is deeper
  931. while (hGraphic != NULL)
  932. {
  933. if ((hGraphic == hLastGraphic) ||
  934. (hGraphic == hTestGraphic))
  935. return( hGraphic );
  936. hCurrentGraphic = hGraphic;
  937. if (g_pwbCore->WBP_GraphicHandle(hPage, hCurrentGraphic, AFTER, &hGraphic) != 0)
  938. return( NULL );
  939. }
  940. // didn't find either one
  941. return( NULL );
  942. }
  943. //
  944. //
  945. // Function: GetNextPage
  946. //
  947. // Purpose: Return the next page of graphic objects
  948. //
  949. //
  950. WB_PAGE_HANDLE PG_GetNextPage
  951. (
  952. WB_PAGE_HANDLE hPage
  953. )
  954. {
  955. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetNextPage");
  956. // Get the handle of the next page
  957. WB_PAGE_HANDLE hNextPage = NULL;
  958. UINT uiReturn = g_pwbCore->WBP_PageHandle(hPage, PAGE_AFTER, &hNextPage);
  959. switch (uiReturn)
  960. {
  961. case 0:
  962. // Got the previous page OK, return it
  963. break;
  964. case WB_RC_NO_SUCH_PAGE:
  965. // There is no previous page, return this page
  966. hNextPage = hPage;
  967. break;
  968. default:
  969. // Throw an exception recording the return code
  970. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  971. break;
  972. }
  973. return(hNextPage);
  974. }
  975. //
  976. //
  977. // Function: GetPreviousPage
  978. //
  979. // Purpose: Return the previous page of graphic objects
  980. //
  981. //
  982. WB_PAGE_HANDLE PG_GetPreviousPage
  983. (
  984. WB_PAGE_HANDLE hPage
  985. )
  986. {
  987. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetPreviousPage");
  988. // Get the handle of the previous page
  989. WB_PAGE_HANDLE hPreviousPage;
  990. UINT uiReturn = g_pwbCore->WBP_PageHandle(hPage, PAGE_BEFORE,
  991. &hPreviousPage);
  992. switch (uiReturn)
  993. {
  994. case 0:
  995. // Got the next page OK, return it
  996. break;
  997. case WB_RC_NO_SUCH_PAGE:
  998. // There is no next page, return this page
  999. hPreviousPage = hPage;
  1000. break;
  1001. default:
  1002. // Throw an exception recording the return code
  1003. DefaultExceptionHandler(WBFE_RC_WB, uiReturn);
  1004. break;
  1005. }
  1006. return(hPreviousPage);
  1007. }
  1008. //
  1009. //
  1010. // Function: GetPageNumber
  1011. //
  1012. // Purpose: Return the page with the given page number
  1013. //
  1014. //
  1015. WB_PAGE_HANDLE PG_GetPageNumber(UINT uiPageNo)
  1016. {
  1017. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetPageNumber");
  1018. // Ensure that the requested page number is within range
  1019. uiPageNo = min(uiPageNo, g_pwbCore->WBP_ContentsCountPages());
  1020. uiPageNo = max(1, uiPageNo);
  1021. // Get the handle of the page with the specified page number
  1022. WB_PAGE_HANDLE hPage;
  1023. UINT uiReturn = g_pwbCore->WBP_PageHandleFromNumber(uiPageNo, &hPage);
  1024. // Since we have been careful to ensure that the page number was
  1025. // in bounds we should always get a good return code from the core.
  1026. ASSERT(uiReturn == 0);
  1027. // Return a page object created from the returned handle
  1028. return(hPage);
  1029. }