Commit 446d8321 authored by Alexandre Julliard's avatar Alexandre Julliard

Store window icons in the window structure so that WM_SETICON can do

the right thing (based on a patch by Aric Stewart).
parent 9741589b
......@@ -845,6 +845,68 @@ static void test_mdi(void)
*/
}
static void test_icons(void)
{
WNDCLASSEXA cls;
HWND hwnd;
HICON icon = LoadIconA(0, (LPSTR)IDI_APPLICATION);
HICON icon2 = LoadIconA(0, (LPSTR)IDI_QUESTION);
HICON small_icon = LoadImageA(0, (LPSTR)IDI_APPLICATION, IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED );
HICON res;
cls.cbSize = sizeof(cls);
cls.style = 0;
cls.lpfnWndProc = DefWindowProcA;
cls.cbClsExtra = 0;
cls.cbWndExtra = 0;
cls.hInstance = 0;
cls.hIcon = LoadIconA(0, (LPSTR)IDI_HAND);
cls.hIconSm = small_icon;
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "IconWindowClass";
RegisterClassExA(&cls);
hwnd = CreateWindowExA(0, "IconWindowClass", "icon test", 0,
100, 100, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL);
assert( hwnd );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
ok( res == 0, "wrong big icon %p/0\n", res );
res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon );
ok( res == 0, "wrong previous big icon %p/0\n", res );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
ok( res == icon, "wrong big icon after set %p/%p\n", res, icon );
res = (HICON)SendMessageA( hwnd, WM_SETICON, ICON_BIG, (LPARAM)icon2 );
ok( res == icon, "wrong previous big icon %p/%p\n", res, icon );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_BIG, 0 );
ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL, 0 );
ok( res == 0, "wrong small icon %p/0\n", res );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
ok( res != 0, "wrong small 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 );
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_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 );
res = (HICON)SendMessageA( hwnd, WM_GETICON, ICON_SMALL2, 0 );
ok( res == small_icon, "wrong small 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 );
ok( res == icon2, "wrong big icon after set %p/%p\n", res, icon2 );
}
START_TEST(win)
{
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
......@@ -871,6 +933,7 @@ START_TEST(win)
test_shell_window();
test_mdi();
test_icons();
UnhookWindowsHookEx(hhook);
}
......@@ -281,10 +281,9 @@ inline static void destroy_icon_window( Display *display, WND *win )
*
* Set the icon wm hints
*/
static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints )
static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints, HICON hIcon )
{
X11DRV_WND_DATA *data = wndPtr->pDriverData;
HICON hIcon = (HICON)GetClassLongA( wndPtr->hwndSelf, GCL_HICON );
if (data->hWMIconBitmap) DeleteObject( data->hWMIconBitmap );
if (data->hWMIconMask) DeleteObject( data->hWMIconMask);
......@@ -473,7 +472,7 @@ void X11DRV_set_wm_hints( Display *display, WND *win )
wm_hints->flags = InputHint | StateHint | WindowGroupHint;
wm_hints->input = !(win->dwStyle & WS_DISABLED);
set_icon_hints( display, win, wm_hints );
set_icon_hints( display, win, wm_hints, (HICON)GetClassLongA( win->hwndSelf, GCL_HICON ));
wm_hints->initial_state = (win->dwStyle & WS_MINIMIZE) ? IconicState : NormalState;
wm_hints->window_group = group_leader;
......@@ -1312,16 +1311,14 @@ void X11DRV_SetFocus( HWND hwnd )
* This is not entirely correct, may need to create
* an icon window and set the pixmap as a background
*/
HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
void X11DRV_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
{
WND *wndPtr;
Display *display = thread_display();
HICON old = (HICON)SetClassLongW(hwnd, small ? GCL_HICONSM : GCL_HICON, (LONG)icon );
SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
if (type != ICON_BIG) return; /* nothing to do here */
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return old;
if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
if (wndPtr->dwExStyle & WS_EX_MANAGED)
{
......@@ -1333,7 +1330,7 @@ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
wine_tsx11_unlock();
if (wm_hints)
{
set_icon_hints( display, wndPtr, wm_hints );
set_icon_hints( display, wndPtr, wm_hints, icon );
wine_tsx11_lock();
XSetWMHints( display, win, wm_hints );
XFree( wm_hints );
......@@ -1341,5 +1338,4 @@ HICON X11DRV_SetWindowIcon( HWND hwnd, HICON icon, BOOL small )
}
}
WIN_ReleasePtr( wndPtr );
return old;
}
......@@ -119,7 +119,7 @@ typedef struct tagUSER_DRIVER {
HWND (*pSetParent)(HWND,HWND);
BOOL (*pSetWindowPos)(WINDOWPOS *);
int (*pSetWindowRgn)(HWND,HRGN,BOOL);
HICON (*pSetWindowIcon)(HWND,HICON,BOOL);
void (*pSetWindowIcon)(HWND,UINT,HICON);
void (*pSetWindowStyle)(HWND,DWORD);
BOOL (*pSetWindowText)(HWND,LPCWSTR);
BOOL (*pShowWindow)(HWND,INT);
......
......@@ -61,6 +61,8 @@ typedef struct tagWND
DWORD helpContext; /* Help context ID */
UINT flags; /* Misc. flags (see below) */
HMENU hSysMenu; /* window's copy of System Menu */
HICON hIcon; /* window's icon */
HICON hIconSmall; /* window's small icon */
int cbWndExtra; /* class cbWndExtra at window creation */
int irefCount; /* window's reference count*/
DWORD userdata; /* User private data */
......
......@@ -653,19 +653,60 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
return 1;
case WM_SETICON:
if (USER_Driver.pSetWindowIcon)
return (LRESULT)USER_Driver.pSetWindowIcon( hwnd, (HICON)lParam, (wParam != ICON_SMALL) );
else
{
HICON hOldIcon = (HICON)SetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM,
lParam);
{
HICON ret;
WND *wndPtr = WIN_GetPtr( hwnd );
switch(wParam)
{
case ICON_SMALL:
ret = wndPtr->hIconSmall;
wndPtr->hIconSmall = (HICON)lParam;
break;
case ICON_BIG:
ret = wndPtr->hIcon;
wndPtr->hIcon = (HICON)lParam;
break;
default:
ret = 0;
break;
}
WIN_ReleasePtr( wndPtr );
if (USER_Driver.pSetWindowIcon)
USER_Driver.pSetWindowIcon( hwnd, wParam, (HICON)lParam );
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE |
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
return (LRESULT)hOldIcon;
}
return (LRESULT)ret;
}
case WM_GETICON:
return GetClassLongW( hwnd, (wParam != ICON_SMALL) ? GCL_HICON : GCL_HICONSM );
{
HICON ret;
WND *wndPtr = WIN_GetPtr( hwnd );
switch(wParam)
{
case ICON_SMALL:
ret = wndPtr->hIconSmall;
break;
case ICON_BIG:
ret = wndPtr->hIcon;
break;
case ICON_SMALL2:
ret = wndPtr->hIconSmall;
if (!ret) ret = (HICON)GetClassLongA( hwnd, GCL_HICONSM );
/* FIXME: should have a default here if class icon is null */
break;
default:
ret = 0;
break;
}
WIN_ReleasePtr( wndPtr );
return (LRESULT)ret;
}
case WM_HELP:
SendMessageW( GetParent(hwnd), msg, wParam, lParam );
......
......@@ -241,7 +241,16 @@ NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
static HICON NC_IconForWindow( HWND hwnd )
{
HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
HICON hIcon = 0;
WND *wndPtr = WIN_GetPtr( hwnd );
if (wndPtr && wndPtr != WND_OTHER_PROCESS)
{
hIcon = wndPtr->hIconSmall;
if (!hIcon) hIcon = wndPtr->hIcon;
WIN_ReleasePtr( wndPtr );
}
if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
/* If there is no hIcon specified and this is a modal dialog,
......
......@@ -1071,6 +1071,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->pVScroll = NULL;
wndPtr->pHScroll = NULL;
wndPtr->userdata = 0;
wndPtr->hIcon = 0;
wndPtr->hIconSmall = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0;
/* Correct the window style - stage 2 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment