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.

198 lines
6.6 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: calcclrc.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * History:
  7. * 10-22-90 MikeHar Ported functions from Win 3.0 sources.
  8. * 01-Feb-1991 mikeke Added Revalidation code
  9. \***************************************************************************/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. /***************************************************************************\
  13. * xxxCalcClientRect
  14. *
  15. * 10-22-90 MikeHar Ported function from Win 3.0 sources.
  16. \***************************************************************************/
  17. VOID xxxCalcClientRect(
  18. PWND pwnd,
  19. LPRECT lprc,
  20. BOOL fHungRedraw)
  21. {
  22. int cxFrame, yTopOld, cBorders;
  23. RECT rcTemp;
  24. PMENU pMenu;
  25. TL tlpMenu;
  26. BOOL fEmptyClient;
  27. BYTE bFramePresent;
  28. CheckLock(pwnd);
  29. UserAssert(IsWinEventNotifyDeferredOK());
  30. bFramePresent = TestWF(pwnd, WFFRAMEPRESENTMASK);
  31. /*
  32. * Clear all the frame bits. NOTE: The HIBYTE of all these #defines
  33. * must stay the same for this line to work.
  34. */
  35. ClrWF(pwnd, WFFRAMEPRESENTMASK);
  36. //
  37. // We need to clear the client border bits also. Otherwise, when the
  38. // window gets really small, the client border will draw over the menu
  39. // and caption.
  40. //
  41. ClrWF(pwnd, WFCEPRESENT);
  42. /*
  43. * If the window is iconic, the client area is empty.
  44. */
  45. if (TestWF(pwnd, WFMINIMIZED)) {
  46. // SetRectEmpty(lprc);
  47. // We must make it an empty rectangle.
  48. // But, that empty rectangle should be at the top left corner of the
  49. // window rect. Else, ScreenToClient() will return bad values.
  50. lprc->right = lprc->left;
  51. lprc->bottom = lprc->top;
  52. goto CalcClientDone;
  53. }
  54. // Save rect into rcTemp for easy local calculations.
  55. CopyRect(&rcTemp, lprc);
  56. // Save the top so we'll know how tall the caption was
  57. yTopOld = rcTemp.top;
  58. // Adjustment for the caption
  59. if (TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION))
  60. {
  61. SetWF(pwnd, WFCPRESENT);
  62. rcTemp.top += GetCaptionHeight(pwnd);
  63. }
  64. // Subtract out window borders
  65. cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE);
  66. cxFrame = cBorders * SYSMETFROMPROCESS(CXBORDER);
  67. InflateRect(&rcTemp, -cxFrame, -cBorders * SYSMETFROMPROCESS(CYBORDER));
  68. if (!TestwndChild(pwnd) && (pMenu = pwnd->spmenu)) {
  69. SetWF(pwnd, WFMPRESENT);
  70. if (!fHungRedraw) {
  71. ThreadLockMenuAlwaysNoModify(pMenu, &tlpMenu);
  72. rcTemp.top += xxxMenuBarCompute(pMenu, pwnd, rcTemp.top - yTopOld,
  73. cxFrame, rcTemp.right - rcTemp.left);
  74. ThreadUnlockMenuNoModify(&tlpMenu);
  75. }
  76. }
  77. /*
  78. * We should have cleared WFMPRESENT in the else case here. Win9x doesn't do
  79. * it either. Any code checking this flag will do the wrong thing...
  80. * It seems that it's pretty unsual for apps to remove the menu....
  81. * No code checking this flag can assume that pwnd->spmenu is not NULL -- we
  82. * would need to clear it way earlier (at unlock time) for such assumption to hold true.
  83. */
  84. //
  85. // Fix for B#1425 -- Sizing window really small used to move children's
  86. // rects because the client calculations were wrong. So we make the
  87. // bottom of the client match up with the top (the bottom of the menu
  88. // bar).
  89. //
  90. fEmptyClient = FALSE;
  91. if (rcTemp.top >= rcTemp.bottom) {
  92. rcTemp.bottom = rcTemp.top;
  93. fEmptyClient = TRUE;
  94. }
  95. //
  96. // BOGUS BOGUS BOGUS
  97. // Hack for Central Point PC Tools.
  98. // Possibly for M5 only.
  99. // B#8445
  100. //
  101. // They check for div-by-zero all over, but they jump to the wrong place
  102. // if a zero divisor is encountered, and end up faulting anyway. So this
  103. // code path was never tested basically. There's a period when starting
  104. // up where the window rect of their drives ribbon is empty. In Win3.x,
  105. // the client would be shrunk to account for the border it had, and it
  106. // would look like it wasn't empty because the width would be negative,
  107. // signed! So we version-switch this code, since other apps have
  108. // reported the non-emptiness as an annoying bug.
  109. //
  110. if (TestWF(pwnd, WFWIN40COMPAT) && (rcTemp.left >= rcTemp.right)) {
  111. rcTemp.right = rcTemp.left;
  112. fEmptyClient = TRUE;
  113. }
  114. if (fEmptyClient) {
  115. goto ClientCalcEnd;
  116. }
  117. //
  118. // Subtract client edge if we have space
  119. //
  120. if ( TestWF(pwnd, WEFCLIENTEDGE) &&
  121. (rcTemp.right - rcTemp.left >= (2 * SYSMETFROMPROCESS(CXEDGE))) &&
  122. (rcTemp.bottom - rcTemp.top >= (2 * SYSMETFROMPROCESS(CYEDGE))) ) {
  123. SetWF(pwnd, WFCEPRESENT);
  124. InflateRect(&rcTemp, -SYSMETFROMPROCESS(CXEDGE), -SYSMETFROMPROCESS(CYEDGE));
  125. }
  126. //
  127. // Subtract scrollbars
  128. // Note compatibility with 3.1:
  129. // * You don't get a horizontal scrollbar unless you have MORE
  130. // space (> ) in your client than you need for one.
  131. // * You get a vertical scrollbar if you have AT LEAST ENOUGH
  132. // space (>=) in your client for one.
  133. //
  134. if (TestWF(pwnd, WFHSCROLL) && (rcTemp.bottom - rcTemp.top > SYSMETFROMPROCESS(CYHSCROLL))) {
  135. SetWF(pwnd, WFHPRESENT);
  136. if (!fHungRedraw) {
  137. rcTemp.bottom -= SYSMETFROMPROCESS(CYHSCROLL);
  138. }
  139. }
  140. if (TestWF(pwnd, WFVSCROLL) && (rcTemp.right - rcTemp.left >= SYSMETFROMPROCESS(CXVSCROLL))) {
  141. SetWF(pwnd, WFVPRESENT);
  142. if (!fHungRedraw) {
  143. if ((!!TestWF(pwnd, WEFLEFTSCROLL)) ^ (!!TestWF(pwnd, WEFLAYOUTRTL))) {
  144. rcTemp.left += SYSMETFROMPROCESS(CXVSCROLL);
  145. } else {
  146. rcTemp.right -= SYSMETFROMPROCESS(CXVSCROLL);
  147. }
  148. }
  149. }
  150. ClientCalcEnd:
  151. CopyRect(lprc, &rcTemp);
  152. CalcClientDone:
  153. if (bFramePresent != TestWF(pwnd, WFFRAMEPRESENTMASK)) {
  154. xxxWindowEvent(EVENT_OBJECT_REORDER, pwnd, OBJID_WINDOW, 0, WEF_USEPWNDTHREAD);
  155. }
  156. }
  157. /***************************************************************************\
  158. * UpdateClientRect()
  159. *
  160. * Make sure the client rect reflects the window styles correctly.
  161. *
  162. * 10-22-90 MikeHar Ported function from Win 3.0 sources.
  163. \***************************************************************************/
  164. VOID xxxUpdateClientRect(
  165. PWND pwnd)
  166. {
  167. RECT rc;
  168. CopyRect(&rc, &pwnd->rcWindow);
  169. xxxCalcClientRect(pwnd, &rc, FALSE);
  170. CopyRect(&pwnd->rcClient, &rc);
  171. }