Set the miter limit in the DC state.

Only SetLastError() in object functions where native does.
Test the error comditions of the gdiobj functions.
Minor documentation updates.
oldstable
Jon Griffiths 2004-11-23 12:19:24 +00:00 committed by Alexandre Julliard
parent 4af7bc87ec
commit 7c1ad31f47
4 changed files with 186 additions and 36 deletions

View File

@ -75,6 +75,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc->vportOrgY = 0;
dc->vportExtX = 1;
dc->vportExtY = 1;
dc->miterLimit = 10.0f; /* 10.0 is the default, from MSDN */
dc->flags = 0;
dc->hClipRgn = 0;
dc->hVisRgn = 0;
@ -2034,3 +2035,51 @@ DWORD WINAPI SetVirtualResolution(HDC hdc, DWORD dw2, DWORD dw3, DWORD dw4, DWOR
FIXME("(%p %08lx %08lx %08lx %08lx): stub!\n", hdc, dw2, dw3, dw4, dw5);
return FALSE;
}
/*******************************************************************
* GetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
{
BOOL bRet = FALSE;
DC *dc;
TRACE("(%p,%p)\n", hdc, peLimit);
dc = DC_GetDCPtr( hdc );
if (dc)
{
if (peLimit)
*peLimit = dc->miterLimit;
GDI_ReleaseObj( hdc );
bRet = TRUE;
}
return bRet;
}
/*******************************************************************
* SetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
{
BOOL bRet = FALSE;
DC *dc;
TRACE("(%p,%f,%p)\n", hdc, eNewLimit, peOldLimit);
dc = DC_GetDCPtr( hdc );
if (dc)
{
if (peOldLimit)
*peOldLimit = dc->miterLimit;
dc->miterLimit = eNewLimit;
GDI_ReleaseObj( hdc );
bRet = TRUE;
}
return bRet;
}

View File

@ -215,6 +215,7 @@ typedef struct tagDC
INT vportOrgY;
INT vportExtX; /* Viewport extent */
INT vportExtY;
FLOAT miterLimit;
int flags;
HRGN hClipRgn; /* Clip region (may be 0) */

View File

