Release 960421

Sat Apr 20 23:23:16 1996  Robert Pouliot <krynos@qbc.clic.net>

	* [resources/sysres_Fr.rc] [resources/TODO]
	Made changes for Choose_Color dialog.

Sat Apr 20 15:43:49 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/button.c]
	Fixed test that got miscompiled by some old gcc versions.

	* [memory/local.c]
	Fixed the layout of handle tables so that moveable handle entries
	can be freed on LocalFree().
	Implemented LocalFlags(), LocalCountFree(), LocalHandleDelta() and
	GetHeapSpaces().

	* [misc/main.c] [ANNOUNCE]
	Update the list of contributors. Please let me know if I forgot
	someone.

Fri Apr 19 20:07:20 1996  Frans van Dorsselaer  <dorssel@rulhm1.leidenuniv.nl>

	* [controls/edit.c] [controls/EDIT.TODO]
	Fixed EM_SETHANDLE / WM_CREATE / EDIT_MakeFir() buffer allocation.
	Fixed ES_NOHIDESEL / WM_MOUSEMOVE / WM_LBUTTONDOWN implementation.
	Added WM_ENABLE implementation (gray text).
	Fixed buffer > 32767 bug.
	Fixed argument types / typecasting.
	Faster selection (re)drawing.

Thu Apr 18 13:38:26 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [misc/registry.c] [include/winreg.h]
	Changed savefile format again to human readable/editable
	(UNICODE chars >0xff are specified by \uXXXX, data by XX).
	Has now global / local registry databases (including merging them).
	HKEY_CLASSES_ROOT == HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes.
	HKEY_CURRENT_USER == HKEY_USERS\\<loginname>.

	* [misc/comm.c]
	Allow " " as COMx: ... spec delimiter too.
	(AOL-CD setup.exe tries to initialize modem2 as "9600,x,x x" (can't 
	remember the x).

Thu Apr 18 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/mdi.c]
	Miscellaneous changes.

	* [windows/winpos.c] 
	Use BitBlt whenever possible in SetWindowPos.

	* [windows/painting.c]
	Fix incompatibilities with hrgnUpdate being 1.

Wed Apr 17 19:19:22 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [misc/commdlg.c]
	Many bugfixes in ChooseColor dialog.
	Added a user defined dialog title in FileOpen-/FileSave- dialog.

	* [misc/commdlg.c][include/commdlg.h]
	  [if1632/commdlg.spec][if1632/winprocs.spec]
	Introduced dialog-, callback- and enum- stub functions
	for ChooseFont dialog

Wed Apr 17 19:08:38 1996  Niels de Carpentier  <niels@cindy.et.tudelft.nl>

	* [objects/metafile.c] [include/metafile.h] [if1632/gdi.spec]
	Implemented EnumMetaFile and CopyMetaFile. Removed METAFILE struct.
	Implemented META_STRETCHDIB in PlayMetaFileRecord, several bug 
	fixes.

	* [windows/winpos.c]
	Don't try to hide the window if it's already hidden.

	* [windows/message.c]
	Let MSG_PeekHardwareMsg fill the message queue with events if
	it's empty.

Wed Apr 17 17:54:04 1996  Tristan Tarrant <tst@sthinc.demon.co.uk>

	* [resources/sysres_It.rc]
	Updated to support the new CHOOSE_COLOR_DIALOG.

Tue Apr 16 11:50:00 1996  Anand Kumria <akumria@ozemail.com.au>

	* [if1632/Makefile] [if1632/relay.c] [if1631/w32sys.spec]
	  [include/w32sys.h] [include/dlls.h]
	  [misc/Makefile] [misc/w32sys.c]
	W32SYS.DLL partially implemented.
diff --git a/windows/mdi.c b/windows/mdi.c
index a22d1de..1a533f8 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -12,8 +12,6 @@
  *        SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE
  *        is not used.
  *
- * To fix:
- *	  Sticky client crollbars 
  */
 
 #include <stdlib.h>
@@ -32,6 +30,10 @@
 #include "stddebug.h"
 #include "debug.h"
 
+
+DWORD SCROLL_SetNCSbState(WND*,int,int,int,int,int,int);
+
+/* ----------------- declarations ----------------- */
 void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCSTR);
 BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND);
 BOOL MDI_RestoreFrameMenu(WND *, HWND);
@@ -39,8 +41,6 @@
 void ScrollChildren(HWND , UINT , WPARAM , LPARAM );
 void CalcChildScroll(HWND, WORD);
 
-/* ----------------- declarations ----------------- */
-
 static LONG MDI_ChildActivate(WND* ,HWND );
 
 /* -------- Miscellaneous service functions ----------
@@ -55,6 +55,16 @@
     return 0;
 }
 
+static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
+{
+ if( !ci->sbNeedUpdate )
+   {
+      ci->sbNeedUpdate = TRUE;
+      PostMessage( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
+   }
+ ci->sbRecalc = recalc;
+}
+
 /**********************************************************************
  *			MDI_MenuAppendItem
  */
@@ -427,9 +437,8 @@
 
         if (flagDestroy)
 	   {
+	     MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
             DestroyWindow(child);
-	    PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L);
-	    ci->sbRecalc |= (SB_BOTH+1);
 	   }
     }
 
@@ -808,9 +817,8 @@
 
  child->dwStyle &= ~WS_SYSMENU;
 
- /* redraw frame */
- SetWindowPos(frame->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | 
-                                 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
+ /* redraw menu */
+ DrawMenuBar(frame->hwndSelf);
 
  return 1;
 }
@@ -837,9 +845,8 @@
  RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
  DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
 
-  /* redraw frame */
- SetWindowPos(hChild, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
-                                 SWP_NOACTIVATE | SWP_NOZORDER );
+ DrawMenuBar(frameWnd->hwndSelf);
+
  return 1;
 }
 
