ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
August 2005
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
23 participants
669 discussions
Start a n
N
ew thread
[sedwards] 17128: turn on more the winetests
by sedwards@svn.reactos.com
turn on more the winetests Modified: trunk/reactos/regtests/winetests/directory.xml _____ Modified: trunk/reactos/regtests/winetests/directory.xml --- trunk/reactos/regtests/winetests/directory.xml 2005-08-07 00:03:28 UTC (rev 17127) +++ trunk/reactos/regtests/winetests/directory.xml 2005-08-07 00:06:29 UTC (rev 17128) @@ -14,6 +14,12 @@ <directory name="psapi"> <xi:include href="psapi/psapi_test.xml" /> </directory> +<directory name="shlwapi"> + <xi:include href="shlwapi/shlwapi_test.xml" /> +</directory> +<directory name="user32"> + <xi:include href="user32/user32_test.xml" /> +</directory> <directory name="version"> <xi:include href="version/version_test.xml" /> </directory>
19 years, 4 months
1
0
0
0
[sedwards] 17127: again dump the .cvsignore
by sedwards@svn.reactos.com
again dump the .cvsignore Deleted: trunk/reactos/regtests/winetests/shlwapi/.cvsignore _____ Deleted: trunk/reactos/regtests/winetests/shlwapi/.cvsignore --- trunk/reactos/regtests/winetests/shlwapi/.cvsignore 2005-08-06 23:58:36 UTC (rev 17126) +++ trunk/reactos/regtests/winetests/shlwapi/.cvsignore 2005-08-07 00:03:28 UTC (rev 17127) @@ -1,9 +0,0 @@ -Makefile -clist.ok -clsid.ok -generated.ok -ordinal.ok -path.ok -shreg.ok -string.ok -testlist.c
19 years, 4 months
1
0
0
0
[sedwards] 17126: add some of the shlwapi tests
by sedwards@svn.reactos.com
add some of the shlwapi tests Added: trunk/reactos/regtests/winetests/shlwapi/ Added: trunk/reactos/regtests/winetests/shlwapi/.cvsignore Added: trunk/reactos/regtests/winetests/shlwapi/clist.c Added: trunk/reactos/regtests/winetests/shlwapi/clsid.c Added: trunk/reactos/regtests/winetests/shlwapi/generated.c Added: trunk/reactos/regtests/winetests/shlwapi/ordinal.c Added: trunk/reactos/regtests/winetests/shlwapi/path.c Added: trunk/reactos/regtests/winetests/shlwapi/shlwapi_test.xml Added: trunk/reactos/regtests/winetests/shlwapi/shreg.c Added: trunk/reactos/regtests/winetests/shlwapi/string.c Added: trunk/reactos/regtests/winetests/shlwapi/testlist.c _____ Added: trunk/reactos/regtests/winetests/shlwapi/.cvsignore --- trunk/reactos/regtests/winetests/shlwapi/.cvsignore 2005-08-06 23:41:45 UTC (rev 17125) +++ trunk/reactos/regtests/winetests/shlwapi/.cvsignore 2005-08-06 23:58:36 UTC (rev 17126) @@ -0,0 +1,9 @@ +Makefile +clist.ok +clsid.ok +generated.ok +ordinal.ok +path.ok +shreg.ok +string.ok +testlist.c Property changes on: trunk/reactos/regtests/winetests/shlwapi/.cvsignore ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/shlwapi/clist.c --- trunk/reactos/regtests/winetests/shlwapi/clist.c 2005-08-06 23:41:45 UTC (rev 17125) +++ trunk/reactos/regtests/winetests/shlwapi/clist.c 2005-08-06 23:58:36 UTC (rev 17126) @@ -0,0 +1,643 @@ +/* Unit test suite for SHLWAPI Compact List and IStream ordinal functions + * + * Copyright 2002 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "objbase.h" + +typedef struct tagSHLWAPI_CLIST +{ + ULONG ulSize; + ULONG ulId; +} SHLWAPI_CLIST, *LPSHLWAPI_CLIST; + +typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST; + +/* Items to add */ +static const SHLWAPI_CLIST SHLWAPI_CLIST_items[] = +{ + {4, 1}, + {8, 3}, + {12, 2}, + {16, 8}, + {20, 9}, + {3, 11}, + {9, 82}, + {33, 16}, + {32, 55}, + {24, 100}, + {39, 116}, + { 0, 0} +}; + +/* Dummy IStream object for testing calls */ +typedef struct +{ + void* lpVtbl; + LONG ref; + int readcalls; + BOOL failreadcall; + BOOL failreadsize; + BOOL readbeyondend; + BOOL readreturnlarge; + int writecalls; + BOOL failwritecall; + BOOL failwritesize; + int seekcalls; + int statcalls; + BOOL failstatcall; + LPCSHLWAPI_CLIST item; + ULARGE_INTEGER pos; +} _IDummyStream; + +static +HRESULT WINAPI QueryInterface(_IDummyStream *This,REFIID riid, LPVOID *ppvObj) +{ + return S_OK; +} + +static ULONG WINAPI AddRef(_IDummyStream *This) +{ + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI Release(_IDummyStream *This) +{ + return InterlockedDecrement(&This->ref); +} + +static HRESULT WINAPI Read(_IDummyStream* This, LPVOID lpMem, ULONG ulSize, + PULONG lpRead) +{ + HRESULT hRet = S_OK; + ++This->readcalls; + + if (This->failreadcall) + { + return STG_E_ACCESSDENIED; + } + else if (This->failreadsize) + { + *lpRead = ulSize + 8; + return S_OK; + } + else if (This->readreturnlarge) + { + *((ULONG*)lpMem) = 0xffff01; + *lpRead = ulSize; + This->readreturnlarge = FALSE; + return S_OK; + } + if (ulSize == sizeof(ULONG)) + { + /* Read size of item */ + *((ULONG*)lpMem) = This->item->ulSize ? This->item->ulSize + sizeof(SHLWAPI_CLIST) : 0; + *lpRead = ulSize; + } + else + { + unsigned int i; + char* buff = (char*)lpMem; + + /* Read item data */ + if (!This->item->ulSize) + { + This->readbeyondend = TRUE; + *lpRead = 0; + return E_FAIL; /* Should never happen */ + } + *((ULONG*)lpMem) = This->item->ulId; + *lpRead = ulSize; + + for (i = 0; i < This->item->ulSize; i++) + buff[4+i] = i*2; + + This->item++; + } + return hRet; +} + +static HRESULT WINAPI Write(_IDummyStream* This, LPVOID lpMem, ULONG ulSize, + PULONG lpWritten) +{ + HRESULT hRet = S_OK; + + ++This->writecalls; + if (This->failwritecall) + { + return STG_E_ACCESSDENIED; + } + else if (This->failwritesize) + { + *lpWritten = 0; + } + else + *lpWritten = ulSize; + return hRet; +} + +static HRESULT WINAPI Seek(_IDummyStream* This, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) +{ + ++This->seekcalls; + This->pos.QuadPart = dlibMove.QuadPart; + if (plibNewPosition) + plibNewPosition->QuadPart = dlibMove.QuadPart; + return S_OK; +} + +static HRESULT WINAPI Stat(_IDummyStream* This, STATSTG* pstatstg, + DWORD grfStatFlag) +{ + ++This->statcalls; + if (This->failstatcall) + return E_FAIL; + if (pstatstg) + pstatstg->cbSize.QuadPart = This->pos.QuadPart; + return S_OK; +} + +/* VTable */ +static void* iclvt[] = +{ + QueryInterface, + AddRef, + Release, + Read, + Write, + Seek, + NULL, /* SetSize */ + NULL, /* CopyTo */ + NULL, /* Commit */ + NULL, /* Revert */ + NULL, /* LockRegion */ + NULL, /* UnlockRegion */ + Stat, + NULL /* Clone */ +}; + +/* Function ptrs for ordinal calls */ +static HMODULE SHLWAPI_hshlwapi = 0; + +static VOID (WINAPI *pSHLWAPI_19)(LPSHLWAPI_CLIST); +static HRESULT (WINAPI *pSHLWAPI_20)(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST); +static BOOL (WINAPI *pSHLWAPI_21)(LPSHLWAPI_CLIST*,ULONG); +static LPSHLWAPI_CLIST (WINAPI *pSHLWAPI_22)(LPSHLWAPI_CLIST,ULONG); +static HRESULT (WINAPI *pSHLWAPI_17)(_IDummyStream*,LPSHLWAPI_CLIST); +static HRESULT (WINAPI *pSHLWAPI_18)(_IDummyStream*,LPSHLWAPI_CLIST*); + +static BOOL (WINAPI *pSHLWAPI_166)(_IDummyStream*); +static HRESULT (WINAPI *pSHLWAPI_184)(_IDummyStream*,LPVOID,ULONG); +static HRESULT (WINAPI *pSHLWAPI_212)(_IDummyStream*,LPCVOID,ULONG); +static HRESULT (WINAPI *pSHLWAPI_213)(_IDummyStream*); +static HRESULT (WINAPI *pSHLWAPI_214)(_IDummyStream*,ULARGE_INTEGER*); + + +static void InitFunctionPtrs(void) +{ + SHLWAPI_hshlwapi = LoadLibraryA("shlwapi.dll"); + ok(SHLWAPI_hshlwapi != 0, "LoadLibrary failed\n"); + if (SHLWAPI_hshlwapi) + { + pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17); + ok(pSHLWAPI_17 != 0, "No Ordinal 17\n"); + pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18); + ok(pSHLWAPI_18 != 0, "No Ordinal 18\n"); + pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19); + ok(pSHLWAPI_19 != 0, "No Ordinal 19\n"); + pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20); + ok(pSHLWAPI_20 != 0, "No Ordinal 20\n"); + pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21); + ok(pSHLWAPI_21 != 0, "No Ordinal 21\n"); + pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22); + ok(pSHLWAPI_22 != 0, "No Ordinal 22\n"); + pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166); + ok(pSHLWAPI_166 != 0, "No Ordinal 166\n"); + pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184); + ok(pSHLWAPI_184 != 0, "No Ordinal 184\n"); + pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212); + ok(pSHLWAPI_212 != 0, "No Ordinal 212\n"); + pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213); + ok(pSHLWAPI_213 != 0, "No Ordinal 213\n"); + pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214); + ok(pSHLWAPI_214 != 0, "No Ordinal 214\n"); + } +} + +static void InitDummyStream(_IDummyStream* iface) +{ + iface->lpVtbl = (void*)iclvt; + iface->ref = 1; + iface->readcalls = 0; + iface->failreadcall = FALSE; + iface->failreadsize = FALSE; + iface->readbeyondend = FALSE; + iface->readreturnlarge = FALSE; + iface->writecalls = 0; + iface->failwritecall = FALSE; + iface->failwritesize = FALSE; + iface->seekcalls = 0; + iface->statcalls = 0; + iface->failstatcall = FALSE; + iface->item = SHLWAPI_CLIST_items; + iface->pos.QuadPart = 0; +} + + +static void test_CList(void) +{ + _IDummyStream streamobj; + LPSHLWAPI_CLIST list = NULL; + LPCSHLWAPI_CLIST item = SHLWAPI_CLIST_items; + HRESULT hRet; + LPSHLWAPI_CLIST inserted; + BYTE buff[64]; + unsigned int i; + + if (!pSHLWAPI_17 || !pSHLWAPI_18 || !pSHLWAPI_19 || !pSHLWAPI_20 || + !pSHLWAPI_21 || !pSHLWAPI_22) + return; + + /* Populate a list and test the items are added correctly */ + while (item->ulSize) + { + /* Create item and fill with data */ + inserted = (LPSHLWAPI_CLIST)buff; + inserted->ulSize = item->ulSize + sizeof(SHLWAPI_CLIST); + inserted->ulId = item->ulId; + for (i = 0; i < item->ulSize; i++) + buff[sizeof(SHLWAPI_CLIST)+i] = i*2; + + /* Add it */ + hRet = pSHLWAPI_20(&list, inserted); + ok(hRet > S_OK, "failed list add\n"); + + if (hRet > S_OK) + { + ok(list && list->ulSize, "item not added\n"); + + /* Find it */ + inserted = pSHLWAPI_22(list, item->ulId); + ok(inserted != NULL, "lost after adding\n"); + + ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n"); + + /* Check size */ + if (inserted && inserted->ulSize & 0x3) + { + /* Contained */ + ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n"); + ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST), + "container too small\n"); + } + else if (inserted) + { + ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST), + "id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize, + item->ulSize+sizeof(SHLWAPI_CLIST)); + } + if (inserted) + { + BOOL bDataOK = TRUE; + LPBYTE bufftest = (LPBYTE)inserted; + + for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++) + if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2) + bDataOK = FALSE; + + ok(bDataOK == TRUE, "data corrupted on insert\n"); + } + ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n"); + } + item++; + } + + /* Write the list */ + InitDummyStream(&streamobj); + + hRet = pSHLWAPI_17(&streamobj, list); + ok(hRet == S_OK, "write failed\n"); + if (hRet == S_OK) + { + /* 1 call for each element, + 1 for OK (use our null element for this) */ + ok(streamobj.writecalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST), + "wrong call count\n"); + ok(streamobj.readcalls == 0,"called Read() in write\n"); + ok(streamobj.seekcalls == 0,"called Seek() in write\n"); + } + + /* Failure cases for writing */ + InitDummyStream(&streamobj); + streamobj.failwritecall = TRUE; + hRet = pSHLWAPI_17(&streamobj, list); + ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n"); + ok(streamobj.writecalls == 1, "called object after failure\n"); + ok(streamobj.readcalls == 0,"called Read() after failure\n"); + ok(streamobj.seekcalls == 0,"called Seek() after failure\n"); + + InitDummyStream(&streamobj); + streamobj.failwritesize = TRUE; + hRet = pSHLWAPI_17(&streamobj, list); + ok(hRet == STG_E_MEDIUMFULL, "changed size failure return\n"); + ok(streamobj.writecalls == 1, "called object after size failure\n"); + ok(streamobj.readcalls == 0,"called Read() after failure\n"); + ok(streamobj.seekcalls == 0,"called Seek() after failure\n"); + + /* Invalid inputs for adding */ + inserted = (LPSHLWAPI_CLIST)buff; + inserted->ulSize = sizeof(SHLWAPI_CLIST) -1; + inserted->ulId = 33; + hRet = pSHLWAPI_20(&list, inserted); + /* The call succeeds but the item is not inserted, except on some early + * versions which return failure. Wine behaves like later versions. + */ +#if 0 + ok(hRet == S_OK, "failed bad element size\n"); +#endif + inserted = pSHLWAPI_22(list, 33); + ok(inserted == NULL, "inserted bad element size\n"); + + inserted = (LPSHLWAPI_CLIST)buff; + inserted->ulSize = 44; + inserted->ulId = ~0UL; + hRet = pSHLWAPI_20(&list, inserted); + /* See comment above, some early versions fail this call */ +#if 0 + ok(hRet == S_OK, "failed adding a container\n"); +#endif + item = SHLWAPI_CLIST_items; + + /* Look for nonexistent item in populated list */ + inserted = pSHLWAPI_22(list, 99999999); + ok(inserted == NULL, "found a nonexistent item\n"); + + while (item->ulSize) + { + /* Delete items */ + BOOL bRet = pSHLWAPI_21(&list, item->ulId); + ok(bRet == TRUE, "couldn't find item to delete\n"); + item++; + } + + /* Look for nonexistent item in empty list */ + inserted = pSHLWAPI_22(list, 99999999); + ok(inserted == NULL, "found an item in empty list\n"); + + /* Create a list by reading in data */ + InitDummyStream(&streamobj); + + hRet = pSHLWAPI_18(&streamobj, &list); + ok(hRet == S_OK, "failed create from Read()\n"); + if (hRet == S_OK) + { + ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); + /* 2 calls per item, but only 1 for the terminator */ + ok(streamobj.readcalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST)*2-1, + "wrong call count\n"); + ok(streamobj.writecalls == 0, "called Write() from create\n"); + ok(streamobj.seekcalls == 0,"called Seek() from create\n"); + + item = SHLWAPI_CLIST_items; + + /* Check the items were added correctly */ + while (item->ulSize) + { + inserted = pSHLWAPI_22(list, item->ulId); + ok(inserted != NULL, "lost after adding\n"); + + ok(!inserted || inserted->ulId != ~0UL, "find returned a container\n"); + + /* Check size */ + if (inserted && inserted->ulSize & 0x3) + { + /* Contained */ + ok(inserted[-1].ulId == ~0UL, "invalid size is not countained\n"); + ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST), + "container too small\n"); + } + else if (inserted) + { + ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST), + "id %ld size wrong (%ld!=%ld)\n", inserted->ulId, inserted->ulSize, + item->ulSize+sizeof(SHLWAPI_CLIST)); + } + ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n"); + if (inserted) + { + BOOL bDataOK = TRUE; + LPBYTE bufftest = (LPBYTE)inserted; + + for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++) + if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2) + bDataOK = FALSE; + + ok(bDataOK == TRUE, "data corrupted on insert\n"); + } + item++; + } + } + + /* Failure cases for reading */ + InitDummyStream(&streamobj); + streamobj.failreadcall = TRUE; + hRet = pSHLWAPI_18(&streamobj, &list); + ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n"); + ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); + ok(streamobj.readcalls == 1, "called object after read failure\n"); + ok(streamobj.writecalls == 0,"called Write() after read failure\n"); + ok(streamobj.seekcalls == 0,"called Seek() after read failure\n"); + + /* Read returns large object */ + InitDummyStream(&streamobj); + streamobj.readreturnlarge = TRUE; + hRet = pSHLWAPI_18(&streamobj, &list); + ok(hRet == S_OK, "failed create from Read() with large item\n"); + ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); + ok(streamobj.readcalls == 1,"wrong call count\n"); + ok(streamobj.writecalls == 0,"called Write() after read failure\n"); + ok(streamobj.seekcalls == 2,"wrong Seek() call count (%d)\n", streamobj.seekcalls); + + pSHLWAPI_19(list); +} + +static BOOL test_SHLWAPI_166(void) +{ + _IDummyStream streamobj; + BOOL bRet; + + if (!pSHLWAPI_166) + return FALSE; + + InitDummyStream(&streamobj); + bRet = pSHLWAPI_166(&streamobj); + + if (bRet != TRUE) + return FALSE; /* This version doesn't support stream ops on clists */ + + ok(streamobj.readcalls == 0, "called Read()\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 0, "called Seek()\n"); + ok(streamobj.statcalls == 1, "wrong call count\n"); + + streamobj.statcalls = 0; + streamobj.pos.QuadPart = 50001; + + bRet = pSHLWAPI_166(&streamobj); + + ok(bRet == FALSE, "failed after seek adjusted\n"); + ok(streamobj.readcalls == 0, "called Read()\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 0, "called Seek()\n"); + ok(streamobj.statcalls == 1, "wrong call count\n"); + + /* Failure cases */ + InitDummyStream(&streamobj); + streamobj.pos.QuadPart = 50001; + streamobj.failstatcall = TRUE; /* 1: Stat() Bad, Read() OK */ + bRet = pSHLWAPI_166(&streamobj); + ok(bRet == FALSE, "should be FALSE after read is OK\n"); + ok(streamobj.readcalls == 1, "wrong call count\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 1, "wrong call count\n"); + ok(streamobj.statcalls == 1, "wrong call count\n"); + ok(streamobj.pos.QuadPart == 0, "Didn't seek to start\n"); + + InitDummyStream(&streamobj); + streamobj.pos.QuadPart = 50001; + streamobj.failstatcall = TRUE; + streamobj.failreadcall = TRUE; /* 2: Stat() Bad, Read() Bad Also */ + bRet = pSHLWAPI_166(&streamobj); + ok(bRet == TRUE, "Should be true after read fails\n"); + ok(streamobj.readcalls == 1, "wrong call count\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 0, "Called Seek()\n"); + ok(streamobj.statcalls == 1, "wrong call count\n"); + ok(streamobj.pos.QuadPart == 50001, "called Seek() after read failed\n"); + return TRUE; +} + +static void test_SHLWAPI_184(void) +{ + _IDummyStream streamobj; + char buff[256]; + HRESULT hRet; + + if (!pSHLWAPI_184) + return; + + InitDummyStream(&streamobj); + hRet = pSHLWAPI_184(&streamobj, buff, sizeof(buff)); + + ok(hRet == S_OK, "failed Read()\n"); + ok(streamobj.readcalls == 1, "wrong call count\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 0, "called Seek()\n"); +} + +static void test_SHLWAPI_212(void) +{ + _IDummyStream streamobj; + char buff[256]; + HRESULT hRet; + + if (!pSHLWAPI_212) + return; + + InitDummyStream(&streamobj); + hRet = pSHLWAPI_212(&streamobj, buff, sizeof(buff)); + + ok(hRet == S_OK, "failed Write()\n"); + ok(streamobj.readcalls == 0, "called Read()\n"); + ok(streamobj.writecalls == 1, "wrong call count\n"); + ok(streamobj.seekcalls == 0, "called Seek()\n"); +} + +static void test_SHLWAPI_213(void) +{ + _IDummyStream streamobj; + ULARGE_INTEGER ul; + LARGE_INTEGER ll; + HRESULT hRet; + + if (!pSHLWAPI_213 || !pSHLWAPI_214) + return; + + InitDummyStream(&streamobj); + ll.QuadPart = 5000l; + Seek(&streamobj, ll, 0, NULL); /* Seek to 5000l */ + + streamobj.seekcalls = 0; + pSHLWAPI_213(&streamobj); /* Should rewind */ + ok(streamobj.statcalls == 0, "called Stat()\n"); + ok(streamobj.readcalls == 0, "called Read()\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 1, "wrong call count\n"); + + ul.QuadPart = 50001; + hRet = pSHLWAPI_214(&streamobj, &ul); + ok(hRet == S_OK, "failed Stat()\n"); + ok(ul.QuadPart == 0, "213 didn't rewind stream\n"); +} + +static void test_SHLWAPI_214(void) +{ + _IDummyStream streamobj; + ULARGE_INTEGER ul; + LARGE_INTEGER ll; + HRESULT hRet; + + if (!pSHLWAPI_214) + return; + + InitDummyStream(&streamobj); + ll.QuadPart = 5000l; + Seek(&streamobj, ll, 0, NULL); + ul.QuadPart = 0; + streamobj.seekcalls = 0; + hRet = pSHLWAPI_214(&streamobj, &ul); + + ok(hRet == S_OK, "failed Stat()\n"); + ok(streamobj.statcalls == 1, "wrong call count\n"); + ok(streamobj.readcalls == 0, "called Read()\n"); + ok(streamobj.writecalls == 0, "called Write()\n"); + ok(streamobj.seekcalls == 0, "called Seek()\n"); + ok(ul.QuadPart == 5000l, "Stat gave wrong size\n"); +} + +START_TEST(clist) +{ + InitFunctionPtrs(); + + test_CList(); + + /* Test streaming if this version supports it */ + if (test_SHLWAPI_166()) + { + test_SHLWAPI_184(); + test_SHLWAPI_212(); + test_SHLWAPI_213(); + test_SHLWAPI_214(); + } + + if (SHLWAPI_hshlwapi) + FreeLibrary(SHLWAPI_hshlwapi); +} Property changes on: trunk/reactos/regtests/winetests/shlwapi/clist.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/shlwapi/clsid.c --- trunk/reactos/regtests/winetests/shlwapi/clsid.c 2005-08-06 23:41:45 UTC (rev 17125) +++ trunk/reactos/regtests/winetests/shlwapi/clsid.c 2005-08-06 23:58:36 UTC (rev 17126) @@ -0,0 +1,171 @@ +/* Unit test suite for SHLWAPI Class ID functions + * + * Copyright 2003 Jon Griffiths + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdio.h> + +#define INITGUID +#include "wine/test.h" +#include "winbase.h" +#include "winerror.h" +#include "winnls.h" +#include "winuser.h" +#include "shlguid.h" +#include "wine/shobjidl.h" + +/* Function ptrs for ordinal calls */ +static HMODULE hShlwapi = 0; +static BOOL (WINAPI *pSHLWAPI_269)(LPCSTR, CLSID *) = 0; +static DWORD (WINAPI *pSHLWAPI_23)(REFGUID, LPSTR, INT) = 0; + +/* GUIDs to test */ +const GUID * TEST_guids[] = { + &CLSID_ShellDesktop, + &CLSID_ShellLink, + &CATID_BrowsableShellExt, + &CATID_BrowseInPlace, + &CATID_DeskBand, + &CATID_InfoBand, + &CATID_CommBand, + &FMTID_Intshcut, + &FMTID_InternetSite, + &CGID_Explorer, + &CGID_ShellDocView, + &CGID_ShellServiceObject, + &CGID_ExplorerBarDoc, + &IID_INewShortcutHookA, + &IID_IShellIcon, + &IID_IShellFolder, + &IID_IShellExtInit, + &IID_IShellPropSheetExt, + &IID_IPersistFolder, + &IID_IExtractIconA, + &IID_IShellDetails, + &IID_IDelayedRelease, + &IID_IShellLinkA, + &IID_IShellCopyHookA, + &IID_IFileViewerA, + &IID_ICommDlgBrowser, + &IID_IEnumIDList, + &IID_IFileViewerSite, + &IID_IContextMenu2, + &IID_IShellExecuteHookA, + &IID_IPropSheetPage, + &IID_INewShortcutHookW, + &IID_IFileViewerW, + &IID_IShellLinkW, + &IID_IExtractIconW, + &IID_IShellExecuteHookW, + &IID_IShellCopyHookW, + &IID_IRemoteComputer, + &IID_IQueryInfo, + &IID_IDockingWindow, + &IID_IDockingWindowSite, + &CLSID_NetworkPlaces, + &CLSID_NetworkDomain, + &CLSID_NetworkServer, + &CLSID_NetworkShare, + &CLSID_MyComputer, + &CLSID_Internet, + &CLSID_ShellFSFolder, + &CLSID_RecycleBin, + &CLSID_ControlPanel, + &CLSID_Printers, + &CLSID_MyDocuments, + NULL +}; + +DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x0A); + +static void test_ClassIDs(void) +{ + const GUID **guids = TEST_guids; + char szBuff[256]; + GUID guid; + DWORD dwLen; + BOOL bRet; + int i = 0; + + if (!pSHLWAPI_269 || !pSHLWAPI_23) + return; + + while (*guids) + { + dwLen = pSHLWAPI_23(*guids, szBuff, 256); + ok(dwLen == 39, "wrong size for id %d\n", i); + + bRet = pSHLWAPI_269(szBuff, &guid); + ok(bRet != FALSE, "created invalid string '%s'\n", szBuff); + + if (bRet) + ok(IsEqualGUID(*guids, &guid), "GUID created wrong %d\n", i); + + guids++; + i++; + } + + /* Test endianess */ + dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 256); + ok(dwLen == 39, "wrong size for IID_Endianess\n"); + + ok(!strcmp(szBuff, "{01020304-0506-0708-090A-0B0C0D0E0F0A}"), + "Endianess Broken, got '%s'\n", szBuff); + + /* test lengths */ + szBuff[0] = ':'; + dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 0); + ok(dwLen == 0, "accepted bad length\n"); + ok(szBuff[0] == ':', "wrote to buffer with no length\n"); + + szBuff[0] = ':'; + dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 38); + ok(dwLen == 0, "accepted bad length\n"); + ok(szBuff[0] == ':', "wrote to buffer with no length\n"); + + szBuff[0] = ':'; + dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 39); + ok(dwLen == 39, "rejected ok length\n"); + ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n"); + + /* Test string */ + strcpy(szBuff, "{xxx-"); + bRet = pSHLWAPI_269(szBuff, &guid); + ok(bRet == FALSE, "accepted invalid string\n"); + + dwLen = pSHLWAPI_23(&IID_Endianess, szBuff, 39); + ok(dwLen == 39, "rejected ok length\n"); + ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n"); +} + + +START_TEST(clsid) +{ + hShlwapi = LoadLibraryA("shlwapi.dll"); + ok(hShlwapi != 0, "LoadLibraryA failed\n"); + if (hShlwapi) + { + pSHLWAPI_269 = (void*)GetProcAddress(hShlwapi, (LPSTR)269); + pSHLWAPI_23 = (void*)GetProcAddress(hShlwapi, (LPSTR)23); + } + + test_ClassIDs(); + + if (hShlwapi) + FreeLibrary(hShlwapi); +} Property changes on: trunk/reactos/regtests/winetests/shlwapi/clsid.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/shlwapi/generated.c --- trunk/reactos/regtests/winetests/shlwapi/generated.c 2005-08-06 23:41:45 UTC (rev 17125) +++ trunk/reactos/regtests/winetests/shlwapi/generated.c 2005-08-06 23:58:36 UTC (rev 17126) @@ -0,0 +1,186 @@ +/* File generated automatically from tools/winapi/test.dat; do not edit! */ +/* This file can be copied, modified and distributed without restriction. */ + +/* + * Unit tests for data structure packing + */ + +#define WINVER 0x0501 +#define _WIN32_IE 0x0501 +#define _WIN32_WINNT 0x0501 + +#define WINE_NOWINSOCK + +#include <stdarg.h> +#include "windef.h" +#include "winbase.h" +#include "wtypes.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "wine/test.h" + +/********************************************************************** * + * Compability macros + */ + +#define DWORD_PTR UINT_PTR +#define LONG_PTR INT_PTR +#define ULONG_PTR UINT_PTR + +/********************************************************************** * + * Windows API extension + */ + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus) +# define FIELD_ALIGNMENT(type, field) __alignof(((type*)0)->field) +#elif defined(__GNUC__) +# define FIELD_ALIGNMENT(type, field) __alignof__(((type*)0)->field) +#else +/* FIXME: Not sure if is possible to do without compiler extension */ +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus) +# define _TYPE_ALIGNMENT(type) __alignof(type) +#elif defined(__GNUC__) +# define _TYPE_ALIGNMENT(type) __alignof__(type) +#else +/* + * FIXME: Not sure if is possible to do without compiler extension + * (if type is not just a name that is, if so the normal) + * TYPE_ALIGNMENT can be used) + */ +#endif + +#if defined(TYPE_ALIGNMENT) && defined(_MSC_VER) && _MSC_VER >= 800 && !defined(__cplusplus) +#pragma warning(disable:4116) +#endif + +#if !defined(TYPE_ALIGNMENT) && defined(_TYPE_ALIGNMENT) +# define TYPE_ALIGNMENT _TYPE_ALIGNMENT +#endif + +/********************************************************************** * + * Test helper macros + */ + +#ifdef FIELD_ALIGNMENT +# define TEST_FIELD_ALIGNMENT(type, field, align) \ + ok(FIELD_ALIGNMENT(type, field) == align, \ + "FIELD_ALIGNMENT(" #type ", " #field ") == %d (expected " #align ")\n", \ + (int)FIELD_ALIGNMENT(type, field)) +#else +# define TEST_FIELD_ALIGNMENT(type, field, align) do { } while (0) +#endif + +#define TEST_FIELD_OFFSET(type, field, offset) \ + ok(FIELD_OFFSET(type, field) == offset, \ + "FIELD_OFFSET(" #type ", " #field ") == %ld (expected " #offset ")\n", \ + (long int)FIELD_OFFSET(type, field)) + +#ifdef _TYPE_ALIGNMENT +#define TEST__TYPE_ALIGNMENT(type, align) \ + ok(_TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)_TYPE_ALIGNMENT(type)) +#else +# define TEST__TYPE_ALIGNMENT(type, align) do { } while (0) +#endif + +#ifdef TYPE_ALIGNMENT +#define TEST_TYPE_ALIGNMENT(type, align) \ + ok(TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)TYPE_ALIGNMENT(type)) +#else +# define TEST_TYPE_ALIGNMENT(type, align) do { } while (0) +#endif + +#define TEST_TYPE_SIZE(type, size) \ + ok(sizeof(type) == size, "sizeof(" #type ") == %d (expected " #size ")\n", ((int) sizeof(type))) + +/********************************************************************** * + * Test macros + */ + +#define TEST_FIELD(type, field_type, field_name, field_offset, field_size, field_align) \ + TEST_TYPE_SIZE(field_type, field_size); \ + TEST_FIELD_ALIGNMENT(type, field_name, field_align); \ + TEST_FIELD_OFFSET(type, field_name, field_offset); \ + +#define TEST_TYPE(type, size, align) \ + TEST_TYPE_ALIGNMENT(type, align); \ + TEST_TYPE_SIZE(type, size) + +#define TEST_TYPE_POINTER(type, size, align) \ + TEST__TYPE_ALIGNMENT(*(type)0, align); \ + TEST_TYPE_SIZE(*(type)0, size) + +#define TEST_TYPE_SIGNED(type) \ + ok((type) -1 < 0, "(" #type ") -1 < 0\n"); + +#define TEST_TYPE_UNSIGNED(type) \ + ok((type) -1 > 0, "(" #type ") -1 > 0\n"); + +static void test_pack_ASSOCF(void) +{ + /* ASSOCF */ + TEST_TYPE(ASSOCF, 4, 4); + TEST_TYPE_UNSIGNED(ASSOCF); +} + +static void test_pack_DLLGETVERSIONPROC(void) +{ + /* DLLGETVERSIONPROC */ + TEST_TYPE(DLLGETVERSIONPROC, 4, 4); +} + +static void test_pack_DLLVERSIONINFO(void) +{ + /* DLLVERSIONINFO (pack 8) */ + TEST_TYPE(DLLVERSIONINFO, 20, 4); + TEST_FIELD(DLLVERSIONINFO, DWORD, cbSize, 0, 4, 4); + TEST_FIELD(DLLVERSIONINFO, DWORD, dwMajorVersion, 4, 4, 4); + TEST_FIELD(DLLVERSIONINFO, DWORD, dwMinorVersion, 8, 4, 4); + TEST_FIELD(DLLVERSIONINFO, DWORD, dwBuildNumber, 12, 4, 4); + TEST_FIELD(DLLVERSIONINFO, DWORD, dwPlatformID, 16, 4, 4); +} + +static void test_pack_DLLVERSIONINFO2(void) [truncated at 1000 lines; 2370 more skipped]
19 years, 4 months
1
0
0
0
[sedwards] 17125: added user32 wine regression test
by sedwards@svn.reactos.com
added user32 wine regression test Added: trunk/reactos/regtests/winetests/user32/ Added: trunk/reactos/regtests/winetests/user32/class.c Added: trunk/reactos/regtests/winetests/user32/clipboard.c Added: trunk/reactos/regtests/winetests/user32/dce.c Added: trunk/reactos/regtests/winetests/user32/dde.c Added: trunk/reactos/regtests/winetests/user32/dialog.c Added: trunk/reactos/regtests/winetests/user32/edit.c Added: trunk/reactos/regtests/winetests/user32/input.c Added: trunk/reactos/regtests/winetests/user32/listbox.c Added: trunk/reactos/regtests/winetests/user32/menu.c Added: trunk/reactos/regtests/winetests/user32/msg.c Added: trunk/reactos/regtests/winetests/user32/resource.c Added: trunk/reactos/regtests/winetests/user32/resource.rc Added: trunk/reactos/regtests/winetests/user32/sysparams.c Added: trunk/reactos/regtests/winetests/user32/testlist.c Added: trunk/reactos/regtests/winetests/user32/text.c Added: trunk/reactos/regtests/winetests/user32/user32_test.xml Added: trunk/reactos/regtests/winetests/user32/win.c Added: trunk/reactos/regtests/winetests/user32/winstation.c Added: trunk/reactos/regtests/winetests/user32/wsprintf.c _____ Added: trunk/reactos/regtests/winetests/user32/class.c --- trunk/reactos/regtests/winetests/user32/class.c 2005-08-06 23:20:14 UTC (rev 17124) +++ trunk/reactos/regtests/winetests/user32/class.c 2005-08-06 23:41:45 UTC (rev 17125) @@ -0,0 +1,613 @@ +/* Unit test suite for window classes. + * + * Copyright 2002 Mike McCormack + * Copyright 2003 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* To get CS_DROPSHADOW with the MSVC headers */ +#define _WIN32_WINNT 0x0501 + +#include <assert.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "winuser.h" + +#define NUMCLASSWORDS 4 + +static LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProcW (hWnd, msg, wParam, lParam); +} + +/********************************************************************** * + */ +static void ClassTest(HINSTANCE hInstance, BOOL global) +{ + WNDCLASSW cls, wc; + static const WCHAR className[] = {'T','e','s','t','C','l','a','s','s',0}; + static const WCHAR winName[] = {'W','i','n','C','l','a','s','s','T','e','s','t',0}; + ATOM test_atom; + HWND hTestWnd; + LONG i; + WCHAR str[20]; + ATOM classatom; + + cls.style = CS_HREDRAW | CS_VREDRAW | (global?CS_GLOBALCLASS:0); + cls.lpfnWndProc = ClassTest_WndProc; + cls.cbClsExtra = NUMCLASSWORDS*sizeof(DWORD); + cls.cbWndExtra = 12; + cls.hInstance = hInstance; + cls.hIcon = LoadIconW (0, (LPWSTR)IDI_APPLICATION); + cls.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject (WHITE_BRUSH); + cls.lpszMenuName = 0; + cls.lpszClassName = className; + + classatom=RegisterClassW(&cls); + if (!classatom && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) + return; + ok(classatom, "failed to register class\n"); + + ok(!RegisterClassW (&cls), + "RegisterClass of the same class should fail for the second time\n"); + + /* Setup windows */ + hTestWnd = CreateWindowW (className, winName, + WS_OVERLAPPEDWINDOW + WS_HSCROLL + WS_VSCROLL, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, + 0, hInstance, 0); + + ok(hTestWnd!=0, "Failed to create window\n"); + + /* test initial values of valid classwords */ + for(i=0; i<NUMCLASSWORDS; i++) + { + SetLastError(0); + ok(!GetClassLongW(hTestWnd,i*sizeof (DWORD)), + "GetClassLongW initial value nonzero!\n"); + ok(!GetLastError(), + "GetClassLongW failed!\n"); + } + +#if 0 + /* + * GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD)) + * does not fail on Win 98, though MSDN says it should + */ + SetLastError(0); + GetClassLongW(hTestWnd, NUMCLASSWORDS*sizeof(DWORD)); + ok(GetLastError(), + "GetClassLongW() with invalid offset did not fail\n"); +#endif + + /* set values of valid class words */ + for(i=0; i<NUMCLASSWORDS; i++) + { + SetLastError(0); + ok(!SetClassLongW(hTestWnd,i*sizeof(DWORD),i+1), + "GetClassLongW(%ld) initial value nonzero!\n",i*sizeof(DWORD)); + ok(!GetLastError(), + "SetClassLongW(%ld) failed!\n",i*sizeof(DWORD)); + } + + /* test values of valid classwords that we set */ + for(i=0; i<NUMCLASSWORDS; i++) + { + SetLastError(0); + ok( (i+1) == GetClassLongW(hTestWnd,i*sizeof (DWORD)), + "GetClassLongW value doesn't match what was set!\n"); + ok(!GetLastError(), + "GetClassLongW failed!\n"); + } + + /* check GetClassName */ + i = GetClassNameW(hTestWnd, str, sizeof(str)); + ok(i == lstrlenW(className), + "GetClassName returned incorrect length\n"); + ok(!lstrcmpW(className,str), + "GetClassName returned incorrect name for this window's class\n"); + + /* check GetClassInfo with our hInstance */ + if((test_atom = GetClassInfoW(hInstance, str, &wc))) + { + ok(test_atom == classatom, + "class atom did not match\n"); + ok(wc.cbClsExtra == cls.cbClsExtra, + "cbClsExtra did not match\n"); + ok(wc.cbWndExtra == cls.cbWndExtra, + "cbWndExtra did not match\n"); + ok(wc.hbrBackground == cls.hbrBackground, + "hbrBackground did not match\n"); + ok(wc.hCursor== cls.hCursor, + "hCursor did not match\n"); + ok(wc.hInstance== cls.hInstance, + "hInstance did not match\n"); + } + else + ok(FALSE,"GetClassInfo (hinstance) failed!\n"); + + /* check GetClassInfo with zero hInstance */ + if(global) + { + if((test_atom = GetClassInfoW(0, str, &wc))) + { + ok(test_atom == classatom, + "class atom did not match %x != %x\n", test_atom, classatom); + ok(wc.cbClsExtra == cls.cbClsExtra, + "cbClsExtra did not match %x!=%x\n",wc.cbClsExtra,cls.cbClsExtra); + ok(wc.cbWndExtra == cls.cbWndExtra, + "cbWndExtra did not match %x!=%x\n",wc.cbWndExtra,cls.cbWndExtra); + ok(wc.hbrBackground == cls.hbrBackground, + "hbrBackground did not match %p!=%p\n",wc.hbrBackground,cls.hbrBackground); + ok(wc.hCursor== cls.hCursor, + "hCursor did not match %p!=%p\n",wc.hCursor,cls.hCursor); + ok(!wc.hInstance, + "hInstance not zero for global class %p\n",wc.hInstance); + } + else + ok(FALSE,"GetClassInfo (0) failed for global class!\n"); + } + else + { + ok(!GetClassInfoW(0, str, &wc), + "GetClassInfo (0) succeeded for local class!\n"); + } + + ok(!UnregisterClassW(className, hInstance), + "Unregister class succeeded with window existing\n"); + + ok(DestroyWindow(hTestWnd), + "DestroyWindow() failed!\n"); + + ok(UnregisterClassW(className, hInstance), + "UnregisterClass() failed\n"); + + return; +} + +static void check_style( const char *name, int must_exist, UINT style, UINT ignore ) +{ + WNDCLASS wc; + + if (GetClassInfo( 0, name, &wc )) + { + ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n", + name, ~wc.style & style, wc.style, style ); + ok( !(wc.style & ~style), "System class %s has extra bits %x (%08x/%08x)\n", + name, wc.style & ~style, wc.style, style ); + } + else + ok( !must_exist, "System class %s does not exist\n", name ); +} + +/* test styles of system classes */ +static void test_styles(void) +{ + /* check style bits */ + check_style( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 ); + check_style( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 ); + check_style( "Edit", 1, CS_PARENTDC | CS_DBLCLKS, 0 ); + check_style( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS, CS_PARENTDC /*FIXME*/ ); + check_style( "MDIClient", 1, 0, 0 ); + check_style( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, 0 ); + check_style( "Static", 1, CS_PARENTDC | CS_DBLCLKS, 0 ); + check_style( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS, 0 ); + check_style( "DDEMLEvent", 0, 0, 0 ); + check_style( "Message", 0, 0, 0 ); + check_style( "#32768", 1, CS_DROPSHADOW | CS_SAVEBITS | CS_DBLCLKS, CS_DROPSHADOW ); /* menu */ + check_style( "#32769", 1, CS_DBLCLKS, 0 ); /* desktop */ + check_style( "#32770", 1, CS_SAVEBITS | CS_DBLCLKS, 0 ); /* dialog */ + todo_wine { check_style( "#32771", 1, CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW, 0 ); } /* task switch */ + check_style( "#32772", 1, 0, 0 ); /* icon title */ +} + +static void check_class(HINSTANCE inst, const char *name, const char *menu_name) +{ + WNDCLASS wc; + UINT atom = GetClassInfo(inst,name,&wc); + ok( atom, "Class %s %p not found\n", name, inst ); + if (atom) + { + if (wc.lpszMenuName && menu_name) + ok( !strcmp( menu_name, wc.lpszMenuName ), "Wrong name %s/%s for class %s %p\n", + wc.lpszMenuName, menu_name, name, inst ); + else + ok( !menu_name == !wc.lpszMenuName, "Wrong name %p/%p for class %s %p\n", + wc.lpszMenuName, menu_name, name, inst ); + } +} + +static void check_instance( const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst ) +{ + WNDCLASSA wc; + HWND hwnd; + + ok( GetClassInfo( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst ); + ok( wc.hInstance == info_inst, "Wrong info instance %p/%p for class %s\n", + wc.hInstance, info_inst, name ); + hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 ); + ok( hwnd != NULL, "Couldn't create window for class %s inst %p\n", name, inst ); + ok( (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ) == gcl_inst, + "Wrong GCL instance %p/%p for class %s\n", + (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ), gcl_inst, name ); + ok( (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ) == inst, + "Wrong GWL instance %p/%p for window %s\n", + (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), inst, name ); + ok(!UnregisterClassA(name, inst), "UnregisterClassA should fail while exists a class window\n"); + ok(GetLastError() == ERROR_CLASS_HAS_WINDOWS, "GetLastError() should be set to ERROR_CLASS_HAS_WINDOWS not %ld\n", GetLastError()); + DestroyWindow(hwnd); +} + +struct class_info +{ + const char *name; + HINSTANCE inst, info_inst, gcl_inst; +}; + +static DWORD WINAPI thread_proc(void *param) +{ + struct class_info *class_info = (struct class_info *)param; + + check_instance(class_info->name, class_info->inst, class_info->info_inst, class_info->gcl_inst); + + return 0; +} + +static void check_thread_instance( const char *name, HINSTANCE inst, HINSTANCE info_inst, HINSTANCE gcl_inst ) +{ + HANDLE hThread; + DWORD tid; + struct class_info class_info; + + class_info.name = name; + class_info.inst = inst; + class_info.info_inst = info_inst; + class_info.gcl_inst = gcl_inst; + + hThread = CreateThread(NULL, 0, thread_proc, &class_info, 0, &tid); + ok(hThread != NULL, "CreateThread failed, error %ld\n", GetLastError()); + ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); + CloseHandle(hThread); +} + +/* test various instance parameters */ +static void test_instances(void) +{ + WNDCLASSA cls, wc; + HWND hwnd, hwnd2; + const char *name = "__test__"; + HINSTANCE kernel32 = GetModuleHandleA("kernel32"); + HINSTANCE user32 = GetModuleHandleA("user32"); + HINSTANCE main_module = GetModuleHandleA(NULL); + + memset( &cls, 0, sizeof(cls) ); + cls.style = CS_HREDRAW | CS_VREDRAW; + cls.lpfnWndProc = ClassTest_WndProc; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.lpszClassName = name; + + cls.lpszMenuName = "main_module"; + cls.hInstance = main_module; + + ok( RegisterClassA( &cls ), "Failed to register local class for main module\n" ); + check_class( main_module, name, "main_module" ); + check_instance( name, main_module, main_module, main_module ); + check_thread_instance( name, main_module, main_module, main_module ); + + cls.lpszMenuName = "kernel32"; + cls.hInstance = kernel32; + ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); + check_class( kernel32, name, "kernel32" ); + check_class( main_module, name, "main_module" ); + check_instance( name, kernel32, kernel32, kernel32 ); + check_thread_instance( name, kernel32, kernel32, kernel32 ); + ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); + + /* Bug 2631 - Supplying an invalid number of bytes fails */ + cls.cbClsExtra = 0; + cls.cbWndExtra = -1; + SetLastError(0xdeadbeef); + ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)), + "Failed with invalid number of WndExtra bytes\n"); + + cls.cbClsExtra = -1; + cls.cbWndExtra = 0; + SetLastError(0xdeadbeef); + ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)), + "Failed with invalid number of ClsExtra bytes\n"); + + cls.cbClsExtra = -1; + cls.cbWndExtra = -1; + SetLastError(0xdeadbeef); + ok( ((RegisterClassA( &cls ) == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)), + "Failed with invalid number of ClsExtra and cbWndExtra bytes\n"); + + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + SetLastError(0xdeadbeef); + + /* setting global flag doesn't change status of class */ + hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 ); + SetClassLongA( hwnd, GCL_STYLE, CS_GLOBALCLASS ); + cls.lpszMenuName = "kernel32"; + cls.hInstance = kernel32; + ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); + check_class( kernel32, name, "kernel32" ); + check_class( main_module, name, "main_module" ); + check_instance( name, kernel32, kernel32, kernel32 ); + check_instance( name, main_module, main_module, main_module ); + check_thread_instance( name, kernel32, kernel32, kernel32 ); + check_thread_instance( name, main_module, main_module, main_module ); + ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); + + /* changing the instance doesn't make it global */ + SetClassLongA( hwnd, GCL_HMODULE, 0 ); + ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); + check_class( kernel32, name, "kernel32" ); + check_instance( name, kernel32, kernel32, kernel32 ); + check_thread_instance( name, kernel32, kernel32, kernel32 ); + ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); + + /* GetClassInfo with instance 0 finds user32 instance */ + SetClassLongA( hwnd, GCL_HMODULE, (LONG)user32 ); + ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); + check_class( kernel32, name, "kernel32" ); + check_class( user32, name, "main_module" ); + check_class( 0, name, "main_module" ); + check_instance( name, kernel32, kernel32, kernel32 ); + check_instance( name, user32, 0, user32 ); + check_instance( name, 0, 0, kernel32 ); + check_thread_instance( name, kernel32, kernel32, kernel32 ); + check_thread_instance( name, user32, 0, user32 ); + check_thread_instance( name, 0, 0, kernel32 ); + ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); + + SetClassLongA( hwnd, GCL_HMODULE, 0x12345678 ); + ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); + check_class( kernel32, name, "kernel32" ); + check_class( (HINSTANCE)0x12345678, name, "main_module" ); + check_instance( name, kernel32, kernel32, kernel32 ); + check_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 ); + check_thread_instance( name, kernel32, kernel32, kernel32 ); + check_thread_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 ); + ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + + /* creating a window with instance 0 uses the first class found */ + cls.hInstance = (HINSTANCE)0xdeadbeef; + cls.lpszMenuName = "deadbeef"; + cls.style = 3; + ok( RegisterClassA( &cls ), "Failed to register local class for deadbeef\n" ); + hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); + ok( (HINSTANCE)GetClassLong( hwnd2, GCL_HMODULE ) == (HINSTANCE)0xdeadbeef, + "Didn't get deadbeef class for null instance\n" ); + DestroyWindow( hwnd2 ); + ok( UnregisterClassA( name, (HINSTANCE)0xdeadbeef ), "Unregister failed for deadbeef\n" ); + + hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); + ok( (HINSTANCE)GetClassLong( hwnd2, GCL_HMODULE ) == kernel32, + "Didn't get kernel32 class for null instance\n" ); + DestroyWindow( hwnd2 ); + + ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); + + hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); + ok( GetClassLong( hwnd2, GCL_HMODULE ) == 0x12345678, + "Didn't get 12345678 class for null instance\n" ); + DestroyWindow( hwnd2 ); + + SetClassLongA( hwnd, GCL_HMODULE, (LONG)main_module ); + DestroyWindow( hwnd ); + + /* null handle means the same thing as main module */ + cls.lpszMenuName = "null"; + cls.hInstance = 0; + ok( !RegisterClassA( &cls ), "Succeeded registering local class for null instance\n" ); + ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %ld\n", GetLastError() ); + ok( UnregisterClassA( name, main_module ), "Unregister failed for main module\n" ); + + ok( RegisterClassA( &cls ), "Failed to register local class for null instance\n" ); + /* must be found with main module handle */ + check_class( main_module, name, "null" ); + check_instance( name, main_module, main_module, main_module ); + check_thread_instance( name, main_module, main_module, main_module ); + ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %ld\n", GetLastError() ); + ok( UnregisterClassA( name, 0 ), "Unregister failed for null instance\n" ); + + /* registering for user32 always fails */ + cls.lpszMenuName = "user32"; + cls.hInstance = user32; + ok( !RegisterClassA( &cls ), "Succeeded registering local class for user32\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %ld\n", GetLastError() ); + cls.style |= CS_GLOBALCLASS; + ok( !RegisterClassA( &cls ), "Succeeded registering global class for user32\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error code %ld\n", GetLastError() ); + + /* unregister is OK though */ + cls.hInstance = main_module; + ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" ); + ok( UnregisterClassA( name, user32 ), "Unregister failed for user32\n" ); + + /* instance doesn't matter for global class */ + cls.style |= CS_GLOBALCLASS; + cls.lpszMenuName = "main_module"; + cls.hInstance = main_module; + ok( RegisterClassA( &cls ), "Failed to register global class for main module\n" ); + cls.lpszMenuName = "kernel32"; + cls.hInstance = kernel32; + ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" ); + ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %ld\n", GetLastError() ); + /* even if global flag is cleared */ + hwnd = CreateWindowExA( 0, name, "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 ); + SetClassLongA( hwnd, GCL_STYLE, 0 ); + ok( !RegisterClassA( &cls ), "Succeeded registering local class for kernel32\n" ); + ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %ld\n", GetLastError() ); + + check_class( main_module, name, "main_module" ); + check_class( kernel32, name, "main_module" ); + check_class( 0, name, "main_module" ); + check_class( (HINSTANCE)0x12345678, name, "main_module" ); + check_instance( name, main_module, main_module, main_module ); + check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module ); + check_thread_instance( name, main_module, main_module, main_module ); + check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module ); + + /* changing the instance for global class doesn't make much difference */ + SetClassLongA( hwnd, GCL_HMODULE, 0xdeadbeef ); + check_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef ); + check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef ); + check_thread_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef ); + check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef ); + + DestroyWindow( hwnd ); + ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" ); + ok( !UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister succeeded the second time\n" ); + ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %ld\n", GetLastError() ); + + cls.hInstance = (HINSTANCE)0x12345678; + ok( RegisterClassA( &cls ), "Failed to register global class for dummy instance\n" ); + check_instance( name, main_module, main_module, (HINSTANCE)0x12345678 ); + check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 ); + check_thread_instance( name, main_module, main_module, (HINSTANCE)0x12345678 ); + check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0x12345678 ); + ok( UnregisterClassA( name, (HINSTANCE)0x87654321 ), "Unregister failed for main module global\n" ); + + /* check system classes */ + + /* we cannot register a global class with the name of a system class */ + cls.style |= CS_GLOBALCLASS; + cls.lpszMenuName = "button_main_module"; + cls.lpszClassName = "BUTTON"; + cls.hInstance = main_module; + ok( !RegisterClassA( &cls ), "Succeeded registering global button class for main module\n" ); + ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %ld\n", GetLastError() ); + cls.hInstance = kernel32; + ok( !RegisterClassA( &cls ), "Succeeded registering global button class for kernel32\n" ); + ok( GetLastError() == ERROR_CLASS_ALREADY_EXISTS, "Wrong error code %ld\n", GetLastError() ); + + /* local class is OK however */ + cls.style &= ~CS_GLOBALCLASS; + cls.lpszMenuName = "button_main_module"; + cls.hInstance = main_module; + ok( RegisterClassA( &cls ), "Failed to register local button class for main module\n" ); + check_class( main_module, "BUTTON", "button_main_module" ); + cls.lpszMenuName = "button_kernel32"; + cls.hInstance = kernel32; + ok( RegisterClassA( &cls ), "Failed to register local button class for kernel32\n" ); + check_class( kernel32, "BUTTON", "button_kernel32" ); + check_class( main_module, "BUTTON", "button_main_module" ); + ok( UnregisterClassA( "BUTTON", kernel32 ), "Unregister failed for kernel32 button\n" ); + ok( UnregisterClassA( "BUTTON", main_module ), "Unregister failed for main module button\n" ); + /* GetClassInfo sets instance to passed value for global classes */ + check_instance( "BUTTON", 0, 0, user32 ); + check_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); + check_instance( "BUTTON", user32, 0, user32 ); + check_thread_instance( "BUTTON", 0, 0, user32 ); + check_thread_instance( "BUTTON", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); + check_thread_instance( "BUTTON", user32, 0, user32 ); + + /* we can unregister system classes */ + ok( GetClassInfo( 0, "BUTTON", &wc ), "Button class not found with null instance\n" ); + ok( GetClassInfo( kernel32, "BUTTON", &wc ), "Button class not found with kernel32\n" ); + ok( UnregisterClass( "BUTTON", (HINSTANCE)0x12345678 ), "Failed to unregister button\n" ); + ok( !UnregisterClass( "BUTTON", (HINSTANCE)0x87654321 ), "Unregistered button a second time\n" ); + ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %ld\n", GetLastError() ); + ok( !GetClassInfo( 0, "BUTTON", &wc ), "Button still exists\n" ); + ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %ld\n", GetLastError() ); + + /* we can change the instance of a system class */ + check_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); + check_thread_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); + hwnd = CreateWindowExA( 0, "EDIT", "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 ); + SetClassLongA( hwnd, GCL_HMODULE, 0xdeadbeef ); + check_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef ); + check_thread_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef ); +} + +static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +static BOOL RegisterTestDialog(HINSTANCE hInstance) +{ + WNDCLASSEX wcx; + ATOM atom = 0; + + ZeroMemory(&wcx, sizeof(WNDCLASSEX)); + wcx.cbSize = sizeof(wcx); + wcx.lpfnWndProc = TestDlgProc; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = DLGWINDOWEXTRA; + wcx.hInstance = hInstance; + wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wcx.hCursor = LoadCursor(NULL, IDC_ARROW); + wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wcx.lpszClassName = "TestDialog"; + wcx.lpszMenuName = "TestDialog"; + wcx.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(5), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + + atom = RegisterClassEx(&wcx); + ok(atom != 0, "RegisterClassEx returned 0\n"); + + return atom; +} + +/* test registering a dialog box created by using the CLASS directive in a + resource file, then test creating the dialog using CreateDialogParam. */ +static void WINAPI CreateDialogParamTest(HINSTANCE hInstance) +{ + HWND hWndMain; + + if (RegisterTestDialog(hInstance)) + { + hWndMain = CreateDialogParam(hInstance, "CLASS_TEST_DIALOG", NULL, 0, 0); + ok(hWndMain != NULL, "CreateDialogParam returned NULL\n"); + ShowWindow(hWndMain, SW_SHOW); + DestroyWindow(hWndMain); + } +} + +START_TEST(class) +{ + HANDLE hInstance = GetModuleHandleA( NULL ); + + if (!GetModuleHandleW(0)) + { + trace("Class test is incompatible with Win9x implementation, skipping\n"); + return; + } + + ClassTest(hInstance,FALSE); + ClassTest(hInstance,TRUE); + CreateDialogParamTest(hInstance); + test_styles(); + test_instances(); +} Property changes on: trunk/reactos/regtests/winetests/user32/class.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/user32/clipboard.c --- trunk/reactos/regtests/winetests/user32/clipboard.c 2005-08-06 23:20:14 UTC (rev 17124) +++ trunk/reactos/regtests/winetests/user32/clipboard.c 2005-08-06 23:41:45 UTC (rev 17125) @@ -0,0 +1,198 @@ +/* + * Unit test suite for clipboard functions. + * + * Copyright 2002 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "wine/test.h" +#include "winbase.h" +#include "winerror.h" +#include "winuser.h" + +static BOOL is_win9x = FALSE; + +#define test_last_error(expected_error) \ + do \ + { \ + if (!is_win9x) \ + ok(GetLastError() == expected_error, \ + "Last error should be set to %d, not %ld\n", \ + expected_error, GetLastError()); \ + } while (0) + +static void test_ClipboardOwner(void) +{ + HWND hWnd1, hWnd2; + BOOL ret; + + SetLastError(0xdeadbeef); + ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, + "could not perform clipboard test: clipboard already owned\n"); + + hWnd1 = CreateWindowExA(0, "static", NULL, WS_POPUP, + 0, 0, 10, 10, 0, 0, 0, NULL); + ok(hWnd1 != 0, "CreateWindowExA error %ld\n", GetLastError()); + trace("hWnd1 = %p\n", hWnd1); + + hWnd2 = CreateWindowExA(0, "static", NULL, WS_POPUP, + 0, 0, 10, 10, 0, 0, 0, NULL); + ok(hWnd2 != 0, "CreateWindowExA error %ld\n", GetLastError()); + trace("hWnd2 = %p\n", hWnd2); + + SetLastError(0xdeadbeef); + ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n"); + test_last_error(ERROR_CLIPBOARD_NOT_OPEN); + + ok(OpenClipboard(0), "OpenClipboard failed\n"); + ok(!GetClipboardOwner(), "clipboard should still be not owned\n"); + ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n"); + ret = CloseClipboard(); + ok( ret, "CloseClipboard error %ld\n", GetLastError()); + + ok(OpenClipboard(hWnd1), "OpenClipboard failed\n"); + + SetLastError(0xdeadbeef); + ok(!OpenClipboard(hWnd2) && GetLastError() == 0xdeadbeef, + "OpenClipboard should fail without setting last error value\n"); + + SetLastError(0xdeadbeef); + ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should still be not owned\n"); + ret = EmptyClipboard(); + ok( ret, "EmptyClipboard error %ld\n", GetLastError()); + ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner()); + + SetLastError(0xdeadbeef); + ok(!OpenClipboard(hWnd2) && GetLastError() == 0xdeadbeef, + "OpenClipboard should fail without setting last error value\n"); + + ret = CloseClipboard(); + ok( ret, "CloseClipboard error %ld\n", GetLastError()); + ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n"); + + ret = DestroyWindow(hWnd1); + ok( ret, "DestroyWindow error %ld\n", GetLastError()); + ret = DestroyWindow(hWnd2); + ok( ret, "DestroyWindow error %ld\n", GetLastError()); + SetLastError(0xdeadbeef); + ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n"); +} + +static void test_RegisterClipboardFormatA(void) +{ + ATOM atom_id; + UINT format_id, format_id2; + char buf[256]; + int len; + BOOL ret; + + format_id = RegisterClipboardFormatA("my_cool_clipboard_format"); + ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id); + + format_id2 = RegisterClipboardFormatA("MY_COOL_CLIPBOARD_FORMAT"); + ok(format_id2 == format_id, "invalid clipboard format id %04x\n", format_id2); + + len = GetClipboardFormatNameA(format_id, buf, 256); + ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len); + ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf); + + lstrcpyA(buf, "foo"); + SetLastError(0xdeadbeef); + len = GetAtomNameA((ATOM)format_id, buf, 256); + ok(len == 0, "GetAtomNameA should fail\n"); + test_last_error(ERROR_INVALID_HANDLE); + +todo_wine +{ + lstrcpyA(buf, "foo"); + SetLastError(0xdeadbeef); + len = GlobalGetAtomNameA((ATOM)format_id, buf, 256); + ok(len == 0, "GlobalGetAtomNameA should fail\n"); + test_last_error(ERROR_INVALID_HANDLE); +} + + SetLastError(0xdeadbeef); + atom_id = FindAtomA("my_cool_clipboard_format"); + ok(atom_id == 0, "FindAtomA should fail\n"); + test_last_error(ERROR_FILE_NOT_FOUND); + +#if 0 + /* this relies on the clipboard and global atom table being different */ + SetLastError(0xdeadbeef); + atom_id = GlobalFindAtomA("my_cool_clipboard_format"); + ok(atom_id == 0, "GlobalFindAtomA should fail\n"); + test_last_error(ERROR_FILE_NOT_FOUND); + + for (format_id = 0; format_id < 0xffff; format_id++) + { + SetLastError(0xdeadbeef); + len = GetClipboardFormatNameA(format_id, buf, 256); + + if (format_id < 0xc000) + { + ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf); + test_last_error(ERROR_INVALID_PARAMETER); + } + else + { + if (len) + trace("%04x: %s\n", format_id, len ? buf : ""); + else + test_last_error(ERROR_INVALID_HANDLE); + } + } +#endif + + ret = OpenClipboard(0); + ok( ret, "OpenClipboard error %ld\n", GetLastError()); + + trace("# of formats available: %d\n", CountClipboardFormats()); + + format_id = 0; + while ((format_id = EnumClipboardFormats(format_id))) + { + ok(IsClipboardFormatAvailable(format_id), "format %04x was listed as available\n", format_id); + len = GetClipboardFormatNameA(format_id, buf, 256); + trace("%04x: %s\n", format_id, len ? buf : ""); + } + + ret = EmptyClipboard(); + ok( ret, "EmptyClipboard error %ld\n", GetLastError()); + ret =CloseClipboard(); + ok( ret, "CloseClipboard error %ld\n", GetLastError()); + + if (CountClipboardFormats()) + { + SetLastError(0xdeadbeef); + ok(!EnumClipboardFormats(0), "EnumClipboardFormats should fail if clipboard wasn't open\n"); + ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, + "Last error should be set to ERROR_CLIPBOARD_NOT_OPEN, not %ld\n", GetLastError()); + } + + SetLastError(0xdeadbeef); + ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n"); + test_last_error(ERROR_CLIPBOARD_NOT_OPEN); +} + +START_TEST(clipboard) +{ + SetLastError(0xdeadbeef); + FindAtomW(NULL); + if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) is_win9x = TRUE; + + test_RegisterClipboardFormatA(); + test_ClipboardOwner(); +} Property changes on: trunk/reactos/regtests/winetests/user32/clipboard.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/user32/dce.c --- trunk/reactos/regtests/winetests/user32/dce.c 2005-08-06 23:20:14 UTC (rev 17124) +++ trunk/reactos/regtests/winetests/user32/dce.c 2005-08-06 23:41:45 UTC (rev 17125) @@ -0,0 +1,416 @@ +/* + * Unit tests for DCE support + * + * Copyright 2005 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include <assert.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" + +static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2; + +/* test behavior of DC attributes with various GetDC/ReleaseDC combinations */ +static void test_dc_attributes(void) +{ + HDC hdc, old_hdc; + INT rop, def_rop; + + /* test cache DC */ + + hdc = GetDC( hwnd_cache ); + def_rop = GetROP2( hdc ); + + SetROP2( hdc, R2_WHITE ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + + ReleaseDC( hwnd_cache, hdc ); + hdc = GetDC( hwnd_cache ); + rop = GetROP2( hdc ); + ok( rop == def_rop, "wrong ROP2 %d after release\n", rop ); + SetROP2( hdc, R2_WHITE ); + ReleaseDC( hwnd_cache, hdc ); + + hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS ); + rop = GetROP2( hdc ); + /* Win9x seems to silently ignore DCX_NORESETATTRS */ + ok( rop == def_rop || rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + + SetROP2( hdc, R2_WHITE ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + + ReleaseDC( hwnd_cache, hdc ); + hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS ); + rop = GetROP2( hdc ); + ok( rop == def_rop || rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); + ReleaseDC( hwnd_cache, hdc ); + + hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE ); + rop = GetROP2( hdc ); + ok( rop == def_rop, "wrong ROP2 %d after release\n", rop ); + ReleaseDC( hwnd_cache, hdc ); + + /* test own DC */ + + hdc = GetDC( hwnd_owndc ); + SetROP2( hdc, R2_WHITE ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + + old_hdc = hdc; + ReleaseDC( hwnd_owndc, hdc ); + hdc = GetDC( hwnd_owndc ); + ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); + ReleaseDC( hwnd_owndc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop ); + + /* test class DC */ + + hdc = GetDC( hwnd_classdc ); + SetROP2( hdc, R2_WHITE ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + + old_hdc = hdc; + ReleaseDC( hwnd_classdc, hdc ); + hdc = GetDC( hwnd_classdc ); + ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); + ReleaseDC( hwnd_classdc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop ); + + /* test class DC with 2 windows */ + + old_hdc = GetDC( hwnd_classdc ); + SetROP2( old_hdc, R2_BLACK ); + hdc = GetDC( hwnd_classdc2 ); + ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_BLACK, "wrong ROP2 %d for other window\n", rop ); + ReleaseDC( hwnd_classdc, old_hdc ); + ReleaseDC( hwnd_classdc, hdc ); + rop = GetROP2( hdc ); + ok( rop == R2_BLACK, "wrong ROP2 %d after release\n", rop ); +} + + +/* test behavior with various invalid parameters */ +static void test_parameters(void) +{ + HDC hdc; + + hdc = GetDC( hwnd_cache ); + ok( ReleaseDC( hwnd_owndc, hdc ), "ReleaseDC with wrong window should succeed\n" ); + + hdc = GetDC( hwnd_cache ); + ok( !ReleaseDC( hwnd_cache, 0 ), "ReleaseDC with wrong HDC should fail\n" ); + ok( ReleaseDC( hwnd_cache, hdc ), "correct ReleaseDC should succeed\n" ); + ok( !ReleaseDC( hwnd_cache, hdc ), "second ReleaseDC should fail\n" ); + + hdc = GetDC( hwnd_owndc ); + ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" ); + hdc = GetDC( hwnd_owndc ); + ok( ReleaseDC( hwnd_owndc, hdc ), "correct ReleaseDC should succeed\n" ); + ok( ReleaseDC( hwnd_owndc, hdc ), "second ReleaseDC should succeed\n" ); + + hdc = GetDC( hwnd_classdc ); + ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" ); + hdc = GetDC( hwnd_classdc ); + ok( ReleaseDC( hwnd_classdc, hdc ), "correct ReleaseDC should succeed\n" ); + ok( ReleaseDC( hwnd_classdc, hdc ), "second ReleaseDC should succeed\n" ); +} + + +static void test_dc_visrgn(void) +{ + HDC old_hdc, hdc; + HRGN hrgn, hrgn2; + RECT rect; + + /* cache DC */ + + SetRect( &rect, 10, 10, 20, 20 ); + MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 ); + hrgn = CreateRectRgnIndirect( &rect ); [truncated at 1000 lines; 15438 more skipped]
19 years, 4 months
1
0
0
0
[sedwards] 17124: we don't need a .cvsignore
by sedwards@svn.reactos.com
we don't need a .cvsignore Deleted: trunk/reactos/regtests/winetests/gdi32/.cvsignore _____ Deleted: trunk/reactos/regtests/winetests/gdi32/.cvsignore --- trunk/reactos/regtests/winetests/gdi32/.cvsignore 2005-08-06 23:19:47 UTC (rev 17123) +++ trunk/reactos/regtests/winetests/gdi32/.cvsignore 2005-08-06 23:20:14 UTC (rev 17124) @@ -1,7 +0,0 @@ -Makefile -bitmap.ok -brush.ok -gdiobj.ok -generated.ok -metafile.ok -testlist.c
19 years, 4 months
1
0
0
0
[sedwards] 17123: added gdi32 wine regression tests
by sedwards@svn.reactos.com
added gdi32 wine regression tests Modified: trunk/reactos/regtests/winetests/directory.xml Added: trunk/reactos/regtests/winetests/gdi32/ Added: trunk/reactos/regtests/winetests/gdi32/.cvsignore Added: trunk/reactos/regtests/winetests/gdi32/bitmap.c Added: trunk/reactos/regtests/winetests/gdi32/brush.c Added: trunk/reactos/regtests/winetests/gdi32/gdi32_test.xml Added: trunk/reactos/regtests/winetests/gdi32/gdiobj.c Added: trunk/reactos/regtests/winetests/gdi32/metafile.c Added: trunk/reactos/regtests/winetests/gdi32/testlist.c _____ Modified: trunk/reactos/regtests/winetests/directory.xml --- trunk/reactos/regtests/winetests/directory.xml 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/directory.xml 2005-08-06 23:19:47 UTC (rev 17123) @@ -5,4 +5,16 @@ <directory name="comctl32"> <xi:include href="comctl32/comctl32_test.xml" /> </directory> +<directory name="gdi32"> + <xi:include href="gdi32/gdi32_test.xml" /> +</directory> +<directory name="msvcrt"> + <xi:include href="msvcrt/msvcrt_test.xml" /> +</directory> +<directory name="psapi"> + <xi:include href="psapi/psapi_test.xml" /> +</directory> +<directory name="version"> + <xi:include href="version/version_test.xml" /> +</directory> </group> _____ Added: trunk/reactos/regtests/winetests/gdi32/.cvsignore --- trunk/reactos/regtests/winetests/gdi32/.cvsignore 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/.cvsignore 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,7 @@ +Makefile +bitmap.ok +brush.ok +gdiobj.ok +generated.ok +metafile.ok +testlist.c Property changes on: trunk/reactos/regtests/winetests/gdi32/.cvsignore ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/gdi32/bitmap.c --- trunk/reactos/regtests/winetests/gdi32/bitmap.c 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/bitmap.c 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,459 @@ +/* + * Unit test suite for bitmaps + * + * Copyright 2004 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> +#include <assert.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "mmsystem.h" + +#include "wine/test.h" + +static BOOL is_win9x; + +static void test_createdibitmap(void) +{ + HDC hdc, hdcmem; + BITMAPINFOHEADER bmih; + BITMAP bm; + HBITMAP hbm, hbm_colour, hbm_old; + INT screen_depth; + + hdc = GetDC(0); + screen_depth = GetDeviceCaps(hdc, BITSPIXEL); + memset(&bmih, 0, sizeof(bmih)); + bmih.biSize = sizeof(bmih); + bmih.biWidth = 10; + bmih.biHeight = 10; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + + /* First create an un-initialised bitmap. The depth of the bitmap + should match that of the hdc and not that supplied in bmih. + */ + + /* First try 32 bits */ + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Now with a monochrome dc we expect a monochrome bitmap */ + hdcmem = CreateCompatibleDC(hdc); + + /* First try 32 bits */ + bmih.biBitCount = 32; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + + /* Now select a polychrome bitmap into the dc and we expect + screen_depth bitmaps again */ + hbm_colour = CreateCompatibleBitmap(hdc, 1, 1); + hbm_old = SelectObject(hdcmem, hbm_colour); + + /* First try 32 bits */ + bmih.biBitCount = 32; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 16 */ + bmih.biBitCount = 16; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + /* Then 1 */ + bmih.biBitCount = 1; + hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == screen_depth, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, screen_depth); + DeleteObject(hbm); + + SelectObject(hdcmem, hbm_old); + DeleteObject(hbm_colour); + DeleteDC(hdcmem); + + /* If hdc == 0 then we get a 1 bpp bitmap */ + if (!is_win9x) { + bmih.biBitCount = 32; + hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0); + ok(hbm != NULL, "CreateDIBitmap failed\n"); + ok(GetObject(hbm, sizeof(bm), &bm), "GetObject failed\n"); + + ok(bm.bmBitsPixel == 1, "CreateDIBitmap created bitmap of incorrect depth %d != %d\n", bm.bmBitsPixel, 1); + DeleteObject(hbm); + } + + ReleaseDC(0, hdc); +} + +#define test_color_todo(got, exp, txt, todo) \ + if (!todo && got != exp && screen_depth < 24) { \ + todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \ + screen_depth, (UINT)got, (UINT)exp); \ + return; \ + } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \ + else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \ + +#define test_color(hdc, color, exp, todo_setp, todo_getp) \ +{ \ + COLORREF c; \ + c = SetPixel(hdc, 0, 0, color); \ + if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \ + c = GetPixel(hdc, 0, 0); \ + test_color_todo(c, exp, GetPixel, todo_getp); \ +} + +static void test_dibsections(void) +{ + HDC hdc, hdcmem, hdcmem2; + HBITMAP hdib, oldbm, hdib2, oldbm2; + char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; + char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)]; + BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf; + BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf; + HBITMAP hcoredib; + char coreBits[256]; + BYTE *bits; + RGBQUAD rgb[256]; + int ret; + char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)]; + LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf; + WORD *index; + DWORD *bits32; + HPALETTE hpal, oldpal; + COLORREF c0, c1; + int i; + int screen_depth; + + hdc = GetDC(0); + screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES); + memset(pbmi, 0, sizeof(bmibuf)); + pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader); + pbmi->bmiHeader.biHeight = 16; + pbmi->bmiHeader.biWidth = 16; + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiColors[0].rgbRed = 0xff; + pbmi->bmiColors[0].rgbGreen = 0; + pbmi->bmiColors[0].rgbBlue = 0; + pbmi->bmiColors[1].rgbRed = 0; + pbmi->bmiColors[1].rgbGreen = 0; + pbmi->bmiColors[1].rgbBlue = 0xff; + + hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + + /* Test if the old BITMAPCOREINFO structure is supported */ + + pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); + pbci->bmciHeader.bcBitCount = 0; + + if (!is_win9x) { + ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS); + ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); + ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16) + && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1), + "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n"); + + ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS); + ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); + ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) && + (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) && + (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff), + "The color table has not been translated to the old BITMAPCOREINFO format\n"); + + hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n"); + + ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE)); + ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS); + ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n"); + ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) && + (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) && + (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff), + "The color table has not been translated to the old BITMAPCOREINFO format\n"); + + DeleteObject(hcoredib); + } + + hdcmem = CreateCompatibleDC(hdc); + oldbm = SelectObject(hdcmem, hdib); + + ret = GetDIBColorTable(hdcmem, 0, 2, rgb); + ok(ret == 2, "GetDIBColorTable returned %d\n", ret); + ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)), + "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", + rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, + rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); + + c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue); + c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue); + + test_color(hdcmem, DIBINDEX(0), c0, 0, 1); + test_color(hdcmem, DIBINDEX(1), c1, 0, 1); + test_color(hdcmem, DIBINDEX(2), c0, 1, 1); + test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1); + test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1); + test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1); + test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, + pbmi->bmiColors[0].rgbBlue), c0, 1, 1); + test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, + pbmi->bmiColors[1].rgbBlue), c1, 1, 1); + test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1); + test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1); + test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1); + + SelectObject(hdcmem, oldbm); + DeleteObject(hdib); + + pbmi->bmiHeader.biBitCount = 8; + + for (i = 0; i < 128; i++) { + pbmi->bmiColors[i].rgbRed = 255 - i * 2; + pbmi->bmiColors[i].rgbGreen = i * 2; + pbmi->bmiColors[i].rgbBlue = 0; + pbmi->bmiColors[255 - i].rgbRed = 0; + pbmi->bmiColors[255 - i].rgbGreen = i * 2; + pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2; + } + hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + oldbm = SelectObject(hdcmem, hdib); + + for (i = 0; i < 256; i++) { + test_color(hdcmem, DIBINDEX(i), + RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0); + test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), + RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0); + } + + SelectObject(hdcmem, oldbm); + DeleteObject(hdib); + + pbmi->bmiHeader.biBitCount = 1; + + /* Now create a palette and a palette indexed dib section */ + memset(plogpal, 0, sizeof(logpalbuf)); + plogpal->palVersion = 0x300; + plogpal->palNumEntries = 2; + plogpal->palPalEntry[0].peRed = 0xff; + plogpal->palPalEntry[0].peBlue = 0xff; + plogpal->palPalEntry[1].peGreen = 0xff; + + index = (WORD*)pbmi->bmiColors; + *index++ = 0; + *index = 1; + hpal = CreatePalette(plogpal); + ok(hpal != NULL, "CreatePalette failed\n"); + oldpal = SelectPalette(hdc, hpal, TRUE); + hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + + /* The colour table has already been grabbed from the dc, so we select back the + old palette */ + + SelectPalette(hdc, oldpal, TRUE); + oldbm = SelectObject(hdcmem, hdib); + oldpal = SelectPalette(hdcmem, hpal, TRUE); + + ret = GetDIBColorTable(hdcmem, 0, 2, rgb); + ok(ret == 2, "GetDIBColorTable returned %d\n", ret); + ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 && + rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff, + "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n", + rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved, + rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved); + + c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue); + c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue); + + test_color(hdcmem, DIBINDEX(0), c0, 0, 1); + test_color(hdcmem, DIBINDEX(1), c1, 0, 1); + test_color(hdcmem, DIBINDEX(2), c0, 1, 1); + test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1); + test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1); + test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1); + test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, + plogpal->palPalEntry[0].peBlue), c0, 1, 1); + test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, + plogpal->palPalEntry[1].peBlue), c1, 1, 1); + test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1); + test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1); + test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1); + test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1); + test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1); + test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1); + + /* Bottom and 2nd row from top green, everything else magenta */ + bits[0] = bits[1] = 0xff; + bits[13 * 4] = bits[13*4 + 1] = 0xff; + + + pbmi->bmiHeader.biBitCount = 32; + + hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0); + ok(hdib2 != NULL, "CreateDIBSection failed\n"); + hdcmem2 = CreateCompatibleDC(hdc); + oldbm2 = SelectObject(hdcmem2, hdib2); + + BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY); + + ok(bits32[0] == 0xff00, "lower left pixel is %08lx\n", bits32[0]); + ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08lx\n", bits32[17]); + + SelectObject(hdcmem2, oldbm2); + DeleteObject(hdib2); + + SelectObject(hdcmem, oldbm); + SelectObject(hdcmem, oldpal); + DeleteObject(hdib); + DeleteObject(hpal); + + + pbmi->bmiHeader.biBitCount = 8; + + memset(plogpal, 0, sizeof(logpalbuf)); + plogpal->palVersion = 0x300; + plogpal->palNumEntries = 256; + + for (i = 0; i < 128; i++) { + plogpal->palPalEntry[i].peRed = 255 - i * 2; + plogpal->palPalEntry[i].peBlue = i * 2; + plogpal->palPalEntry[i].peGreen = 0; + plogpal->palPalEntry[255 - i].peRed = 0; + plogpal->palPalEntry[255 - i].peGreen = i * 2; + plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2; + } + + index = (WORD*)pbmi->bmiColors; + for (i = 0; i < 256; i++) { + *index++ = i; + } + + hpal = CreatePalette(plogpal); + ok(hpal != NULL, "CreatePalette failed\n"); + oldpal = SelectPalette(hdc, hpal, TRUE); + hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0); + ok(hdib != NULL, "CreateDIBSection failed\n"); + + SelectPalette(hdc, oldpal, TRUE); + oldbm = SelectObject(hdcmem, hdib); + oldpal = SelectPalette(hdcmem, hpal, TRUE); + + ret = GetDIBColorTable(hdcmem, 0, 256, rgb); + ok(ret == 256, "GetDIBColorTable returned %d\n", ret); + for (i = 0; i < 256; i++) { + ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && + rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && + rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, + "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n", + i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved); + } + + for (i = 0; i < 256; i++) { + test_color(hdcmem, DIBINDEX(i), + RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0); + test_color(hdcmem, PALETTEINDEX(i), + RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0); + test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), + RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0); + } + + SelectPalette(hdcmem, oldpal, TRUE); + SelectObject(hdcmem, oldbm); + DeleteObject(hdib); + DeleteObject(hpal); + + + DeleteDC(hdcmem); + ReleaseDC(0, hdc); +} + +START_TEST(bitmap) +{ + HWND hWnd; + + hWnd = CreateWindowExA(0, "EDIT", NULL, 0, + 10, 10, 300, 300, + NULL, NULL, NULL, NULL); + assert(hWnd); + is_win9x = GetWindowLongW(hWnd, GWL_WNDPROC) == 0; + DestroyWindow(hWnd); + + test_createdibitmap(); + test_dibsections(); +} Property changes on: trunk/reactos/regtests/winetests/gdi32/bitmap.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/gdi32/brush.c --- trunk/reactos/regtests/winetests/gdi32/brush.c 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/brush.c 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,80 @@ +/* + * Unit test suite for brushes + * + * Copyright 2004 Kevin Koltzau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" + +#include "wine/test.h" + +typedef struct _STOCK_BRUSH { + COLORREF color; + int stockobj; + const char *name; +} STOCK_BRUSH; + +static void test_solidbrush(void) +{ + static const STOCK_BRUSH stock[] = { + {RGB(255,255,255), WHITE_BRUSH, "white"}, + {RGB(192,192,192), LTGRAY_BRUSH, "ltgray"}, + {RGB(128,128,128), GRAY_BRUSH, "gray"}, + {RGB(0,0,0), BLACK_BRUSH, "black"}, + {RGB(0,0,255), -1, "blue"} + }; + HBRUSH solidBrush; + HBRUSH stockBrush; + LOGBRUSH br; + size_t i; + INT ret; + + for(i=0; i<sizeof(stock)/sizeof(stock[0]); i++) { + solidBrush = CreateSolidBrush(stock[i].color); + + if(stock[i].stockobj != -1) { + stockBrush = (HBRUSH)GetStockObject(stock[i].stockobj); + ok(stockBrush!=solidBrush, "Stock %s brush equals solid %s brush\n", stock[i].name, stock[i].name); + } + else + stockBrush = NULL; + memset(&br, sizeof(br), 0); + ret = GetObject(solidBrush, sizeof(br), &br); + ok( ret !=0, "GetObject on solid %s brush failed, error=%ld\n", stock[i].name, GetLastError()); + ok(br.lbStyle==BS_SOLID, "%s brush has wrong style, got %d expected %d\n", stock[i].name, br.lbStyle, BS_SOLID); + ok(br.lbColor==stock[i].color, "%s brush has wrong color, got 0x%08lx expected 0x%08lx\n", stock[i].name, br.lbColor, stock[i].color); + + if(stockBrush) { + /* Sanity check, make sure the colors being compared do in fact have a stock brush */ + ret = GetObject(stockBrush, sizeof(br), &br); + ok( ret !=0, "GetObject on stock %s brush failed, error=%ld\n", stock[i].name, GetLastError()); + ok(br.lbColor==stock[i].color, "stock %s brush unexpected color, got 0x%08lx expected 0x%08lx\n", stock[i].name, br.lbColor, stock[i].color); + } + + DeleteObject(solidBrush); + ok(GetObject(solidBrush, sizeof(br), &br)==0, "GetObject succeeded on a deleted %s brush\n", stock[i].name); + } +} + +START_TEST(brush) +{ + test_solidbrush(); +} Property changes on: trunk/reactos/regtests/winetests/gdi32/brush.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/gdi32/gdi32_test.xml --- trunk/reactos/regtests/winetests/gdi32/gdi32_test.xml 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/gdi32_test.xml 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,11 @@ +<module name="gdi32_test" type="win32cui" installbase="bin" installname="gdi32_test.exe" warnings="true"> + <include base="gdi32_test">.</include> + <define name="__USE_W32API" /> + <library>ntdll</library> + <library>gdi32</library> + <file>bitmap.c</file> + <file>brush.c</file> + <file>gdiobj.c</file> + <file>metafile.c</file> + <file>testlist.c</file> +</module> _____ Added: trunk/reactos/regtests/winetests/gdi32/gdiobj.c --- trunk/reactos/regtests/winetests/gdi32/gdiobj.c 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/gdiobj.c 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,335 @@ +/* + * Unit test suite for GDI objects + * + * Copyright 2002 Mike McCormack + * Copyright 2004 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" + + +static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont) +{ + LOGFONTA getobj_lf; + int ret, minlen = 0; + + if (!hfont) + return; + + ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf); + /* NT4 tries to be clever and only returns the minimum length */ + while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1) + minlen++; + minlen += FIELD_OFFSET(LOGFONTA, lfFaceName) + 1; + ok(ret == sizeof(LOGFONTA) || ret == minlen, + "%s: GetObject returned %d expected %d or %d\n", test, ret, sizeof(LOGFONTA), minlen); + ok(!memcmp(&lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test); + ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName), + "%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName); +} + +static HFONT create_font(const char* test, const LOGFONTA* lf) +{ + HFONT hfont = CreateFontIndirectA(lf); + ok(hfont != 0, "%s: CreateFontIndirect failed\n", test); + if (hfont) + check_font(test, lf, hfont); + return hfont; +} + +static void test_logfont(void) +{ + LOGFONTA lf; + HFONT hfont; + + memset(&lf, 0, sizeof lf); + + lf.lfCharSet = ANSI_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfWeight = FW_DONTCARE; + lf.lfHeight = 16; + lf.lfWidth = 16; + lf.lfQuality = DEFAULT_QUALITY; + + lstrcpyA(lf.lfFaceName, "Arial"); + hfont = create_font("Arial", &lf); + DeleteObject(hfont); + + memset(&lf, 'A', sizeof(lf)); + hfont = CreateFontIndirectA(&lf); + ok(hfont != 0, "CreateFontIndirectA with strange LOGFONT failed\n"); + + lf.lfFaceName[LF_FACESIZE - 1] = 0; + check_font("AAA...", &lf, hfont); + DeleteObject(hfont); +} + +static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + if (type & RASTER_FONTTYPE) + { + LOGFONT *lf = (LOGFONT *)lParam; + *lf = *elf; + return 0; /* stop enumeration */ + } + + return 1; /* continue enumeration */ +} + +static void test_font_metrics(HDC hdc, HFONT hfont, const char *test_str, + INT test_str_len, const TEXTMETRICA *tm_orig, + const SIZE *size_orig, INT width_orig, + INT scale_x, INT scale_y) +{ + HFONT old_hfont; + TEXTMETRICA tm; + SIZE size; + INT width; + + if (!hfont) + return; + + old_hfont = SelectObject(hdc, hfont); + + GetTextMetricsA(hdc, &tm); + + ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%ld != %ld\n", tm.tmHeight, tm_orig->tmHeight * scale_y); + ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%ld != %ld\n", tm.tmAscent, tm_orig->tmAscent * scale_y); + ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%ld != %ld\n", tm.tmDescent, tm_orig->tmDescent * scale_y); + ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%ld != %ld\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x); + + GetTextExtentPoint32A(hdc, test_str, test_str_len, &size); + + ok(size.cx == size_orig->cx * scale_x, "%ld != %ld\n", size.cx, size_orig->cx * scale_x); + ok(size.cy == size_orig->cy * scale_y, "%ld != %ld\n", size.cy, size_orig->cy * scale_y); + + GetCharWidthA(hdc, 'A', 'A', &width); + + ok(width == width_orig * scale_x, "%d != %d\n", width, width_orig * scale_x); + + SelectObject(hdc, old_hfont); +} + +/* see whether GDI scales bitmap font metrics */ +static void test_bitmap_font(void) +{ + static const char test_str[11] = "Test String"; + HDC hdc; + LOGFONTA bitmap_lf; + HFONT hfont, old_hfont; + TEXTMETRICA tm_orig; + SIZE size_orig; + INT ret, i, width_orig, height_orig; + + hdc = GetDC(0); + + /* "System" has only 1 pixel size defined, otherwise the test breaks */ + ret = EnumFontFamiliesA(hdc, "System", font_enum_proc, (LPARAM)&bitmap_lf); + if (ret) + { + ReleaseDC(0, hdc); + trace("no bitmap fonts were found, skipping the test\n"); + return; + } + + trace("found bitmap font %s, height %ld\n", bitmap_lf.lfFaceName, bitmap_lf.lfHeight); + + height_orig = bitmap_lf.lfHeight; + hfont = create_font("bitmap", &bitmap_lf); + + old_hfont = SelectObject(hdc, hfont); + ok(GetTextMetricsA(hdc, &tm_orig), "GetTextMetricsA failed\n"); + ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n"); + ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n"); + SelectObject(hdc, old_hfont); + DeleteObject(hfont); + + /* test fractional scaling */ + for (i = 1; i < height_orig; i++) + { + hfont = create_font("fractional", &bitmap_lf); + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1); + DeleteObject(hfont); + } + + /* test integer scaling 3x2 */ + bitmap_lf.lfHeight = height_orig * 2; + bitmap_lf.lfWidth *= 3; + hfont = create_font("3x2", &bitmap_lf); +todo_wine +{ + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2); +} + DeleteObject(hfont); + + /* test integer scaling 3x3 */ + bitmap_lf.lfHeight = height_orig * 3; + bitmap_lf.lfWidth = 0; + hfont = create_font("3x3", &bitmap_lf); + +todo_wine +{ + test_font_metrics(hdc, hfont, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3); +} + DeleteObject(hfont); + + ReleaseDC(0, hdc); +} + +static void test_gdi_objects(void) +{ + BYTE buff[256]; + HDC hdc = GetDC(NULL); + HPEN hp; + int i; + BOOL ret; + + /* 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 */ + ret = DeleteObject(NULL); + ok( !ret && !GetLastError(), + "DeleteObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n", + ret, 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); +} + +static void test_GdiGetCharDimensions(void) +{ + HDC hdc; + TEXTMETRICW tm; + LONG ret; + SIZE size; + LONG avgwidth, height; + static const char szAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + typedef LONG (WINAPI *fnGdiGetCharDimensions)(HDC hdc, LPTEXTMETRICW lptm, LONG *height); + fnGdiGetCharDimensions GdiGetCharDimensions = (fnGdiGetCharDimensions)GetProcAddress(LoadLibrary("gdi32"), "GdiGetCharDimensions"); + if (!GdiGetCharDimensions) return; + + hdc = CreateCompatibleDC(NULL); + + GetTextExtentPoint(hdc, szAlphabet, strlen(szAlphabet), &size); + avgwidth = ((size.cx / 26) + 1) / 2; + + ret = GdiGetCharDimensions(hdc, &tm, &height); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + ok(height == tm.tmHeight, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", tm.tmHeight, height); + + ret = GdiGetCharDimensions(hdc, &tm, NULL); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + + ret = GdiGetCharDimensions(hdc, NULL, NULL); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + + height = 0; + ret = GdiGetCharDimensions(hdc, NULL, &height); + ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret); + ok(height == size.cy, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", size.cy, height); + + DeleteDC(hdc); +} + +static void test_text_extents(void) +{ + LOGFONTA lf; + TEXTMETRICA tm; + HDC hdc; + HFONT hfont; + SIZE sz; + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Arial"); + lf.lfHeight = 20; + + hfont = CreateFontIndirectA(&lf); + hdc = GetDC(0); + hfont = SelectObject(hdc, hfont); + GetTextMetricsA(hdc, &tm); + GetTextExtentPointA(hdc, "o", 1, &sz); + ok(sz.cy == tm.tmHeight, "cy %ld tmHeight %ld\n", sz.cy, tm.tmHeight); + + SelectObject(hdc, hfont); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); +} + +START_TEST(gdiobj) +{ + test_logfont(); + test_bitmap_font(); + test_gdi_objects(); + test_GdiGetCharDimensions(); + test_text_extents(); +} Property changes on: trunk/reactos/regtests/winetests/gdi32/gdiobj.c ___________________________________________________________________ Name: svn:executable + * _____ Added: trunk/reactos/regtests/winetests/gdi32/metafile.c --- trunk/reactos/regtests/winetests/gdi32/metafile.c 2005-08-06 23:12:16 UTC (rev 17122) +++ trunk/reactos/regtests/winetests/gdi32/metafile.c 2005-08-06 23:19:47 UTC (rev 17123) @@ -0,0 +1,612 @@ +/* + * Unit tests for metafile functions + * + * Copyright (c) 2002 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <assert.h> +#include <stdio.h> +#include <math.h> + +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + +static LOGFONTA orig_lf; +static BOOL emr_processed = FALSE; + +/* Arbitrarily chosen values for the second co-ordinate of a metafile line */ +#define LINE_X 55.0f +#define LINE_Y 15.0f + +static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, + const ENHMETARECORD *emr, int n_objs, LPARAM param) +{ + static int n_record; [truncated at 1000 lines; 609 more skipped]
19 years, 4 months
1
0
0
0
[sedwards] 17122: moved psapi test
by sedwards@svn.reactos.com
moved psapi test Deleted: trunk/reactos/lib/psapi/tests/
19 years, 4 months
1
0
0
0
[sedwards] 17121: moved psapi test
by sedwards@svn.reactos.com
moved psapi test Added: trunk/reactos/regtests/winetests/psapi/ Added: trunk/reactos/regtests/winetests/psapi/psapi_test.xml _____ Copied: trunk/reactos/regtests/winetests/psapi (from rev 17118, trunk/reactos/lib/psapi/tests) _____ Added: trunk/reactos/regtests/winetests/psapi/psapi_test.xml --- trunk/reactos/lib/psapi/tests/psapi_test.xml 2005-08-06 22:08:13 UTC (rev 17118) +++ trunk/reactos/regtests/winetests/psapi/psapi_test.xml 2005-08-06 23:11:59 UTC (rev 17121) @@ -0,0 +1,8 @@ +<module name="psapi_test" type="win32cui" installbase="bin" installname="psapi_test.exe" warnings="true"> + <include base="psapi_test">.</include> + <define name="__USE_W32API" /> + <library>ntdll</library> + <library>psapi</library> + <file>testlist.c</file> + <file>module.c</file> +</module>
19 years, 4 months
1
0
0
0
[sedwards] 17120: add version tests
by sedwards@svn.reactos.com
add version tests Added: trunk/reactos/regtests/winetests/version/version_test.xml _____ Added: trunk/reactos/regtests/winetests/version/version_test.xml --- trunk/reactos/regtests/winetests/version/version_test.xml 2005-08-06 23:05:16 UTC (rev 17119) +++ trunk/reactos/regtests/winetests/version/version_test.xml 2005-08-06 23:08:51 UTC (rev 17120) @@ -0,0 +1,8 @@ +<module name="version_test" type="win32cui" installbase="bin" installname="version_test.exe" warnings="true"> + <include base="version_test">.</include> + <define name="__USE_W32API" /> + <library>ntdll</library> + <library>version</library> + <file>testlist.c</file> + <file>info.c</file> +</module>
19 years, 4 months
1
0
0
0
[sedwards] 17119: added msvcrt regression test
by sedwards@svn.reactos.com
added msvcrt regression test Added: trunk/reactos/regtests/winetests/msvcrt/msvcrt_test.xml _____ Added: trunk/reactos/regtests/winetests/msvcrt/msvcrt_test.xml --- trunk/reactos/regtests/winetests/msvcrt/msvcrt_test.xml 2005-08-06 22:08:13 UTC (rev 17118) +++ trunk/reactos/regtests/winetests/msvcrt/msvcrt_test.xml 2005-08-06 23:05:16 UTC (rev 17119) @@ -0,0 +1,14 @@ +<module name="msvcrt_test" type="win32cui" installbase="bin" installname="msvcrt_test.exe" warnings="true"> + <include base="msvcrt_test">.</include> + <define name="__USE_W32API" /> + <library>ntdll</library> + <file>cpp.c</file> + <file>environ.c</file> + <file>file.c</file> + <file>heap.c</file> + <file>printf.c</file> + <file>scanf.c</file> + <file>string.c</file> + <file>testlist.c</file> + <file>time.c</file> +</module>
19 years, 4 months
1
0
0
0
← Newer
1
...
45
46
47
48
49
50
51
...
67
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Results per page:
10
25
50
100
200