2 // System.Windows.Forms.NativeWindow.cs
5 // stubbed out by Paul Osman (paul.osman@sympatico.ca)
6 // Dennis Hayes (dennish@Raytek.com)
7 // WINELib implementation started by John Sohn (jsohn@columbus.rr.com)
9 // (C) 2002/3 Ximian, Inc
12 using System.Runtime.Remoting;
13 using System.Runtime.InteropServices;
14 using System.Runtime.CompilerServices;
15 using System.Collections;
17 namespace System.Windows.Forms {
22 public class NativeWindow : MarshalByRefObject {
25 private IntPtr windowHandle;
26 static private Hashtable windowCollection = new Hashtable ();
27 static bool registeredClass = false;
29 // Important! If this variable was initialized and supplied to Windows API,
30 // we cannot *free* (GC) a delegate until all our windows destroyed, or better
32 static Win32.WndProc wp = null;
37 public NativeWindow ()
39 windowHandle = (IntPtr) 0;
40 // Important! Do not reinitialize wp, because this will *free* (GC)
41 // WindowProc delegate on every Control creation, but this delegate could
42 // already be passed to RegisterClass for the Form and others windows.
43 // We will get problems in Get/Translate/Dispatch Message loop
44 // (like call to invalid address)
49 // --- Public Properties
61 public void AssignHandle (IntPtr handle)
63 if (windowHandle != (IntPtr) 0)
64 windowCollection.Remove (windowHandle);
66 windowHandle = handle;
67 windowCollection.Add (windowHandle, this);
71 public virtual void CreateHandle (CreateParams cp)
74 IntPtr createdHWnd = (IntPtr) 0;
76 if (!registeredClass) {
77 WNDCLASS wndClass = new WNDCLASS();
79 wndClass.style = (int) (CS_.CS_OWNDC /*|
82 wndClass.lpfnWndProc = GetWindowProc();
83 wndClass.cbClsExtra = 0;
84 wndClass.cbWndExtra = 0;
85 wndClass.hInstance = (IntPtr)0;
86 wndClass.hIcon = (IntPtr)0;
87 wndClass.hCursor = Win32.LoadCursor( (IntPtr)0, LC_.IDC_ARROW);
88 wndClass.hbrBackground = (IntPtr)((int)GetSysColorIndex.COLOR_BTNFACE + 1);
89 wndClass.lpszMenuName = "";
90 wndClass.lpszClassName = "mono_native_window";
92 if (Win32.RegisterClass(ref wndClass) != 0) {
93 registeredClass = true;
95 windowHandle = (IntPtr)0;
100 IntPtr lParam = IntPtr.Zero;
102 if ( cp.Param != null && cp.Param is CLIENTCREATESTRUCT ) {
103 lParam = Marshal.AllocHGlobal ( Marshal.SizeOf ( cp.Param ) );
104 Marshal.StructureToPtr ( cp.Param, lParam, false );
107 windowHandle = Win32.CreateWindowEx (
108 (uint) cp.ExStyle, cp.ClassName,
109 cp.Caption,(uint) cp.Style,
110 cp.X, cp.Y, cp.Width, cp.Height,
111 (IntPtr) cp.Parent, (IntPtr) 0,
114 if ( lParam != IntPtr.Zero )
115 Marshal.FreeHGlobal ( lParam );
117 if (windowHandle != (IntPtr) 0) {
118 windowCollection.Add (windowHandle, this);
119 if( (cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
120 IntPtr curId = Win32.GetWindowLong( windowHandle, GetWindowLongFlag.GWL_ID);
121 if( curId == IntPtr.Zero)
122 Win32.SetWindowLong(windowHandle, GetWindowLongFlag.GWL_ID, (int)windowHandle);
127 System.Console.WriteLine("Cannot create window {0}", Win32.FormatMessage(Win32.GetLastError()));
132 public void DefWndProc (ref Message m)
134 m.Result = Win32.DefWindowProcA (m.HWnd, m.Msg,
138 internal void DefMDIChildProc ( ref Message m ) {
139 m.Result = Win32.DefMDIChildProc(m.HWnd, m.Msg, m.WParam, m.LParam);
142 internal void DefFrameProc ( ref Message m , Control MdiClient) {
143 m.Result = Win32.DefFrameProc(m.HWnd, MdiClient != null ? MdiClient.Handle : IntPtr.Zero,
144 m.Msg, m.WParam, m.LParam);
147 public virtual void DestroyHandle ()
149 windowCollection.Remove (windowHandle);
150 Win32.DestroyWindow (windowHandle);
151 windowHandle = (IntPtr)0;
154 public static NativeWindow FromHandle (IntPtr handle)
156 NativeWindow window = new NativeWindow ();
157 window.AssignHandle (handle);
161 public virtual void ReleaseHandle ()
163 windowHandle = (IntPtr) 0;
168 // --- Protected Methods
173 protected virtual void OnHandleChange ()
179 protected virtual void OnThreadException (Exception e)
181 Application.OnThreadException(e);
182 //Console.WriteLine(e.Message + "\n" + ex.StackTrace);
185 protected virtual void WndProc (ref Message m)
187 if (m.Msg == Msg.WM_CREATE)
188 Console.WriteLine ("NW WndProc WM_CREATE");
197 if ( windowHandle != IntPtr.Zero )
201 static private IntPtr WndProc (
202 IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam)
204 // Console.WriteLine("NativeWindow.Message {0}", msg);
205 Message message = new Message ();
206 NativeWindow window = null;
207 // CHECKME: This try/catch is implemented to keep Message Handlers "Exception safe"
209 // windowCollection is a collection of all the
210 // NativeWindow(s) that have been created.
211 // Dispatch the current message to the approriate
213 window = (NativeWindow) windowCollection[hWnd];
216 message.WParam = wParam;
217 message.LParam = lParam;
218 message.Result = (IntPtr) 0;
221 if (msg == Msg.WM_CREATE)
222 Console.WriteLine ("WM_CREATE (static)");
225 if (window != null) {
226 if (msg == Msg.WM_CREATE) {
227 // Console.WriteLine ("WM_CREATE (static != null)");
229 window.WndProc(ref message);
231 // Console.WriteLine ("no window, defwndproc");
232 // even though we are not managing the
233 // window let the window get the message
234 message.Result = Win32.DefWindowProcA (
235 hWnd, msg, wParam, lParam);
238 catch( System.Exception ex) {
240 window.OnThreadException(ex);
242 //Console.WriteLine("NativeWindow.Message {0}, result {1}", msg, message.Result);
243 return message.Result;
246 internal static Win32.WndProc GetWindowProc() {
248 wp = new Win32.WndProc (WndProc);