win32u: Move NtUserGetIconInfo implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-02-23 13:40:33 +01:00 committed by Alexandre Julliard
parent 0885c7cc5a
commit 5b4a57dcc8
8 changed files with 182 additions and 74 deletions

View File

@ -217,35 +217,6 @@ int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
}
/***********************************************************************
* copy_bitmap
*
* Helper function to duplicate a bitmap.
*/
static HBITMAP copy_bitmap( HBITMAP bitmap )
{
HDC src, dst = 0;
HBITMAP new_bitmap = 0;
BITMAP bmp;
if (!bitmap) return 0;
if (!GetObjectW( bitmap, sizeof(bmp), &bmp )) return 0;
if ((src = CreateCompatibleDC( 0 )) && (dst = CreateCompatibleDC( 0 )))
{
SelectObject( src, bitmap );
if ((new_bitmap = CreateCompatibleBitmap( src, bmp.bmWidth, bmp.bmHeight )))
{
SelectObject( dst, new_bitmap );
BitBlt( dst, 0, 0, bmp.bmWidth, bmp.bmHeight, src, 0, 0, SRCCOPY );
}
}
DeleteDC( dst );
DeleteDC( src );
return new_bitmap;
}
/***********************************************************************
* is_dib_monochrome
*
@ -1886,57 +1857,31 @@ BOOL WINAPI GetIconInfoExA( HICON icon, ICONINFOEXA *info )
/**********************************************************************
* GetIconInfoExW (USER32.@)
*/
BOOL WINAPI GetIconInfoExW( HICON icon, ICONINFOEXW *info )
BOOL WINAPI GetIconInfoExW( HICON handle, ICONINFOEXW *ret )
{
struct cursoricon_frame *frame;
struct cursoricon_object *ptr;
BOOL ret = TRUE;
UNICODE_STRING module, res_name;
ICONINFO info;
if (info->cbSize != sizeof(*info))
if (ret->cbSize != sizeof(*ret))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (!(ptr = get_icon_ptr( icon )))
{
SetLastError( ERROR_INVALID_CURSOR_HANDLE );
return FALSE;
}
frame = get_icon_frame( ptr, 0 );
if (!frame)
{
release_user_handle_ptr( ptr );
SetLastError( ERROR_INVALID_CURSOR_HANDLE );
return FALSE;
}
TRACE("%p => %dx%d\n", icon, frame->width, frame->height);
info->fIcon = ptr->is_icon;
info->xHotspot = frame->hotspot.x;
info->yHotspot = frame->hotspot.y;
info->hbmColor = copy_bitmap( frame->color );
info->hbmMask = copy_bitmap( frame->mask );
info->wResID = 0;
info->szModName[0] = 0;
info->szResName[0] = 0;
if (ptr->module.Length)
{
if (IS_INTRESOURCE( ptr->resname )) info->wResID = LOWORD( ptr->resname );
else lstrcpynW( info->szResName, ptr->resname, MAX_PATH );
memcpy( info->szModName, ptr->module.Buffer, ptr->module.Length );
info->szModName[ptr->module.Length / sizeof(WCHAR)] = 0;
}
if (!info->hbmMask || (!info->hbmColor && frame->color))
{
DeleteObject( info->hbmMask );
DeleteObject( info->hbmColor );
ret = FALSE;
}
release_icon_frame( ptr, frame );
release_user_handle_ptr( ptr );
return ret;
module.Buffer = ret->szModName;
module.MaximumLength = sizeof(ret->szModName) - sizeof(WCHAR);
res_name.Buffer = ret->szResName;
res_name.MaximumLength = sizeof(ret->szResName) - sizeof(WCHAR);
if (!NtUserGetIconInfo( handle, &info, &module, &res_name, NULL, 0 )) return FALSE;
ret->fIcon = info.fIcon;
ret->xHotspot = info.xHotspot;
ret->yHotspot = info.yHotspot;
ret->hbmColor = info.hbmColor;
ret->hbmMask = info.hbmMask;
ret->wResID = res_name.Length ? 0 : LOWORD( res_name.Buffer );
ret->szModName[module.Length] = 0;
ret->szResName[res_name.Length] = 0;
return TRUE;
}
/* copy an icon bitmap, even when it can't be selected into a DC */

View File

