1 // Permission is hereby granted, free of charge, to any person obtaining 2 // a copy of this software and associated documentation files (the 3 // "Software"), to deal in the Software without restriction, including 4 // without limitation the rights to use, copy, modify, merge, publish, 5 // distribute, sublicense, and/or sell copies of the Software, and to 6 // permit persons to whom the Software is furnished to do so, subject to 7 // the following conditions: 8 // 9 // The above copyright notice and this permission notice shall be 10 // included in all copies or substantial portions of the Software. 11 // 12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 // 20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com) 21 // 22 // Authors: 23 // Jackson Harper (jackson@ximian.com) 24 // 25 // 26 27 28 using System; 29 using System.Drawing; 30 using System.Drawing.Drawing2D; 31 using System.Runtime.InteropServices; 32 33 namespace System.Windows.Forms { 34 35 internal class MdiWindowManager : InternalWindowManager { 36 37 private MainMenu merged_menu; 38 private MainMenu maximized_menu; 39 private MenuItem icon_menu; 40 private ContextMenu icon_popup_menu; 41 internal bool was_minimized; 42 43 private PaintEventHandler draw_maximized_buttons; 44 internal EventHandler form_closed_handler; 45 46 private MdiClient mdi_container; 47 private Rectangle prev_virtual_position; 48 49 private Point icon_clicked; 50 private DateTime icon_clicked_time; 51 private bool icon_dont_show_popup; 52 53 private TitleButtons maximized_title_buttons; 54 private bool is_visible_pending; 55 private byte last_activation_event; // 0 = none, 1 = activated, 2 = deactivated. 56 RaiseActivated()57 public void RaiseActivated () 58 { 59 if (last_activation_event == 1) 60 return; 61 62 last_activation_event = 1; 63 form.OnActivatedInternal (); 64 form.SelectActiveControl (); 65 } 66 RaiseDeactivate()67 public void RaiseDeactivate () 68 { 69 if (last_activation_event != 1) 70 return; 71 last_activation_event = 2; 72 form.OnDeactivateInternal (); 73 } 74 75 public override int MenuHeight { 76 get { 77 // Mdi children don't get menus on the form, they're shown on the main form. 78 return 0; 79 } 80 } 81 82 internal bool IsVisiblePending { 83 get { 84 return is_visible_pending; 85 } 86 set { 87 is_visible_pending = value; 88 } 89 } 90 91 private TitleButtons MaximizedTitleButtons { 92 get { 93 if (maximized_title_buttons == null) { 94 maximized_title_buttons = new TitleButtons (this.Form); 95 maximized_title_buttons.CloseButton.Visible = true; 96 maximized_title_buttons.RestoreButton.Visible = true; 97 maximized_title_buttons.MinimizeButton.Visible = true; 98 } 99 return maximized_title_buttons; 100 } 101 } 102 103 internal override Rectangle MaximizedBounds { 104 get { 105 Rectangle pb = mdi_container.ClientRectangle; 106 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); 107 int tw = TitleBarHeight; 108 109 Rectangle new_bounds = new Rectangle (pb.Left - bw, 110 pb.Top - tw - bw, 111 pb.Width + bw * 2, 112 pb.Height + tw + bw * 2); 113 return new_bounds; 114 } 115 } 116 117 118 MdiWindowManager(Form form, MdiClient mdi_container)119 public MdiWindowManager (Form form, MdiClient mdi_container) : base (form) 120 { 121 this.mdi_container = mdi_container; 122 if (form.WindowState == FormWindowState.Normal) { 123 NormalBounds = form.Bounds; 124 } 125 form_closed_handler = new EventHandler (FormClosed); 126 form.Closed += form_closed_handler; 127 form.TextChanged += new EventHandler (FormTextChangedHandler); 128 form.SizeChanged += new EventHandler (FormSizeChangedHandler); 129 form.LocationChanged += new EventHandler (FormLocationChangedHandler); 130 form.VisibleChanged += new EventHandler (FormVisibleChangedHandler); 131 draw_maximized_buttons = new PaintEventHandler (DrawMaximizedButtons); 132 CreateIconMenus (); 133 } 134 FormVisibleChangedHandler(object sender, EventArgs e)135 private void FormVisibleChangedHandler (object sender, EventArgs e) 136 { 137 if (mdi_container == null) 138 return; 139 140 if (form.Visible) { 141 mdi_container.ActivateChild (form); 142 } else if (mdi_container.Controls.Count > 1) { 143 mdi_container.ActivateActiveMdiChild (); 144 } 145 } 146 FormTextChangedHandler(object sender, EventArgs e)147 private void FormTextChangedHandler (object sender, EventArgs e) 148 { 149 mdi_container.SetParentText (false); 150 151 if (form.MdiParent.MainMenuStrip != null) 152 form.MdiParent.MainMenuStrip.RefreshMdiItems (); 153 } 154 FormLocationChangedHandler(object sender, EventArgs e)155 private void FormLocationChangedHandler (object sender, EventArgs e) 156 { 157 if (form.window_state == FormWindowState.Minimized) 158 IconicBounds = form.Bounds; 159 form.MdiParent.MdiContainer.SizeScrollBars (); 160 } 161 FormSizeChangedHandler(object sender, EventArgs e)162 private void FormSizeChangedHandler (object sender, EventArgs e) 163 { 164 if (form.window_state == FormWindowState.Maximized && form.Bounds != MaximizedBounds) 165 form.Bounds = MaximizedBounds; 166 167 form.MdiParent.MdiContainer.SizeScrollBars (); 168 } 169 170 public MainMenu MergedMenu { 171 get { 172 if (merged_menu == null) 173 merged_menu = CreateMergedMenu (); 174 return merged_menu; 175 } 176 } 177 CreateMergedMenu()178 private MainMenu CreateMergedMenu () 179 { 180 Form parent = (Form) mdi_container.Parent; 181 MainMenu clone; 182 if (parent.Menu != null) 183 clone = (MainMenu) parent.Menu.CloneMenu (); 184 else 185 clone = new MainMenu (); 186 187 if (form.WindowState == FormWindowState.Maximized) { 188 189 } 190 clone.MergeMenu (form.Menu); 191 clone.MenuChanged += new EventHandler (MenuChangedHandler); 192 clone.SetForm (parent); 193 return clone; 194 } 195 196 public MainMenu MaximizedMenu { 197 get { 198 if (maximized_menu == null) 199 maximized_menu = CreateMaximizedMenu (); 200 return maximized_menu; 201 } 202 } 203 CreateMaximizedMenu()204 private MainMenu CreateMaximizedMenu () 205 { 206 Form parent = (Form) mdi_container.Parent; 207 208 if (form.MainMenuStrip != null || parent.MainMenuStrip != null) 209 return null; 210 211 MainMenu res = new MainMenu (); 212 213 if (parent.Menu != null) { 214 MainMenu clone = (MainMenu) parent.Menu.CloneMenu (); 215 res.MergeMenu (clone); 216 } 217 218 if (form.Menu != null) { 219 MainMenu clone = (MainMenu) form.Menu.CloneMenu (); 220 res.MergeMenu (clone); 221 } 222 223 if (res.MenuItems.Count == 0) 224 res.MenuItems.Add (new MenuItem ()); // Dummy item to get the menu height correct 225 226 res.MenuItems.Insert (0, icon_menu); 227 228 res.SetForm (parent); 229 return res; 230 } 231 CreateIconMenus()232 private void CreateIconMenus () 233 { 234 icon_menu = new MenuItem (); 235 icon_popup_menu = new ContextMenu (); 236 237 icon_menu.OwnerDraw = true; 238 icon_menu.MeasureItem += new MeasureItemEventHandler (MeasureIconMenuItem); 239 icon_menu.DrawItem += new DrawItemEventHandler (DrawIconMenuItem); 240 icon_menu.Click += new EventHandler (ClickIconMenuItem); 241 242 MenuItem restore = new MenuItem ("&Restore", new EventHandler (RestoreItemHandler)); 243 MenuItem move = new MenuItem ("&Move", new EventHandler (MoveItemHandler)); 244 MenuItem size = new MenuItem ("&Size", new EventHandler (SizeItemHandler)); 245 MenuItem minimize = new MenuItem ("Mi&nimize", new EventHandler (MinimizeItemHandler)); 246 MenuItem maximize = new MenuItem ("Ma&ximize", new EventHandler (MaximizeItemHandler)); 247 MenuItem close = new MenuItem ("&Close", new EventHandler (CloseItemHandler)); 248 MenuItem next = new MenuItem ("Nex&t", new EventHandler (NextItemHandler)); 249 250 icon_menu.MenuItems.AddRange (new MenuItem [] { restore, move, size, minimize, 251 maximize, close, next }); 252 icon_popup_menu.MenuItems.AddRange (new MenuItem [] { restore, move, size, minimize, 253 maximize, close, next }); 254 } 255 ClickIconMenuItem(object sender, EventArgs e)256 private void ClickIconMenuItem(object sender, EventArgs e) 257 { 258 if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime) { 259 form.Close (); 260 return; 261 } 262 icon_clicked_time = DateTime.Now; 263 Point pnt = Point.Empty; 264 pnt = form.MdiParent.PointToScreen (pnt); 265 pnt = form.PointToClient (pnt); 266 ShowPopup (pnt); 267 } 268 ShowPopup(Point pnt)269 internal void ShowPopup (Point pnt) 270 { 271 // If we are using MainMenuStrip, display that menu instead 272 if (form.WindowState == FormWindowState.Maximized && form.MdiParent.MainMenuStrip != null) 273 if (form.MdiParent.MainMenuStrip.Items.Count > 0) { 274 ToolStripItem tsi = form.MdiParent.MainMenuStrip.Items[0]; 275 276 if (tsi is MdiControlStrip.SystemMenuItem) { 277 (tsi as MdiControlStrip.SystemMenuItem).ShowDropDown (); 278 return; 279 } 280 } 281 282 icon_popup_menu.MenuItems[0].Enabled = form.window_state != FormWindowState.Normal; // restore 283 icon_popup_menu.MenuItems[1].Enabled = form.window_state != FormWindowState.Maximized; // move 284 icon_popup_menu.MenuItems[2].Enabled = form.window_state != FormWindowState.Maximized; // size 285 icon_popup_menu.MenuItems[3].Enabled = form.window_state != FormWindowState.Minimized; // minimize 286 icon_popup_menu.MenuItems[4].Enabled = form.window_state != FormWindowState.Maximized; // maximize 287 icon_popup_menu.MenuItems[5].Enabled = true; // close 288 icon_popup_menu.MenuItems[6].Enabled = true; // next 289 290 icon_popup_menu.Show(form, pnt); 291 } 292 RestoreItemHandler(object sender, EventArgs e)293 private void RestoreItemHandler (object sender, EventArgs e) 294 { 295 form.WindowState = FormWindowState.Normal; 296 } 297 MoveItemHandler(object sender, EventArgs e)298 private void MoveItemHandler (object sender, EventArgs e) 299 { 300 int x = 0; 301 int y = 0; 302 303 PointToScreen (ref x, ref y); 304 Cursor.Position = new Point (x, y); 305 form.Cursor = Cursors.Cross; 306 state = State.Moving; 307 form.Capture = true; 308 } 309 SizeItemHandler(object sender, EventArgs e)310 private void SizeItemHandler (object sender, EventArgs e) 311 { 312 int x = 0; 313 int y = 0; 314 315 PointToScreen (ref x, ref y); 316 Cursor.Position = new Point (x, y); 317 form.Cursor = Cursors.Cross; 318 state = State.Sizing; 319 form.Capture = true; 320 } 321 MinimizeItemHandler(object sender, EventArgs e)322 private void MinimizeItemHandler (object sender, EventArgs e) 323 { 324 form.WindowState = FormWindowState.Minimized; 325 } 326 MaximizeItemHandler(object sender, EventArgs e)327 private void MaximizeItemHandler (object sender, EventArgs e) 328 { 329 if (form.WindowState != FormWindowState.Maximized) 330 form.WindowState = FormWindowState.Maximized; 331 } 332 CloseItemHandler(object sender, EventArgs e)333 private void CloseItemHandler (object sender, EventArgs e) 334 { 335 form.Close (); 336 } 337 NextItemHandler(object sender, EventArgs e)338 private void NextItemHandler (object sender, EventArgs e) 339 { 340 mdi_container.ActivateNextChild (); 341 } 342 DrawIconMenuItem(object sender, DrawItemEventArgs de)343 private void DrawIconMenuItem (object sender, DrawItemEventArgs de) 344 { 345 de.Graphics.DrawIcon (form.Icon, new Rectangle (de.Bounds.X + 2, de.Bounds.Y + 2, 346 de.Bounds.Height - 4, de.Bounds.Height - 4)); 347 } 348 MeasureIconMenuItem(object sender, MeasureItemEventArgs me)349 private void MeasureIconMenuItem (object sender, MeasureItemEventArgs me) 350 { 351 int size = SystemInformation.MenuHeight; 352 me.ItemHeight = size; 353 me.ItemWidth = size + 2; // some padding 354 } 355 MenuChangedHandler(object sender, EventArgs e)356 private void MenuChangedHandler (object sender, EventArgs e) 357 { 358 CreateMergedMenu (); 359 } 360 PointToClient(ref int x, ref int y)361 public override void PointToClient (ref int x, ref int y) 362 { 363 XplatUI.ScreenToClient (mdi_container.Handle, ref x, ref y); 364 } 365 PointToScreen(ref int x, ref int y)366 public override void PointToScreen (ref int x, ref int y) 367 { 368 XplatUI.ClientToScreen (mdi_container.Handle, ref x, ref y); 369 } 370 UpdateWindowDecorations(FormWindowState window_state)371 public override void UpdateWindowDecorations (FormWindowState window_state) 372 { 373 if (MaximizedMenu != null) { 374 switch (window_state) { 375 case FormWindowState.Minimized: 376 case FormWindowState.Normal: 377 MaximizedMenu.Paint -= draw_maximized_buttons; 378 MaximizedTitleButtons.Visible = false; 379 TitleButtons.Visible = true; 380 break; 381 case FormWindowState.Maximized: 382 MaximizedMenu.Paint += draw_maximized_buttons; 383 MaximizedTitleButtons.Visible = true; 384 TitleButtons.Visible = false; 385 break; 386 } 387 } 388 389 base.UpdateWindowDecorations (window_state); 390 } 391 SetWindowState(FormWindowState old_state, FormWindowState window_state)392 public override void SetWindowState (FormWindowState old_state, FormWindowState window_state) 393 { 394 mdi_container.SetWindowState (form, old_state, window_state, false); 395 } 396 FormClosed(object sender, EventArgs e)397 private void FormClosed (object sender, EventArgs e) 398 { 399 mdi_container.ChildFormClosed (form); 400 401 if (form.MdiParent.MainMenuStrip != null) 402 form.MdiParent.MainMenuStrip.RefreshMdiItems (); 403 404 mdi_container.RemoveControlMenuItems (this); 405 } 406 DrawMaximizedButtons(object sender, PaintEventArgs pe)407 public override void DrawMaximizedButtons (object sender, PaintEventArgs pe) 408 { 409 Size bs = ThemeEngine.Current.ManagedWindowGetMenuButtonSize (this); 410 Point pnt = XplatUI.GetMenuOrigin (mdi_container.ParentForm.Handle); 411 int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this); 412 TitleButtons buttons = MaximizedTitleButtons; 413 414 buttons.Visible = true; 415 TitleButtons.Visible = false; 416 417 buttons.CloseButton.Rectangle = new Rectangle (mdi_container.ParentForm.Size.Width - 1 - bw - bs.Width - 2, 418 pnt.Y + 2, bs.Width, bs.Height); 419 420 buttons.RestoreButton.Rectangle = new Rectangle (buttons.CloseButton.Rectangle.Left - 2 - bs.Width, 421 pnt.Y + 2, bs.Width, bs.Height); 422 423 buttons.MinimizeButton.Rectangle = new Rectangle (buttons.RestoreButton.Rectangle.Left - bs.Width, 424 pnt.Y + 2, bs.Width, bs.Height); 425 426 DrawTitleButton (pe.Graphics, buttons.MinimizeButton, pe.ClipRectangle); 427 DrawTitleButton (pe.Graphics, buttons.RestoreButton, pe.ClipRectangle); 428 DrawTitleButton (pe.Graphics, buttons.CloseButton, pe.ClipRectangle); 429 430 buttons.MinimizeButton.Rectangle.Y -= pnt.Y; 431 buttons.RestoreButton.Rectangle.Y -= pnt.Y; 432 buttons.CloseButton.Rectangle.Y -= pnt.Y; 433 } 434 HandleMenuMouseDown(MainMenu menu, int x, int y)435 public bool HandleMenuMouseDown (MainMenu menu, int x, int y) 436 { 437 Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); 438 439 HandleTitleBarDown (pt.X, pt.Y); 440 return TitleButtons.AnyPushedTitleButtons; 441 } 442 HandleMenuMouseUp(MainMenu menu, int x, int y)443 public void HandleMenuMouseUp (MainMenu menu, int x, int y) 444 { 445 Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); 446 447 HandleTitleBarUp (pt.X, pt.Y); 448 } 449 HandleMenuMouseLeave(MainMenu menu, int x, int y)450 public void HandleMenuMouseLeave (MainMenu menu, int x, int y) 451 { 452 Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); 453 HandleTitleBarLeave (pt.X, pt.Y); 454 455 } 456 HandleMenuMouseMove(MainMenu menu, int x, int y)457 public void HandleMenuMouseMove (MainMenu menu, int x, int y) 458 { 459 Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y)); 460 461 HandleTitleBarMouseMove (pt.X, pt.Y); 462 463 } 464 HandleTitleBarLeave(int x, int y)465 protected override void HandleTitleBarLeave (int x, int y) 466 { 467 base.HandleTitleBarLeave (x, y); 468 469 if (maximized_title_buttons != null) { 470 maximized_title_buttons.MouseLeave (x, y); 471 } 472 473 if (IsMaximized) 474 XplatUI.InvalidateNC (form.MdiParent.Handle); 475 } 476 HandleTitleBarUp(int x, int y)477 protected override void HandleTitleBarUp (int x, int y) 478 { 479 if (IconRectangleContains (x, y)) { 480 if (!icon_dont_show_popup) { 481 if (IsMaximized) 482 ClickIconMenuItem (null, null); 483 else 484 ShowPopup (Point.Empty); 485 } else { 486 icon_dont_show_popup = false; 487 } 488 return; 489 } 490 491 bool was_maximized = IsMaximized; 492 base.HandleTitleBarUp (x, y); 493 if (maximized_title_buttons != null && was_maximized) { 494 maximized_title_buttons.MouseUp (x, y); 495 } 496 497 if (IsMaximized) 498 XplatUI.InvalidateNC (mdi_container.Parent.Handle); 499 } 500 HandleTitleBarDoubleClick(int x, int y)501 protected override void HandleTitleBarDoubleClick (int x, int y) 502 { 503 if (IconRectangleContains (x, y)) { 504 form.Close (); 505 } else if (form.MaximizeBox == true) { 506 form.WindowState = FormWindowState.Maximized; 507 } 508 base.HandleTitleBarDoubleClick (x, y); 509 } 510 HandleTitleBarDown(int x, int y)511 protected override void HandleTitleBarDown (int x, int y) 512 { 513 if (IconRectangleContains (x, y)) { 514 if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime && icon_clicked.X == x && icon_clicked.Y == y) { 515 form.Close (); 516 } else { 517 icon_clicked_time = DateTime.Now; 518 icon_clicked.X = x; 519 icon_clicked.Y = y; 520 } 521 522 return; 523 } 524 525 base.HandleTitleBarDown (x, y); 526 527 if (maximized_title_buttons != null) { 528 maximized_title_buttons.MouseDown (x, y); 529 } 530 531 if (IsMaximized) { 532 XplatUI.InvalidateNC (mdi_container.Parent.Handle); 533 } 534 } 535 HandleTitleBarMouseMove(int x, int y)536 protected override void HandleTitleBarMouseMove (int x, int y) 537 { 538 base.HandleTitleBarMouseMove (x, y); 539 540 if (maximized_title_buttons != null && maximized_title_buttons.MouseMove (x, y)) 541 XplatUI.InvalidateNC (form.MdiParent.Handle); 542 } 543 HandleLButtonDblClick(ref Message m)544 protected override bool HandleLButtonDblClick (ref Message m) 545 { 546 547 int x = Control.LowOrder ((int)m.LParam.ToInt32 ()); 548 int y = Control.HighOrder ((int)m.LParam.ToInt32 ()); 549 550 // Correct since we are in NC land. 551 NCClientToNC (ref x, ref y); 552 553 if (IconRectangleContains (x, y)) { 554 icon_popup_menu.Wnd.Hide (); 555 form.Close (); 556 return true; 557 } 558 559 return base.HandleLButtonDblClick (ref m); 560 } 561 HandleLButtonDown(ref Message m)562 protected override bool HandleLButtonDown (ref Message m) 563 { 564 565 int x = Control.LowOrder ((int)m.LParam.ToInt32 ()); 566 int y = Control.HighOrder ((int)m.LParam.ToInt32 ()); 567 568 // Correct y since we are in NC land. 569 NCClientToNC(ref x, ref y); 570 571 if (IconRectangleContains (x, y)){ 572 if ((DateTime.Now - icon_clicked_time).TotalMilliseconds <= SystemInformation.DoubleClickTime) { 573 if (icon_popup_menu != null && icon_popup_menu.Wnd != null) { 574 icon_popup_menu.Wnd.Hide (); 575 } 576 form.Close (); 577 return true; 578 } else if (form.Capture) { 579 icon_dont_show_popup = true; 580 } 581 } 582 return base.HandleLButtonDown (ref m); 583 } 584 ShouldRemoveWindowManager(FormBorderStyle style)585 protected override bool ShouldRemoveWindowManager (FormBorderStyle style) 586 { 587 return false; 588 } 589 HandleWindowMove(Message m)590 protected override void HandleWindowMove (Message m) 591 { 592 Point pos = Cursor.Position; 593 Point move = MouseMove (pos); 594 595 if (move.X == 0 && move.Y == 0) 596 return; 597 598 int x = virtual_position.X + move.X; 599 int y = virtual_position.Y + move.Y; 600 601 Rectangle client = mdi_container.ClientRectangle; 602 if (mdi_container.VerticalScrollbarVisible) 603 client.Width -= SystemInformation.VerticalScrollBarWidth; 604 if (mdi_container.HorizontalScrollbarVisible) 605 client.Height -= SystemInformation.HorizontalScrollBarHeight; 606 607 UpdateVP (x, y, form.Width, form.Height); 608 609 start = pos; 610 } 611 HandleNCMouseMove(ref Message m)612 protected override bool HandleNCMouseMove (ref Message m) 613 { 614 XplatUI.RequestAdditionalWM_NCMessages (form.Handle, true, true); 615 return base.HandleNCMouseMove (ref m); 616 } 617 DrawVirtualPosition(Rectangle virtual_position)618 protected override void DrawVirtualPosition (Rectangle virtual_position) 619 { 620 ClearVirtualPosition (); 621 622 if (form.Parent != null) 623 XplatUI.DrawReversibleRectangle (form.Parent.Handle, virtual_position, 2); 624 prev_virtual_position = virtual_position; 625 } 626 ClearVirtualPosition()627 protected override void ClearVirtualPosition () 628 { 629 if (prev_virtual_position != Rectangle.Empty && form.Parent != null) 630 XplatUI.DrawReversibleRectangle (form.Parent.Handle, 631 prev_virtual_position, 2); 632 prev_virtual_position = Rectangle.Empty; 633 } 634 OnWindowFinishedMoving()635 protected override void OnWindowFinishedMoving () 636 { 637 form.Refresh (); 638 } 639 640 public override bool IsActive { 641 get { 642 if (mdi_container == null) 643 return false; 644 return mdi_container.ActiveMdiChild == form; 645 } 646 } 647 Activate()648 protected override void Activate () 649 { 650 if (mdi_container.ActiveMdiChild != form) { 651 mdi_container.ActivateChild (form); 652 } 653 base.Activate (); 654 } 655 } 656 } 657 658