mirror of
https://github.com/reactos/reactos.git
synced 2026-06-09 17:33:50 +08:00
[COMCTL32][COMCTL32_APITEST] Implement ImageList Get/SetFlags and the system flag (#7701)
The shell needs to be able to change the color depth of the system image lists on the fly and it does that by changing the ILC_COLOR* flags.
This commit is contained in:
@@ -121,7 +121,13 @@ struct _IMAGELIST
|
||||
#ifdef __REACTOS__
|
||||
#define IMAGELIST_MAGIC_DESTROYED 0x44454144
|
||||
#define IMAGELIST_VERSION 0x101
|
||||
#endif
|
||||
|
||||
#define WinVerMajor() LOBYTE(GetVersion())
|
||||
|
||||
#include <comctl32_undoc.h>
|
||||
#define ILC_PUBLICFLAGS ( 0xFFFFFFFF ) /* Allow all flags for now */
|
||||
#define ILC_COLORMASK 0xFE
|
||||
#endif /* __REACTOS__ */
|
||||
|
||||
/* Header used by ImageList_Read() and ImageList_Write() */
|
||||
#include "pshpack2.h"
|
||||
@@ -935,7 +941,12 @@ BOOL WINAPI
|
||||
ImageList_Destroy (HIMAGELIST himl)
|
||||
{
|
||||
if (!is_valid(himl))
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
if ((himl->flags & ILC_SYSTEM) && WinVerMajor() >= 6)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
IImageList_Release((IImageList *) himl);
|
||||
return TRUE;
|
||||
@@ -1944,7 +1955,7 @@ ImageList_GetFlags(HIMAGELIST himl)
|
||||
#ifdef __REACTOS__
|
||||
if(!is_valid2(himl))
|
||||
return 0;
|
||||
return himl->flags;
|
||||
return himl->flags & ILC_PUBLICFLAGS;
|
||||
#else
|
||||
return is_valid(himl) ? himl->flags : 0;
|
||||
#endif
|
||||
@@ -3047,12 +3058,46 @@ ImageList_SetFilter (HIMAGELIST himl, INT i, DWORD dwFilter)
|
||||
* Stub.
|
||||
*/
|
||||
|
||||
#ifdef __REACTOS__
|
||||
static BOOL
|
||||
ChangeColorDepth(HIMAGELIST himl)
|
||||
{
|
||||
UINT ilc = himl->flags & ILC_COLORMASK;
|
||||
if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
|
||||
himl->uBitsPixel = ilc;
|
||||
else
|
||||
himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
|
||||
|
||||
/* Create new himl->hbmImage for BPP changes (for SHELL32) */
|
||||
return ((IImageList*)himl)->lpVtbl->SetImageCount((IImageList*)himl, 0) == S_OK;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
ImageList_SetFlags(HIMAGELIST himl, DWORD flags)
|
||||
{
|
||||
if (!is_valid(himl))
|
||||
return FALSE;
|
||||
|
||||
if (flags & ~ILC_PUBLICFLAGS)
|
||||
return FALSE;
|
||||
|
||||
if (((himl->flags ^ flags) & ILC_SYSTEM) && WinVerMajor() < 6)
|
||||
return FALSE; /* Can't change this flag */
|
||||
|
||||
if (himl->flags == flags && WinVerMajor() >= 6)
|
||||
return TRUE;
|
||||
|
||||
himl->flags = flags;
|
||||
return ChangeColorDepth(himl);
|
||||
}
|
||||
#else
|
||||
DWORD WINAPI
|
||||
ImageList_SetFlags(HIMAGELIST himl, DWORD flags)
|
||||
{
|
||||
FIXME("(%p %08x):empty stub\n", himl, flags);
|
||||
return 0;
|
||||
}
|
||||
#endif /* __REACTOS__ */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
add_executable(comctl32_apitest button.c propsheet.c toolbar.c testlist.c ../include/msgtrace.c comctl32_apitest.rc)
|
||||
add_executable(comctl32_apitest button.c imagelist.c propsheet.c toolbar.c testlist.c ../include/msgtrace.c comctl32_apitest.rc)
|
||||
target_link_libraries(comctl32_apitest wine)
|
||||
set_module_type(comctl32_apitest win32cui)
|
||||
add_importlibs(comctl32_apitest uxtheme comctl32 user32 gdi32 msvcrt kernel32 ntdll)
|
||||
|
||||
152
modules/rostests/apitests/comctl32/imagelist.c
Normal file
152
modules/rostests/apitests/comctl32/imagelist.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Test for imagelist
|
||||
* COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
|
||||
*/
|
||||
|
||||
#include "wine/test.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <comctl32_undoc.h>
|
||||
|
||||
#define WinVerMajor() LOBYTE(GetVersion())
|
||||
|
||||
#define ILC_COLORMASK 0xfe
|
||||
#define IL_IMGSIZE 16
|
||||
|
||||
static BOOL IL_IsValid(HIMAGELIST himl)
|
||||
{
|
||||
int w = -42, h;
|
||||
if (!himl || IsBadReadPtr(himl, sizeof(void*)))
|
||||
return FALSE;
|
||||
return ImageList_GetIconSize(himl, &w, &h) && w != -42;
|
||||
}
|
||||
|
||||
static HRESULT IL_Destroy(HIMAGELIST himl)
|
||||
{
|
||||
if (himl && !IL_IsValid(himl))
|
||||
return E_INVALIDARG;
|
||||
return ImageList_Destroy(himl) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
static inline HIMAGELIST IL_Create(UINT flags)
|
||||
{
|
||||
return ImageList_Create(IL_IMGSIZE, IL_IMGSIZE, flags, 1, 0);
|
||||
}
|
||||
|
||||
static UINT IL_CalculateOtherBpp(UINT ilc)
|
||||
{
|
||||
UINT bpp = (ilc & ILC_COLORMASK) == ILC_COLOR32 ? ILC_COLOR16 : ILC_COLOR32;
|
||||
return (ilc & ~ILC_COLORMASK) | bpp;
|
||||
}
|
||||
|
||||
static BOOL IL_AddImagesForTest(HIMAGELIST himl)
|
||||
{
|
||||
int idx = -1;
|
||||
HINSTANCE hInst = LoadLibraryW(L"USER32");
|
||||
if (!hInst)
|
||||
return FALSE;
|
||||
HICON hIco = (HICON)LoadImage(hInst, MAKEINTRESOURCE(100), /* Windows */
|
||||
IMAGE_ICON, IL_IMGSIZE, IL_IMGSIZE, 0);
|
||||
if (!hIco)
|
||||
hIco = (HICON)LoadImage(hInst, MAKEINTRESOURCE(32512), /* ReactOS */
|
||||
IMAGE_ICON, IL_IMGSIZE, IL_IMGSIZE, 0);
|
||||
|
||||
if (hIco)
|
||||
{
|
||||
idx = ImageList_AddIcon(himl, hIco);
|
||||
DestroyIcon(hIco);
|
||||
}
|
||||
FreeLibrary(hInst);
|
||||
return idx != -1;
|
||||
}
|
||||
|
||||
static void Test_SystemIL(void)
|
||||
{
|
||||
const UINT flags = ILC_COLOR16 | ILC_MASK;
|
||||
HIMAGELIST himl;
|
||||
|
||||
himl = IL_Create(flags);
|
||||
ok(IL_Destroy(himl) == S_OK && !IL_IsValid(himl), "Can destroy normal\n");
|
||||
|
||||
/* You can (sometimes) destroy a system imagelist!
|
||||
* On Win9x it destroys it for all processes according to
|
||||
* https://sporks.space/2021/09/18/notes-on-the-system-image-list/ and
|
||||
* https://www.catch22.net/tuts/win32/system-image-list/
|
||||
*/
|
||||
himl = IL_Create(flags | ILC_SYSTEM);
|
||||
if (WinVerMajor() >= 6)
|
||||
ok(IL_Destroy(himl) == S_FALSE && IL_IsValid(himl), "Can't destroy system\n");
|
||||
else
|
||||
ok(IL_Destroy(himl) == S_OK && !IL_IsValid(himl), "Can destroy system\n");
|
||||
}
|
||||
|
||||
static void Test_Flags(void)
|
||||
{
|
||||
const UINT flags = ILC_COLOR16 | ILC_MASK;
|
||||
UINT flagsIn, flagsOut;
|
||||
HIMAGELIST himl;
|
||||
|
||||
himl = IL_Create(flagsIn = flags);
|
||||
flagsOut = ImageList_GetFlags(himl);
|
||||
if (himl ? TRUE : (skip("Could not initialize\n"), FALSE))
|
||||
{
|
||||
ok((flagsOut & ILC_COLORMASK) == (flagsIn & ILC_COLORMASK), "ILC_COLOR\n");
|
||||
ok(!(flagsOut & ILC_SYSTEM), "!ILC_SYSTEM\n");
|
||||
|
||||
ok(IL_AddImagesForTest(himl), "Initialize\n");
|
||||
flagsIn = IL_CalculateOtherBpp(flagsIn);
|
||||
ok(ImageList_SetFlags(himl, flagsIn), "Can change BPP\n");
|
||||
ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images\n");
|
||||
|
||||
ok(IL_AddImagesForTest(himl), "Initialize\n");
|
||||
ok(ImageList_SetFlags(himl, ImageList_GetFlags(himl)), "Can set same flags\n");
|
||||
if (WinVerMajor() >= 6)
|
||||
{
|
||||
ok(ImageList_GetImageCount(himl) != 0, "SetFlags does not delete with same flags\n");
|
||||
ok(ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can change ILC_SYSTEM\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images even with same flags\n");
|
||||
ok(!ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can't change ILC_SYSTEM\n");
|
||||
}
|
||||
|
||||
IL_Destroy(himl);
|
||||
}
|
||||
|
||||
himl = IL_Create(flagsIn = flags | ILC_SYSTEM);
|
||||
flagsOut = ImageList_GetFlags(himl);
|
||||
if (himl ? TRUE : (skip("Could not initialize\n"), FALSE))
|
||||
{
|
||||
ok((flagsOut & ILC_SYSTEM), "ILC_SYSTEM\n"); /* Flag is not hidden */
|
||||
|
||||
ok(IL_AddImagesForTest(himl), "Initialize\n");
|
||||
|
||||
flagsIn = IL_CalculateOtherBpp(flagsIn);
|
||||
ok(ImageList_SetFlags(himl, flagsIn), "Can change BPP\n");
|
||||
ok(ImageList_GetImageCount(himl) == 0, "SetFlags deletes all images\n");
|
||||
|
||||
ok(IL_AddImagesForTest(himl), "Initialize\n");
|
||||
ok(ImageList_SetFlags(himl, ImageList_GetFlags(himl)), "Can set same flags\n");
|
||||
if (WinVerMajor() >= 6)
|
||||
{
|
||||
ok(ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can change ILC_SYSTEM\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(!ImageList_SetFlags(himl, flagsIn ^ ILC_SYSTEM), "Can't change ILC_SYSTEM\n");
|
||||
}
|
||||
|
||||
IL_Destroy(himl);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(imagelist)
|
||||
{
|
||||
InitCommonControls();
|
||||
Test_SystemIL();
|
||||
Test_Flags();
|
||||
}
|
||||
@@ -2,12 +2,14 @@
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_button(void);
|
||||
extern void func_imagelist(void);
|
||||
extern void func_propsheet(void);
|
||||
extern void func_toolbar(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "buttonv6", func_button },
|
||||
{ "imagelist", func_imagelist },
|
||||
{ "propsheetv6", func_propsheet },
|
||||
{ "toolbarv6", func_toolbar },
|
||||
{ 0, 0 }
|
||||
|
||||
@@ -140,6 +140,14 @@ typedef INT (WINAPI *FN_FreeMRUList)(HANDLE);
|
||||
|
||||
// #define GET_PROC(hComCtl32, fn) fn = (FN_##fn)GetProcAddress((hComCtl32), (LPSTR)I_##fn)
|
||||
|
||||
#ifndef NOIMAGEAPIS
|
||||
|
||||
#define ILC_SYSTEM 0x0100 /* Used by the shell system image lists */
|
||||
DWORD WINAPI ImageList_GetFlags(HIMAGELIST himl);
|
||||
BOOL WINAPI ImageList_SetFlags(HIMAGELIST himl, DWORD flags);
|
||||
|
||||
#endif /* NOIMAGEAPIS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
Reference in New Issue
Block a user