[Mono-winforms-list] SWF patch ( MDI interface )

Aleksey Ryabchuk ryabchuk@yahoo.com
Tue, 1 Apr 2003 08:15:05 -0800 (PST)


--0-609220278-1049213705=:89260
Content-Type: text/plain; charset=us-ascii
Content-Id: 
Content-Disposition: inline

Hello there,

Control.cs
Form.cs
NativeWindow.cs
Win32functions.cs
Win32structs.cs : initial implementation of MDI
interface.

Regards
Aleksey



__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online, calculators, forms, and more
http://platinum.yahoo.com
--0-609220278-1049213705=:89260
Content-Type: text/plain; name=patch
Content-Description: patch
Content-Disposition: inline; filename=patch

Index: Control.cs
===================================================================
RCS file: /mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs,v
retrieving revision 1.32
diff -u -r1.32 Control.cs
--- Control.cs	24 Mar 2003 23:28:11 -0000	1.32
+++ Control.cs	1 Apr 2003 16:06:01 -0000
@@ -81,6 +81,8 @@
     		bool tabStop;
     		string text;
     		bool visible;
+		bool isDisposed;
+
 			object tag;
 			protected bool mouseIsInside_;
 			bool recreatingHandle;
@@ -191,6 +193,8 @@
     			text = "";
     			visible = true;
     			parent = null;
+			isDisposed = false;
+
 				mouseIsInside_ = false;
 				recreatingHandle = false;
 				// Do not create Handle here, only in CreateHandle
@@ -473,7 +477,7 @@
 				rc.right = value.Width;
 				rc.bottom = value.Height;
 				