@ -875,7 +875,6 @@ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
if (!ptr)
{
_LeaveSysLevel( &GDI_level );
SetLastError( ERROR_INVALID_HANDLE );
WARN( "Invalid handle %p\n", handle );
}
else TRACE_SEC( handle, "enter" );
@ -907,6 +906,17 @@ void GDI_CheckNotLock(void)
/***********************************************************************
* DeleteObject (GDI32.@)
*
* Delete a Gdi object.
*
* PARAMS
* obj [I] Gdi object to delete
*
* RETURNS
* Success: TRUE. If obj was not returned from GetStockObject(), any resources
* it consumed are released.
* Failure: FALSE, if obj is not a valid Gdi object, or is currently selected
* into a DC.
*/
BOOL WINAPI DeleteObject( HGDIOBJ obj )
{
@ -1120,7 +1130,11 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle )
INT result = 0;
TRACE("%p\n", handle );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
switch(GDIMAGIC(ptr->wMagic))
{
@ -1173,6 +1187,24 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle )
/***********************************************************************
* GetCurrentObject (GDI32.@)
*
* Get the currently selected object of a given type in a device context.
*
* PARAMS
* hdc [I] Device context to get the current object from
* type [I] Type of current object to get (OBJ_* defines from "wingdi.h")
*
* RETURNS
* Success: The current object of the given type selected in hdc.
* Failure: A NULL handle.
*
* NOTES
* - only the following object types are supported:
*| OBJ_PEN
*| OBJ_BRUSH
*| OBJ_PAL
*| OBJ_FONT
*| OBJ_BITMAP
*/
HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type)
{
@ -1200,25 +1232,49 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type)
/***********************************************************************
* SelectObject (GDI32.@)
*
* Select a Gdi object into a device context.
*
* PARAMS
* hdc [I] Device context to associate the object with
* hObj [I] Gdi object to associate with hdc
*
* RETURNS
* Success: A non-NULL handle representing the previously selected object of
* the same type as hObj.
* Failure: A NULL object. If hdc is invalid, GetLastError() returns ERROR_INVALID_HANDLE.
* if hObj is not a valid object handle, no last error is set. In either
* case, hdc is unaffected by the call.
*/
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj )
{
HGDIOBJ ret = 0;
GDIOBJHDR *header = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
if (!header) return 0;
GDIOBJHDR *header;
DC *dc;
TRACE("hdc=%p %p\n", hdc, handle );
TRACE( "(%p,%p)\n", hdc, hObj );
if (header->funcs && header->funcs->pSelectObject)
if (!(dc = DC_GetDCPtr( hdc )))
SetLastError( ERROR_INVALID_HANDLE );
else
{
ret = header->funcs->pSelectObject( handle, header, hdc );
if (ret && ret != handle && (INT)ret > COMPLEXREGION)
GDI_ReleaseObj( (GDIOBJHDR *)dc );
header = GDI_GetObjPtr( hObj, MAGIC_DONTCARE );
if (header)
{
inc_ref_count( handle );
dec_ref_count( ret );
if (header->funcs && header->funcs->pSelectObject)
{
ret = header->funcs->pSelectObject( hObj, header, hdc );
if (ret && ret != hObj && (INT)ret > COMPLEXREGION)
{
inc_ref_count( hObj );
dec_ref_count( ret );
}
}
GDI_ReleaseObj( hObj );
}
}
GDI_ReleaseObj( handle );
return ret;
}
@ -1478,30 +1534,6 @@ BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
return 0;
}
/*******************************************************************
* GetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
{
FIXME("GetMiterLimit, stub\n");
return 0;
}
/*******************************************************************
* SetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
{
FIXME("(%p,%f,%p) stub\n", hdc, eNewLimit, peOldLimit);
if (peOldLimit)
*peOldLimit = 10.0; /* Default miter is 10, see msdn */
return TRUE;
}
/*******************************************************************
* GdiComment [GDI32.@]
*

View File

@ -205,8 +205,76 @@ todo_wine
ReleaseDC(0, hdc);
}
static void test_gdi_objects(void)
{
BYTE buff[256];
HDC hdc = GetDC(NULL);
HPEN hp;
int i;
/* SelectObject() with a NULL DC returns 0 and sets ERROR_INVALID_HANDLE.
* Note: Under XP at least invalid ptrs can also be passed, not just NULL;
* Don't test that here in case it crashes earlier win versions.
*/
SetLastError(0);
hp = SelectObject(NULL, GetStockObject(BLACK_PEN));
ok(!hp && GetLastError() == ERROR_INVALID_HANDLE,
"SelectObject(NULL DC) expected 0, ERROR_INVALID_HANDLE, got %p, 0x%08lx\n",
hp, GetLastError());
/* With a valid DC and a NULL object, the call returns 0 but does not SetLastError() */
SetLastError(0);
hp = SelectObject(hdc, NULL);
ok(!hp && !GetLastError(),
"SelectObject(NULL obj) expected 0, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* The DC is unaffected by the NULL SelectObject */
SetLastError(0);
hp = SelectObject(hdc, GetStockObject(BLACK_PEN));
ok(hp && !GetLastError(),
"SelectObject(post NULL) expected non-null, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* GetCurrentObject does not SetLastError() on a null object */
SetLastError(0);
hp = GetCurrentObject(NULL, OBJ_PEN);
ok(!hp && !GetLastError(),
"GetCurrentObject(NULL DC) expected 0, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* DeleteObject does not SetLastError() on a null object */
ok(!DeleteObject(NULL) && !GetLastError(),
"DeleteObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
DeleteObject(NULL), GetLastError());
/* GetObject does not SetLastError() on a null object */
SetLastError(0);
i = GetObjectA(NULL, sizeof(buff), buff);
ok (!i && !GetLastError(),
"GetObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
i, GetLastError());
/* GetObjectType does SetLastError() on a null object */
SetLastError(0);
i = GetObjectType(NULL);
ok (!i && GetLastError() == ERROR_INVALID_HANDLE,
"GetObjectType(NULL obj), expected 0, ERROR_INVALID_HANDLE, got %d, 0x%08lx\n",
i, GetLastError());
/* UnrealizeObject does not SetLastError() on a null object */
SetLastError(0);
i = UnrealizeObject(NULL);
ok (!i && !GetLastError(),
"UnrealizeObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
i, GetLastError());
ReleaseDC(NULL, hdc);
}
START_TEST(gdiobj)
{
test_logfont();
test_bitmap_font();
test_gdi_objects();
}