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 Button close_button;
18 private Button maximize_button;
19 private Button minimize_button;
24 private FormPos sizing_edge;
25 private Rectangle virtual_position;
26 private Rectangle prev_bounds;
27 private bool maximized;
37 private enum FormPos {
48 TopRight = Top | Right,
50 BottomLeft = Bottom | Left,
51 BottomRight = Bottom | Right,
53 AnyEdge = Top | Left | Right | Bottom,
56 public MdiChildContext (Form form)
58 titlebar_color = Color.FromArgb (255, 0, 0, 255);
61 form.Paint += new PaintEventHandler (PaintWindowDecorations);
63 minimize_button = new Button ();
64 minimize_button.Bounds = new Rectangle (form.Width - 62,
65 BorderWidth + 2, 18, 22);
66 minimize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
67 minimize_button.Paint += new PaintEventHandler (PaintButtonHandler);
68 minimize_button.Click += new EventHandler (OnMinimizeHandler);
70 maximize_button = new Button ();
71 maximize_button.Bounds = new Rectangle (form.Width - 44,
72 BorderWidth + 2, 18, 22);
73 maximize_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
74 maximize_button.Paint += new PaintEventHandler (PaintButtonHandler);
75 maximize_button.Click += new EventHandler (OnMaximizeHandler);
77 close_button = new Button ();
78 close_button.Bounds = new Rectangle (form.Width - 24,
79 BorderWidth + 2, 18, 22);
80 close_button.Anchor = AnchorStyles.Top | AnchorStyles.Right;
81 close_button.Paint += new PaintEventHandler (PaintButtonHandler);
82 close_button.Click += new EventHandler (CloseButtonClicked);
85 form.Controls.Add (close_button);
86 form.Controls.Add (maximize_button);
87 form.Controls.Add (minimize_button);
90 public bool HandleMessage (ref Message m)
94 //DrawWindowDecorations (form.CreateGraphics ());
97 case Msg.WM_LBUTTONDOWN:
98 return HandleLButtonDown (form, ref m);
100 case Msg.WM_MOUSEMOVE:
101 return HandleMouseMove (form, ref m);
103 case Msg.WM_LBUTTONUP:
104 HandleLButtonUp (ref m);
111 private bool HandleLButtonDown (Form form, ref Message m)
113 form.BringToFront ();
115 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
116 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
117 FormPos pos = FormPosForCoords (x, y);
119 start = new Point (x, y);
120 virtual_position = form.Bounds;
122 if (pos == FormPos.TitleBar) {
123 HandleTitleBarDown (x, y);
127 SetCursorForPos (pos);
129 if ((pos & FormPos.AnyEdge) == 0)
132 state = State.Sizing;
139 private void HandleTitleBarDown (int x, int y)
141 state = State.Moving;
145 private bool HandleMouseMove (Form form, ref Message m)
149 HandleWindowMove (m);
156 int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
157 int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
158 FormPos pos = FormPosForCoords (x, y);
160 SetCursorForPos (pos);
166 private void SetCursorForPos (FormPos pos)
169 case FormPos.TopLeft:
170 case FormPos.BottomRight:
171 form.Cursor = Cursors.SizeNWSE;
173 case FormPos.TopRight:
174 case FormPos.BottomLeft:
175 form.Cursor = Cursors.SizeNESW;
179 form.Cursor = Cursors.SizeNS;
183 form.Cursor = Cursors.SizeWE;
186 form.Cursor = Cursors.Default;
191 private void HandleWindowMove (Message m)
193 Point move = MouseMove (m);
195 virtual_position.X = form.Left + move.X;
196 virtual_position.Y = form.Top + move.Y;
197 virtual_position.Width = form.Width;
198 virtual_position.Height = form.Height;
200 Graphics g = form.Parent.CreateGraphics ();
201 DrawVirtualPosition (g);
204 private void HandleSizing (Message m)
206 Point move = MouseMove (m);
207 Rectangle pos = virtual_position;
208 int mw = MinTitleBarSize.Width + (BorderWidth * 2);
209 int mh = MinTitleBarSize.Height + (BorderWidth * 2);
211 if ((sizing_edge & FormPos.Top) != 0) {
212 int height = form.Height - move.Y;
214 move.Y += height - mh;
217 pos.Y = form.Top + move.Y;
219 } else if ((sizing_edge & FormPos.Bottom) != 0) {
220 int height = form.Height + move.Y;
222 move.Y -= height - mh;
223 pos.Height = form.Height + move.Y;
226 if ((sizing_edge & FormPos.Left) != 0) {
227 int width = form.Width - move.X;
229 move.X += width - mw;
232 pos.X = form.Left + move.X;
234 } else if ((sizing_edge & FormPos.Right) != 0) {
235 int width = form.Width + move.X;
237 move.X -= width - mw;
238 pos.Width = form.Width + move.X;
244 private void UpdateVP (Rectangle r)
246 UpdateVP (r.X, r.Y, r.Width, r.Height);
249 private void UpdateVP (Point loc, int w, int h)
251 UpdateVP (loc.X, loc.Y, w, h);
254 private void UpdateVP (int x, int y, int w, int h)
256 virtual_position.X = x;
257 virtual_position.Y = y;
258 virtual_position.Width = w;
259 virtual_position.Height = h;
261 Graphics g = form.Parent.CreateGraphics ();
262 DrawVirtualPosition (g);
265 private void HandleLButtonUp (ref Message m)
267 if (state == State.Idle)
270 form.Capture = false;
272 // Clear the virtual position
273 Graphics g = form.Parent.CreateGraphics ();
274 g.Clear (form.Parent.BackColor);
276 form.Bounds = virtual_position;
280 private void PaintWindowDecorations (object sender, PaintEventArgs pe)
282 Color color = titlebar_color;
284 color = ThemeEngine.Current.ColorButtonFace;
285 pe.Graphics.FillRectangle (new SolidBrush (color),
286 BorderWidth, BorderWidth,
287 form.Width - BorderWidth, TitleBarHeight);
289 if (form.Icon != null) {
290 pe.Graphics.DrawIcon (form.Icon, BorderWidth, BorderWidth);
293 Pen bp = new Pen (ThemeEngine.Current.ColorButtonFace,
296 // HACK: kludge the borders around
297 Rectangle border = form.ClientRectangle;
302 pe.Graphics.DrawRectangle (bp, border);
304 Border3DStyle style = Border3DStyle.Raised | Border3DStyle.Bump;
305 border = form.ClientRectangle;
308 style = Border3DStyle.SunkenInner;
309 border.Y = TitleBarHeight + BorderWidth * 2;
310 border.Height -= TitleBarHeight;
313 ControlPaint.DrawBorder3D (pe.Graphics, border,
315 Border3DSide.Left | Border3DSide.Right |
316 Border3DSide.Top | Border3DSide.Bottom);
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 // For now just use a solid pen as it is 10 billion times
389 // faster then using the hatch, and what we really need is invert
390 private void DrawVirtualPosition (Graphics graphics)
392 Pen pen = new Pen (Color.Black, 3);
394 graphics.Clear (form.Parent.BackColor);
395 graphics.DrawRectangle (pen, virtual_position);
399 private FormPos FormPosForCoords (int x, int y)
401 if (y < TitleBarHeight + BorderWidth) {
403 if (y > BorderWidth && x > BorderWidth &&
404 x < form.Width - BorderWidth)
405 return FormPos.TitleBar;
407 if (x < BorderWidth || (x < 20 && y < BorderWidth))
408 return FormPos.TopLeft;
410 if (x > form.Width - BorderWidth ||
411 (x > form.Width - 20 && y < BorderWidth))
412 return FormPos.TopRight;
417 } else if (y > form.Height - 20) {
419 if (x < BorderWidth ||
420 (x < 20 && y > form.Height - BorderWidth))
421 return FormPos.BottomLeft;
423 if (x > form.Width - BorderWidth ||
424 (x > form.Width - 20 &&
425 y > form.Height - BorderWidth))
426 return FormPos.BottomRight;
428 if (y > form.Height - BorderWidth)
429 return FormPos.Bottom;
432 } else if (x < BorderWidth) {
434 } else if (x > form.Width - BorderWidth) {
435 return FormPos.Right;