Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.7.0/WinFormsUI-2.7.0/Docking/DockPanel.MdiClientController.cs @ 16749

Last change on this file since 16749 was 8616, checked in by mkommend, 12 years ago

#1939: Added DockPanelSuite 2.7.0 to ExtLibs.

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