mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Added Wine Common Control Regression tests.
As of 2004-10-7 we pass all of these tests. svn path=/trunk/; revision=11572
This commit is contained in:
parent
515d472b0f
commit
af0423f839
7 changed files with 1202 additions and 0 deletions
5
reactos/lib/comctl32/tests/.cvsignore
Normal file
5
reactos/lib/comctl32/tests/.cvsignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
*.o
|
||||
*.a
|
||||
*.exe
|
||||
*.map
|
||||
*.sym
|
30
reactos/lib/comctl32/tests/Makefile
Normal file
30
reactos/lib/comctl32/tests/Makefile
Normal file
|
@ -0,0 +1,30 @@
|
|||
# $Id: Makefile,v 1.1 2004/11/07 14:36:23 sedwards Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
# require os code to explicitly request A/W version of structs/functions
|
||||
TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \
|
||||
-D_WIN32_WINNT=0x0501
|
||||
|
||||
TARGET_NAME = comctl32_test
|
||||
|
||||
TARGET_SDKLIBS = gdi32.a comctl32.a ntdll.a
|
||||
|
||||
TARGET_OBJECTS = \
|
||||
testlist.o \
|
||||
dpa.o \
|
||||
imagelist.o \
|
||||
subclass.o \
|
||||
tab.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
81
reactos/lib/comctl32/tests/dpa.c
Normal file
81
reactos/lib/comctl32/tests/dpa.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Unit tests for DPA functions
|
||||
*
|
||||
* Copyright 2003 Uwe Bonnes
|
||||
*
|
||||
* 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 "winnls.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static HDPA (WINAPI *pDPA_Create)(int);
|
||||
static BOOL (WINAPI *pDPA_Grow)(const HDPA hdpa, INT nGrow);
|
||||
static BOOL (WINAPI *pDPA_Destroy)(const HDPA hdpa);
|
||||
static BOOL (WINAPI *pDPA_SetPtr)(const HDPA hdpa, INT i, LPVOID p);
|
||||
|
||||
static INT CALLBACK dpa_strcmp(LPVOID pvstr1, LPVOID pvstr2, LPARAM flags)
|
||||
{
|
||||
LPCSTR str1 = (LPCSTR)pvstr1;
|
||||
LPCSTR str2 = (LPCSTR)pvstr2;
|
||||
|
||||
return lstrcmpA (str1, str2);
|
||||
}
|
||||
|
||||
void DPA_test()
|
||||
{
|
||||
HDPA dpa_ret;
|
||||
INT int_ret;
|
||||
CHAR test_str0[]="test0";
|
||||
|
||||
if (!pDPA_Create)
|
||||
return;
|
||||
|
||||
dpa_ret = pDPA_Create(0);
|
||||
ok((dpa_ret !=0), "DPA_Create failed\n");
|
||||
int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED);
|
||||
ok((int_ret == -1), "DPA_Search found invalid item\n");
|
||||
int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTBEFORE);
|
||||
ok((int_ret == 0), "DPA_Search proposed bad item\n");
|
||||
int_ret = DPA_Search(dpa_ret,test_str0,0, dpa_strcmp,0, DPAS_SORTED|DPAS_INSERTAFTER);
|
||||
ok((int_ret == 0), "DPA_Search proposed bad item\n");
|
||||
int_ret = pDPA_Grow(dpa_ret,0);
|
||||
ok(int_ret != 0, "DPA_Grow failed\n");
|
||||
int_ret = pDPA_SetPtr(dpa_ret, 0, (void*)0xdeadbeef);
|
||||
ok(int_ret != 0, "DPA_SetPtr failed\n");
|
||||
int_ret = pDPA_Destroy(dpa_ret);
|
||||
ok(int_ret != 0, "DPA_Destory failed\n");
|
||||
}
|
||||
|
||||
START_TEST(dpa)
|
||||
{
|
||||
HMODULE hdll;
|
||||
|
||||
hdll=GetModuleHandleA("comctl32.dll");
|
||||
pDPA_Create=(void*)GetProcAddress(hdll,(LPCSTR)328);
|
||||
pDPA_Destroy=(void*)GetProcAddress(hdll,(LPCSTR)329);
|
||||
pDPA_Grow=(void*)GetProcAddress(hdll,(LPCSTR)330);
|
||||
pDPA_SetPtr=(void*)GetProcAddress(hdll,(LPCSTR)335);
|
||||
|
||||
DPA_test();
|
||||
}
|
560
reactos/lib/comctl32/tests/imagelist.c
Normal file
560
reactos/lib/comctl32/tests/imagelist.c
Normal file
|
@ -0,0 +1,560 @@
|
|||
/* Unit test suite for imagelist control.
|
||||
*
|
||||
* Copyright 2004 Michael Stefaniuc
|
||||
* Copyright 2002 Mike McCormack for CodeWeavers
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#undef VISIBLE
|
||||
|
||||
#ifdef VISIBLE
|
||||
#define WAIT Sleep (1000)
|
||||
#define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
|
||||
#else
|
||||
#define WAIT
|
||||
#define REDRAW(hwnd)
|
||||
#endif
|
||||
|
||||
|
||||
static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*) = NULL;
|
||||
|
||||
static HDC desktopDC;
|
||||
static HINSTANCE hinst;
|
||||
|
||||
/* These macros build cursor/bitmap data in 4x4 pixel blocks */
|
||||
#define B(x,y) ((x?0xf0:0)|(y?0xf:0))
|
||||
#define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h)
|
||||
#define ROW32(a,b,c,d,e,f,g,h) ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h), \
|
||||
ROW1(a,b,c,d,e,f,g,h), ROW1(a,b,c,d,e,f,g,h)
|
||||
#define ROW2(a,b,c,d,e,f,g,h,i,j,k,l) ROW1(a,b,c,d,e,f,g,h),B(i,j),B(k,l)
|
||||
#define ROW48(a,b,c,d,e,f,g,h,i,j,k,l) ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
|
||||
ROW2(a,b,c,d,e,f,g,h,i,j,k,l), ROW2(a,b,c,d,e,f,g,h,i,j,k,l), \
|
||||
ROW2(a,b,c,d,e,f,g,h,i,j,k,l)
|
||||
|
||||
static const BYTE empty_bits[48*48/8];
|
||||
|
||||
static const BYTE icon_bits[32*32/8] =
|
||||
{
|
||||
ROW32(0,0,0,0,0,0,0,0),
|
||||
ROW32(0,0,1,1,1,1,0,0),
|
||||
ROW32(0,1,1,1,1,1,1,0),
|
||||
ROW32(0,1,1,0,0,1,1,0),
|
||||
ROW32(0,1,1,0,0,1,1,0),
|
||||
ROW32(0,1,1,1,1,1,1,0),
|
||||
ROW32(0,0,1,1,1,1,0,0),
|
||||
ROW32(0,0,0,0,0,0,0,0)
|
||||
};
|
||||
|
||||
static const BYTE bitmap_bits[48*48/8] =
|
||||
{
|
||||
ROW48(0,0,0,0,0,0,0,0,0,0,0,0),
|
||||
ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
|
||||
ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
|
||||
ROW48(0,1,0,0,0,0,0,0,1,0,1,0),
|
||||
ROW48(0,1,0,0,0,0,0,1,0,0,1,0),
|
||||
ROW48(0,1,0,0,0,0,1,0,0,0,1,0),
|
||||
ROW48(0,1,0,0,0,1,0,0,0,0,1,0),
|
||||
ROW48(0,1,0,0,1,0,0,0,0,0,1,0),
|
||||
ROW48(0,1,0,1,0,0,0,0,0,0,1,0),
|
||||
ROW48(0,1,1,0,0,0,0,0,0,1,1,0),
|
||||
ROW48(0,1,1,1,1,1,1,1,1,1,1,0),
|
||||
ROW48(0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
};
|
||||
|
||||
static HIMAGELIST createImageList(cx, cy)
|
||||
{
|
||||
/* Create an ImageList and put an image into it */
|
||||
HIMAGELIST himl = ImageList_Create(cx, cy, ILC_COLOR, 1, 1);
|
||||
HBITMAP hbm = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ImageList_Add(himl, hbm, NULL);
|
||||
return himl;
|
||||
}
|
||||
|
||||
static HWND create_a_window(void)
|
||||
{
|
||||
char className[] = "bmwnd";
|
||||
char winName[] = "Test Bitmap";
|
||||
HWND hWnd;
|
||||
static int registered = 0;
|
||||
|
||||
if (!registered)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
|
||||
cls.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
|
||||
cls.lpfnWndProc = DefWindowProcA;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = 0;
|
||||
cls.hIcon = LoadIconA (0, (LPSTR)IDI_APPLICATION);
|
||||
cls.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
|
||||
cls.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
|
||||
cls.lpszMenuName = 0;
|
||||
cls.lpszClassName = className;
|
||||
|
||||
RegisterClassA (&cls);
|
||||
registered = 1;
|
||||
}
|
||||
|
||||
/* Setup window */
|
||||
hWnd = CreateWindowA (className, winName,
|
||||
WS_OVERLAPPEDWINDOW ,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
|
||||
0, hinst, 0);
|
||||
|
||||
#ifdef VISIBLE
|
||||
ShowWindow (hWnd, SW_SHOW);
|
||||
#endif
|
||||
REDRAW(hWnd);
|
||||
WAIT;
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size,
|
||||
LPCSTR loc, BOOL clear)
|
||||
{
|
||||
HDC hdc = NULL;
|
||||
#ifdef VISIBLE
|
||||
if (!himl) return NULL;
|
||||
|
||||
SetWindowText(hwnd, loc);
|
||||
hdc = GetDC(hwnd);
|
||||
ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT);
|
||||
|
||||
REDRAW(hwnd);
|
||||
WAIT;
|
||||
|
||||
if (clear)
|
||||
{
|
||||
BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
hdc = NULL;
|
||||
}
|
||||
#endif /* VISIBLE */
|
||||
return hdc;
|
||||
}
|
||||
|
||||
/* Useful for checking differences */
|
||||
#if 0
|
||||
static void dump_bits(const BYTE *p, const BYTE *q, int size)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
size /= 8;
|
||||
|
||||
for (i = 0; i < size * 2; i++)
|
||||
{
|
||||
printf("|");
|
||||
for (j = 0; j < size; j++)
|
||||
printf("%c%c", p[j] & 0xf0 ? 'X' : ' ', p[j] & 0xf ? 'X' : ' ');
|
||||
printf(" -- ");
|
||||
for (j = 0; j < size; j++)
|
||||
printf("%c%c", q[j] & 0xf0 ? 'X' : ' ', q[j] & 0xf ? 'X' : ' ');
|
||||
printf("|\n");
|
||||
p += size * 4;
|
||||
q += size * 4;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size,
|
||||
const BYTE *checkbits, LPCSTR loc)
|
||||
{
|
||||
#ifdef VISIBLE
|
||||
BYTE bits[100*100/8];
|
||||
COLORREF c;
|
||||
HDC hdc;
|
||||
int x, y, i = -1;
|
||||
|
||||
if (!himl) return;
|
||||
|
||||
memset(bits, 0, sizeof(bits));
|
||||
hdc = show_image(hwnd, himl, idx, size, loc, FALSE);
|
||||
|
||||
c = GetPixel(hdc, 0, 0);
|
||||
|
||||
for (y = 0; y < size; y ++)
|
||||
{
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
if (!(x & 0x7)) i++;
|
||||
if (GetPixel(hdc, x, y) != c) bits[i] |= (0x80 >> (x & 0x7));
|
||||
}
|
||||
}
|
||||
|
||||
BitBlt(hdc, 0, 0, size, size, hdc, size+1, size+1, SRCCOPY);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
ok (memcmp(bits, checkbits, (size * size)/8) == 0,
|
||||
"%s: bits different\n", loc);
|
||||
if (memcmp(bits, checkbits, (size * size)/8))
|
||||
dump_bits(bits, checkbits, size);
|
||||
#endif /* VISIBLE */
|
||||
}
|
||||
|
||||
static void testHotspot (void)
|
||||
{
|
||||
struct hotspot {
|
||||
int dx;
|
||||
int dy;
|
||||
};
|
||||
|
||||
#define SIZEX1 47
|
||||
#define SIZEY1 31
|
||||
#define SIZEX2 11
|
||||
#define SIZEY2 17
|
||||
#define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
|
||||
static const struct hotspot hotspots[HOTSPOTS_MAX] = {
|
||||
{ 10, 7 },
|
||||
{ SIZEX1, SIZEY1 },
|
||||
{ -9, -8 },
|
||||
{ -7, 35 }
|
||||
};
|
||||
int i, j, ret;
|
||||
HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
|
||||
HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
|
||||
HWND hwnd = create_a_window();
|
||||
|
||||
|
||||
for (i = 0; i < HOTSPOTS_MAX; i++) {
|
||||
for (j = 0; j < HOTSPOTS_MAX; j++) {
|
||||
int dx1 = hotspots[i].dx;
|
||||
int dy1 = hotspots[i].dy;
|
||||
int dx2 = hotspots[j].dx;
|
||||
int dy2 = hotspots[j].dy;
|
||||
int correctx, correcty, newx, newy;
|
||||
char loc[256];
|
||||
HIMAGELIST himlNew;
|
||||
POINT ppt;
|
||||
|
||||
ret = ImageList_BeginDrag(himl1, 0, dx1, dy1);
|
||||
ok(ret != 0, "BeginDrag failed for { %d, %d }\n", dx1, dy1);
|
||||
sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
|
||||
show_image(hwnd, himl1, 0, max(SIZEX1, SIZEY1), loc, TRUE);
|
||||
|
||||
/* check merging the dragged image with a second image */
|
||||
ret = ImageList_SetDragCursorImage(himl2, 0, dx2, dy2);
|
||||
ok(ret != 0, "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
|
||||
dx1, dy1, dx2, dy2);
|
||||
sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
|
||||
show_image(hwnd, himl2, 0, max(SIZEX2, SIZEY2), loc, TRUE);
|
||||
|
||||
/* check new hotspot, it should be the same like the old one */
|
||||
himlNew = ImageList_GetDragImage(NULL, &ppt);
|
||||
ok(ppt.x == dx1 && ppt.y == dy1,
|
||||
"Expected drag hotspot [%d,%d] got [%ld,%ld]\n",
|
||||
dx1, dy1, ppt.x, ppt.y);
|
||||
/* check size of new dragged image */
|
||||
ImageList_GetIconSize(himlNew, &newx, &newy);
|
||||
correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
|
||||
correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
|
||||
ok(newx == correctx && newy == correcty,
|
||||
"Expected drag image size [%d,%d] got [%d,%d]\n",
|
||||
correctx, correcty, newx, newy);
|
||||
sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
|
||||
show_image(hwnd, himlNew, 0, max(correctx, correcty), loc, TRUE);
|
||||
ImageList_EndDrag();
|
||||
}
|
||||
}
|
||||
#undef SIZEX1
|
||||
#undef SIZEY1
|
||||
#undef SIZEX2
|
||||
#undef SIZEY2
|
||||
#undef HOTSPOTS_MAX
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static BOOL DoTest1(void)
|
||||
{
|
||||
HIMAGELIST himl ;
|
||||
|
||||
HICON hicon1 ;
|
||||
HICON hicon2 ;
|
||||
HICON hicon3 ;
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(84,84,0x10,0,3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon1 != 0, "no hicon1\n");
|
||||
hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon2 != 0, "no hicon2\n");
|
||||
hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon3 != 0, "no hicon3\n");
|
||||
|
||||
/* remove when nothing exists */
|
||||
ok(!ImageList_Remove(himl,0),"removed non-existent icon\n");
|
||||
/* removing everything from an empty imagelist should succeed */
|
||||
ok(ImageList_RemoveAll(himl),"removed non-existent icon\n");
|
||||
|
||||
/* add three */
|
||||
ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
|
||||
ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
|
||||
ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
|
||||
|
||||
/* remove an index out of range */
|
||||
ok(!ImageList_Remove(himl,4711),"removed non-existent icon\n");
|
||||
|
||||
/* remove three */
|
||||
ok(ImageList_Remove(himl,0),"can't remove 0\n");
|
||||
ok(ImageList_Remove(himl,0),"can't remove 0\n");
|
||||
ok(ImageList_Remove(himl,0),"can't remove 0\n");
|
||||
|
||||
/* remove one extra */
|
||||
ok(!ImageList_Remove(himl,0),"removed non-existent icon\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
|
||||
|
||||
/* icons should be deleted by the imagelist */
|
||||
ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL DoTest2(void)
|
||||
{
|
||||
HIMAGELIST himl ;
|
||||
|
||||
HICON hicon1 ;
|
||||
HICON hicon2 ;
|
||||
HICON hicon3 ;
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(84,84,0x10,0,3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon1 != 0, "no hicon1\n");
|
||||
hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon2 != 0, "no hicon2\n");
|
||||
hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon3 != 0, "no hicon3\n");
|
||||
|
||||
/* add three */
|
||||
ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n");
|
||||
ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n");
|
||||
ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
|
||||
|
||||
/* icons should be deleted by the imagelist */
|
||||
ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL DoTest3(void)
|
||||
{
|
||||
HIMAGELIST himl;
|
||||
|
||||
HBITMAP hbm1;
|
||||
HBITMAP hbm2;
|
||||
HBITMAP hbm3;
|
||||
|
||||
IMAGELISTDRAWPARAMS imldp;
|
||||
HDC hdc;
|
||||
HWND hwndfortest;
|
||||
|
||||
if (!pImageList_DrawIndirect)
|
||||
{
|
||||
HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
|
||||
pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
|
||||
if (!pImageList_DrawIndirect)
|
||||
{
|
||||
trace("ImageList_DrawIndirect not available, skipping test\n");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
hwndfortest = create_a_window();
|
||||
hdc = GetDC(hwndfortest);
|
||||
ok(hdc!=NULL, "couldn't get DC\n");
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(48,48,0x10,0,3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm1 != 0, "no bitmap 1\n");
|
||||
hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm2 != 0, "no bitmap 2\n");
|
||||
hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm3 != 0, "no bitmap 3\n");
|
||||
|
||||
/* add three */
|
||||
ok(0==ImageList_Add(himl, hbm1, 0),"failed to add bitmap 1\n");
|
||||
ok(1==ImageList_Add(himl, hbm2, 0),"failed to add bitmap 2\n");
|
||||
|
||||
ok(ImageList_SetImageCount(himl,3),"Setimage count failed\n");
|
||||
/*ok(2==ImageList_Add(himl, hbm3, NULL),"failed to add bitmap 3\n"); */
|
||||
ok(ImageList_Replace(himl, 2, hbm3, 0),"failed to replace bitmap 3\n");
|
||||
|
||||
memset(&imldp, 0, sizeof (imldp));
|
||||
ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n");
|
||||
imldp.cbSize = sizeof (imldp);
|
||||
ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n");
|
||||
imldp.hdcDst = hdc;
|
||||
ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n");
|
||||
imldp.himl = himl;
|
||||
if (!pImageList_DrawIndirect(&imldp))
|
||||
{
|
||||
/* Earlier versions of native comctl32 use a smaller structure */
|
||||
imldp.cbSize -= 3 * sizeof(DWORD);
|
||||
ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n");
|
||||
}
|
||||
REDRAW(hwndfortest);
|
||||
WAIT;
|
||||
|
||||
imldp.fStyle = SRCCOPY;
|
||||
imldp.rgbBk = CLR_DEFAULT;
|
||||
imldp.rgbFg = CLR_DEFAULT;
|
||||
imldp.y = 100;
|
||||
imldp.x = 100;
|
||||
ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(pImageList_DrawIndirect(&imldp),"should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(!pImageList_DrawIndirect(&imldp),"should fail\n");
|
||||
|
||||
/* remove three */
|
||||
ok(ImageList_Remove(himl, 0), "removing 1st bitmap\n");
|
||||
ok(ImageList_Remove(himl, 0), "removing 2nd bitmap\n");
|
||||
ok(ImageList_Remove(himl, 0), "removing 3rd bitmap\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
|
||||
|
||||
/* bitmaps should not be deleted by the imagelist */
|
||||
ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
|
||||
ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
|
||||
ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
|
||||
|
||||
ReleaseDC(hwndfortest, hdc);
|
||||
DestroyWindow(hwndfortest);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void testMerge()
|
||||
{
|
||||
HIMAGELIST himl1, himl2, hmerge;
|
||||
HICON hicon1;
|
||||
HWND hwnd = create_a_window();
|
||||
|
||||
himl1 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl1 != NULL,"failed to create himl1\n");
|
||||
|
||||
himl2 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl2 != NULL,"failed to create himl2\n");
|
||||
|
||||
hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon1 != NULL, "failed to create hicon1\n");
|
||||
|
||||
if (!himl1 || !himl2 || !hicon1)
|
||||
return;
|
||||
|
||||
ok(0==ImageList_AddIcon(himl2, hicon1),"add icon1 to himl2 failed\n");
|
||||
check_bits(hwnd, himl2, 0, 32, icon_bits, "add icon1 to himl2");
|
||||
|
||||
/* If himl1 has no images, merge still succeeds */
|
||||
hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
|
||||
ok(hmerge != NULL, "merge himl1,-1 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,-1");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
|
||||
ok(hmerge != NULL,"merge himl1,0 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1,0");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
/* Same happens if himl2 is empty */
|
||||
ImageList_Destroy(himl2);
|
||||
himl2 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl2 != NULL,"failed to recreate himl2\n");
|
||||
if (!himl2)
|
||||
return;
|
||||
|
||||
hmerge = ImageList_Merge(himl1, -1, himl2, -1, 0, 0);
|
||||
ok(hmerge != NULL, "merge himl2,-1 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,-1");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
hmerge = ImageList_Merge(himl1, -1, himl2, 0, 0, 0);
|
||||
ok(hmerge != NULL, "merge himl2,0 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2,0");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
/* Now try merging an image with itself */
|
||||
ok(0==ImageList_AddIcon(himl2, hicon1),"re-add icon1 to himl2 failed\n");
|
||||
|
||||
hmerge = ImageList_Merge(himl2, 0, himl2, 0, 0, 0);
|
||||
ok(hmerge != NULL, "merge himl2 with itself failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl2 with itself");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
/* Try merging 2 different image lists */
|
||||
ok(0==ImageList_AddIcon(himl1, hicon1),"add icon1 to himl1 failed\n");
|
||||
|
||||
hmerge = ImageList_Merge(himl1, 0, himl2, 0, 0, 0);
|
||||
ok(hmerge != NULL, "merge himl1 with himl2 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
hmerge = ImageList_Merge(himl1, 0, himl2, 0, 8, 16);
|
||||
ok(hmerge != NULL, "merge himl1 with himl2 8,16 failed\n");
|
||||
check_bits(hwnd, hmerge, 0, 32, empty_bits, "merge himl1 with himl2, 8,16");
|
||||
if (hmerge) ImageList_Destroy(hmerge);
|
||||
|
||||
ImageList_Destroy(himl1);
|
||||
ImageList_Destroy(himl2);
|
||||
DeleteObject(hicon1);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(imagelist)
|
||||
{
|
||||
desktopDC=GetDC(NULL);
|
||||
hinst = GetModuleHandleA(NULL);
|
||||
|
||||
InitCommonControls();
|
||||
|
||||
testHotspot();
|
||||
DoTest1();
|
||||
DoTest2();
|
||||
DoTest3();
|
||||
testMerge();
|
||||
}
|
298
reactos/lib/comctl32/tests/subclass.c
Normal file
298
reactos/lib/comctl32/tests/subclass.c
Normal file
|
@ -0,0 +1,298 @@
|
|||
/* Unit tests for subclassed windows.
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define _WIN32_WINNT 0x0501 /* For SetWindowSubclass/etc */
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
|
||||
static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
|
||||
static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
#define SEND_NEST 0x01
|
||||
#define DELETE_SELF 0x02
|
||||
#define DELETE_PREV 0x04
|
||||
|
||||
struct message {
|
||||
int procnum; /* WndProc id message is expected from */
|
||||
WPARAM wParam; /* expected value of wParam */
|
||||
};
|
||||
|
||||
static int sequence_cnt, sequence_size;
|
||||
static struct message* sequence;
|
||||
|
||||
static const struct message Sub_BasicTest[] = {
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 2, 2 },
|
||||
{ 1, 2 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_DeletedTest[] = {
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_AfterDeletedTest[] = {
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_OldAfterNewTest[] = {
|
||||
{ 3, 1 },
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 3, 2 },
|
||||
{ 2, 2 },
|
||||
{ 1, 2 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_MixTest[] = {
|
||||
{ 3, 1 },
|
||||
{ 4, 1 },
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_MixAndNestTest[] = {
|
||||
{ 3, 1 },
|
||||
{ 4, 1 },
|
||||
{ 3, 2 },
|
||||
{ 4, 2 },
|
||||
{ 2, 2 },
|
||||
{ 1, 2 },
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_MixNestDelTest[] = {
|
||||
{ 3, 1 },
|
||||
{ 4, 1 },
|
||||
{ 3, 2 },
|
||||
{ 2, 2 },
|
||||
{ 1, 2 },
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message Sub_MixDelPrevTest[] = {
|
||||
{ 3, 1 },
|
||||
{ 5, 1 },
|
||||
{ 2, 1 },
|
||||
{ 1, 1 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void add_message(const struct message *msg)
|
||||
{
|
||||
if (!sequence)
|
||||
{
|
||||
sequence_size = 10;
|
||||
sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
|
||||
}
|
||||
if (sequence_cnt == sequence_size)
|
||||
{
|
||||
sequence_size *= 2;
|
||||
sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
|
||||
}
|
||||
assert(sequence);
|
||||
|
||||
sequence[sequence_cnt].wParam = msg->wParam;
|
||||
sequence[sequence_cnt].procnum = msg->procnum;
|
||||
|
||||
sequence_cnt++;
|
||||
}
|
||||
|
||||
static void flush_sequence()
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, sequence);
|
||||
sequence = 0;
|
||||
sequence_cnt = sequence_size = 0;
|
||||
}
|
||||
|
||||
static void ok_sequence(const struct message *expected, const char *context)
|
||||
{
|
||||
static const struct message end_of_sequence = { 0, 0 };
|
||||
const struct message *actual;
|
||||
|
||||
add_message(&end_of_sequence);
|
||||
|
||||
actual = sequence;
|
||||
|
||||
while(expected->procnum && actual->procnum)
|
||||
{
|
||||
ok(expected->procnum == actual->procnum,
|
||||
"%s: the procnum %d was expected, but got procnum %d instead\n",
|
||||
context, expected->procnum, actual->procnum);
|
||||
ok(expected->wParam == actual->wParam,
|
||||
"%s: in procnum %d expecting wParam 0x%x got 0x%x\n",
|
||||
context, expected->procnum, expected->wParam, actual->wParam);
|
||||
expected++;
|
||||
actual++;
|
||||
}
|
||||
ok(!expected->procnum, "Received fewer messages than expected\n");
|
||||
ok(!actual->procnum, "Received more messages than expected\n");
|
||||
flush_sequence();
|
||||
}
|
||||
|
||||
static LRESULT WINAPI WndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = 1;
|
||||
add_message(&msg);
|
||||
}
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
static WNDPROC origProc3;
|
||||
static LRESULT WINAPI WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = 3;
|
||||
add_message(&msg);
|
||||
}
|
||||
return CallWindowProc(origProc3, hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI WndProcSub(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uldSubclass, DWORD_PTR dwRefData)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = uldSubclass;
|
||||
add_message(&msg);
|
||||
|
||||
if(lParam) {
|
||||
if(dwRefData & DELETE_SELF) {
|
||||
pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass);
|
||||
pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass);
|
||||
}
|
||||
if(dwRefData & DELETE_PREV)
|
||||
pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass-1);
|
||||
if(dwRefData & SEND_NEST)
|
||||
SendMessage(hwnd, WM_USER, wParam+1, 0);
|
||||
}
|
||||
}
|
||||
return pDefSubclassProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static void test_subclass()
|
||||
{
|
||||
HWND hwnd = CreateWindowExA(0, "TestSubclass", "Test subclass", WS_OVERLAPPEDWINDOW,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
assert(hwnd);
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 2, 0);
|
||||
SendMessage(hwnd, WM_USER, 1, 0);
|
||||
SendMessage(hwnd, WM_USER, 2, 0);
|
||||
ok_sequence(Sub_BasicTest, "Basic");
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 2, DELETE_SELF);
|
||||
SendMessage(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_DeletedTest, "Deleted");
|
||||
|
||||
SendMessage(hwnd, WM_USER, 1, 0);
|
||||
ok_sequence(Sub_AfterDeletedTest, "After Deleted");
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 2, 0);
|
||||
origProc3 = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WndProc3);
|
||||
SendMessage(hwnd, WM_USER, 1, 0);
|
||||
SendMessage(hwnd, WM_USER, 2, 0);
|
||||
ok_sequence(Sub_OldAfterNewTest, "Old after New");
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 4, 0);
|
||||
SendMessage(hwnd, WM_USER, 1, 0);
|
||||
ok_sequence(Sub_MixTest, "Mix");
|
||||
|
||||
/* Now the fun starts */
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 4, SEND_NEST);
|
||||
SendMessage(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixAndNestTest, "Mix and nest");
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 4, SEND_NEST | DELETE_SELF);
|
||||
SendMessage(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixNestDelTest, "Mix, nest, del");
|
||||
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 4, 0);
|
||||
pSetWindowSubclass(hwnd, WndProcSub, 5, DELETE_PREV);
|
||||
SendMessage(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixDelPrevTest, "Mix and del prev");
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static BOOL RegisterWindowClasses(void)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = WndProc1;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleA(0);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = NULL;
|
||||
cls.hbrBackground = NULL;
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "TestSubclass";
|
||||
if(!RegisterClassA(&cls)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
START_TEST(subclass)
|
||||
{
|
||||
HMODULE hdll;
|
||||
|
||||
hdll = GetModuleHandleA("comctl32.dll");
|
||||
assert(hdll);
|
||||
pSetWindowSubclass = (void*)GetProcAddress(hdll, "SetWindowSubclass");
|
||||
pRemoveWindowSubclass = (void*)GetProcAddress(hdll, "RemoveWindowSubclass");
|
||||
pDefSubclassProc = (void*)GetProcAddress(hdll, "DefSubclassProc");
|
||||
|
||||
if(!pSetWindowSubclass || !pRemoveWindowSubclass || !pDefSubclassProc)
|
||||
return;
|
||||
|
||||
if(!RegisterWindowClasses()) assert(0);
|
||||
|
||||
test_subclass();
|
||||
}
|
197
reactos/lib/comctl32/tests/tab.c
Normal file
197
reactos/lib/comctl32/tests/tab.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* Unit test suite for tab control.
|
||||
*
|
||||
* Copyright 2003 Vitaliy Margolen
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#undef VISIBLE
|
||||
|
||||
#define TAB_DEFAULT_WIDTH 96
|
||||
#define TAB_PADDING_X 2
|
||||
#define TAB_PADDING_Y 2
|
||||
|
||||
#ifdef VISIBLE
|
||||
#define WAIT Sleep (1000)
|
||||
#define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW)
|
||||
#define trace_tab(str) trace(str)
|
||||
#else
|
||||
#define WAIT
|
||||
#define REDRAW(hwnd)
|
||||
#define trace_tab(str)
|
||||
#endif
|
||||
|
||||
HWND
|
||||
create_tabcontrol (DWORD style)
|
||||
{
|
||||
HWND handle;
|
||||
TCITEM tcNewTab;
|
||||
|
||||
handle = CreateWindow (
|
||||
WC_TABCONTROLA,
|
||||
"TestTab",
|
||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
|
||||
10, 10, 300, 100,
|
||||
NULL, NULL, NULL, 0);
|
||||
|
||||
assert (handle);
|
||||
|
||||
SetWindowLong(handle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style);
|
||||
|
||||
tcNewTab.mask = TCIF_TEXT | TCIF_IMAGE;
|
||||
tcNewTab.pszText = "Tab 1";
|
||||
tcNewTab.iImage = 0;
|
||||
SendMessage (handle, TCM_INSERTITEM, 0, (LPARAM) &tcNewTab);
|
||||
tcNewTab.pszText = "Wide Tab 2";
|
||||
tcNewTab.iImage = 1;
|
||||
SendMessage (handle, TCM_INSERTITEM, 1, (LPARAM) &tcNewTab);
|
||||
tcNewTab.pszText = "T 3";
|
||||
tcNewTab.iImage = 2;
|
||||
SendMessage (handle, TCM_INSERTITEM, 2, (LPARAM) &tcNewTab);
|
||||
|
||||
#ifdef VISIBLE
|
||||
ShowWindow (handle, SW_SHOW);
|
||||
#endif
|
||||
REDRAW(handle);
|
||||
WAIT;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void CheckSize(HWND hwnd, INT width, INT height)
|
||||
{
|
||||
RECT rTab, r1;
|
||||
|
||||
r1.left=r1.top=r1.right=r1.bottom=0;
|
||||
SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);
|
||||
SendMessage (hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM) &r1);
|
||||
/* trace ("Got (%ld,%ld)-(%ld,%ld)\n", rTab.left, rTab.top, rTab.right, rTab.bottom); */
|
||||
trace (" (%ld,%ld)-(%ld,%ld)\n", r1.left, r1.top, r1.right, r1.bottom);
|
||||
if ((width >= 0) && (height < 0))
|
||||
ok (width == rTab.right - rTab.left, "Expected [%d] got [%ld]\n", width, rTab.right - rTab.left);
|
||||
else if ((height >= 0) && (width < 0))
|
||||
ok (height == rTab.bottom - rTab.top, "Expected [%d] got [%ld]\n", height, rTab.bottom - rTab.top);
|
||||
else
|
||||
ok ((width == rTab.right - rTab.left) &&
|
||||
(height == rTab.bottom - rTab.top ),
|
||||
"Expected [%d,%d] got [%ld,%ld]\n", width, height, rTab.right - rTab.left, rTab.bottom - rTab.top);
|
||||
}
|
||||
|
||||
void TabCheckSetSize(HWND hwnd, INT SetWidth, INT SetHeight, INT ExpWidth, INT ExpHeight)
|
||||
{
|
||||
SendMessage (hwnd, TCM_SETITEMSIZE, 0,
|
||||
(LPARAM) MAKELPARAM((SetWidth >= 0) ? SetWidth:0, (SetHeight >= 0) ? SetHeight:0));
|
||||
REDRAW(hwnd);
|
||||
CheckSize(hwnd, ExpWidth, ExpHeight);
|
||||
WAIT;
|
||||
}
|
||||
|
||||
START_TEST(tab)
|
||||
{
|
||||
HWND hwTab;
|
||||
HIMAGELIST himl = ImageList_Create(21, 21, ILC_COLOR, 3, 4);
|
||||
|
||||
InitCommonControls();
|
||||
|
||||
|
||||
hwTab = create_tabcontrol(TCS_FIXEDWIDTH);
|
||||
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH tabs no icon...\n");
|
||||
trace_tab (" default width...\n");
|
||||
CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
|
||||
trace_tab (" set size...\n");
|
||||
TabCheckSetSize(hwTab, 50, 20, 50, 20);
|
||||
WAIT;
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 0, 1);
|
||||
WAIT;
|
||||
|
||||
SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
|
||||
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH tabs with icon...\n");
|
||||
trace_tab (" set size > icon...\n");
|
||||
TabCheckSetSize(hwTab, 50, 30, 50, 30);
|
||||
trace_tab (" set size < icon...\n");
|
||||
TabCheckSetSize(hwTab, 20, 20, 25, 20);
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 25, 1);
|
||||
|
||||
DestroyWindow (hwTab);
|
||||
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH buttons no icon...\n");
|
||||
hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BUTTONS);
|
||||
|
||||
trace_tab (" default width...\n");
|
||||
CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
|
||||
trace_tab (" set size 1...\n");
|
||||
TabCheckSetSize(hwTab, 20, 20, 20, 20);
|
||||
trace_tab (" set size 2...\n");
|
||||
TabCheckSetSize(hwTab, 10, 50, 10, 50);
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 0, 1);
|
||||
|
||||
SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
|
||||
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH buttons with icon...\n");
|
||||
trace_tab (" set size > icon...\n");
|
||||
TabCheckSetSize(hwTab, 50, 30, 50, 30);
|
||||
trace_tab (" set size < icon...\n");
|
||||
TabCheckSetSize(hwTab, 20, 20, 25, 20);
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 25, 1);
|
||||
trace_tab (" Add padding...\n");
|
||||
SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 25, 1);
|
||||
|
||||
DestroyWindow (hwTab);
|
||||
|
||||
hwTab = create_tabcontrol(TCS_FIXEDWIDTH | TCS_BOTTOM);
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs no icon...\n");
|
||||
|
||||
trace_tab (" default width...\n");
|
||||
CheckSize(hwTab, TAB_DEFAULT_WIDTH, -1);
|
||||
trace_tab (" set size 1...\n");
|
||||
TabCheckSetSize(hwTab, 20, 20, 20, 20);
|
||||
trace_tab (" set size 2...\n");
|
||||
TabCheckSetSize(hwTab, 10, 50, 10, 50);
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 0, 1);
|
||||
|
||||
SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl);
|
||||
|
||||
trace_tab ("Testing TCS_FIXEDWIDTH | TCS_BOTTOM tabs with icon...\n");
|
||||
trace_tab (" set size > icon...\n");
|
||||
TabCheckSetSize(hwTab, 50, 30, 50, 30);
|
||||
trace_tab (" set size < icon...\n");
|
||||
TabCheckSetSize(hwTab, 20, 20, 25, 20);
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 25, 1);
|
||||
trace_tab (" Add padding...\n");
|
||||
SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4));
|
||||
trace_tab (" min size...\n");
|
||||
TabCheckSetSize(hwTab, 0, 1, 25, 1);
|
||||
|
||||
DestroyWindow (hwTab);
|
||||
|
||||
|
||||
ImageList_Destroy(himl);
|
||||
}
|
31
reactos/lib/comctl32/tests/testlist.c
Normal file
31
reactos/lib/comctl32/tests/testlist.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Automatically generated file; DO NOT EDIT!! */
|
||||
|
||||
/* stdarg.h is needed for Winelib */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
||||
extern void func_dpa(void);
|
||||
extern void func_imagelist(void);
|
||||
extern void func_subclass(void);
|
||||
extern void func_tab(void);
|
||||
|
||||
struct test
|
||||
{
|
||||
const char *name;
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
static const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "dpa", func_dpa },
|
||||
{ "imagelist", func_imagelist },
|
||||
{ "subclass", func_subclass },
|
||||
{ "tab", func_tab },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#define WINETEST_WANT_MAIN
|
||||
#include "wine/test.h"
|
Loading…
Reference in a new issue