On Mon, 6 Nov 2000, Uwe Bonnes wrote:
> Francois Gouget writes:
> >
> >
> > The DrawFocusRect mystery is still not completely resolved.
> >
> > Because of this I think Wine's component should not try to draw their
> > focus box themselves. The only place I know of where we do this is
> > dlls/comctl32/tab.c. I tried modifying it to use DrawFocusRect and
> > attached the patch.
> > But I don't know how to test it. Is it correct?
> >
> Hallo,
>
> there is an application called "cobtrolspy" out there which is quite
> good for testing comctl32 applications.
Thanks. I found an application that was using tabs and AFAICS it
works just fine with (despite) my modifications. I also downloaded a
ControlSpy program from MS's site:
http://www.microsoft.com/msj/defaulttop.asp?page=/msj/0798/controlspytop.htm
I think it should be on the standard list of tools to test Wine with
(unless we develop our own (in which case we could add menus, regular
buttons, etc.))
Back to Tabs, as I was looking at them with xzoom, I noticed that we
are missing the inner highlighted border. Also there is a dot on the
top-right edge which is black instead of white. The latter is caused by
this code:
if(infoPtr->items[iItem].rect.left == 0) /* if leftmost draw the line
longer */
MoveToEx (hdc, r.left, r.bottom, NULL);
else
MoveToEx (hdc, r.left, r.bottom - 1, NULL);
LineTo (hdc, r.left, r.top + ROUND_CORNER_SIZE);
LineTo (hdc, r.left + ROUND_CORNER_SIZE, r.top);
LineTo (hdc, r.right - ROUND_CORNER_SIZE, r.top);
/* shadow */
SelectObject(hdc, hbPen);
LineTo (hdc, r.right, r.top + ROUND_CORNER_SIZE);
LineTo (hdc, r.right, r.bottom + 1);
Plus more of the same in other places. Notice how when we switch pen,
the first LineTo puts a black dot at (r.right - ROUND_CORNER_SIZE,
r.top) which should be white.
The solution is to do things in the other order:
/* shadow */
SelectObject(hdc, hbPen);
MoveToEx(hdc, r.right, r.bottom, NULL);
LineTo (hdc, r.right, r.top + ROUND_CORNER_SIZE);
LineTo (hdc, r.right - ROUND_CORNER_SIZE, r.top);
/* highlight */
SelectObject(hdc, hwPen);
LineTo (hdc, r.left + ROUND_CORNER_SIZE, r.top);
LineTo (hdc, r.left, r.top + ROUND_CORNER_SIZE);
if(infoPtr->items[iItem].rect.left == 0) /* if leftmost draw the line longer
*/
LineTo (hdc, r.left, r.bottom + 1);
else
LineTo (hdc, r.left, r.bottom);
But this needs to be done in all the different cases: vertical or
not, bottom or not, flat or not, etc. I wonder if it would not be
simpler instead to use some an array describing what to do:
#define MOVE 1
#define LEFT 2
#define HWPEN 4
#define HBPEN 8
#define LEFT 0
#define RIGHT 100
#define TOP 0
#define BOTTOM 100
draw_operations={
{MOVE|HBPEN, RIGHT,BOTTOM},
{LINE,RIGHT,TOP+ROUND_CORNER_SIZE},
{LINE,RIGHT-ROUND_CORNER_SIZE,TOP},
{LINE|HWPEN,LEFT+ROUND_CORNER_SIZE,TOP},
{LINE,LEFT,TOP+ROUND_CORNER_SIZE},
{LINE,LEFT,BOTTOM},
...
};
Then if a coordinate is <50 it is relative to the left/top, and to
the right/bottom otherwise. Also from this it should even be possible to
derive the instructions for drawing a tab that is at the bottom rather
than the top.
It's almost like a metafile except I don't think it's worth bothering
with a metafile here. I think the above could reduce the code
duplication and thus simplify maintenance.
Should I give this a try next week-end? Is anyone interested in
working on this?
--
Francois Gouget [EMAIL PROTECTED] http://fgouget.free.fr/
Any sufficiently advanced Operating System is indistinguishable from Linux