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