Answer to yesterday’s exercise

Date:July 30, 2003 / year-entry #9
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20030730-00/?p=43013
Comments:    5
Summary:iMin is the lowest-index element which intersects the paint rectangle, so a simple truncating division produces the desired index. The formula for iMax can be interpreted two ways. One is that it is the roundup of the first invisible line. Recall the rectangles are exclusive of the endpoint, so rcPaint.bottom is actually the first row...

iMin is the lowest-index element which intersects the paint rectangle, so a simple truncating division produces the desired index.

The formula for iMax can be interpreted two ways. One is that it is the roundup of the first invisible line. Recall the rectangles are exclusive of the endpoint, so rcPaint.bottom is actually the first row outside the rectangle. Since we want the first element that is completely outside the rectangle, we must round up.

A second interpretation begins with the seemingly equivalent formula. First, the expression

    (pps->rcPaint.bottom - 1) / g_cyLine

computes the index of the last visible item. By adding unity, we get the index of the first invisible item.

In both cases, we do not allow the computed value to exceed g_cItems so we don't try to draw items that don't exist.

The answer to the next question is that the seemingly equivalent formula does not work correctly when rcPaint.bottom is zero or negative because the result of integer division is rounded towards zero, which would result in an erroneous computation that the value of iMax should be one instead of zero. If integer divisions were rounded towards negative infinity, then the formula would be correct.

And the answer to the final question is that the only harm is that we sometimes draw one item that we really didn't need to. In our example, this is not that big a deal since drawing an item is relatively fast. But in cases where drawing an item is expensive, avoiding the drawing of even a single item may prove significant.

And we'll see in Part 4 that playing with the origin can cause the paint rectangle to end up in odd positions.


Comments (5)
  1. "Recall the rectangles are exclusive of the endpoint, so rcPaint.bottom is actually the first row outside the rectangle."

    MSDN Libraries for both October 2001 and October 2003 have the following characteristics.

    For GetClientRect(), the description contradicts itself. The first paragraph falsely says that the lower-right corner is involved. A later paragraph correctly says that the width and height are involved.

    For GetWindowRect(), the description is false only. The first paragraph doesn’t say, but a later paragraph says that the lower-right corner is involved.

    The fact is exactly as you say, a point which is adjacent but outside of the lower-right corner is involved.

    For one customer, I had to position a bunch of scrollbars and their related frames. Every time I resized the main window, every scroll bar grew in width. I fixed it by deliberately coding some off-by-one errors. Then I remembered your series on scrollbars, and here is your information, you got it right and the MSDN library got it wrong.

    Sometimes you hinted that you have contacts at MSDN. Please see if you can persuade them to fix the descriptions of GetClientRect() and GetWindowRect().

  2. Raymond Chen says:

    Done. I also asked for a special remark in the documentation for RECT to indicate that "By convention, the bottom right coordinates of rectangles are normally exclusive. In other words, the pixel whose coordinates are (right, bottom) lies immediately outside the rectangle." Hopefully this blanket statement will cover all the other functions that operate on rectangles.

  3. Thank you for making that request, but may I also ask you to make the English a bit clearer? Even though I handle English much better than I handle Japanese, I would still get tripped up on "normally exclusive". Backing up and reparsing the sentence yields a more meaningful result, "are normally", but the word "exclusive" isn’t quite clear. The second sentence does clear up the confusion, but still there’s no need for the first sentence to create confusion.

    Maybe "By convention, the bottom right coordinates of rectangles are usually the height and width instead of the actual bottom and right." The second sentence still helps explain it fully.

  4. Raymond Chen says:

    Except that’s still not correct. If top/left is not (0,0) then bottom and right are not the height and width. I have a blog entry scheduled for February 17th to explain rectangles better – I hope you can hold out until then.

  5. You’re right, my wording isn’t correct for GetWindowRect().

    For GetClientRect() I think my wording is correct and understandable. If you agree with that, then we can fix the wording for GetWindowRect() next. Anyway, I think it is possible to be both correct and non-obfuscatory.

    Yes I’ll wait until February 17th.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index