-				if( Handle != IntPtr.Zero){
+				if( IsHandleCreated ){
 					int style = Win32.GetWindowLong( Handle, GetWindowLongFlag.GWL_STYLE).ToInt32();
 					int menuExists = 0;
 					if( (style & (int)WindowStyles.WS_CHILD) == 0 ){
@@ -783,18 +787,18 @@
     		}
     		
     		public bool IsDisposed {
-    			get {
-    				if (Handle == (IntPtr) 0)
-    					return true;
-    				return false;
-    			}
+    			get {	return isDisposed; }
+    				//if (Handle == (IntPtr) 0)
+    				//	return true;
+    				//return false;
     		}
     		
     		public bool IsHandleCreated {
     			get {
-    				if (Handle != (IntPtr) 0)
-    					return true;
-    				return false;
+				return window != null && window.Handle != IntPtr.Zero;
+    				//if (Handle != (IntPtr) 0)
+    				//	return true;
+    				//return false;
     			}
     		}
     		
@@ -1172,28 +1176,31 @@
     	
     		protected virtual void CreateHandle ()
     		{
-				if( !IsHandleCreated) {
-					if( window == null) {
-						window = new ControlNativeWindow (this);
-					}
-					if( window != null) {
-						CreateParams createParams = CreateParams;
-						if( !Enabled) {
-							createParams.Style |= (int)WindowStyles.WS_DISABLED;
-						}
-						window.CreateHandle (createParams);
-					}
-					if( Handle != IntPtr.Zero) {
-						if( controlsCollection[Handle] == null) {
-							controlsCollection.Add(Handle, this);
-						}
-						SubclassWindow();
+			if( IsDisposed )
+				throw new ObjectDisposedException ( Name );
 
-						CreatorThreadId_ = Win32.GetCurrentThreadId();
+			if( IsHandleCreated ) 
+				return;
 
-						OnHandleCreated (new EventArgs());
-					}
-				}
+			if( window == null)
+				window = new ControlNativeWindow (this);
+
+			CreateParams createParams = CreateParams;
+			if( !Enabled) {
+				createParams.Style |= (int)WindowStyles.WS_DISABLED;
+			}
+			window.CreateHandle (createParams);
+
+			if( window.Handle != IntPtr.Zero) {
+				if( !controlsCollection.Contains( window.Handle ) )
+					controlsCollection.Add( window.Handle, this );
+
+				SubclassWindow();
+
+				CreatorThreadId_ = Win32.GetCurrentThreadId();
+
+				OnHandleCreated ( EventArgs.Empty );
+			}
     		}
     	
     		protected virtual void DefWndProc (ref Message m)
@@ -1203,6 +1210,7 @@
     		
     		protected virtual void DestroyHandle ()
     		{
+			if ( IsHandleCreated ) {
 				if( Handle != IntPtr.Zero) {
 					controlsCollection.Remove(Handle);
 				}
@@ -1210,9 +1218,11 @@
 					window.DestroyHandle ();
 				}
 			}
+		}
     	
     		protected override void Dispose (bool disposing) 
     		{
+			isDisposed = true;
 				//FIXME: 
     			base.Dispose(disposing);
     		}
@@ -2523,6 +2533,10 @@
     				OnSizeChanged (eventArgs);
 					CallControlWndProc(ref m);
 					break;
+			case Msg.WM_WINDOWPOSCHANGED:
+				OnResize (eventArgs);
+				CallControlWndProc(ref m);
+			break;
     			case Msg.WM_STYLECHANGED:
     				OnStyleChanged (eventArgs);
 					CallControlWndProc(ref m);
@@ -2672,9 +2686,14 @@
     		/// --- IWin32Window properties
     		public IntPtr Handle {
     			get { 
-    				if (window != null) 
-    					return window.Handle; 
-    				return (IntPtr) 0;
+				// If the handle has not yet been created,
+				// referencing this property will force the
+				// handle to be created. ( MSDN )
+
+    				if ( !IsHandleCreated ) 
+					CreateHandle ( );
+
+    				return window.Handle;
     			}
     		}
     		
Index: Form.cs
===================================================================
RCS file: /mono/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs,v
retrieving revision 1.32
diff -u -r1.32 Form.cs
--- Form.cs	23 Mar 2003 20:46:53 -0000	1.32
+++ Form.cs	1 Apr 2003 16:06:02 -0000
@@ -36,6 +36,41 @@
 
 			// End of temperay varibles
 
+		internal class MdiClient : Control {
+			public MdiClient ( Control parent ) : base (parent, "") {
+			}
+			protected override CreateParams CreateParams {
+				get {
+					CreateParams pars = new CreateParams();
+
+					pars.ClassName = Win32.MDICLIENTCLASSNAME;
+					pars.Style = (int) (	WindowStyles.WS_CHILDWINDOW |
+								WindowStyles.WS_CLIPCHILDREN |
+								WindowStyles.WS_CLIPSIBLINGS |
+								WindowStyles.WS_OVERLAPPED |
+								WindowStyles.WS_VISIBLE |
+								WindowStyles.WS_VSCROLL |
+								WindowStyles.WS_HSCROLL );
+					pars.ExStyle = (int) (  WindowExStyles.WS_EX_CLIENTEDGE );
+
+					pars.Parent = Parent.Handle;
+					CLIENTCREATESTRUCT cs = new CLIENTCREATESTRUCT();
+					cs.hWindowMenu = IntPtr.Zero;
+					cs.idFirstChild = 100;
+
+					pars.Param = cs;
+					
+					return pars;
+				}
+			}
+			public void DestroyControl ( ) {
+				DestroyHandle ( );
+			}
+		}
+
+		MdiClient mdiClientWnd;
+		Form      mdiParent;
+
 			public Form () : base ()
     		{
 				opacity = 0;
@@ -128,7 +163,7 @@
     		[MonoTODO]
     		public new Size ClientSize {
     			get {
-    				throw new NotImplementedException ();
+    				return base.ClientSize;
     			}
     			set {
 					//bool MenuReady;
@@ -218,28 +253,12 @@
 					 //FIXME:
 				 }
     		}
-    
-    		[MonoTODO]
-    		public bool IsMidiChild {
-    			get {
-    				throw new NotImplementedException ();
-    			}
-    			set {
-					//FIXME:
-				}
-    		}
-    
-    		[MonoTODO]
-    		public bool IsMidiContainer {
-    			get {
-    				throw new NotImplementedException ();
-    			}
-    			set {
-					//FIXME:
-				}
+
+    		public bool IsMdiChild {
+    			get {	return mdiParent != null; }
     		}
-    
-    		[MonoTODO]
+
+       		[MonoTODO]
     		public bool KeyPreview {
     			get {
     				throw new NotImplementedException ();
@@ -273,21 +292,26 @@
     		[MonoTODO]
     		public Form[] MdiChildren {
     			get {
-    				throw new NotImplementedException ();
+				Form[] forms = new Form[0];
+				return forms;
     			}
-    			set {
-					//FIXME:
-				}
     		}
     
     		[MonoTODO]
     		public Form MdiParent {
     			get {
-    				throw new NotImplementedException ();
+    				return mdiParent;
     			}
     			set {
-					//FIXME:
-				}
+				if ( !value.IsMdiContainer || ( value.IsMdiContainer && value.IsMdiChild ) )
+					throw new Exception( );
+
+				mdiParent = value;
+				mdiParent.MdiClientControl.Controls.Add ( this );
+				
+				if ( mdiParent.IsHandleCreated )
+					CreateControl ( );
+			}
     		}
     
  			//Compact Framework
@@ -367,7 +391,18 @@
     				opacity = value;
     			}
     		}
-    
+
+		[MonoTODO]
+		public bool IsMdiContainer {
+			get {	return mdiClientWnd != null; }
+			set {
+				if ( value )
+					createMdiClient ( );
+				else
+					destroyMdiClient ( );
+			}
+		}
+
     		[MonoTODO]
     		public Form[] OwnedForms {
     			get {
@@ -498,11 +533,32 @@
     			Win32.DestroyWindow (Handle);
     		}
     
-   			[MonoTODO]
     		public void LayoutMdi (MdiLayout value)
     		{
-				//FIXME:
+			if ( IsMdiContainer && mdiClientWnd.IsHandleCreated ) {
+				int mes = 0;
+				int wp  = 0;
+
+				switch ( value ) {
+				case MdiLayout.Cascade:
+					mes = (int)Msg.WM_MDICASCADE;
+				break;
+				case MdiLayout.ArrangeIcons:
+					mes = (int)Msg.WM_MDIICONARRANGE;
+				break;
+				case MdiLayout.TileHorizontal:
+					mes = (int)Msg.WM_MDITILE;
+					wp = 1;
+				break;
+				case MdiLayout.TileVertical:
+					mes = (int)Msg.WM_MDITILE;
+				break;
+				}
+				
+				if ( mes != 0 )
+					Win32.SendMessage ( mdiClientWnd.Handle, mes, wp, 0 );
 			}
+		}
     
     		[MonoTODO]
     		public void RemoveOwnedForm (Form ownedForm)
@@ -540,6 +596,7 @@
     		public event EventHandler Activated;
     		
     		public event EventHandler Closed;
+		public event CancelEventHandler Closing;
     		 
   			//Compact Framework
     		// CancelEventHandler not yet implemented/stubbed
@@ -565,11 +622,18 @@
     		protected override CreateParams CreateParams {
     			get {
 				CreateParams pars = base.CreateParams;
-				pars.Style |= (int)( WindowStyles.WS_OVERLAPPEDWINDOW | 
+				
+				if ( IsMdiChild ) {
+					pars.Style |= (int)( WindowStyles.WS_CHILD | WindowStyles.WS_VISIBLE );
+					pars.ExStyle |= (int)WindowExStyles.WS_EX_MDICHILD;
+				}
+				else 
+					pars.Style |= (int)( WindowStyles.WS_OVERLAPPEDWINDOW | 
 							WindowStyles.WS_CLIPSIBLINGS /* |
 							WindowStyles.WS_CLIPCHILDREN */);
 				// should have WS_CLIPCHILDREN style but there are
 				// problems with GroupBox at the moment
+
 				return pars;
     			}
     		}
@@ -624,16 +688,16 @@
     		protected override void CreateHandle ()
     		{
     			base.CreateHandle ();
-/*
- *	This is called in base class    
-    			if (IsHandleCreated)
-    				OnHandleCreated (new EventArgs());
-*/					
     		}
     
     		protected override void DefWndProc (ref Message m)
     		{
-    			window.DefWndProc (ref m);
+			if ( IsMdiChild )
+				window.DefMDIChildProc ( ref m );
+			else if ( IsMdiContainer && mdiClientWnd.IsHandleCreated )
+				window.DefFrameProc ( ref m, mdiClientWnd );
+			else
+    				window.DefWndProc (ref m);
     		}
 
   			//Compact Framework
@@ -644,10 +708,10 @@
     		}
     
 	  		//Compact Framework
-    		[MonoTODO]
     		protected virtual void  OnClosing(CancelEventArgs e)
     		{
-    				throw new NotImplementedException ();
+			if ( Closing != null )
+    				Closing ( this, e);
     		}
     
     		protected override void OnCreateControl ()
@@ -664,9 +728,10 @@
     		protected override void OnHandleCreated (EventArgs e)
     		{
     			base.OnHandleCreated (e);
-				Console.WriteLine ("Form.OnHandleCreated");
-				assignMenu();
-			}
+			if ( IsMdiChild ) 
+				activateMdiChild ( );
+			assignMenu();
+		}
     
     		protected override void OnHandleDestroyed (EventArgs e)
     		{
@@ -738,8 +803,8 @@
  			//Compact Framework
     		protected override void  OnResize (EventArgs e)
     		{
-
     			base.OnResize (e);
+			resizeMdiClient ();
     		}
     
     		protected override void  OnStyleChanged (EventArgs e)
@@ -787,6 +852,12 @@
 					}
 				}
 				else {
+					if ( IsMdiContainer && m.LParam != IntPtr.Zero ) {
+						// we need to pass unhandled commands
+						// to DefFrameProc
+						m.Result = (IntPtr)1;
+						return;
+					}
 					base.OnWmCommand(ref m);
 				}
 			}
