explorer: Create a standalone tray window wrapper if the driver doesn't provide native implementation. Take 2.
Dmitry Timoshkov
dmitry at codeweavers.com
Fri Oct 22 08:14:26 CDT 2010
This patch makes sure that "Shell_TrayWnd" window doesn't have a caption
since some apps depend on it being empty. The bug #20129 lists one of such
applications. It does FindWindow("Shell_TrayWnd", "") and expects that it
returns a valid tray window handle.
---
dlls/user32/tests/win.c | 1 -
programs/explorer/systray.c | 67 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 80aad49..5a378de 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -6266,7 +6266,6 @@ static void test_FindWindowEx(void)
/* test behaviour with a window title that is an empty character */
found = FindWindowExA( 0, 0, "Shell_TrayWnd", title );
-todo_wine
ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
found = FindWindowExA( 0, 0, "Shell_TrayWnd", NULL );
ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
diff --git a/programs/explorer/systray.c b/programs/explorer/systray.c
index 615768f..a05250f 100644
--- a/programs/explorer/systray.c
+++ b/programs/explorer/systray.c
@@ -109,7 +109,6 @@ static SIZE get_window_size(void)
rect.top = 0;
rect.right = icon_cx * max( nb_displayed, MIN_DISPLAYED );
rect.bottom = icon_cy;
- AdjustWindowRect( &rect, WS_CAPTION, FALSE );
size.cx = rect.right - rect.left;
size.cy = rect.bottom - rect.top;
return size;
@@ -204,6 +203,61 @@ static void invalidate_icons( unsigned int start, unsigned int end )
InvalidateRect( tray_window, &rect, TRUE );
}
+static LRESULT WINAPI tray_wrapper_wndproc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+ switch (msg)
+ {
+ case WM_MOVE:
+ SetWindowPos( tray_window, 0, LOWORD(lparam), HIWORD(lparam), 0,0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ break;
+
+ case WM_CLOSE:
+ /* don't destroy the tray window, just hide it */
+ ShowWindow( hwnd, SW_HIDE );
+ return 0;
+
+ default:
+ break;
+ }
+ return DefWindowProcW( hwnd, msg, wparam, lparam );
+}
+
+static void embed_tray_window( void )
+{
+ static const WCHAR classW[] = {'w','i','n','e',' ','t','r','a','y',' ','w','r','a','p','p','e','r',0};
+ static const WCHAR captionW[] = {'W','i','n','e',' ','S','y','s','t','e','m',' ','T','r','a','y',0};
+ static const LONG style = WS_POPUP | WS_CAPTION | WS_BORDER;
+ static HWND tray_window_wrapper;
+ WNDCLASSEXW class;
+ SIZE sz;
+ RECT rc;
+
+ if (tray_window_wrapper) return;
+
+ memset( &class, 0, sizeof(class) );
+ class.cbSize = sizeof(class);
+ class.style = CS_DBLCLKS;
+ class.lpfnWndProc = tray_wrapper_wndproc;
+ class.hIcon = LoadIconW( 0, (LPCWSTR)IDI_WINLOGO );
+ class.hCursor = LoadCursorW( 0, (LPCWSTR)IDC_ARROW );
+ class.hbrBackground = (HBRUSH)COLOR_WINDOW;
+ class.lpszClassName = classW;
+
+ if (!RegisterClassExW( &class )) return;
+
+ sz = get_window_size();
+ SetRect( &rc, 0, 0, sz.cx, sz.cy );
+ AdjustWindowRect( &rc, style, FALSE );
+ tray_window_wrapper = CreateWindowExW( 0, classW, captionW, style,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ rc.right - rc.left, rc.bottom - rc.top,
+ 0, 0, 0, 0 );
+ if (!tray_window_wrapper) return;
+
+ SetWindowLongPtrW( tray_window, GWLP_HWNDPARENT, (LONG_PTR)tray_window_wrapper );
+ ShowWindow( tray_window_wrapper, SW_SHOWNA );
+}
+
/* make an icon visible */
static BOOL show_icon(struct icon *icon)
{
@@ -234,7 +288,11 @@ static BOOL show_icon(struct icon *icon)
}
else if (nb_displayed == 1)
{
- if (!hide_systray) ShowWindow( tray_window, SW_SHOWNA );
+ if (!hide_systray)
+ {
+ embed_tray_window();
+ ShowWindow( tray_window, SW_SHOWNA );
+ }
}
create_tooltip(icon);
@@ -562,7 +620,6 @@ void initialize_systray(void)
SIZE size;
WNDCLASSEXW class;
static const WCHAR classname[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d',0};
- static const WCHAR winname[] = {'W','i','n','e',' ','S','y','s','t','e','m',' ','T','r','a','y',0};
if ((x11drv = GetModuleHandleA( "winex11.drv" )))
wine_notify_icon = (void *)GetProcAddress( x11drv, "wine_notify_icon" );
@@ -580,7 +637,7 @@ void initialize_systray(void)
class.hIcon = LoadIconW(0, (LPCWSTR)IDI_WINLOGO);
class.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
class.hbrBackground = (HBRUSH) COLOR_WINDOW;
- class.lpszClassName = (WCHAR *) &classname;
+ class.lpszClassName = classname;
if (!RegisterClassExW(&class))
{
@@ -589,7 +646,7 @@ void initialize_systray(void)
}
size = get_window_size();
- tray_window = CreateWindowW( classname, winname, WS_OVERLAPPED | WS_CAPTION,
+ tray_window = CreateWindowW( classname, NULL, WS_POPUP,
CW_USEDEFAULT, CW_USEDEFAULT, size.cx, size.cy, 0, 0, 0, 0 );
if (!tray_window)
{
--
1.7.0.6
More information about the wine-patches
mailing list