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)
59 titlebar_color = Color.FromArgb (255, 0, 0, 255);
62 form.Paint += new PaintEventHandler (PaintWindowDecorations);
64 minimize_button = new Button ();
65 minimize_button.Bounds = new Rectangle (form.Width - 62,
66 BorderWidth + 2, 18, 22);
67 minimize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
68 minimize_button.Paint += new PaintEventHandler (PaintButtonHandler);
69 minimize_button.Click += new EventHandler (OnMinimizeHandler);
71 maximize_button = new Button ();
72 maximize_button.Bounds = new Rectangle (form.Width - 44,
73 BorderWidth + 2, 18, 22);
74 maximize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
75 maximize_button.Paint += new PaintEventHandler (PaintButtonHandler);
76 maximize_button.Click += new EventHandler (OnMaximizeHandler);
78 close_button = new Button ();
79 close_button.Bounds = new Rectangle (form.Width - 24,
80 BorderWidth + 2, 18, 22);
81 close_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
82 close_button.Paint += new PaintEventHandler (PaintButtonHandler);
83 close_button.Click += new EventHandler (CloseButtonClicked);
85 form.Controls.AddImplicit (close_button);
86 form.Controls.AddImplicit (maximize_button);
87 form.Controls.AddImplicit (minimize_button);
89 mdi_container = (MdiClient) form.Parent;
91 form.InternalBorderStyle = BorderStyle.FixedSingle;
94 public bool HandleMessage (ref Message m)
98 case Msg.WM_LBUTTONDOWN:
99 return HandleLButtonDown (form, ref m);
101 case Msg.WM_MOUSEMOVE:
102 return HandleMouseMove (form, ref m);
104 case Msg.WM_LBUTTONUP:
105 HandleLButtonUp (ref m);
112 private bool HandleLButtonDown (Form form, ref Message m)
114 form.BringToFront ();
115 mdi_container.ActiveMdiChild = form;
117 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
118 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
119 FormPos pos = FormPosForCoords (x, y);
121 start = new Point (x, y);
122 virtual_position = form.Bounds;
124 if (pos == FormPos.TitleBar) {
125 HandleTitleBarDown (x, y);
130 SetCursorForPos (pos);
132 if ((pos & FormPos.AnyEdge) == 0)
135 state = State.Sizing;
144 private void HandleTitleBarDown (int x, int y)
146 state = State.Moving;
150 private bool HandleMouseMove (Form form, ref Message m)
154 HandleWindowMove (m);
162 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
163 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
164 FormPos pos = FormPosForCoords (x, y);
166 SetCursorForPos (pos);
168 ClearVirtualPosition ();
175 private void SetCursorForPos (FormPos pos)
178 case FormPos.TopLeft:
179 case FormPos.BottomRight:
180 form.Cursor = Cursors.SizeNWSE;
182 case FormPos.TopRight:
183 case FormPos.BottomLeft:
184 form.Cursor = Cursors.SizeNESW;
188 form.Cursor = Cursors.SizeNS;
192 form.Cursor = Cursors.SizeWE;
195 form.Cursor = Cursors.Default;
200 private void HandleWindowMove (Message m)
202 Point move = MouseMove (m);
204 virtual_position.X = form.Left + move.X;
205 virtual_position.Y = form.Top + move.Y;
206 virtual_position.Width = form.Width;
207 virtual_position.Height = form.Height;
209 DrawVirtualPosition ();
212 private void HandleSizing (Message m)
214 Point move = MouseMove (m);
215 Rectangle pos = virtual_position;
216 int mw = MinTitleBarSize.Width + (BorderWidth * 2);
217 int mh = MinTitleBarSize.Height + (BorderWidth * 2);
219 if ((sizing_edge & FormPos.Top) != 0) {
220 int height = form.Height - move.Y;
222 move.Y += height - mh;
225 pos.Y = form.Top + move.Y;
227 } else if ((sizing_edge & FormPos.Bottom) != 0) {
228 int height = form.Height + move.Y;
230 move.Y -= height - mh;
231 pos.Height = form.Height + move.Y;
234 if ((sizing_edge & FormPos.Left) != 0) {
235 int width = form.Width - move.X;
237 move.X += width - mw;
240 pos.X = form.Left + move.X;
242 } else if ((sizing_edge & FormPos.Right) != 0) {
243 int width = form.Width + move.X;
245 move.X -= width - mw;
246 pos.Width = form.Width + move.X;
252 private bool IsSizable {
254 switch (form.FormBorderStyle) {
255 case FormBorderStyle.Sizable:
256 case FormBorderStyle.SizableToolWindow:
264 private void UpdateVP (Rectangle r)
266 UpdateVP (r.X, r.Y, r.Width, r.Height);
269 private void UpdateVP (Point loc, int w, int h)
271 UpdateVP (loc.X, loc.Y, w, h);
274 private void UpdateVP (int x, int y, int w, int h)
276 virtual_position.X = x;
277 virtual_position.Y = y;
278 virtual_position.Width = w;
279 virtual_position.Height = h;
281 DrawVirtualPosition ();
284 private void HandleLButtonUp (ref Message m)
286 if (state == State.Idle)
289 ClearVirtualPosition ();
291 form.Capture = false;
292 form.Bounds = virtual_position;
296 private void PaintWindowDecorations (object sender, PaintEventArgs pe)
298 Color color = titlebar_color;
300 color = ThemeEngine.Current.ColorControl;
301 Rectangle tb = new Rectangle (BorderWidth, BorderWidth,
302 form.Width - BorderWidth, TitleBarHeight);
304 pe.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color),
305 BorderWidth, BorderWidth,
306 form.Width - BorderWidth, TitleBarHeight);
308 if (form.Text != null) {
309 StringFormat format = new StringFormat ();
310 format.LineAlignment = StringAlignment.Center;
311 pe.Graphics.DrawString (form.Text, form.Font,
312 ThemeEngine.Current.ResPool.GetSolidBrush (form.ForeColor),
316 if (form.Icon != null) {
317 pe.Graphics.DrawIcon (form.Icon, BorderWidth, BorderWidth);
321 Pen bp = new Pen (ThemeEngine.Current.ColorControl,
324 // HACK: kludge the borders around
325 Rectangle border = form.ClientRectangle;
330 pe.Graphics.DrawRectangle (bp, border);
332 Border3DStyle style = Border3DStyle.Raised | Border3DStyle.Bump;
333 border = form.ClientRectangle;
336 style = Border3DStyle.SunkenInner;
337 border.Y = TitleBarHeight + BorderWidth * 2;
338 border.Height -= TitleBarHeight;
341 ControlPaint.DrawBorder3D (pe.Graphics, border,
343 Border3DSide.Left | Border3DSide.Right |
344 Border3DSide.Top | Border3DSide.Bottom);
348 private void PaintButtonHandler (object sender, PaintEventArgs pe)
350 if (sender == close_button) {
351 ControlPaint.DrawCaptionButton (pe.Graphics,
352 close_button.ClientRectangle,
354 close_button.ButtonState);
355 } else if (sender == maximize_button) {
356 ControlPaint.DrawCaptionButton (pe.Graphics,
357 maximize_button.ClientRectangle,
358 CaptionButton.Maximize,
359 maximize_button.ButtonState);
360 } else if (sender == minimize_button) {
361 ControlPaint.DrawCaptionButton (pe.Graphics,
362 minimize_button.ClientRectangle,
363 CaptionButton.Minimize,
364 minimize_button.ButtonState);
368 private void CloseButtonClicked (object sender, EventArgs e)
371 // form.Close should set visibility to false somewhere
372 // in it's closing chain but currently does not.
373 form.Visible = false;
376 private void OnMinimizeHandler (object sender, EventArgs e)
378 form.SuspendLayout ();
379 form.Width = MinTitleBarSize.Width + (BorderWidth * 2);
380 form.Height = MinTitleBarSize.Height + (BorderWidth * 2);
381 form.ResumeLayout ();
384 private void OnMaximizeHandler (object sender, EventArgs e)
387 form.Bounds = prev_bounds;
390 prev_bounds = form.Bounds;
391 form.Bounds = form.Parent.Bounds;
396 private Point NewLocation (Message m)
398 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
399 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
400 int x_move = x - start.X;
401 int y_move = y - start.Y;
403 return new Point (form.Left + x_move, form.Top + y_move);
406 private Point MouseMove (Message m)
408 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
409 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
410 int x_move = x - start.X;
411 int y_move = y - start.Y;
413 return new Point (x_move, y_move);
416 // For now just use a solid pen as it is 10 billion times
417 // faster then using the hatch, and what we really need is invert
418 private void DrawVirtualPosition ()
420 ClearVirtualPosition ();
422 XplatUI.DrawReversibleRectangle (mdi_container.Handle, virtual_position);
423 prev_virtual_position = virtual_position;
426 private void ClearVirtualPosition ()
428 if (prev_virtual_position != Rectangle.Empty)
429 XplatUI.DrawReversibleRectangle (mdi_container.Handle,
430 prev_virtual_position);
431 prev_virtual_position = Rectangle.Empty;
434 private FormPos FormPosForCoords (int x, int y)
436 if (y < TitleBarHeight + BorderWidth) {
438 if (y > BorderWidth && x > BorderWidth &&
439 x < form.Width - BorderWidth)
440 return FormPos.TitleBar;
442 if (x < BorderWidth || (x < 20 && y < BorderWidth))
443 return FormPos.TopLeft;
445 if (x > form.Width - BorderWidth ||
446 (x > form.Width - 20 && y < BorderWidth))
447 return FormPos.TopRight;
452 } else if (y > form.Height - 20) {
454 if (x < BorderWidth ||
455 (x < 20 && y > form.Height - BorderWidth))
456 return FormPos.BottomLeft;
458 if (x > form.Width - BorderWidth ||
459 (x > form.Width - 20 &&
460 y > form.Height - BorderWidth))
461 return FormPos.BottomRight;
463 if (y > form.Height - BorderWidth)
464 return FormPos.Bottom;
467 } else if (x < BorderWidth) {
469 } else if (x > form.Width - BorderWidth) {
470 return FormPos.Right;