@ -494,3 +494,101 @@ HCURSOR WINAPI NtUserGetCursorFrameInfo( HCURSOR cursor, DWORD istep, DWORD *rat
release_user_handle_ptr( obj );
return ret;
}
/***********************************************************************
* copy_bitmap
*
* Helper function to duplicate a bitmap.
*/
static HBITMAP copy_bitmap( HBITMAP bitmap )
{
HDC src, dst = 0;
HBITMAP new_bitmap = 0;
BITMAP bmp;
if (!bitmap) return 0;
if (!NtGdiExtGetObjectW( bitmap, sizeof(bmp), &bmp )) return 0;
if ((src = NtGdiCreateCompatibleDC( 0 )) && (dst = NtGdiCreateCompatibleDC( 0 )))
{
NtGdiSelectBitmap( src, bitmap );
if ((new_bitmap = NtGdiCreateCompatibleBitmap( src, bmp.bmWidth, bmp.bmHeight )))
{
NtGdiSelectBitmap( dst, new_bitmap );
NtGdiBitBlt( dst, 0, 0, bmp.bmWidth, bmp.bmHeight, src, 0, 0, SRCCOPY, 0, 0 );
}
}
NtGdiDeleteObjectApp( dst );
NtGdiDeleteObjectApp( src );
return new_bitmap;
}
/**********************************************************************
* NtUserGetIconInfo (win32u.@)
*/
BOOL WINAPI NtUserGetIconInfo( HICON icon, ICONINFO *info, UNICODE_STRING *module,
UNICODE_STRING *res_name, DWORD *bpp, LONG unk )
{
struct cursoricon_object *obj, *frame_obj;
BOOL ret = TRUE;
if (!(obj = get_icon_ptr( icon )))
{
SetLastError( ERROR_INVALID_CURSOR_HANDLE );
return FALSE;
}
if (!(frame_obj = get_icon_frame_ptr( icon, 0 )))
{
release_user_handle_ptr( obj );
return FALSE;
}
TRACE( "%p => %dx%d\n", icon, frame_obj->frame.width, frame_obj->frame.height );
info->fIcon = obj->is_icon;
info->xHotspot = frame_obj->frame.hotspot.x;
info->yHotspot = frame_obj->frame.hotspot.y;
info->hbmColor = copy_bitmap( frame_obj->frame.color );
info->hbmMask = copy_bitmap( frame_obj->frame.mask );
if (!info->hbmMask || (!info->hbmColor && frame_obj->frame.color))
{
NtGdiDeleteObjectApp( info->hbmMask );
NtGdiDeleteObjectApp( info->hbmColor );
ret = FALSE;
}
else if (obj->module.Length)
{
if (module)
{
size_t size = min( module->MaximumLength, obj->module.Length );
if (size) memcpy( module->Buffer, obj->module.Buffer, size );
module->Length = size / sizeof(WCHAR); /* length in chars, not bytes */
}
if (res_name)
{
if (IS_INTRESOURCE( obj->resname ))
{
res_name->Buffer = obj->resname;
res_name->Length = 0;
}
else
{
size_t size = min( res_name->MaximumLength, lstrlenW( obj->resname) * sizeof(WCHAR) );
if (size) memcpy( res_name->Buffer, obj->resname, size );
module->Length = size / sizeof(WCHAR); /* length in chars, not bytes */
}
}
}
else
{
if (module) module->Length = 0;
if (res_name)
{
res_name->Length = 0;
res_name->Buffer = NULL;
}
}
release_user_handle_ptr( frame_obj );
release_user_handle_ptr( obj );
return ret;
}

View File

@ -1162,6 +1162,7 @@ static struct unix_funcs unix_funcs =
NtUserEnumDisplaySettings,
NtUserGetAsyncKeyState,
NtUserGetDisplayConfigBufferSizes,
NtUserGetIconInfo,
NtUserGetKeyNameText,
NtUserGetKeyboardLayoutList,
NtUserGetPriorityClipboardFormat,

View File

