From: Paul N on
I have a question about scrolling. I put a detailed question into
comp.os.ms-windows.programmer.win32 but it hasn’t gathered any replies
yet. So I’m posting a more general question here, in the hope that
someone will be able to give me a nudge in the right direction.

I’m using Windows. As you probably know, if a window is displayed on
the screen, and another window covers part or all of it and is then
removed, Windows sends a WM_PAINT message to the window to tell it to
re-draw the missing part. It is possible to scroll a window, and one
way of doing this is to use a function called ScrollWindow to scroll
the contents of a window to a new place and then WM_PAINT to fill in
the new part.

Microsoft provide a function called DrawFocusRect, which puts a dotted
box around something. It does an EOR, that is, if you do it twice it
takes the dotted box off again. However, according to MSDN, at
http://msdn.microsoft.com/en-us/library/dd162479(VS.85).aspx "This
function draws a rectangle that cannot be scrolled. To scroll an area
containing a rectangle drawn by this function, call DrawFocusRect to
remove the rectangle from the screen, scroll the area, and then call
DrawFocusRect again to draw the rectangle in the new position."

Can anyone explain to me why this should be true? I thought a bit
about invalid rectangles and the like but I can’t see why.

Even assuming that it is true, I'm not sure how to go about it. You
see, if my program gets a WM_PAINT message because a window that was
previously covering half my dotted box has now been removed, then I
only want to draw the missing half of the box - the other half is
already there, and would disappear if I tried to redraw it. However,
if I do a redraw as part of a scroll, then after the scroll I would
apparently need to redraw the whole dotted box, even if part of it was
on the “new” area and part of it was on the “scrolled” area.

Can anyone explain why the system might work like this and how it
should be used?

Thanks very much.
Paul.

From: bartc on
Paul N wrote:
> I have a question about scrolling. I put a detailed question into

> Microsoft provide a function called DrawFocusRect, which puts a dotted
> box around something. It does an EOR, that is, if you do it twice it
> takes the dotted box off again. However, according to MSDN, at
> http://msdn.microsoft.com/en-us/library/dd162479(VS.85).aspx "This
> function draws a rectangle that cannot be scrolled. To scroll an area
> containing a rectangle drawn by this function, call DrawFocusRect to
> remove the rectangle from the screen, scroll the area, and then call
> DrawFocusRect again to draw the rectangle in the new position."
>
> Can anyone explain to me why this should be true? I thought a bit
> about invalid rectangles and the like but I can�t see why.

I guess that if this focus rectangle has to be linked in Win32's focus
handling, then it needs to know where it is in order to undraw it (or
perhaps to display input, or a caret, inside). It wouldn't be able to keep
track of the position if it was just scrolled like everything else.
Otherwise there's no reason why you can't draw your own focus rectangle
using a dotted line style.

> Even assuming that it is true, I'm not sure how to go about it. You
> see, if my program gets a WM_PAINT message because a window that was
> previously covering half my dotted box has now been removed, then I
> only want to draw the missing half of the box - the other half is
> already there, and would disappear if I tried to redraw it. However,
> if I do a redraw as part of a scroll, then after the scroll I would
> apparently need to redraw the whole dotted box, even if part of it was
> on the �new� area and part of it was on the �scrolled� area.

If that is an issue, then you just set a clip window around the region that
needs updating. Then, the focus rectangle redraw should be limited to that;
the bit outside should be unaffected.

> Can anyone explain why the system might work like this and how it
> should be used?

Welcome to Win32 and GDI. It's designed to be difficult...

--
bartc

From: Paul N on
On 22 Dec, 00:38, "bartc" <ba...(a)freeuk.com> wrote:
> Paul N wrote:
> > I have a question about scrolling. I put a detailed question into
> > Microsoft provide a function called DrawFocusRect, which puts a dotted
> > box around something. It does an EOR, that is, if you do it twice it
> > takes the dotted box off again. However, according to MSDN, at
> >http://msdn.microsoft.com/en-us/library/dd162479(VS.85).aspx"This
> > function draws a rectangle that cannot be scrolled. To scroll an area
> > containing a rectangle drawn by this function, call DrawFocusRect to
> > remove the rectangle from the screen, scroll the area, and then call
> > DrawFocusRect again to draw the rectangle in the new position."
>
> > Can anyone explain to me why this should be true? I thought a bit
> > about invalid rectangles and the like but I can’t see why.
>
> I guess that if this focus rectangle has to be linked in Win32's focus
> handling, then it needs to know where it is in order to undraw it (or
> perhaps to display input, or a caret, inside). It wouldn't be able to keep
> track of the position if it was just scrolled like everything else.

That could be it. Luckily, my program doesn't use the dotted rectangle
in a way that would involve Windows' focus handling, so hopefully I
can simply ignore the problem.

> Otherwise there's no reason why you can't draw your own focus rectangle
> using a dotted line style.
>
> > Even assuming that it is true, I'm not sure how to go about it. You
> > see, if my program gets a WM_PAINT message because a window that was
> > previously covering half my dotted box has now been removed, then I
> > only want to draw the missing half of the box - the other half is
> > already there, and would disappear if I tried to redraw it. However,
> > if I do a redraw as part of a scroll, then after the scroll I would
> > apparently need to redraw the whole dotted box, even if part of it was
> > on the “new” area and part of it was on the “scrolled” area.
>
> If that is an issue, then you just set a clip window around the region that
> needs updating. Then, the focus rectangle redraw should be limited to that;
> the bit outside should be unaffected.

My worry (which I'm now ignoring, see above) was assessing whether the
clip window was needed or not. If you scroll by removing the
rectangle, scrolling and putting it back on, you don't want to be
drawing half a rectangle after the scroll. But if half the rectangle
was covered and it's now come back into sight, you do want to draw
only the half rectangle.

> > Can anyone explain why the system might work like this and how it
> > should be used?
>
> Welcome to Win32 and GDI. It's designed to be difficult...