4 using System.Drawing.Drawing2D;
6 namespace System.Windows.Forms {
8 internal class MdiChildContext {
10 private static Color titlebar_color;
12 private int BorderWidth = 3;
13 private int TitleBarHeight = 25;
14 private Size MinTitleBarSize = new Size (115, 25);
17 private MdiClient mdi_container;
18 private Button close_button;
19 private Button maximize_button;
20 private Button minimize_button;
25 private FormPos sizing_edge;
26 private Rectangle virtual_position;
27 private Rectangle prev_virtual_position;
28 private Rectangle prev_bounds;
29 private bool maximized;
38 private enum FormPos {
49 TopRight = Top | Right,
51 BottomLeft = Bottom | Left,
52 BottomRight = Bottom | Right,
54 AnyEdge = Top | Left | Right | Bottom,
57 public MdiChildContext (Form form, MdiClient mdi_container)
59 titlebar_color = Color.FromArgb (255, 0, 0, 255);
61 this.mdi_container = mdi_container;
63 form.Paint += new PaintEventHandler (PaintWindowDecorations);
65 minimize_button = new Button ();
66 minimize_button.Bounds = new Rectangle (form.Width - 62,
67 BorderWidth + 2, 18, 22);
68 minimize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
69 minimize_button.Paint += new PaintEventHandler (PaintButtonHandler);
70 minimize_button.Click += new EventHandler (OnMinimizeHandler);
72 maximize_button = new Button ();
73 maximize_button.Bounds = new Rectangle (form.Width - 44,
74 BorderWidth + 2, 18, 22);
75 maximize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
76 maximize_button.Paint += new PaintEventHandler (PaintButtonHandler);
77 maximize_button.Click += new EventHandler (OnMaximizeHandler);
79 close_button = new Button ();
80 close_button.Bounds = new Rectangle (form.Width - 24,
81 BorderWidth + 2, 18, 22);
82 close_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
83 close_button.Paint += new PaintEventHandler (PaintButtonHandler);
84 close_button.Click += new EventHandler (CloseButtonClicked);
86 form.Controls.AddImplicit (close_button);
87 form.Controls.AddImplicit (maximize_button);
88 form.Controls.AddImplicit (minimize_button);
91 public bool HandleMessage (ref Message m)
95 case Msg.WM_LBUTTONDOWN:
96 return HandleLButtonDown (form, ref m);
98 case Msg.WM_MOUSEMOVE:
99 return HandleMouseMove (form, ref m);
101 case Msg.WM_LBUTTONUP:
102 HandleLButtonUp (ref m);
109 private bool HandleLButtonDown (Form form, ref Message m)
111 form.BringToFront ();
112 mdi_container.ActiveMdiChild = form;
114 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
115 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
116 FormPos pos = FormPosForCoords (x, y);
118 start = new Point (x, y);
119 virtual_position = form.Bounds;
121 if (pos == FormPos.TitleBar) {
122 HandleTitleBarDown (x, y);
127 SetCursorForPos (pos);
129 if ((pos & FormPos.AnyEdge) == 0)
132 state = State.Sizing;
141 private void HandleTitleBarDown (int x, int y)
143 state = State.Moving;
147 private bool HandleMouseMove (Form form, ref Message m)
151 HandleWindowMove (m);
159 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
160 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
161 FormPos pos = FormPosForCoords (x, y);
163 SetCursorForPos (pos);
165 ClearVirtualPosition ();
172 private void SetCursorForPos (FormPos pos)
175 case FormPos.TopLeft:
176 case FormPos.BottomRight:
177 form.Cursor = Cursors.SizeNWSE;
179 case FormPos.TopRight:
180 case FormPos.BottomLeft:
181 form.Cursor = Cursors.SizeNESW;
185 form.Cursor = Cursors.SizeNS;
189 form.Cursor = Cursors.SizeWE;
192 form.Cursor = Cursors.Default;
197 private void HandleWindowMove (Message m)
199 Point move = MouseMove (m);
201 virtual_position.X = form.Left + move.X;
202 virtual_position.Y = form.Top + move.Y;
203 virtual_position.Width = form.Width;
204 virtual_position.Height = form.Height;
206 DrawVirtualPosition ();
209 private void HandleSizing (Message m)
211 Point move = MouseMove (m);
212 Rectangle pos = virtual_position;
213 int mw = MinTitleBarSize.Width + (BorderWidth * 2);
214 int mh = MinTitleBarSize.Height + (BorderWidth * 2);
216 if ((sizing_edge & FormPos.Top) != 0) {
217 int height = form.Height - move.Y;
219 move.Y += height - mh;
222 pos.Y = form.Top + move.Y;
224 } else if ((sizing_edge & FormPos.Bottom) != 0) {
225 int height = form.Height + move.Y;
227 move.Y -= height - mh;
228 pos.Height = form.Height + move.Y;
231 if ((sizing_edge & FormPos.Left) != 0) {
232 int width = form.Width - move.X;
234 move.X += width - mw;
237 pos.X = form.Left + move.X;
239 } else if ((sizing_edge & FormPos.Right) != 0) {
240 int width = form.Width + move.X;
242 move.X -= width - mw;
243 pos.Width = form.Width + move.X;
249 private bool IsSizable {
251 switch (form.FormBorderStyle) {
252 case FormBorderStyle.Sizable:
253 case FormBorderStyle.SizableToolWindow:
261 private void UpdateVP (Rectangle r)
263 UpdateVP (r.X, r.Y, r.Width, r.Height);
266 private void UpdateVP (Point loc, int w, int h)
268 UpdateVP (loc.X, loc.Y, w, h);
271 private void UpdateVP (int x, int y, int w, int h)
273 virtual_position.X = x;
274 virtual_position.Y = y;
275 virtual_position.Width = w;
276 virtual_position.Height = h;
278 DrawVirtualPosition ();
281 private void HandleLButtonUp (ref Message m)
283 if (state == State.Idle)
286 ClearVirtualPosition ();
288 form.Capture = false;
289 form.Bounds = virtual_position;
293 private void PaintWindowDecorations (object sender, PaintEventArgs pe)
295 Color color = titlebar_color;
297 color = ThemeEngine.Current.ColorControl;
298 Rectangle tb = new Rectangle (BorderWidth, BorderWidth,
299 form.Width - BorderWidth, TitleBarHeight);
301 pe.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color),
302 BorderWidth, BorderWidth,
303 form.Width - BorderWidth, TitleBarHeight);
305 tb.X += 18; // Room for the icon
306 if (form.Text != null) {
307 StringFormat format = new StringFormat ();
308 format.LineAlignment = StringAlignment.Center;
309 pe.Graphics.DrawString (form.Text, form.Font,
310 ThemeEngine.Current.ResPool.GetSolidBrush (form.ForeColor),
314 if (form.Icon != null) {
315 pe.Graphics.DrawIcon (form.Icon, new Rectangle (BorderWidth + 2,
316 BorderWidth + 2, 16, 16));
320 private void PaintButtonHandler (object sender, PaintEventArgs pe)
322 if (sender == close_button) {
323 ControlPaint.DrawCaptionButton (pe.Graphics,
324 close_button.ClientRectangle,
326 close_button.ButtonState);
327 } else if (sender == maximize_button) {
328 ControlPaint.DrawCaptionButton (pe.Graphics,
329 maximize_button.ClientRectangle,
330 CaptionButton.Maximize,
331 maximize_button.ButtonState);
332 } else if (sender == minimize_button) {
333 ControlPaint.DrawCaptionButton (pe.Graphics,
334 minimize_button.ClientRectangle,
335 CaptionButton.Minimize,
336 minimize_button.ButtonState);
340 private void CloseButtonClicked (object sender, EventArgs e)
343 // form.Close should set visibility to false somewhere
344 // in it's closing chain but currently does not.
345 form.Visible = false;
348 private void OnMinimizeHandler (object sender, EventArgs e)
350 form.SuspendLayout ();
351 form.Width = MinTitleBarSize.Width + (BorderWidth * 2);
352 form.Height = MinTitleBarSize.Height + (BorderWidth * 2);
353 form.ResumeLayout ();
356 private void OnMaximizeHandler (object sender, EventArgs e)
359 form.Bounds = prev_bounds;
362 prev_bounds = form.Bounds;
363 form.Bounds = form.Parent.Bounds;
368 private Point NewLocation (Message m)
370 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
371 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
372 int x_move = x - start.X;
373 int y_move = y - start.Y;
375 return new Point (form.Left + x_move, form.Top + y_move);
378 private Point MouseMove (Message m)
380 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
381 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
382 int x_move = x - start.X;
383 int y_move = y - start.Y;
385 return new Point (x_move, y_move);
388 private void DrawVirtualPosition ()
390 ClearVirtualPosition ();
392 XplatUI.DrawReversibleRectangle (mdi_container.Handle, virtual_position, 2);
393 prev_virtual_position = virtual_position;
396 private void ClearVirtualPosition ()
398 if (prev_virtual_position != Rectangle.Empty)
399 XplatUI.DrawReversibleRectangle (mdi_container.Handle,
400 prev_virtual_position, 2);
401 prev_virtual_position = Rectangle.Empty;
404 private FormPos FormPosForCoords (int x, int y)
406 if (y < TitleBarHeight + BorderWidth) {
408 if (y > BorderWidth && x > BorderWidth &&
409 x < form.Width - BorderWidth)
410 return FormPos.TitleBar;
412 if (x < BorderWidth || (x < 20 && y < BorderWidth))
413 return FormPos.TopLeft;
415 if (x > form.Width - BorderWidth ||
416 (x > form.Width - 20 && y < BorderWidth))
417 return FormPos.TopRight;
422 } else if (y > form.Height - 20) {
424 if (x < BorderWidth ||
425 (x < 20 && y > form.Height - BorderWidth))
426 return FormPos.BottomLeft;
428 if (x > form.Width - BorderWidth ||
429 (x > form.Width - 20 &&
430 y > form.Height - BorderWidth))
431 return FormPos.BottomRight;
433 if (y > form.Height - BorderWidth)
434 return FormPos.Bottom;
437 } else if (x < BorderWidth) {
439 } else if (x > form.Width - BorderWidth) {
440 return FormPos.Right;