Store window icons in the window structure so that WM_SETICON can do
the right thing (based on a patch by Aric Stewart).
This commit is contained in:
parent
9741589bdf
commit
446d8321a7
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue