**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / NativeWindow.cs
blob6fd1e5a0c188dd3dd7093bca7d506e58806741b3
1 //
2 // System.Windows.Forms.NativeWindow.cs
3 //
4 // Author:
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)
8 //
9 // (C) 2002/3 Ximian, Inc
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Runtime.Remoting;
34 using System.Runtime.InteropServices;
35 using System.Runtime.CompilerServices;
36 using System.Collections;
38 namespace System.Windows.Forms {
40 // <summary>
41 // </summary>
43 public class NativeWindow : MarshalByRefObject {
45 // the window's HWND
46 private IntPtr windowHandle;
47 static private Hashtable windowCollection = new Hashtable ();
48 static bool registeredClass = false;
50 // Important! If this variable was initialized and supplied to Windows API,
51 // we cannot *free* (GC) a delegate until all our windows destroyed, or better
52 // keep it forever.
53 static Win32.WndProc wp = null;
56 // --- Constructor
58 public NativeWindow ()
60 windowHandle = (IntPtr) 0;
61 // Important! Do not reinitialize wp, because this will *free* (GC)
62 // WindowProc delegate on every Control creation, but this delegate could
63 // already be passed to RegisterClass for the Form and others windows.
64 // We will get problems in Get/Translate/Dispatch Message loop
65 // (like call to invalid address)
66 // wp = null;
70 // --- Public Properties
72 public IntPtr Handle
74 get {
75 return windowHandle;
80 // --- Public Methods
82 public void AssignHandle (IntPtr handle)
84 if (windowHandle != (IntPtr) 0)
85 windowCollection.Remove (windowHandle);
87 windowHandle = handle;
88 windowCollection.Add (windowHandle, this);
89 OnHandleChange ();
92 public virtual void CreateHandle (CreateParams cp)
94 if( cp != null ) {
95 IntPtr createdHWnd = (IntPtr) 0;
97 if (!registeredClass) {
98 WNDCLASS wndClass = new WNDCLASS();
100 wndClass.style = (int) (CS_.CS_OWNDC /*|
101 CS_.CS_VREDRAW |
102 CS_.CS_HREDRAW*/);
103 wndClass.lpfnWndProc = GetWindowProc();
104 wndClass.cbClsExtra = 0;
105 wndClass.cbWndExtra = 0;
106 wndClass.hInstance = (IntPtr)0;
107 wndClass.hIcon = (IntPtr)0;
108 wndClass.hCursor = Win32.LoadCursor( (IntPtr)0, LC_.IDC_ARROW);
109 wndClass.hbrBackground = (IntPtr)((int)GetSysColorIndex.COLOR_BTNFACE + 1);
110 wndClass.lpszMenuName = "";
111 wndClass.lpszClassName = "mono_native_window";
113 if (Win32.RegisterClass(ref wndClass) != 0) {
114 registeredClass = true;
115 } else {
116 windowHandle = (IntPtr)0;
117 return;
121 IntPtr lParam = IntPtr.Zero;
123 if ( cp.Param != null && cp.Param is CLIENTCREATESTRUCT ) {
124 lParam = Marshal.AllocHGlobal ( Marshal.SizeOf ( cp.Param ) );
125 Marshal.StructureToPtr ( cp.Param, lParam, false );
128 windowHandle = Win32.CreateWindowEx (
129 (uint) cp.ExStyle, cp.ClassName,
130 cp.Caption,(uint) cp.Style,
131 cp.X, cp.Y, cp.Width, cp.Height,
132 (IntPtr) cp.Parent, (IntPtr) 0,
133 (IntPtr) 0, lParam);
135 if ( lParam != IntPtr.Zero )
136 Marshal.FreeHGlobal ( lParam );
138 if (windowHandle != (IntPtr) 0) {
139 windowCollection.Add (windowHandle, this);
140 if( (cp.Style & (int)WindowStyles.WS_CHILD) != 0) {
141 IntPtr curId = Win32.GetWindowLong( windowHandle, GetWindowLongFlag.GWL_ID);
142 if( curId == IntPtr.Zero)
143 Win32.SetWindowLong(windowHandle, GetWindowLongFlag.GWL_ID, (int)windowHandle);
146 //debug
147 else {
148 System.Console.WriteLine("Cannot create window {0}", Win32.FormatMessage(Win32.GetLastError()));
153 public void DefWndProc (ref Message m)
155 m.Result = Win32.DefWindowProcA (m.HWnd, (Msg) m.Msg,
156 m.WParam, m.LParam);
159 internal void DefMDIChildProc ( ref Message m ) {
160 m.Result = Win32.DefMDIChildProc(m.HWnd,(Msg) m.Msg, m.WParam, m.LParam);
163 internal void DefFrameProc ( ref Message m , Control MdiClient) {
164 m.Result = Win32.DefFrameProc(m.HWnd, MdiClient != null ? MdiClient.Handle : IntPtr.Zero,
165 (Msg) m.Msg, m.WParam, m.LParam);
168 public virtual void DestroyHandle ()
170 windowCollection.Remove (windowHandle);
171 Win32.DestroyWindow (windowHandle);
172 windowHandle = (IntPtr)0;
175 public static NativeWindow FromHandle (IntPtr handle)
177 NativeWindow window = new NativeWindow ();
178 window.AssignHandle (handle);
179 return window;
182 public virtual void ReleaseHandle ()
184 windowHandle = (IntPtr) 0;
185 OnHandleChange ();
189 // --- Protected Methods
193 [MonoTODO]
194 protected virtual void OnHandleChange ()
196 // to be overridden
199 [MonoTODO]
200 protected virtual void OnThreadException (Exception e)
202 Application.OnThreadException(e);
203 //Console.WriteLine(e.Message + "\n" + ex.StackTrace);
206 protected virtual void WndProc (ref Message m)
208 if (m.Msg == (int) Msg.WM_CREATE)
209 Console.WriteLine ("NW WndProc WM_CREATE");
210 DefWndProc (ref m);
214 // --- Destructor
216 ~NativeWindow ()
218 if ( windowHandle != IntPtr.Zero )
219 DestroyHandle ( );
222 static private IntPtr WndProc (
223 IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam)
225 // Console.WriteLine("NativeWindow.Message {0}", msg);
226 Message message = new Message ();
227 NativeWindow window = null;
228 // CHECKME: This try/catch is implemented to keep Message Handlers "Exception safe"
229 try {
230 // windowCollection is a collection of all the
231 // NativeWindow(s) that have been created.
232 // Dispatch the current message to the approriate
233 // window.
234 window = (NativeWindow) windowCollection[hWnd];
235 message.HWnd = hWnd;
236 message.Msg = (int) msg;
237 message.WParam = wParam;
238 message.LParam = lParam;
239 message.Result = (IntPtr) 0;
241 #if false
242 if (msg == Msg.WM_CREATE)
243 Console.WriteLine ("WM_CREATE (static)");
244 #endif
246 if (window != null) {
247 if (msg == Msg.WM_CREATE) {
248 // Console.WriteLine ("WM_CREATE (static != null)");
250 window.WndProc(ref message);
251 } else {
252 // Console.WriteLine ("no window, defwndproc");
253 // even though we are not managing the
254 // window let the window get the message
255 message.Result = Win32.DefWindowProcA (
256 hWnd, msg, wParam, lParam);
259 catch( System.Exception ex) {
260 if( window != null)
261 window.OnThreadException(ex);
263 //Console.WriteLine("NativeWindow.Message {0}, result {1}", msg, message.Result);
264 return message.Result;
267 internal static Win32.WndProc GetWindowProc() {
268 if( wp == null){
269 wp = new Win32.WndProc (WndProc);
271 return wp;