http://bugs.winehq.org/show_bug.cgi?id=18145
--- Comment #3 from Marintsev Miron marintsev@gmail.com 2009-04-29 05:18:28 --- (In reply to comment #2)
Probably what happens is that FillRect() ignores an error of SelectObject() when an invalid brush handle is passed. That needs a test case.
#1. FillRect && GetSysColorBrush FillRect code: ... if ( hbrush <= (HBRUSH) (COLOR_MAX + 1)) hbrush = GetSysColorBrush( HandleToULong(hbrush) - 1 ); ...
GetSysColorBrush( (unsigned) -1 ) returns NULL under windows, but wine returns GetStockObject( LTGRAY_BRUSH ).
So it's necessary to add such code to dlls/user32/sysparams.c/GetSysColorBrush: if( (unsigned int) -1 == index ) return NULL;
MSDN says:
Return Value
The return value identifies a logical brush if the nIndex parameter is supported by the current platform. Otherwise, it returns NULL.
#2. SelectObject( hdc, 0 ) There is no problem with SelectObject( hdc, 0 ). It returns 0 and do nothing both under Windows and wine.
#3. FillRect && SelectObject( hdc, 0 )
dlls/user32/uitools.c/FillRect code:
... if ( !(prevBrush = SelectObject( hdc, hbrush ))) return 0; PatBlt( hdc, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, PATCOPY ); SelectObject( hdc, prevBrush ); ...
SelectObject( hdc, 0 ) will return 0, so prevBrush will be 0 and FillRect returns 0, before drawing using PatBlt. It's improper.
According to item #2 it's safely to use SelectObject( hdc, 0 ) before and after PatBlt, but lacks performance.
So this is my vision of FillRect reconstruction: if ( hbrush && !(prevBrush = SelectObject( hdc, hbrush ))) return 0; PatBlt( hdc, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, PATCOPY ); if( hbrush ) SelectObject( hdc, prevBrush );