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
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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
{
43 public class NativeWindow
: MarshalByRefObject
{
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
53 static Win32
.WndProc wp
= null;
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)
70 // --- Public Properties
82 public void AssignHandle (IntPtr handle
)
84 if (windowHandle
!= (IntPtr
) 0)
85 windowCollection
.Remove (windowHandle
);
87 windowHandle
= handle
;
88 windowCollection
.Add (windowHandle
, this);
92 public virtual void CreateHandle (CreateParams cp
)
95 IntPtr createdHWnd
= (IntPtr
) 0;
97 if (!registeredClass
) {
98 WNDCLASS wndClass
= new WNDCLASS();
100 wndClass
.style
= (int) (CS_
.CS_OWNDC
/*|
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;
116 windowHandle
= (IntPtr
)0;
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,
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
);
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
,
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
);
182 public virtual void ReleaseHandle ()
184 windowHandle
= (IntPtr
) 0;
189 // --- Protected Methods
194 protected virtual void OnHandleChange ()
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");
218 if ( windowHandle
!= IntPtr
.Zero
)
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"
230 // windowCollection is a collection of all the
231 // NativeWindow(s) that have been created.
232 // Dispatch the current message to the approriate
234 window
= (NativeWindow
) windowCollection
[hWnd
];
236 message
.Msg
= (int) msg
;
237 message
.WParam
= wParam
;
238 message
.LParam
= lParam
;
239 message
.Result
= (IntPtr
) 0;
242 if (msg
== Msg
.WM_CREATE
)
243 Console
.WriteLine ("WM_CREATE (static)");
246 if (window
!= null) {
247 if (msg
== Msg
.WM_CREATE
) {
248 // Console.WriteLine ("WM_CREATE (static != null)");
250 window
.WndProc(ref message
);
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
) {
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() {
269 wp
= new Win32
.WndProc (WndProc
);