Is there a reason why my patch (attached) hasn't been included yet? This is my first patch, so maybe someone can help me get it in.
Joel
>From e8398597bfe4772e065ebd98aa3f93a9f681a2fc Mon Sep 17 00:00:00 2001 From: Joel Holdsworth <j...@airwebreathe.org.uk> Date: Sat, 2 May 2009 10:13:45 +0100 Subject: [PATCH] Added tests for DrawIcon and DrawIconEx --- dlls/user32/tests/cursoricon.c | 209 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 209 insertions(+), 0 deletions(-) diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c index 9475534..de3c582 100644 --- a/dlls/user32/tests/cursoricon.c +++ b/dlls/user32/tests/cursoricon.c @@ -58,12 +58,54 @@ typedef struct static char **test_argv; static int test_argc; + +static HINSTANCE hinst; + static HWND child = 0; static HWND parent = 0; static HANDLE child_process; #define PROC_INIT (WM_USER+1) +static HWND create_a_window(void) +{ + char className[] = "icownd"; + char winName[] = "Test DrawIcon"; + 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, IDI_APPLICATION); + cls.hCursor = LoadCursorA (0, IDC_ARROW); + cls.hbrBackground = 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, 100, 100, 0, + 0, hinst, 0); + + ShowWindow (hWnd, SW_SHOW); + + Sleep(200); + + return hWnd; +} + static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL ret; @@ -956,6 +998,169 @@ static void test_CreateIconFromResource(void) HeapFree(GetProcessHeap(), 0, hotspot); } +static void check_icon_draw(HWND hwnd, BOOL drawiconex, BOOL maskvalue, + UINT32 color, int bpp, COLORREF background, + COLORREF expected) +{ + COLORREF result; + HDC hdc = NULL; + HICON hicon; + RECT rect = {0, 0, 1, 1}; + HBRUSH backgroundBrush; + UINT32 mask; + + if (!hwnd) return; + + mask = maskvalue ? 0xFFFFFFFF : 0x00000000; + hicon = CreateIcon(hinst, 1, 1, 1, bpp, &mask, &color); + + if (!hicon) return; + + hdc = GetDC(hwnd); + + backgroundBrush = CreateSolidBrush(background); + FillRect(hdc, &rect, backgroundBrush); + DeleteObject(backgroundBrush); + + if(drawiconex) + DrawIconEx(hdc, 0, 0, hicon, 1, 1, 0, NULL, DI_NORMAL); + else + DrawIcon(hdc, 0, 0, hicon); + + result = GetPixel(hdc, 0, 0); + + ReleaseDC(hwnd, hdc); + + ok (result == expected, + "Overlaying Mask %d on Color %08X. Expected %08X with %s. Got %08X\n", + maskvalue, (unsigned int)color, (unsigned int)expected, + drawiconex ? "DrawIconEx" : "DrawIcon", (unsigned int)result); +} + +static void check_alpha_draw(HWND hwnd, BOOL drawiconex, BOOL alpha, int bpp) +{ + COLORREF result; + HDC hdc = NULL; + HICON hicon; + RECT rect = {0, 0, 1, 1}; + HBRUSH backgroundBrush; + UINT32 mask; + UINT32 color[2]; + COLORREF expected; + + if (!hwnd) return; + + mask = 0x00000000; + color[0] = 0x00A0B0C0; + color[1] = alpha ? 0xFF000000 : 0x00000000; + expected = alpha ? 0x00FFFFFF : 0x00C0B0A0; + + hicon = CreateIcon(hinst, 2, 1, 1, bpp, &mask, &color); + + if (!hicon) return; + + hdc = GetDC(hwnd); + + backgroundBrush = CreateSolidBrush(0x00FFFFFF); + FillRect(hdc, &rect, backgroundBrush); + DeleteObject(backgroundBrush); + + if(drawiconex) + DrawIconEx(hdc, 0, 0, hicon, 2, 1, 0, NULL, DI_NORMAL); + else + DrawIcon(hdc, 0, 0, hicon); + + result = GetPixel(hdc, 0, 0); + + ReleaseDC(hwnd, hdc); + + ok (result == expected, + "%s. Expected %08X with %s. Got %08X\n", + alpha ? "Alpha blending" : "Not alpha blending", + (unsigned int)expected, drawiconex ? "DrawIconEx" : "DrawIcon", + (unsigned int)result); +} + +static void test_DrawIcon(BOOL drawiconex) +{ + HWND hwnd = create_a_window(); + + UINT display_bpp; + HDC hdc; + + hdc = GetDC(0); + display_bpp = GetDeviceCaps(hdc, BITSPIXEL); + ReleaseDC(0, hdc); + + if(display_bpp == 16) + { + check_icon_draw(hwnd, drawiconex, FALSE, 0x00A0B0C0, 16, 0x00FFFFFF, 0x000018B5); + check_icon_draw(hwnd, drawiconex, TRUE, 0x00A0B0C0, 16, 0x00FFFFFF, 0x00FFE74A); + + check_icon_draw(hwnd, drawiconex, FALSE, 0xFFA0B0C0, 16, 0x00FFFFFF, 0x000018B5); + check_icon_draw(hwnd, drawiconex, TRUE, 0xFFA0B0C0, 16, 0x00FFFFFF, 0x00FFE74A); + check_icon_draw(hwnd, drawiconex, FALSE, 0x80A0B0C0, 16, 0x00FFFFFF, 0x000018B5); + check_icon_draw(hwnd, drawiconex, TRUE, 0x80A0B0C0, 16, 0x00FFFFFF, 0x00FFE74A); + } + + if(display_bpp == 24) + { + check_icon_draw(hwnd, drawiconex, FALSE, 0x00A0B0C0, 24, 0x00FFFFFF, 0x00C0B0A0); + check_icon_draw(hwnd, drawiconex, TRUE, 0x00A0B0C0, 24, 0x00FFFFFF, 0x003F4F5F); + + check_icon_draw(hwnd, drawiconex, FALSE, 0xFFA0B0C0, 24, 0x00FFFFFF, 0x00C0B0A0); + check_icon_draw(hwnd, drawiconex, TRUE, 0xFFA0B0C0, 24, 0x00FFFFFF, 0x003F4F5F); + check_icon_draw(hwnd, drawiconex, FALSE, 0x80A0B0C0, 24, 0x00FFFFFF, 0x00C0B0A0); + check_icon_draw(hwnd, drawiconex, TRUE, 0x80A0B0C0, 24, 0x00FFFFFF, 0x003F4F5F); + } + + if(display_bpp == 32) + { + /* Mask is only heeded if alpha channel is 0x00 */ + check_icon_draw(hwnd, drawiconex, FALSE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0); + + if(drawiconex) + { + todo_wine + { + check_icon_draw(hwnd, TRUE, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F); + } + } + else + check_icon_draw(hwnd, FALSE, TRUE, 0x00A0B0C0, 32, 0x00FFFFFF, 0x003F4F5F); + + check_icon_draw(hwnd, drawiconex, FALSE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0); + + todo_wine + { + check_icon_draw(hwnd, drawiconex, TRUE, 0xFFA0B0C0, 32, 0x00FFFFFF, 0x00C0B0A0); + + check_icon_draw(hwnd, drawiconex, FALSE, 0x80A0B0C0, 32, 0x00000000, 0x00605850); + check_icon_draw(hwnd, drawiconex, TRUE, 0x80A0B0C0, 32, 0x00000000, 0x00605850); + check_icon_draw(hwnd, drawiconex, FALSE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF); + check_icon_draw(hwnd, drawiconex, TRUE, 0x80A0B0C0, 32, 0x00FFFFFF, 0x00DFD7CF); + + check_icon_draw(hwnd, drawiconex, FALSE, 0x01FFFFFF, 32, 0x00000000, 0x00010101); + check_icon_draw(hwnd, drawiconex, TRUE, 0x01FFFFFF, 32, 0x00000000, 0x00010101); + check_icon_draw(hwnd, drawiconex, FALSE, 0xFEFFFFFF, 32, 0x00000000, 0x00FEFEFE); + check_icon_draw(hwnd, drawiconex, TRUE, 0xFEFFFFFF, 32, 0x00000000, 0x00FEFEFE); + } + + /* Test detecting of alpha channel */ + /* If a single pixels alpha channel is non-zero, the icon + will be alpha blended, otherwise it will be draw with + and + xor blts. */ + check_alpha_draw(hwnd, drawiconex, FALSE, 32); + + todo_wine + { + check_alpha_draw(hwnd, drawiconex, TRUE, 32); + } + } + + DestroyWindow(hwnd); +} + static void test_DestroyCursor(void) { static const BYTE bmp_bits[4096]; @@ -1038,6 +1243,8 @@ static void test_DestroyCursor(void) START_TEST(cursoricon) { + hinst = GetModuleHandleA(NULL); + test_argc = winetest_get_mainargs(&test_argv); if (test_argc >= 3) @@ -1063,6 +1270,8 @@ START_TEST(cursoricon) test_CreateIcon(); test_LoadImage(); test_CreateIconFromResource(); + test_DrawIcon(FALSE); + test_DrawIcon(TRUE); test_DestroyCursor(); do_parent(); test_child_process(); -- 1.6.0.4