@ -182,11 +182,14 @@ static void test_NtUserBuildHwndList(void)
static void test_cursoricon(void)
{
WCHAR module[MAX_PATH], res_buf[MAX_PATH];
UNICODE_STRING module_str, res_str;
BYTE bmp_bits[1024];
LONG width, height;
DWORD rate, steps;
HCURSOR frame;
HANDLE handle;
ICONINFO info;
unsigned int i;
BOOL ret;
@ -212,6 +215,34 @@ static void test_cursoricon(void)
ok( rate == 0, "rate = %lu\n", rate );
ok( steps == 1, "steps = %lu\n", steps );
ret = NtUserGetIconInfo( handle, &info, NULL, NULL, NULL, 0 );
ok( ret, "NtUserGetIconInfo failed: %lu\n", GetLastError() );
ok( info.fIcon == TRUE, "fIcon = %x\n", info.fIcon );
ok( info.xHotspot == 8, "xHotspot = %lx\n", info.xHotspot );
ok( info.yHotspot == 8, "yHotspot = %lx\n", info.yHotspot );
DeleteObject( info.hbmColor );
DeleteObject( info.hbmMask );
memset( module, 0xcc, sizeof(module) );
module_str.Buffer = module;
module_str.Length = 0xdead;
module_str.MaximumLength = sizeof(module);
memset( res_buf, 0xcc, sizeof(res_buf) );
res_str.Buffer = res_buf;
res_str.Length = 0xdead;
res_str.MaximumLength = sizeof(res_buf);
ret = NtUserGetIconInfo( handle, &info, &module_str, &res_str, NULL, 0 );
ok( ret, "NtUserGetIconInfo failed: %lu\n", GetLastError() );
ok( info.fIcon == TRUE, "fIcon = %x\n", info.fIcon );
ok( !module_str.Length, "module_str.Length = %u\n", module_str.Length );
ok( !res_str.Length, "res_str.Length = %u\n", res_str.Length );
ok( module_str.Buffer == module, "module_str.Buffer = %p\n", module_str.Buffer );
ok( !res_str.Buffer, "res_str.Buffer = %p\n", res_str.Buffer );
ok( module[0] == 0xcccc, "module[0] = %x\n", module[0] );
ok( res_buf[0] == 0xcccc, "res_buf[0] = %x\n", res_buf[0] );
DeleteObject( info.hbmColor );
DeleteObject( info.hbmMask );
ret = NtUserDestroyCursor( handle, 0 );
ok( ret, "NtUserDestroyIcon failed: %lu\n", GetLastError() );
@ -229,6 +260,28 @@ static void test_cursoricon(void)
ok( height == 64, "height = %ld\n", height );
ok( ret, "NtUserGetIconSize failed: %lu\n", GetLastError() );
memset( module, 0xcc, sizeof(module) );
module_str.Buffer = module;
module_str.Length = 0xdead;
module_str.MaximumLength = sizeof(module);
memset( res_buf, 0xcc, sizeof(res_buf) );
res_str.Buffer = res_buf;
res_str.Length = 0xdead;
res_str.MaximumLength = sizeof(res_buf);
ret = NtUserGetIconInfo( handle, &info, &module_str, &res_str, NULL, 0 );
ok( ret, "NtUserGetIconInfo failed: %lu\n", GetLastError() );
ok( info.fIcon == TRUE, "fIcon = %x\n", info.fIcon );
ok( module_str.Length, "module_str.Length = 0\n" );
ok( !res_str.Length, "res_str.Length = %u\n", res_str.Length );
ok( module_str.Buffer == module, "module_str.Buffer = %p\n", module_str.Buffer );
ok( res_str.Buffer == (WCHAR *)IDI_HAND, "res_str.Buffer = %p\n", res_str.Buffer );
DeleteObject( info.hbmColor );
DeleteObject( info.hbmMask );
module[module_str.Length] = 0;
ok( GetModuleHandleW(module) == GetModuleHandleW(L"user32.dll"),
"GetIconInfoEx wrong module %s\n", wine_dbgstr_w(module) );
ret = DestroyIcon(handle);
ok(ret, "Destroy icon failed, error %lu.\n", GetLastError());
}

View File

@ -934,7 +934,7 @@
@ stub NtUserGetGuiResources
@ stub NtUserGetHDevName
@ stub NtUserGetHimetricScaleFactorFromPixelLocation
@ stub NtUserGetIconInfo
@ stdcall NtUserGetIconInfo(long ptr ptr ptr ptr long)
@ stdcall -syscall NtUserGetIconSize(long long ptr ptr)
@ stub NtUserGetImeHotKey
@ stub NtUserGetImeInfoEx

View File

@ -199,6 +199,8 @@ struct unix_funcs
SHORT (WINAPI *pNtUserGetAsyncKeyState)( INT key );
LONG (WINAPI *pNtUserGetDisplayConfigBufferSizes)( UINT32 flags, UINT32 *num_path_info,
UINT32 *num_mode_info );
BOOL (WINAPI *pNtUserGetIconInfo)( HICON icon, ICONINFO *info, UNICODE_STRING *module,
UNICODE_STRING *res_name, DWORD *bpp, LONG unk );
INT (WINAPI *pNtUserGetKeyNameText)( LONG lparam, WCHAR *buffer, INT size );
UINT (WINAPI *pNtUserGetKeyboardLayoutList)( INT size, HKL *layouts );
INT (WINAPI *pNtUserGetPriorityClipboardFormat)( UINT *list, INT count );

View File

@ -777,6 +777,13 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path_in
return unix_funcs->pNtUserGetDisplayConfigBufferSizes( flags, num_path_info, num_mode_info );
}
BOOL WINAPI NtUserGetIconInfo( HICON icon, ICONINFO *info, UNICODE_STRING *module,
UNICODE_STRING *res_name, DWORD *bpp, LONG unk )
{
if (!unix_funcs) return FALSE;
return unix_funcs->pNtUserGetIconInfo( icon, info, module, res_name, bpp, unk );
}
UINT WINAPI NtUserGetKeyboardLayoutList( INT size, HKL *layouts )
{
if (!unix_funcs) return 0;

View File

@ -206,6 +206,8 @@ LONG WINAPI NtUserGetDisplayConfigBufferSizes( UINT32 flags, UINT32 *num_path
UINT WINAPI NtUserGetDoubleClickTime(void);
BOOL WINAPI NtUserGetDpiForMonitor( HMONITOR monitor, UINT type, UINT *x, UINT *y );
HWND WINAPI NtUserGetForegroundWindow(void);
BOOL WINAPI NtUserGetIconInfo( HICON icon, ICONINFO *info, UNICODE_STRING *module,
UNICODE_STRING *res_name, DWORD *bpp, LONG unk );
BOOL WINAPI NtUserGetIconSize( HICON handle, UINT step, LONG *width, LONG *height );
INT WINAPI NtUserGetKeyNameText( LONG lparam, WCHAR *buffer, INT size );
SHORT WINAPI NtUserGetKeyState( INT vkey );