@@ -837,8 +908,12 @@
     		{
     			switch (m.Msg) {
     			case Msg.WM_CLOSE:
-    				EventArgs closeArgs = new EventArgs();
-    				OnClosed (closeArgs);
+				CancelEventArgs args = new CancelEventArgs( false );
+				OnClosing( args );
+				if ( !args.Cancel ) {
+    					OnClosed ( EventArgs.Empty );
+					base.WndProc ( ref m );
+				}
     				break;
     				//case ?:
     				//OnCreateControl()
@@ -880,6 +955,7 @@
     			case Msg.WM_MDIACTIVATE:
     				EventArgs mdiActivateArgs = new EventArgs();
     				OnMdiChildActivate (mdiActivateArgs);
+				base.WndProc ( ref m );
     				break;
     			case Msg.WM_EXITMENULOOP:
     				EventArgs menuCompleteArgs = new EventArgs();
@@ -947,6 +1023,39 @@
 			}
 			#endregion
 			
+		private void createMdiClient ( ) {
+			if(  mdiClientWnd == null ) {
+				mdiClientWnd = new MdiClient ( this );
+				Controls.Add ( mdiClientWnd );
+				mdiClientWnd.Dock = DockStyle.Fill;
+				if ( IsHandleCreated )
+					mdiClientWnd.CreateControl ( );
+			}
+		}
+
+		private void destroyMdiClient ( ) {
+			if ( mdiClientWnd != null ) {
+				Controls.Remove ( mdiClientWnd );
+				mdiClientWnd.DestroyControl ( );
+				mdiClientWnd = null;
+			}
+		}
+		private void resizeMdiClient ( ) {
+			if ( IsMdiContainer && mdiClientWnd.IsHandleCreated ) {
+				Win32.MoveWindow ( mdiClientWnd.Handle,
+					Location.X, Location.Y,
+					ClientSize.Width,
+					ClientSize.Height, true );
+			}
+		}
+
+		private void activateMdiChild ( ) {
+			Win32.SendMessage ( Parent.Handle, Msg.WM_MDIACTIVATE, Handle.ToInt32(), 0 );
+		}
+
+		internal Control MdiClientControl {
+			get { return this.mdiClientWnd; }
+		}
 
     		//sub class
     		//System.Windows.Forms.Form.ControlCollection.cs
Index: NativeWindow.cs
===================================================================
RCS file: /mono/mcs/class/System.Windows.Forms/System.Windows.Forms/NativeWindow.cs,v
retrieving revision 1.21
diff -u -r1.21 NativeWindow.cs
--- NativeWindow.cs	1 Mar 2003 21:20:31 -0000	1.21
+++ NativeWindow.cs	1 Apr 2003 16:06:03 -0000
@@ -72,7 +72,6 @@
 		{
 			if( cp != null ) {
 				IntPtr createdHWnd = (IntPtr) 0;
-				Object lpParam = new Object();
 
 				if (!registeredClass) {
 					WNDCLASS wndClass = new WNDCLASS();
@@ -98,12 +97,14 @@
 					}
 				}
 
+				System.Console.WriteLine("Creating window {0}", cp.ClassName);
+				object lParam = cp.Param;
 				windowHandle = Win32.CreateWindowEx (
 					(uint) cp.ExStyle, cp.ClassName,
 					cp.Caption,(uint) cp.Style,
 					cp.X, cp.Y, cp.Width, cp.Height,
 					(IntPtr) cp.Parent, (IntPtr) 0,
-					(IntPtr) 0, ref lpParam);
+					(IntPtr) 0, ref lParam);
 
 				if (windowHandle != (IntPtr) 0) {
 					windowCollection.Add (windowHandle, this);
@@ -122,6 +123,15 @@
 		{
 			m.Result = Win32.DefWindowProcA (m.HWnd, m.Msg, 
 							 m.WParam, m.LParam);
+		}
+
+		internal void DefMDIChildProc ( ref Message m ) {
+			m.Result = Win32.DefMDIChildProc(m.HWnd, m.Msg, m.WParam, m.LParam);
+		}
+
+		internal void DefFrameProc ( ref Message m , Control MdiClient) {
+			m.Result = Win32.DefFrameProc(m.HWnd, MdiClient != null ? MdiClient.Handle : IntPtr.Zero, 
+							m.Msg, m.WParam, m.LParam);
 		}
 
 		public virtual void DestroyHandle () 
Index: win32Structs.cs
===================================================================
RCS file: /mono/mcs/class/System.Windows.Forms/System.Windows.Forms/win32Structs.cs,v
retrieving revision 1.8
diff -u -r1.8 win32Structs.cs
--- win32Structs.cs	26 Mar 2003 23:44:37 -0000	1.8
+++ win32Structs.cs	1 Apr 2003 16:06:07 -0000
@@ -765,7 +765,13 @@
 		internal int     iPos;
 		internal int     iDelta;
 	}
-	
+
+	[StructLayout(LayoutKind.Sequential)]
+	internal struct CLIENTCREATESTRUCT {
+		internal IntPtr hWindowMenu; 
+		internal uint   idFirstChild; 
+	}
+
 	//
 	//
 	//		[StructLayout(LayoutKind.Sequential)]
Index: win32functions.cs
===================================================================
RCS file: /mono/mcs/class/System.Windows.Forms/System.Windows.Forms/win32functions.cs,v
retrieving revision 1.16
diff -u -r1.16 win32functions.cs
--- win32functions.cs	26 Mar 2003 23:44:37 -0000	1.16
+++ win32functions.cs	1 Apr 2003 16:06:07 -0000
@@ -52,6 +52,7 @@
 		internal const string PROGRESSBARCLASSNAME = "msctls_progress32";
 		internal const string SCROLLBAR = "SCROLLBAR";
 		internal const string TOOLTIPS_CLASS = "tooltips_class32";
+		internal const string MDICLIENTCLASSNAME = "MDICLIENT";
 		
 		#endregion
 
@@ -445,6 +446,12 @@
 		[DllImport("user32.dll", CharSet=CharSet.Auto,EntryPoint="DefWindowProcA")]
 		static internal extern int DefWindowProc(IntPtr hWnd, int message, int wParam, int lParam);
 
+		[DllImport("user32.dll", CharSet=CharSet.Unicode,EntryPoint="DefMDIChildProcA")]
+		static internal extern IntPtr DefMDIChildProc(IntPtr hWnd, Msg Msg, IntPtr wParam, IntPtr lParam);
+
+		[DllImport("user32.dll", CharSet=CharSet.Unicode,EntryPoint="DefFrameProcA")]
+		static internal extern IntPtr DefFrameProc(IntPtr hWnd, IntPtr hWndMDIClient, Msg Msg, IntPtr wParam, IntPtr lParam);
+		
 		[DllImport("user32.dll", CharSet=CharSet.Auto,EntryPoint="LoadCursorA")]
 		static internal extern IntPtr LoadCursor(IntPtr hInstance, LC_ standardCursor);
 

--0-609220278-1049213705=:89260--