mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 17:35:07 +00:00
Added Wine regression tests for comctl32. (Untested)
svn path=/trunk/; revision=13950
This commit is contained in:
parent
eab893a17c
commit
e8451b25d5
80
reactos/lib/comctl32/winetest/dpa.c
Normal file
80
reactos/lib/comctl32/winetest/dpa.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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 "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/winetest/imagelist.c
Normal file
560
reactos/lib/comctl32/winetest/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(int cx, int 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 nonexistent icon\n");
|
||||||
|
/* removing everything from an empty imagelist should succeed */
|
||||||
|
ok(ImageList_RemoveAll(himl),"removed nonexistent 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 nonexistent 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 nonexistent 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();
|
||||||
|
}
|
31
reactos/lib/comctl32/winetest/makefile
Normal file
31
reactos/lib/comctl32/winetest/makefile
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# $Id: Makefile 12745 2005-01-03 02:37:10Z sedwards $
|
||||||
|
|
||||||
|
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 -D__REACTOS__
|
||||||
|
|
||||||
|
TARGET_NAME = comctl32_test
|
||||||
|
|
||||||
|
TARGET_SDKLIBS = shlwapi.a gdi32.a comctl32.a ntdll.a wine.a
|
||||||
|
|
||||||
|
TARGET_OBJECTS = \
|
||||||
|
testlist.o \
|
||||||
|
dpa.o \
|
||||||
|
imagelist.o \
|
||||||
|
mru.o \
|
||||||
|
subclass.o \
|
||||||
|
tab.o
|
||||||
|
|
||||||
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
|
include $(TOOLS_PATH)/helper.mk
|
||||||
|
|
||||||
|
# EOF
|
295
reactos/lib/comctl32/winetest/mru.c
Normal file
295
reactos/lib/comctl32/winetest/mru.c
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
* comctl32 MRU unit tests
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
|
||||||
|
*
|
||||||
|
* 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 "winreg.h"
|
||||||
|
#include "commctrl.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
/* Keys for testing MRU functions */
|
||||||
|
#define REG_TEST_BASEKEYA "Software\\Wine"
|
||||||
|
#define REG_TEST_BASESUBKEYA "Test"
|
||||||
|
#define REG_TEST_KEYA REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
|
||||||
|
#define REG_TEST_SUBKEYA "MRUTest"
|
||||||
|
#define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
|
||||||
|
|
||||||
|
/* Undocumented MRU structures & functions */
|
||||||
|
typedef struct tagCREATEMRULISTA
|
||||||
|
{
|
||||||
|
DWORD cbSize;
|
||||||
|
DWORD nMaxItems;
|
||||||
|
DWORD dwFlags;
|
||||||
|
HKEY hKey;
|
||||||
|
LPCSTR lpszSubKey;
|
||||||
|
PROC lpfnCompare;
|
||||||
|
} CREATEMRULISTA, *LPCREATEMRULISTA;
|
||||||
|
|
||||||
|
#define MRUF_STRING_LIST 0
|
||||||
|
#define MRUF_BINARY_LIST 1
|
||||||
|
#define MRUF_DELAYED_SAVE 2
|
||||||
|
|
||||||
|
#define LIST_SIZE 3 /* Max entries for each mru */
|
||||||
|
|
||||||
|
static CREATEMRULISTA mruA =
|
||||||
|
{
|
||||||
|
sizeof(CREATEMRULISTA),
|
||||||
|
LIST_SIZE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_TEST_SUBKEYA,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static HMODULE hComctl32;
|
||||||
|
static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA);
|
||||||
|
static void (WINAPI *pFreeMRUList)(HANDLE);
|
||||||
|
static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
|
||||||
|
/*
|
||||||
|
static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
|
||||||
|
static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
|
||||||
|
*/
|
||||||
|
|
||||||
|
static BOOL create_reg_entries(void)
|
||||||
|
{
|
||||||
|
HKEY hKey = NULL;
|
||||||
|
|
||||||
|
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
|
||||||
|
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||||
|
if (!hKey) return FALSE;
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_reg_entries(void)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_BASEKEYA, 0, KEY_ALL_ACCESS,
|
||||||
|
&hKey))
|
||||||
|
return;
|
||||||
|
SHDeleteKeyA(hKey, REG_TEST_BASESUBKEYA);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_reg_entries(const char *mrulist, const char**items)
|
||||||
|
{
|
||||||
|
char buff[128];
|
||||||
|
HKEY hKey = NULL;
|
||||||
|
DWORD type, size, ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
ok(!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
|
||||||
|
"Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
|
||||||
|
if (!hKey) return;
|
||||||
|
|
||||||
|
type = REG_SZ;
|
||||||
|
size = sizeof(buff);
|
||||||
|
buff[0] = '\0';
|
||||||
|
ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
|
||||||
|
|
||||||
|
ok(!ret && buff[0], "Checking MRU: got %ld from RegQueryValueExW\n", ret);
|
||||||
|
if(ret || !buff[0]) return;
|
||||||
|
|
||||||
|
ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
|
||||||
|
mrulist, buff);
|
||||||
|
if(strcmp(buff, mrulist)) return;
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(mrulist); i++)
|
||||||
|
{
|
||||||
|
char name[2];
|
||||||
|
name[0] = mrulist[i];
|
||||||
|
name[1] = '\0';
|
||||||
|
type = REG_SZ;
|
||||||
|
size = sizeof(buff);
|
||||||
|
buff[0] = '\0';
|
||||||
|
ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
|
||||||
|
ok(!ret && buff[0],
|
||||||
|
"Checking MRU item %d ('%c'): got %ld from RegQueryValueExW\n",
|
||||||
|
i, mrulist[i], ret);
|
||||||
|
if(ret || !buff[0]) return;
|
||||||
|
ok(!strcmp(buff, items[mrulist[i]-'a']),
|
||||||
|
"Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
|
||||||
|
i, mrulist[i], buff, items[mrulist[i] - 'a']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT CALLBACK cmp_mru_strA(LPCVOID data1, LPCVOID data2)
|
||||||
|
{
|
||||||
|
return lstrcmpiA(data1, data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE create_mruA(HKEY hKey, DWORD flags, PROC cmp)
|
||||||
|
{
|
||||||
|
mruA.dwFlags = flags;
|
||||||
|
mruA.lpfnCompare = cmp;
|
||||||
|
mruA.hKey = hKey;
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
return pCreateMRUListA(&mruA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_MRUListA(void)
|
||||||
|
{
|
||||||
|
const char *checks[LIST_SIZE+1];
|
||||||
|
HANDLE hMRU;
|
||||||
|
HKEY hKey;
|
||||||
|
INT iRet;
|
||||||
|
|
||||||
|
pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
|
||||||
|
pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
|
||||||
|
pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
|
||||||
|
if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0 /* Create (NULL) - crashes native */
|
||||||
|
hMRU = pCreateMRUListA(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Create (size too small) */
|
||||||
|
mruA.cbSize = sizeof(mruA) - 2;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(too small) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.cbSize = sizeof(mruA);
|
||||||
|
|
||||||
|
/* Create (size too big) */
|
||||||
|
mruA.cbSize = sizeof(mruA) + 2;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(too big) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.cbSize = sizeof(mruA);
|
||||||
|
|
||||||
|
/* Create (NULL hKey) */
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(NULL key) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
|
||||||
|
/* Create (NULL name) */
|
||||||
|
mruA.lpszSubKey = NULL;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(NULL name) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.lpszSubKey = REG_TEST_SUBKEYA;
|
||||||
|
|
||||||
|
/* Create a string MRU */
|
||||||
|
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
|
||||||
|
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||||
|
if (!hKey)
|
||||||
|
return;
|
||||||
|
hMRU = create_mruA(hKey, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok(hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(string) expected non-NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
|
||||||
|
if (hMRU)
|
||||||
|
{
|
||||||
|
checks[0] = "Test 1";
|
||||||
|
checks[1] = "Test 2";
|
||||||
|
checks[2] = "Test 3";
|
||||||
|
checks[3] = "Test 4";
|
||||||
|
|
||||||
|
/* Add (NULL list) */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(NULL, checks[0]);
|
||||||
|
ok(iRet == -1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(NULL list) expected -1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
|
||||||
|
/* Add (NULL string) */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, NULL);
|
||||||
|
ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
|
||||||
|
/* Add 3 strings. Check the registry is correct after each add */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[0]);
|
||||||
|
ok(iRet == 0 && !GetLastError(),
|
||||||
|
"AddMRUStringA(1) expected 0,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("a", checks);
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||||
|
ok(iRet == 1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(2) expected 1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("ba", checks);
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[2]);
|
||||||
|
ok(iRet == 2 && !GetLastError(),
|
||||||
|
"AddMRUStringA(2) expected 2,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("cba", checks);
|
||||||
|
|
||||||
|
/* Add a duplicate of the 2nd string - it should move to the front,
|
||||||
|
* but keep the same index in the registry.
|
||||||
|
*/
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||||
|
ok(iRet == 1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(re-add 1) expected 1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("bca", checks);
|
||||||
|
|
||||||
|
/* Add a new string - replaces the oldest string + moves to the front */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[3]);
|
||||||
|
ok(iRet == 0 && !GetLastError(),
|
||||||
|
"AddMRUStringA(add new) expected 0,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
checks[0] = checks[3];
|
||||||
|
check_reg_entries("abc", checks);
|
||||||
|
|
||||||
|
/* Finished with this MRU */
|
||||||
|
pFreeMRUList(hMRU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free (NULL list) - Doesn't crash */
|
||||||
|
pFreeMRUList(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(mru)
|
||||||
|
{
|
||||||
|
hComctl32 = GetModuleHandleA("comctl32.dll");
|
||||||
|
if (!hComctl32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete_reg_entries();
|
||||||
|
if (!create_reg_entries())
|
||||||
|
return;
|
||||||
|
|
||||||
|
test_MRUListA();
|
||||||
|
|
||||||
|
delete_reg_entries();
|
||||||
|
}
|
298
reactos/lib/comctl32/winetest/subclass.c
Normal file
298
reactos/lib/comctl32/winetest/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/winetest/tab.c
Normal file
197
reactos/lib/comctl32/winetest/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);
|
||||||
|
}
|
33
reactos/lib/comctl32/winetest/testlist.c
Normal file
33
reactos/lib/comctl32/winetest/testlist.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/* 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_mru(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 },
|
||||||
|
{ "mru", func_mru },
|
||||||
|
{ "subclass", func_subclass },
|
||||||
|
{ "tab", func_tab },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define WINETEST_WANT_MAIN
|
||||||
|
#include "wine/test.h"
|
Loading…
Reference in a new issue