Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.3.1/WinFormsUI-2.3.1/Docking/DockPanel.MdiClientController.cs @ 5304

Last change on this file since 5304 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 13.1 KB
Line 
1using System;
2using System.ComponentModel;
3using System.ComponentModel.Design;
4using System.Drawing;
5using System.Windows.Forms;
6
7namespace WeifenLuo.WinFormsUI.Docking {
8  partial class DockPanel {
9    //  This class comes from Jacob Slusser's MdiClientController class:
10    //  http://www.codeproject.com/cs/miscctrl/mdiclientcontroller.asp
11    private class MdiClientController : NativeWindow, IComponent, IDisposable {
12      private bool m_autoScroll = true;
13      private BorderStyle m_borderStyle = BorderStyle.Fixed3D;
14      private MdiClient m_mdiClient = null;
15      private Form m_parentForm = null;
16      private ISite m_site = null;
17
18      public MdiClientController() {
19      }
20
21      public void Dispose() {
22        Dispose(true);
23        GC.SuppressFinalize(this);
24      }
25
26      protected virtual void Dispose(bool disposing) {
27        if (disposing) {
28          lock (this) {
29            if (Site != null && Site.Container != null)
30              Site.Container.Remove(this);
31
32            if (Disposed != null)
33              Disposed(this, EventArgs.Empty);
34          }
35        }
36      }
37
38      public bool AutoScroll {
39        get { return m_autoScroll; }
40        set {
41          // By default the MdiClient control scrolls. It can appear though that
42          // there are no scrollbars by turning them off when the non-client
43          // area is calculated. I decided to expose this method following
44          // the .NET vernacular of an AutoScroll property.
45          m_autoScroll = value;
46          if (MdiClient != null)
47            UpdateStyles();
48        }
49      }
50
51      public BorderStyle BorderStyle {
52        set {
53          // Error-check the enum.
54          if (!Enum.IsDefined(typeof(BorderStyle), value))
55            throw new InvalidEnumArgumentException();
56
57          m_borderStyle = value;
58
59          if (MdiClient == null)
60            return;
61
62          // This property can actually be visible in design-mode,
63          // but to keep it consistent with the others,
64          // prevent this from being show at design-time.
65          if (Site != null && Site.DesignMode)
66            return;
67
68          // There is no BorderStyle property exposed by the MdiClient class,
69          // but this can be controlled by Win32 functions. A Win32 ExStyle
70          // of WS_EX_CLIENTEDGE is equivalent to a Fixed3D border and a
71          // Style of WS_BORDER is equivalent to a FixedSingle border.
72
73          // This code is inspired Jason Dori's article:
74          // "Adding designable borders to user controls".
75          // http://www.codeproject.com/cs/miscctrl/CsAddingBorders.asp
76
77          // Get styles using Win32 calls
78          int style = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE);
79          int exStyle = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE);
80
81          // Add or remove style flags as necessary.
82          switch (m_borderStyle) {
83            case BorderStyle.Fixed3D:
84              exStyle |= (int)Win32.WindowExStyles.WS_EX_CLIENTEDGE;
85              style &= ~((int)Win32.WindowStyles.WS_BORDER);
86              break;
87
88            case BorderStyle.FixedSingle:
89              exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
90              style |= (int)Win32.WindowStyles.WS_BORDER;
91              break;
92
93            case BorderStyle.None:
94              style &= ~((int)Win32.WindowStyles.WS_BORDER);
95              exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
96              break;
97          }
98
99          // Set the styles using Win32 calls
100          NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE, style);
101          NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE, exStyle);
102
103          // Cause an update of the non-client area.
104          UpdateStyles();
105        }
106      }
107
108      public MdiClient MdiClient {
109        get { return m_mdiClient; }
110      }
111
112      [Browsable(false)]
113      public Form ParentForm {
114        get { return m_parentForm; }
115        set {
116          // If the ParentForm has previously been set,
117          // unwire events connected to the old parent.
118          if (m_parentForm != null) {
119            m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
120            m_parentForm.MdiChildActivate -= new EventHandler(ParentFormMdiChildActivate);
121          }
122
123          m_parentForm = value;
124
125          if (m_parentForm == null)
126            return;
127
128          // If the parent form has not been created yet,
129          // wait to initialize the MDI client until it is.
130          if (m_parentForm.IsHandleCreated) {
131            InitializeMdiClient();
132            RefreshProperties();
133          } else
134            m_parentForm.HandleCreated += new EventHandler(ParentFormHandleCreated);
135
136          m_parentForm.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
137        }
138      }
139
140      public ISite Site {
141        get { return m_site; }
142        set {
143          m_site = value;
144
145          if (m_site == null)
146            return;
147
148          // If the component is dropped onto a form during design-time,
149          // set the ParentForm property.
150          IDesignerHost host = (value.GetService(typeof(IDesignerHost)) as IDesignerHost);
151          if (host != null) {
152            Form parent = host.RootComponent as Form;
153            if (parent != null)
154              ParentForm = parent;
155          }
156        }
157      }
158
159      public void RenewMdiClient() {
160        // Reinitialize the MdiClient and its properties.
161        InitializeMdiClient();
162        RefreshProperties();
163      }
164
165      public event EventHandler Disposed;
166
167      public event EventHandler HandleAssigned;
168
169      public event EventHandler MdiChildActivate;
170
171      public event LayoutEventHandler Layout;
172
173      protected virtual void OnHandleAssigned(EventArgs e) {
174        // Raise the HandleAssigned event.
175        if (HandleAssigned != null)
176          HandleAssigned(this, e);
177      }
178
179      protected virtual void OnMdiChildActivate(EventArgs e) {
180        // Raise the MdiChildActivate event
181        if (MdiChildActivate != null)
182          MdiChildActivate(this, e);
183      }
184
185      protected virtual void OnLayout(LayoutEventArgs e) {
186        // Raise the Layout event
187        if (Layout != null)
188          Layout(this, e);
189      }
190
191      public event PaintEventHandler Paint;
192
193      protected virtual void OnPaint(PaintEventArgs e) {
194        // Raise the Paint event.
195        if (Paint != null)
196          Paint(this, e);
197      }
198
199      protected override void WndProc(ref Message m) {
200        switch (m.Msg) {
201          case (int)Win32.Msgs.WM_NCCALCSIZE:
202            // If AutoScroll is set to false, hide the scrollbars when the control
203            // calculates its non-client area.
204            if (!AutoScroll)
205              NativeMethods.ShowScrollBar(m.HWnd, (int)Win32.ScrollBars.SB_BOTH, 0 /*false*/);
206            break;
207        }
208
209        base.WndProc(ref m);
210      }
211
212      private void ParentFormHandleCreated(object sender, EventArgs e) {
213        // The form has been created, unwire the event, and initialize the MdiClient.
214        this.m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
215        InitializeMdiClient();
216        RefreshProperties();
217      }
218
219      private void ParentFormMdiChildActivate(object sender, EventArgs e) {
220        OnMdiChildActivate(e);
221      }
222
223      private void MdiClientLayout(object sender, LayoutEventArgs e) {
224        OnLayout(e);
225      }
226
227      private void MdiClientHandleDestroyed(object sender, EventArgs e) {
228        // If the MdiClient handle has been released, drop the reference and
229        // release the handle.
230        if (m_mdiClient != null) {
231          m_mdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
232          m_mdiClient = null;
233        }
234
235        ReleaseHandle();
236      }
237
238      private void InitializeMdiClient() {
239        // If the mdiClient has previously been set, unwire events connected
240        // to the old MDI.
241        if (MdiClient != null) {
242          MdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
243          MdiClient.Layout -= new LayoutEventHandler(MdiClientLayout);
244        }
245
246        if (ParentForm == null)
247          return;
248
249        // Get the MdiClient from the parent form.
250        foreach (Control control in ParentForm.Controls) {
251          // If the form is an MDI container, it will contain an MdiClient control
252          // just as it would any other control.
253
254          m_mdiClient = control as MdiClient;
255          if (m_mdiClient == null)
256            continue;
257
258          // Assign the MdiClient Handle to the NativeWindow.
259          ReleaseHandle();
260          AssignHandle(MdiClient.Handle);
261
262          // Raise the HandleAssigned event.
263          OnHandleAssigned(EventArgs.Empty);
264
265          // Monitor the MdiClient for when its handle is destroyed.
266          MdiClient.HandleDestroyed += new EventHandler(MdiClientHandleDestroyed);
267          MdiClient.Layout += new LayoutEventHandler(MdiClientLayout);
268
269          break;
270        }
271      }
272
273      private void RefreshProperties() {
274        // Refresh all the properties
275        BorderStyle = m_borderStyle;
276        AutoScroll = m_autoScroll;
277      }
278
279      private void UpdateStyles() {
280        // To show style changes, the non-client area must be repainted. Using the
281        // control's Invalidate method does not affect the non-client area.
282        // Instead use a Win32 call to signal the style has changed.
283        NativeMethods.SetWindowPos(MdiClient.Handle, IntPtr.Zero, 0, 0, 0, 0,
284            Win32.FlagsSetWindowPos.SWP_NOACTIVATE |
285            Win32.FlagsSetWindowPos.SWP_NOMOVE |
286            Win32.FlagsSetWindowPos.SWP_NOSIZE |
287            Win32.FlagsSetWindowPos.SWP_NOZORDER |
288            Win32.FlagsSetWindowPos.SWP_NOOWNERZORDER |
289            Win32.FlagsSetWindowPos.SWP_FRAMECHANGED);
290      }
291    }
292
293    private MdiClientController m_mdiClientController = null;
294    private MdiClientController GetMdiClientController() {
295      if (m_mdiClientController == null) {
296        m_mdiClientController = new MdiClientController();
297        m_mdiClientController.HandleAssigned += new EventHandler(MdiClientHandleAssigned);
298        m_mdiClientController.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
299        m_mdiClientController.Layout += new LayoutEventHandler(MdiClient_Layout);
300      }
301
302      return m_mdiClientController;
303    }
304
305    private void ParentFormMdiChildActivate(object sender, EventArgs e) {
306      if (GetMdiClientController().ParentForm == null)
307        return;
308
309      IDockContent content = GetMdiClientController().ParentForm.ActiveMdiChild as IDockContent;
310      if (content == null)
311        return;
312
313      if (content.DockHandler.DockPanel == this && content.DockHandler.Pane != null)
314        content.DockHandler.Pane.ActiveContent = content;
315    }
316
317    private bool MdiClientExists {
318      get { return GetMdiClientController().MdiClient != null; }
319    }
320
321    private void SetMdiClientBounds(Rectangle bounds) {
322      GetMdiClientController().MdiClient.Bounds = bounds;
323    }
324
325    private void SuspendMdiClientLayout() {
326      if (GetMdiClientController().MdiClient != null)
327        GetMdiClientController().MdiClient.SuspendLayout();
328    }
329
330    private void ResumeMdiClientLayout(bool perform) {
331      if (GetMdiClientController().MdiClient != null)
332        GetMdiClientController().MdiClient.ResumeLayout(perform);
333    }
334
335    private void PerformMdiClientLayout() {
336      if (GetMdiClientController().MdiClient != null)
337        GetMdiClientController().MdiClient.PerformLayout();
338    }
339
340    // Called when:
341    // 1. DockPanel.DocumentStyle changed
342    // 2. DockPanel.Visible changed
343    // 3. MdiClientController.Handle assigned
344    private void SetMdiClient() {
345      MdiClientController controller = GetMdiClientController();
346
347      if (this.DocumentStyle == DocumentStyle.DockingMdi) {
348        controller.AutoScroll = false;
349        controller.BorderStyle = BorderStyle.None;
350        if (MdiClientExists)
351          controller.MdiClient.Dock = DockStyle.Fill;
352      } else if (DocumentStyle == DocumentStyle.DockingSdi || DocumentStyle == DocumentStyle.DockingWindow) {
353        controller.AutoScroll = true;
354        controller.BorderStyle = BorderStyle.Fixed3D;
355        if (MdiClientExists)
356          controller.MdiClient.Dock = DockStyle.Fill;
357      } else if (this.DocumentStyle == DocumentStyle.SystemMdi) {
358        controller.AutoScroll = true;
359        controller.BorderStyle = BorderStyle.Fixed3D;
360        if (controller.MdiClient != null) {
361          controller.MdiClient.Dock = DockStyle.None;
362          controller.MdiClient.Bounds = SystemMdiClientBounds;
363        }
364      }
365    }
366
367    internal Rectangle RectangleToMdiClient(Rectangle rect) {
368      if (MdiClientExists)
369        return GetMdiClientController().MdiClient.RectangleToClient(rect);
370      else
371        return Rectangle.Empty;
372    }
373  }
374}
Note: See TracBrowser for help on using the repository browser.