[PATCH 3/3] user32: Fall back to downscaling the big icon for ICON_SMALL2.

Alex Henrie alexhenrie24 at gmail.com
Thu May 14 02:37:57 CDT 2015


Based on
https://source.winehq.org/git/wine.git/commitdiff/3d4db9f28f13a360e87a1a057248c87c06d82b72
---
 dlls/user32/defwnd.c    | 24 +++++++++++++++++++++++-
 dlls/user32/tests/win.c | 15 ++++++---------
 dlls/user32/win.c       |  2 ++
 dlls/user32/win.h       |  1 +
 4 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index fa6b0fa..68d9480 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -605,10 +605,32 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
             {
             case ICON_SMALL:
                 ret = wndPtr->hIconSmall;
+                if (ret && !lParam && wndPtr->hIcon)
+                {
+                    wndPtr->hIconSmall2 = CopyImage( wndPtr->hIcon, IMAGE_ICON,
+                                                     GetSystemMetrics( SM_CXSMICON ),
+                                                     GetSystemMetrics( SM_CYSMICON ), 0 );
+                }
+                else if (lParam && wndPtr->hIconSmall2)
+                {
+                    DestroyIcon( wndPtr->hIconSmall2 );
+                    wndPtr->hIconSmall2 = NULL;
+                }
                 wndPtr->hIconSmall = (HICON)lParam;
                 break;
             case ICON_BIG:
                 ret = wndPtr->hIcon;
+                if (wndPtr->hIconSmall2)
+                {
+                    DestroyIcon( wndPtr->hIconSmall2 );
+                    wndPtr->hIconSmall2 = NULL;
+                }
+                if (lParam && !wndPtr->hIconSmall)
+                {
+                    wndPtr->hIconSmall2 = CopyImage( (HICON)lParam, IMAGE_ICON,
+                                                     GetSystemMetrics( SM_CXSMICON ),
+                                                     GetSystemMetrics( SM_CYSMICON ), 0 );
+                }
                 wndPtr->hIcon = (HICON)lParam;
                 break;
             default:
@@ -639,7 +661,7 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
                 ret = wndPtr->hIcon;
                 break;
             case ICON_SMALL2:
-                ret = wndPtr->hIconSmall;
+                ret = wndPtr->hIconSmall ? wndPtr->hIconSmall : wndPtr->hIconSmall2;
                 break;
             default:
                 ret = 0;
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index a547eee..689f0a2 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -2007,23 +2007,20 @@ static void test_icons(void)
 
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == 0, "wrong small icon %p/0\n", res );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res != 0, "wrong small icon %p\n", res );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( (res && res != small_icon && res != icon2) || broken(!res), "wrong small2 icon %p\n", res );
     res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)icon );
     ok( res == 0, "wrong previous small icon %p/0\n", res );
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res == icon, "wrong small icon after set %p/%p\n", res, icon );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( res == icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, icon );
     res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_SMALL, (LPARAM)small_icon );
     ok( res == icon, "wrong previous small icon %p/%p\n", res, icon );
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
     ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );
-    /* this test is XP specific */
-    /*res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
-    ok( res == small_icon, "wrong small icon after set %p/%p\n", res, small_icon );*/
+    res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
+    ok( res == small_icon || broken(!res), "wrong small2 icon after set %p/%p\n", res, small_icon );
 
     /* make sure the big icon hasn't changed */
     res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 8ff3ebd..7090cb0 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -978,6 +978,7 @@ LRESULT WIN_DestroyWindow( HWND hwnd )
     wndPtr->text = NULL;
     HeapFree( GetProcessHeap(), 0, wndPtr->pScroll );
     wndPtr->pScroll = NULL;
+    DestroyIcon( wndPtr->hIconSmall2 );
     surface = wndPtr->surface;
     wndPtr->surface = NULL;
     WIN_ReleasePtr( wndPtr );
@@ -1468,6 +1469,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
     wndPtr->userdata       = 0;
     wndPtr->hIcon          = 0;
     wndPtr->hIconSmall     = 0;
+    wndPtr->hIconSmall2    = 0;
     wndPtr->hSysMenu       = 0;
 
     wndPtr->min_pos.x = wndPtr->min_pos.y = -1;
diff --git a/dlls/user32/win.h b/dlls/user32/win.h
index a182778..8da9c24 100644
--- a/dlls/user32/win.h
+++ b/dlls/user32/win.h
@@ -60,6 +60,7 @@ typedef struct tagWND
     HMENU          hSysMenu;      /* window's copy of System Menu */
     HICON          hIcon;         /* window's icon */
     HICON          hIconSmall;    /* window's small icon */
+    HICON          hIconSmall2;   /* window's secondary small icon, derived from hIcon */
     struct window_surface *surface; /* Window surface if any */
     struct tagDIALOGINFO *dlgInfo;/* Dialog additional info (dialogs only) */
     int            pixel_format;  /* Pixel format set by the graphics driver */
-- 
2.4.0




More information about the wine-patches mailing list