TopLevelWindow Maximize
Katia Maculan
katia.maculan at isis-papyrus.com
Fri Dec 17 04:25:46 CST 2004
This patch solves 2 problems in maximizing a TopLevelWindow:
1) If at run-time an application decides to maximize a TopLevelWindow by
program, the window size is increased but the window is not really
maximized (the maximizebox is not changed for a future restore and the
window can be resized dragging the borders)
2) if a user maximize TopLevelWindow by maximizebox the Window styles
are not changed.
Inside the patch there are also 2 regression tests.
Regards
Katia
--
Katia Maculan
Developer
ISIS Papyrus Italy Srl
Tel: (+39) 0125 6455400 Fax: (+39) 0125 6455150
E-mail: katia.maculan at isis-papyrus.com
Info: info at isis-papyrus.com
Hotline: +43-2236-27551-111
Visit our Website: http://www.isis-papyrus.com
-------------- next part --------------
diff -urN oldwinedir/dlls/user/tests/win.c newwinedir/dlls/user/tests/win.c
--- oldwinedir/dlls/user/tests/win.c 2004-10-11 21:55:28.000000000 +0200
+++ newwinedir/dlls/user/tests/win.c 2004-12-17 10:39:29.000000000 +0100
@@ -2099,8 +2099,174 @@
ok(!PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "message %04x available\n", msg.message);
}
+LRESULT CALLBACK WndProc1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ RECT rect;
+ switch (message)
+ {
+ case WM_SHOWWINDOW:
+ case WM_SIZE:
+ DefWindowProc(hWnd, message, wParam, lParam);
+ PostMessage (hWnd, WM_PAINT, 0, 0);
+ return 0;
+
+ case WM_PAINT:
+ {
+ HDC hdc = GetDC (hWnd);
+ if (IsZoomed (hWnd))
+ {
+ char *buff = strdup ("Now the window is maximized ");
+ TextOut (hdc, 50, 50, buff, strlen (buff));
+ free (buff);
+ }
+ else
+ {
+ char *buff = strdup ("The window is NOT maximized, please maximize it");
+ TextOut (hdc, 50, 50, buff, strlen (buff));
+ free (buff);
+ }
+ ReleaseDC (hWnd, hdc);
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static void TopLevelStyle ()
+{
+ WNDCLASS cls;
+ HANDLE hWnd;
+ MSG msg;
+
+ cls.style = 0;
+ cls.lpfnWndProc = WndProc1;
+ cls.cbClsExtra = 0;
+ cls.cbWndExtra = 0;
+ cls.hInstance = GetModuleHandleA(0);
+ cls.hIcon = 0;
+ cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
+ cls.hbrBackground = GetStockObject(WHITE_BRUSH);
+ cls.lpszMenuName = NULL;
+ cls.lpszClassName = "MainWindowClass1";
+
+ if (!RegisterClass (&cls))
+ return NULL;
+
+ hWnd = CreateWindow ("MainWindowClass1", "MaxButtonTest", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
+ GetModuleHandleA(0), NULL);
+
+ if (!hWnd)
+ return;
+
+ ShowWindow(hWnd, SW_SHOW);
+
+ UpdateWindow(hWnd);
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+static BOOL maxim = FALSE;
+
+ switch (message)
+ {
+ case WM_SHOWWINDOW:
+ case WM_SIZE:
+ DefWindowProc(hWnd, message, wParam, lParam);
+ PostMessage (hWnd, WM_PAINT, 0, 0);
+ return 0;
+
+ case WM_TIMER:
+ if (wParam == 100)
+ {
+ KillTimer (hWnd, 100);
+ maxim = TRUE;
+ ShowWindow(hWnd, SW_SHOWMAXIMIZED);
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ HDC hdc = GetDC (hWnd);
+ if (!maxim)
+ {
+ char *buff = strdup ("The window will be maximized");
+ TextOut (hdc, 50, 50, buff, strlen (buff));
+ free (buff);
+ }
+ if (IsZoomed (hWnd))
+ {
+ char *buff = strdup ("Now the window is maximized: is the maximize button correct?");
+ TextOut (hdc, 50, 50, buff, strlen (buff));
+ free (buff);
+ }
+ ReleaseDC (hWnd, hdc);
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static void TopLevelMaximized ()
+{
+ MSG msg;
+ WNDCLASS cls;
+ HANDLE hWnd;
+
+ cls.style = 0;
+ cls.lpfnWndProc = WndProc;
+ cls.cbClsExtra = 0;
+ cls.cbWndExtra = 0;
+ cls.hInstance = GetModuleHandleA(0);
+ cls.hIcon = 0;
+ cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
+ cls.hbrBackground = GetStockObject(WHITE_BRUSH);
+ cls.lpszMenuName = NULL;
+ cls.lpszClassName = "MainWindowClass";
+
+ if (!RegisterClass (&cls))
+ return;
+
+ hWnd = CreateWindow ("MainWindowClass", "MaxButtonTest", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
+ GetModuleHandleA(0), NULL);
+
+ if (!hWnd)
+ return;
+
+ ShowWindow(hWnd, SW_SHOW);
+
+ SetTimer (hWnd, 100, 1000, NULL);
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return (int) msg.wParam;
+}
+
START_TEST(win)
{
+#if 0
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
pGetWindowInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetWindowInfo" );
@@ -2155,4 +2321,8 @@
test_keyboard_input(hwndMain);
UnhookWindowsHookEx(hhook);
+#endif
+ TopLevelMaximized ();
+ TopLevelStyle ();
}
diff -urN oldwinedir/dlls/x11drv/window.c newwinedir/dlls/x11drv/window.c
--- oldwinedir/dlls/x11drv/window.c 2004-09-22 21:14:19.000000000 +0200
+++ newwinedir/dlls/x11drv/window.c 2004-12-17 10:38:24.000000000 +0100
@@ -101,7 +101,10 @@
"text/html",
"text/plain",
"text/rtf",
- "text/richtext"
+ "text/richtext",
+ "_NET_WM_STATE",
+ "_NET_WM_STATE_MAXIMIZED_HORZ",
+ "_NET_WM_STATE_MAXIMIZED_VERT"
};
static LPCSTR whole_window_atom;
@@ -504,8 +507,82 @@
XFree(wm_hints);
wine_tsx11_unlock();
}
+ if (win->dwStyle & WS_MAXIMIZE)
+ X11DRV_maximize_window( win );
}
+/***********************************************************************
+ * X11DRV_maximize_window
+ *
+ * Set the X11 WS_MAXIMIZED style
+ */
+void X11DRV_maximize_window( WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ Display *display = thread_display();
+
+ Atom prots[6];
+
+ prots[0] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ);
+ prots[1] = x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT);
+
+ wine_tsx11_lock();
+
+ if (is_window_top_level(win))
+ {
+ BOOL bChangeMap = FALSE;
+ if (X11DRV_is_window_rect_mapped( &win->rectWindow ))
+ {
+ bChangeMap = TRUE;
+ XFlush (display);
+ XUnmapWindow( display, get_whole_window(win) );
+ }
+ XSync (display, False);
+ XChangeProperty (display, data->whole_window,
+ x11drv_atom(_NET_WM_STATE), XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)prots, 2);
+ if (bChangeMap)
+ XMapWindow( display, get_whole_window(win) );
+ }
+ wine_tsx11_unlock();
+}
+
+/***********************************************************************
+ * X11DRV_is_maximize_window
+ *
+ * Verify if the window is maximize
+ */
+BOOL X11DRV_is_maximize_window( WND *win )
+{
+ struct x11drv_win_data *data = win->pDriverData;
+ Display *display = thread_display();
+ BOOL ret = FALSE;
+
+ Atom ret_atom;
+ int actual_type;
+ unsigned long num_prop;
+ unsigned long byte_to_read;
+ unsigned char *buff = NULL;
+
+ wine_tsx11_lock();
+
+ ret = XGetWindowProperty (display, data->whole_window, x11drv_atom(_NET_WM_STATE),
+ 0, 65538, False, AnyPropertyType, &ret_atom,
+ &actual_type, &num_prop, &byte_to_read, &buff);
+ if (ret == Success && buff)
+ {
+ if (buff[0] == (unsigned char) x11drv_atom(_NET_WM_STATE_MAXIMIZED_HORZ) ||
+ buff[0] == (unsigned char) x11drv_atom(_NET_WM_STATE_MAXIMIZED_VERT))
+ ret = TRUE;
+ else
+ ret = FALSE;
+ }
+ wine_tsx11_unlock();
+
+ return (ret);
+}
/***********************************************************************
* X11DRV_set_iconic_state
diff -urN oldwinedir/dlls/x11drv/winpos.c newwinedir/dlls/x11drv/winpos.c
--- oldwinedir/dlls/x11drv/winpos.c 2004-09-17 20:20:11.000000000 +0200
+++ newwinedir/dlls/x11drv/winpos.c 2004-12-17 10:38:43.000000000 +0100
@@ -1192,6 +1192,8 @@
case SW_MAXIMIZE:
WINPOS_GetMinMaxInfo( hwnd, &size, &wpl.ptMaxPosition, NULL, NULL );
+ X11DRV_maximize_window( wndPtr );
+
old_style = WIN_SetStyle( hwnd, (wndPtr->dwStyle & ~WS_MINIMIZE) | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{
@@ -1661,6 +1663,21 @@
/* if nothing changed, don't do anything */
if (winpos.flags == (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE)) return;
+ if (is_window_top_level(win))
+ {
+ BOOL bmax = X11DRV_is_maximize_window(win);
+ if (bmax && !(win->dwStyle & WS_MAXIMIZE))
+ {
+ WIN_SetStyle( hwnd, (win->dwStyle & ~WS_MINIMIZE) | WS_MAXIMIZE );
+ }
+ else
+ if (!bmax && (win->dwStyle & WS_MAXIMIZE))
+ {
+ WIN_SetStyle( hwnd, (win->dwStyle & ~WS_MAXIMIZE) );
+ }
+ }
SetWindowPos( hwnd, winpos.hwndInsertAfter, winpos.x, winpos.y,
winpos.cx, winpos.cy, winpos.flags | SWP_WINE_NOHOSTMOVE );
}
diff -urN oldwinedir/dlls/x11drv/x11drv.h newwinedir/dlls/x11drv/x11drv.h
--- oldwinedir/dlls/x11drv/x11drv.h 2004-09-16 21:10:14.000000000 +0200
+++ newwinedir/dlls/x11drv/x11drv.h 2004-12-17 10:37:55.000000000 +0100
@@ -448,6 +448,9 @@
XATOM_text_plain,
XATOM_text_rtf,
XATOM_text_richtext,
+ XATOM__NET_WM_STATE,
+ XATOM__NET_WM_STATE_MAXIMIZED_HORZ,
+ XATOM__NET_WM_STATE_MAXIMIZED_VERT,
NB_XATOMS
};
@@ -565,6 +568,8 @@
extern int X11DRV_sync_client_window_position( Display *display, WND *win );
extern void X11DRV_set_window_rectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClient );
extern void X11DRV_set_wm_hints( Display *display, WND *win );
+extern void X11DRV_maximize_window( WND *win );
+extern BOOL X11DRV_is_maximize_window( WND *win );
extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
extern void X11DRV_Settings_AddDepthModes(void);
More information about the wine-patches
mailing list