| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- /*******************************************************************************
- * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
- * 类的信息:
- * 1.程序名称:DockPanel.cs
- * 2.功能描述:类文件
- * 编辑履历:
- * 作者 日期 版本 修改内容
- * 陈晓野 2014/09/01 1.00 新建
- *******************************************************************************/
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- namespace Dongke.IBOSS.PRD.Basics.DockPanel
- {
- /// <summary>
- /// 类文件
- /// </summary>
- internal interface IContentFocusManager
- {
- void Activate(IDockContent content);
- void GiveUpFocus(IDockContent content);
- void AddToList(IDockContent content);
- void RemoveFromList(IDockContent content);
- }
- partial class DockPanel
- {
- private interface IFocusManager
- {
- void SuspendFocusTracking();
- void ResumeFocusTracking();
- bool IsFocusTrackingSuspended
- {
- get;
- }
- IDockContent ActiveContent
- {
- get;
- }
- DockPane ActivePane
- {
- get;
- }
- IDockContent ActiveDocument
- {
- get;
- }
- DockPane ActiveDocumentPane
- {
- get;
- }
- }
- private class FocusManagerImpl : Component, IContentFocusManager, IFocusManager
- {
- private class HookEventArgs : EventArgs
- {
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public int HookCode;
- [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
- public IntPtr wParam;
- public IntPtr lParam;
- }
- private class LocalWindowsHook : IDisposable
- {
- // Internal properties
- private IntPtr m_hHook = IntPtr.Zero;
- private NativeMethods.HookProc m_filterFunc = null;
- private Win32.HookType m_hookType;
- // Event delegate
- public delegate void HookEventHandler(object sender, HookEventArgs e);
- // Event: HookInvoked
- public event HookEventHandler HookInvoked;
- protected void OnHookInvoked(HookEventArgs e)
- {
- if (HookInvoked != null)
- HookInvoked(this, e);
- }
- public LocalWindowsHook(Win32.HookType hook)
- {
- m_hookType = hook;
- m_filterFunc = new NativeMethods.HookProc(this.CoreHookProc);
- }
- // Default filter function
- public IntPtr CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
- {
- if (code < 0)
- return NativeMethods.CallNextHookEx(m_hHook, code, wParam, lParam);
- // Let clients determine what to do
- HookEventArgs e = new HookEventArgs();
- e.HookCode = code;
- e.wParam = wParam;
- e.lParam = lParam;
- OnHookInvoked(e);
- // Yield to the next hook in the chain
- return NativeMethods.CallNextHookEx(m_hHook, code, wParam, lParam);
- }
- // Install the hook
- public void Install()
- {
- if (m_hHook != IntPtr.Zero)
- Uninstall();
- int threadId = NativeMethods.GetCurrentThreadId();
- m_hHook = NativeMethods.SetWindowsHookEx(m_hookType, m_filterFunc, IntPtr.Zero, threadId);
- }
- // Uninstall the hook
- public void Uninstall()
- {
- if (m_hHook != IntPtr.Zero)
- {
- NativeMethods.UnhookWindowsHookEx(m_hHook);
- m_hHook = IntPtr.Zero;
- }
- }
- ~LocalWindowsHook()
- {
- Dispose(false);
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- Uninstall();
- }
- }
- private static LocalWindowsHook sm_localWindowsHook;
- private LocalWindowsHook.HookEventHandler m_hookEventHandler;
- // Use a static instance of the windows hook to prevent stack overflows in the windows kernel.
- static FocusManagerImpl()
- {
- if (Win32Helper.IsRunningOnMono)
- return;
- sm_localWindowsHook = new LocalWindowsHook(Win32.HookType.WH_CALLWNDPROCRET);
- sm_localWindowsHook.Install();
- }
- public FocusManagerImpl(DockPanel dockPanel)
- {
- m_dockPanel = dockPanel;
- if (Win32Helper.IsRunningOnMono)
- return;
- m_hookEventHandler = new LocalWindowsHook.HookEventHandler(HookEventHandler);
- sm_localWindowsHook.HookInvoked += m_hookEventHandler;
- }
- private DockPanel m_dockPanel;
- public DockPanel DockPanel
- {
- get
- {
- return m_dockPanel;
- }
- }
- private bool m_disposed = false;
- protected override void Dispose(bool disposing)
- {
- lock (this)
- {
- if (!m_disposed && disposing)
- {
- if (!Win32Helper.IsRunningOnMono)
- sm_localWindowsHook.HookInvoked -= m_hookEventHandler;
- m_disposed = true;
- }
- base.Dispose(disposing);
- }
- }
- private IDockContent m_contentActivating = null;
- private IDockContent ContentActivating
- {
- get
- {
- return m_contentActivating;
- }
- set
- {
- m_contentActivating = value;
- }
- }
- public void Activate(IDockContent content)
- {
- if (IsFocusTrackingSuspended)
- {
- ContentActivating = content;
- return;
- }
- if (content == null)
- return;
- DockContentHandler handler = content.DockHandler;
- if (handler.Form.IsDisposed)
- return; // Should not reach here, but better than throwing an exception
- if (ContentContains(content, handler.ActiveWindowHandle))
- if (!Win32Helper.IsRunningOnMono)
- NativeMethods.SetFocus(handler.ActiveWindowHandle);
- if (!handler.Form.ContainsFocus)
- {
- if (!handler.Form.SelectNextControl(handler.Form.ActiveControl, true, true, true, true))
- // Since DockContent Form is not selectalbe, use Win32 SetFocus instead
- if (!Win32Helper.IsRunningOnMono)
- NativeMethods.SetFocus(handler.Form.Handle);
- }
- }
- private List<IDockContent> m_listContent = new List<IDockContent>();
- private List<IDockContent> ListContent
- {
- get
- {
- return m_listContent;
- }
- }
- public void AddToList(IDockContent content)
- {
- if (ListContent.Contains(content) || IsInActiveList(content))
- return;
- ListContent.Add(content);
- }
- public void RemoveFromList(IDockContent content)
- {
- if (IsInActiveList(content))
- RemoveFromActiveList(content);
- if (ListContent.Contains(content))
- ListContent.Remove(content);
- }
- private IDockContent m_lastActiveContent = null;
- private IDockContent LastActiveContent
- {
- get
- {
- return m_lastActiveContent;
- }
- set
- {
- m_lastActiveContent = value;
- }
- }
- private bool IsInActiveList(IDockContent content)
- {
- return !(content.DockHandler.NextActive == null && LastActiveContent != content);
- }
- private void AddLastToActiveList(IDockContent content)
- {
- IDockContent last = LastActiveContent;
- if (last == content)
- return;
- DockContentHandler handler = content.DockHandler;
- if (IsInActiveList(content))
- RemoveFromActiveList(content);
- handler.PreviousActive = last;
- handler.NextActive = null;
- LastActiveContent = content;
- if (last != null)
- last.DockHandler.NextActive = LastActiveContent;
- }
- private void RemoveFromActiveList(IDockContent content)
- {
- if (LastActiveContent == content)
- LastActiveContent = content.DockHandler.PreviousActive;
- IDockContent prev = content.DockHandler.PreviousActive;
- IDockContent next = content.DockHandler.NextActive;
- if (prev != null)
- prev.DockHandler.NextActive = next;
- if (next != null)
- next.DockHandler.PreviousActive = prev;
- content.DockHandler.PreviousActive = null;
- content.DockHandler.NextActive = null;
- }
- public void GiveUpFocus(IDockContent content)
- {
- DockContentHandler handler = content.DockHandler;
- if (!handler.Form.ContainsFocus)
- return;
- if (IsFocusTrackingSuspended)
- DockPanel.DummyControl.Focus();
- if (LastActiveContent == content)
- {
- IDockContent prev = handler.PreviousActive;
- if (prev != null)
- Activate(prev);
- else if (ListContent.Count > 0)
- Activate(ListContent[ListContent.Count - 1]);
- }
- else if (LastActiveContent != null)
- Activate(LastActiveContent);
- else if (ListContent.Count > 0)
- Activate(ListContent[ListContent.Count - 1]);
- }
- private static bool ContentContains(IDockContent content, IntPtr hWnd)
- {
- Control control = Control.FromChildHandle(hWnd);
- for (Control parent = control; parent != null; parent = parent.Parent)
- if (parent == content.DockHandler.Form)
- return true;
- return false;
- }
- private int m_countSuspendFocusTracking = 0;
- public void SuspendFocusTracking()
- {
- m_countSuspendFocusTracking++;
- if (!Win32Helper.IsRunningOnMono)
- sm_localWindowsHook.HookInvoked -= m_hookEventHandler;
- }
- public void ResumeFocusTracking()
- {
- if (m_countSuspendFocusTracking > 0)
- m_countSuspendFocusTracking--;
- if (m_countSuspendFocusTracking == 0)
- {
- if (ContentActivating != null)
- {
- Activate(ContentActivating);
- ContentActivating = null;
- }
- if (!Win32Helper.IsRunningOnMono)
- sm_localWindowsHook.HookInvoked += m_hookEventHandler;
- if (!InRefreshActiveWindow)
- RefreshActiveWindow();
- }
- }
- public bool IsFocusTrackingSuspended
- {
- get
- {
- return m_countSuspendFocusTracking != 0;
- }
- }
- // Windows hook event handler
- private void HookEventHandler(object sender, HookEventArgs e)
- {
- Win32.Msgs msg = (Win32.Msgs)Marshal.ReadInt32(e.lParam, IntPtr.Size * 3);
- if (msg == Win32.Msgs.WM_KILLFOCUS)
- {
- IntPtr wParam = Marshal.ReadIntPtr(e.lParam, IntPtr.Size * 2);
- DockPane pane = GetPaneFromHandle(wParam);
- if (pane == null)
- RefreshActiveWindow();
- }
- else if (msg == Win32.Msgs.WM_SETFOCUS)
- RefreshActiveWindow();
- }
- private DockPane GetPaneFromHandle(IntPtr hWnd)
- {
- Control control = Control.FromChildHandle(hWnd);
- IDockContent content = null;
- DockPane pane = null;
- for (; control != null; control = control.Parent)
- {
- content = control as IDockContent;
- if (content != null)
- content.DockHandler.ActiveWindowHandle = hWnd;
- if (content != null && content.DockHandler.DockPanel == DockPanel)
- return content.DockHandler.Pane;
- pane = control as DockPane;
- if (pane != null && pane.DockPanel == DockPanel)
- break;
- }
- return pane;
- }
- private bool m_inRefreshActiveWindow = false;
- private bool InRefreshActiveWindow
- {
- get
- {
- return m_inRefreshActiveWindow;
- }
- }
- private void RefreshActiveWindow()
- {
- SuspendFocusTracking();
- m_inRefreshActiveWindow = true;
- DockPane oldActivePane = ActivePane;
- IDockContent oldActiveContent = ActiveContent;
- IDockContent oldActiveDocument = ActiveDocument;
- SetActivePane();
- SetActiveContent();
- SetActiveDocumentPane();
- SetActiveDocument();
- DockPanel.AutoHideWindow.RefreshActivePane();
- ResumeFocusTracking();
- m_inRefreshActiveWindow = false;
- if (oldActiveContent != ActiveContent)
- DockPanel.OnActiveContentChanged(EventArgs.Empty);
- if (oldActiveDocument != ActiveDocument)
- DockPanel.OnActiveDocumentChanged(EventArgs.Empty);
- if (oldActivePane != ActivePane)
- DockPanel.OnActivePaneChanged(EventArgs.Empty);
- }
- private DockPane m_activePane = null;
- public DockPane ActivePane
- {
- get
- {
- return m_activePane;
- }
- }
- private void SetActivePane()
- {
- DockPane value = Win32Helper.IsRunningOnMono ? null : GetPaneFromHandle(NativeMethods.GetFocus());
- if (m_activePane == value)
- return;
- if (m_activePane != null)
- m_activePane.SetIsActivated(false);
- m_activePane = value;
- if (m_activePane != null)
- m_activePane.SetIsActivated(true);
- }
- private IDockContent m_activeContent = null;
- public IDockContent ActiveContent
- {
- get
- {
- return m_activeContent;
- }
- }
- internal void SetActiveContent()
- {
- IDockContent value = ActivePane == null ? null : ActivePane.ActiveContent;
- if (m_activeContent == value)
- return;
- if (m_activeContent != null)
- m_activeContent.DockHandler.IsActivated = false;
- m_activeContent = value;
- if (m_activeContent != null)
- {
- m_activeContent.DockHandler.IsActivated = true;
- if (!DockHelper.IsDockStateAutoHide((m_activeContent.DockHandler.DockState)))
- AddLastToActiveList(m_activeContent);
- }
- }
- private DockPane m_activeDocumentPane = null;
- public DockPane ActiveDocumentPane
- {
- get
- {
- return m_activeDocumentPane;
- }
- }
- private void SetActiveDocumentPane()
- {
- DockPane value = null;
- if (ActivePane != null && ActivePane.DockState == DockState.Document)
- value = ActivePane;
- if (value == null && DockPanel.DockWindows != null)
- {
- if (ActiveDocumentPane == null)
- value = DockPanel.DockWindows[DockState.Document].DefaultPane;
- else if (ActiveDocumentPane.DockPanel != DockPanel || ActiveDocumentPane.DockState != DockState.Document)
- value = DockPanel.DockWindows[DockState.Document].DefaultPane;
- else
- value = ActiveDocumentPane;
- }
- if (m_activeDocumentPane == value)
- return;
- if (m_activeDocumentPane != null)
- m_activeDocumentPane.SetIsActiveDocumentPane(false);
- m_activeDocumentPane = value;
- if (m_activeDocumentPane != null)
- m_activeDocumentPane.SetIsActiveDocumentPane(true);
- }
- private IDockContent m_activeDocument = null;
- public IDockContent ActiveDocument
- {
- get
- {
- return m_activeDocument;
- }
- }
- private void SetActiveDocument()
- {
- IDockContent value = ActiveDocumentPane == null ? null : ActiveDocumentPane.ActiveContent;
- if (m_activeDocument == value)
- return;
- m_activeDocument = value;
- }
- }
- private IFocusManager FocusManager
- {
- get
- {
- return m_focusManager;
- }
- }
- internal IContentFocusManager ContentFocusManager
- {
- get
- {
- return m_focusManager;
- }
- }
- internal void SaveFocus()
- {
- DummyControl.Focus();
- }
- [Browsable(false)]
- public IDockContent ActiveContent
- {
- get
- {
- return FocusManager.ActiveContent;
- }
- }
- [Browsable(false)]
- public DockPane ActivePane
- {
- get
- {
- return FocusManager.ActivePane;
- }
- }
- [Browsable(false)]
- public IDockContent ActiveDocument
- {
- get
- {
- return FocusManager.ActiveDocument;
- }
- }
- [Browsable(false)]
- public DockPane ActiveDocumentPane
- {
- get
- {
- return FocusManager.ActiveDocumentPane;
- }
- }
- private static readonly object ActiveDocumentChangedEvent = new object();
- [LocalizedCategory("Category_PropertyChanged")]
- [LocalizedDescription("DockPanel_ActiveDocumentChanged_Description")]
- public event EventHandler ActiveDocumentChanged
- {
- add
- {
- Events.AddHandler(ActiveDocumentChangedEvent, value);
- }
- remove
- {
- Events.RemoveHandler(ActiveDocumentChangedEvent, value);
- }
- }
- protected virtual void OnActiveDocumentChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[ActiveDocumentChangedEvent];
- if (handler != null)
- handler(this, e);
- }
- private static readonly object ActiveContentChangedEvent = new object();
- [LocalizedCategory("Category_PropertyChanged")]
- [LocalizedDescription("DockPanel_ActiveContentChanged_Description")]
- public event EventHandler ActiveContentChanged
- {
- add
- {
- Events.AddHandler(ActiveContentChangedEvent, value);
- }
- remove
- {
- Events.RemoveHandler(ActiveContentChangedEvent, value);
- }
- }
- protected void OnActiveContentChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[ActiveContentChangedEvent];
- if (handler != null)
- handler(this, e);
- }
- private static readonly object ActivePaneChangedEvent = new object();
- [LocalizedCategory("Category_PropertyChanged")]
- [LocalizedDescription("DockPanel_ActivePaneChanged_Description")]
- public event EventHandler ActivePaneChanged
- {
- add
- {
- Events.AddHandler(ActivePaneChangedEvent, value);
- }
- remove
- {
- Events.RemoveHandler(ActivePaneChangedEvent, value);
- }
- }
- protected virtual void OnActivePaneChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[ActivePaneChangedEvent];
- if (handler != null)
- handler(this, e);
- }
- }
- }
|