@@ -962,7 +969,7 @@
 	ci->flagChildMaximized  = 0;
 	ci->nActiveChildren	= 0;
 	ci->hFrameTitle		= frameWnd->hText;
-	ci->sbStop		= 0;
+	ci->sbNeedUpdate	= 0;
 	ci->self		= hwnd;
 	ci->obmClose		= CreateMDIMenuBitmap();
 	ci->obmRestore		= LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
@@ -1014,11 +1021,11 @@
 		((LONG) (ci->flagChildMaximized>0) << 16));
 
       case WM_MDIICONARRANGE:
-	       ci->sbStop = TRUE;
-	       MDIIconArrange(hwnd);
-	       ci->sbStop = FALSE;
-	       SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
-	       return 0;
+	ci->sbNeedUpdate = TRUE;
+	MDIIconArrange(hwnd);
+	ci->sbRecalc = SB_BOTH+1;
+	SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
+	return 0;
 	
       case WM_MDIMAXIMIZE:
 	ShowWindow((HWND)wParam, SW_MAXIMIZE);
@@ -1040,17 +1047,17 @@
 #endif
 	
       case WM_MDITILE:
-	ci->sbStop = TRUE;
+	ci->sbNeedUpdate = TRUE;
 	ShowScrollBar(hwnd,SB_BOTH,FALSE);
 	MDITile(hwnd, ci,wParam);
-        ci->sbStop = FALSE;
+        ci->sbNeedUpdate = FALSE;
         return 0;
 
       case WM_VSCROLL:
       case WM_HSCROLL:
-	ci->sbStop = TRUE;
+	ci->sbNeedUpdate = TRUE;
         ScrollChildren(hwnd,message,wParam,lParam);
-	ci->sbStop = FALSE;
+	ci->sbNeedUpdate = FALSE;
         return 0;
 
       case WM_SETFOCUS:
@@ -1099,18 +1106,16 @@
 			rect.right - rect.left, rect.bottom - rect.top, 1);
 	  }
 	else
-	  {
-	     PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
-	     ci->sbRecalc |= (SB_BOTH+1);
-	  }
+	  MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
+
 	break;
 
       case WM_MDICALCCHILDSCROLL:
-	if( !ci->sbStop )
+	if( ci->sbNeedUpdate )
 	  if( ci->sbRecalc )
 	    {
 	      CalcChildScroll(hwnd, ci->sbRecalc-1);
-	      ci->sbRecalc = 0;
+	      ci->sbRecalc = ci->sbNeedUpdate = 0;
 	    }
 	return 0;
     }
@@ -1256,11 +1261,10 @@
 	return 0;
 
       case WM_SETVISIBLE:
-         if( !ci->sbStop && !ci->flagChildMaximized)
-          {
-            PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L);
-            ci->sbRecalc |= (SB_BOTH+1);
-          }
+         if( ci->flagChildMaximized)
+             ci->sbNeedUpdate = 0;
+	 else
+            MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
 	break;
 
       case WM_SIZE:
@@ -1305,12 +1309,8 @@
 	    if( switchTo )
 	        SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L);
 	  }
-	    
-        if( !ci->sbStop )
-          {
-            PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L);
-            ci->sbRecalc |= (SB_BOTH+1);
-          }
+	  
+	MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
 	break;
 
       case WM_MENUCHAR:
@@ -1379,27 +1379,47 @@
 void CalcChildScroll( HWND hwnd, WORD scroll )
 {
     RECT childRect, clientRect;
-    WND *pWnd;
+    INT  vmin, vmax, hmin, hmax, vpos, hpos;
+    BOOL noscroll = FALSE;
+    WND *pWnd, *Wnd;
 
-    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return;
+    if (!(Wnd = pWnd = WIN_FindWndPtr( hwnd ))) return;
     GetClientRect( hwnd, &clientRect );
     SetRectEmpty( &childRect );
-    for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
-        UnionRect( &childRect, &pWnd->rectWindow, &childRect );
+
+    for ( pWnd = pWnd->child; pWnd; pWnd = pWnd->next )
+	{
+          UnionRect( &childRect, &pWnd->rectWindow, &childRect );
+	  if( pWnd->dwStyle & WS_MAXIMIZE )
+	      noscroll = TRUE;
+	} 
     UnionRect( &childRect, &clientRect, &childRect );
 
-    if ((scroll == SB_HORZ) || (scroll == SB_BOTH))
-    {
-        SetScrollRange( hwnd, SB_HORZ, childRect.left,
-                        childRect.right - clientRect.right, FALSE );
-        SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE );
-    }
-    if ((scroll == SB_VERT) || (scroll == SB_BOTH))
-    {
-        SetScrollRange( hwnd, SB_VERT, childRect.top,
-                        childRect.bottom - clientRect.bottom, FALSE );
-        SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE );
-    }
+    /* jump through the hoops to prevent excessive flashing 
+     */
+
+    hmin = childRect.left; hmax = childRect.right - clientRect.right;
+    hpos = clientRect.left - childRect.left;
+    vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
+    vpos = clientRect.top - childRect.top;
+
+    if( noscroll )
+	ShowScrollBar(hwnd, SB_BOTH, FALSE);
+    else
+    switch( scroll )
+      {
+	case SB_HORZ:
+			vpos = hpos; vmin = hmin; vmax = hmax;
+	case SB_VERT:
+			SetScrollPos(hwnd, scroll, vpos, FALSE);
+			SetScrollRange(hwnd, scroll, vmin, vmax, TRUE);
+			break;
+	case SB_BOTH:
+			SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
+						  hmin, hmax, hpos);
+			SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
+                                 | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
+      }    
 }
 
 /***********************************************************************