mmclibrary-svn Mailing List for MMC .NET Library
Brought to you by:
imjimmurphy,
kachalkov
You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(5) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
|
From: <tig...@us...> - 2009-10-08 09:03:53
|
Revision: 13 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=13&view=rev Author: tigerharry Date: 2009-10-08 09:03:34 +0000 (Thu, 08 Oct 2009) Log Message: ----------- little improvement of marshall size Modified Paths: -------------- MMCLib2/Core/SnapinData.cs Modified: MMCLib2/Core/SnapinData.cs =================================================================== --- MMCLib2/Core/SnapinData.cs 2009-10-08 09:01:59 UTC (rev 12) +++ MMCLib2/Core/SnapinData.cs 2009-10-08 09:03:34 UTC (rev 13) @@ -164,7 +164,7 @@ writer.Flush(); - IntPtr dataSentPtr = Marshal.AllocCoTaskMem(4); + IntPtr dataSentPtr = Marshal.AllocCoTaskMem(IntPtr.Size); pStream.Write(stream.GetBuffer(), (int)stream.Length, dataSentPtr); int dataSent = Marshal.ReadInt32(dataSentPtr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2009-10-08 09:02:20
|
Revision: 12 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=12&view=rev Author: tigerharry Date: 2009-10-08 09:01:59 +0000 (Thu, 08 Oct 2009) Log Message: ----------- fixed wrong comparison of MMC_VIEW_OPTIONS.NOLISTVIEWS leading to an access violation when refresh is triggered on a non ReportNode Modified Paths: -------------- MMCLib2/Core/Component.cs Modified: MMCLib2/Core/Component.cs =================================================================== --- MMCLib2/Core/Component.cs 2009-07-15 08:44:24 UTC (rev 11) +++ MMCLib2/Core/Component.cs 2009-10-08 09:01:59 UTC (rev 12) @@ -750,7 +750,7 @@ //This allow not to clear items while OnShow event int pvo = 0; node.GetResultViewType(ref pvo); - if ((pvo & (int)MMC_VIEW_OPTIONS.NOLISTVIEWS) != 0) + if ((pvo & (int)MMC_VIEW_OPTIONS.NOLISTVIEWS) == 0) ((IResultData)_console).DeleteAllRsltItems(); node.OnRefresh(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2009-07-15 08:44:45
|
Revision: 11 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=11&view=rev Author: tigerharry Date: 2009-07-15 08:44:24 +0000 (Wed, 15 Jul 2009) Log Message: ----------- added event BeforeSnapinSaved Modified Paths: -------------- MMCLib2/Core/SnapinBase.cs Modified: MMCLib2/Core/SnapinBase.cs =================================================================== --- MMCLib2/Core/SnapinBase.cs 2008-06-09 09:53:49 UTC (rev 10) +++ MMCLib2/Core/SnapinBase.cs 2009-07-15 08:44:24 UTC (rev 11) @@ -236,7 +236,15 @@ #endregion + #region Events /// <summary> + /// Event triggered before snapin is saved by MMC. + /// With this event there is no need to override SnapinState class. + /// </summary> + public event EventHandler BeforeSnapinSaved; + #endregion Events + + /// <summary> /// Add the node to the currently active nodes in the snapin. /// </summary> /// <param name="bn">The node to add</param> @@ -1053,7 +1061,19 @@ } } + /// <summary> + /// Invoke method for BeforeSnapinSaved event. + /// <see cref="this.BeforeSnapinSaved"/> + /// </summary> + /// <param name="e"></param> + protected virtual void OnBeforeSnapinSaved(EventArgs e) + { + if (BeforeSnapinSaved != null) + BeforeSnapinSaved(this, e); + } + + /// <summary> /// Delegate back to the snapin-state for serialization. /// </summary> /// <param name="pStm"></param> @@ -1062,6 +1082,7 @@ { try { + OnBeforeSnapinSaved(new EventArgs()); System.Diagnostics.Debug.WriteLine("Save"); ComStream cs = new ComStream(pStm); this.SnapinState.WriteState(cs); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2008-06-09 09:53:52
|
Revision: 10 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=10&view=rev Author: tigerharry Date: 2008-06-09 02:53:49 -0700 (Mon, 09 Jun 2008) Log Message: ----------- - add MMC_BUTTON_STATE_B to be used with SetButtonState for the third param Modified Paths: -------------- MMCLib2/Common.cs MMCLib2/Interfaces.cs Modified: MMCLib2/Common.cs =================================================================== --- MMCLib2/Common.cs 2008-06-09 09:06:56 UTC (rev 9) +++ MMCLib2/Common.cs 2008-06-09 09:53:49 UTC (rev 10) @@ -195,6 +195,12 @@ BUTTONPRESSED = 0x10 } + public enum MMC_BUTTON_STATE_B + { + CLEAR = 0, + SET = 1 + } + public enum MMC_CONSOLE_VERB { NONE = 0x0000, Modified: MMCLib2/Interfaces.cs =================================================================== --- MMCLib2/Interfaces.cs 2008-06-09 09:06:56 UTC (rev 9) +++ MMCLib2/Interfaces.cs 2008-06-09 09:53:49 UTC (rev 10) @@ -470,7 +470,7 @@ void InsertButton(int nIndex, ref MMCBUTTON lpButton); void DeleteButton(int nIndex); void GetButtonState(int idCommand, MMC_BUTTON_STATE nState, out int pState); - void SetButtonState(int idCommand, MMC_BUTTON_STATE nState, int bState); + void SetButtonState(int idCommand, MMC_BUTTON_STATE nState, MMC_BUTTON_STATE_B bState); } [ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2008-06-09 09:07:17
|
Revision: 9 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=9&view=rev Author: tigerharry Date: 2008-06-09 02:06:56 -0700 (Mon, 09 Jun 2008) Log Message: ----------- - creating _component in constructor - added property ToolBar - added property ToolbarImageIndex - added property ToolbarButtons ==> now it's easy to add a toolBar Modified Paths: -------------- MMCLib2/Core/SnapinBase.cs Modified: MMCLib2/Core/SnapinBase.cs =================================================================== --- MMCLib2/Core/SnapinBase.cs 2008-06-06 14:22:50 UTC (rev 8) +++ MMCLib2/Core/SnapinBase.cs 2008-06-09 09:06:56 UTC (rev 9) @@ -18,1070 +18,1122 @@ namespace Ironring.MMC.Core { - /// <summary> - /// The Base class for the snapin object implements the IComponentData interface that is the primary - /// communication conduit to MMC. Contains our IComponent implementation as well to handle the other - /// part of the MMC dialog. This class also contains the master collection of Nodes and will dispatch - /// to the appropriate Node when notifications arrive. All nodes must register back to this class on - /// creation for registration in the master collection. This happen automatically in the BaseNode - /// contructor. - /// </summary> - public class SnapinBase : - //Added by Alexander Kachalkov - //Allow marshaling from the Property Sheet thread - //using Invoke method - System.Windows.Forms.Control - ,IComponentData - ,IExtendPropertySheet - ,IExtendContextMenu - ,IPersistStream - { - /// <summary> - /// Master list of all Nodes displayed in the snapin - /// this collection "owns" them and assignes cookie values - /// </summary> - protected HybridDictionary _nodes = new HybridDictionary(8); + /// <summary> + /// The Base class for the snapin object implements the IComponentData interface that is the primary + /// communication conduit to MMC. Contains our IComponent implementation as well to handle the other + /// part of the MMC dialog. This class also contains the master collection of Nodes and will dispatch + /// to the appropriate Node when notifications arrive. All nodes must register back to this class on + /// creation for registration in the master collection. This happen automatically in the BaseNode + /// contructor. + /// </summary> + public class SnapinBase : + //Added by Alexander Kachalkov + //Allow marshaling from the Property Sheet thread + //using Invoke method + System.Windows.Forms.Control + , IComponentData + , IExtendPropertySheet + , IExtendContextMenu + , IPersistStream + { + /// <summary> + /// Master list of all Nodes displayed in the snapin + /// this collection "owns" them and assignes cookie values + /// </summary> + protected HybridDictionary _nodes = new HybridDictionary(8); - /////////////////////////////////////////////////////////////////////// - // - // Private vars - // - #region + /////////////////////////////////////////////////////////////////////// + // + // Private vars + // + #region - /// <summary> - /// We only want to see one Manager per Snapin - /// </summary> - private bool _showSnapinManager = true; + /// <summary> + /// We only want to see one Manager per Snapin + /// </summary> + private bool _showSnapinManager = true; - /// <summary> - /// Contained object that implements IComponent on our behalf - /// </summary> - private Component _component = null; + /// <summary> + /// Contained object that implements IComponent on our behalf + /// </summary> + private Component _component = null; - private IConsole2 _console = null; - private IConsoleNameSpace2 _consoleNameSpace = null; - private int _nodeId = 0; - private BaseNode _currentScopeNode; - private ImageList _images = new ImageList(); - private BaseNode _selectedNodes = null; - private IntPtr _handle; - private System.Windows.Forms.ContextMenu _filterMenu; - private static ResourceManager _translator; - private MMC_VERSION _mmcVersion; - #endregion + private IConsole2 _console = null; + private IConsoleNameSpace2 _consoleNameSpace = null; + private int _nodeId = 0; + private BaseNode _currentScopeNode; + private ImageList _images = new ImageList(); + private BaseNode _selectedNodes = null; + private IntPtr _handle; + private System.Windows.Forms.ContextMenu _filterMenu; + private static ResourceManager _translator; + private MMC_VERSION _mmcVersion; + #endregion - /////////////////////////////////////////////////////////////////////// - // - // Properties - // - #region - // Added by MAM - /// <summary> - /// Get or set the scope node that is currently selected for this snapin. This is needed - /// for component.cs which goes through hoops to get the currently selected - /// ScopeNode. - /// </summary> - public BaseNode CurrentScopeNode - { - get { return _currentScopeNode; } - set { _currentScopeNode = value; } - } + /////////////////////////////////////////////////////////////////////// + // + // Properties + // + #region + // Added by MAM + /// <summary> + /// Get or set the scope node that is currently selected for this snapin. This is needed + /// for component.cs which goes through hoops to get the currently selected + /// ScopeNode. + /// </summary> + public BaseNode CurrentScopeNode + { + get { return _currentScopeNode; } + set { _currentScopeNode = value; } + } - //Added by Alexander Kachalkov - /// <summary> - /// returns global images collection - /// Using it from Component class while creating Toolbar. - /// </summary> - public ImageList Images - { - get { return _images; } - } + //added by Harald Binkle [tigerharry] + //give access to component to be able to add toolbars + public Component Component + { + get + { + return _component; + } + } - /// <summary> - /// Returns if there is a scope node selected - /// </summary> - public virtual bool ScopeNodeSelected - { - get { return _selectedNodes != null; } - } - /// <summary> - /// Get the set of selected scope nodes. In MMC this always returns 0 or 1 nodes. - /// </summary> - public virtual BaseNode SelectedScopeNodes - { - get { return _selectedNodes; } - } + //added by Harald Binkle [tigerharry] + public MMCBUTTON[] ToolbarButtons + { + get + { + return _component.ToolbarButtons; + } + set + { + _component.ToolbarButtons = value; + } + } - /// <summary> - /// returns if there is a view-item selected - /// </summary> - public virtual bool ViewItemSelected - { - get - { - ReportNode rne = _currentScopeNode as ReportNode; - if(rne != null) - { - return rne.GetCurrentSelected().Length != 0; - } - else - { - return false; - } - } - } + //added by Harald Binkle [tigerharry] + public int ToolbarImageIndex + { + get + { + return _component.ToolbarImageIndex; + } + set + { + _component.ToolbarImageIndex = value; + } + } - /// <summary> - /// Get the last selected scope node. This is the node that is currently active, - /// or the last node that was clicked before focus was transfered to the result-pane. - /// </summary> - public virtual BaseNode LastSelectedScopeNode - { - get { return _currentScopeNode; } - } + //added by Harald Binkle [tigerharry] + public IToolbar ToolBar + { + get + { + return _component.ToolBar; + } + } - /// <summary> - /// Get all selected items in the result-pane. - /// </summary> - /// <remarks>In the current incarnation of MMCLib/MMCLib2 - /// there is no multiselection possible. This is not a guarantee - /// that it won't be possible to do it in the future though! - /// </remarks> - public ResultViewItem[] SelectedViewItems - { - get - { - ArrayList retval = new ArrayList(); - ReportNode rne = _currentScopeNode as ReportNode; - if(rne != null) - return rne.GetCurrentSelected(); - else - return new ResultViewItem[0]; - } - } - - /// <summary> - /// returns the window handle that the control is bound to. - /// </summary> - public IntPtr SnapinHandle - { - get {return _handle;} - } - /// <summary> - /// - /// </summary> - public System.Windows.Forms.ContextMenu FilterMenu - { - get { return _filterMenu; } - set { _filterMenu = value; } - } + //Added by Alexander Kachalkov + /// <summary> + /// returns global images collection + /// Using it from Component class while creating Toolbar. + /// </summary> + public ImageList Images + { + get { return _images; } + } - /// <summary> - /// Cached MMCVersion - /// </summary> - public MMC_VERSION MMCVersion - { - get{ return _mmcVersion;} - set{ _mmcVersion = value; } - } + /// <summary> + /// Returns if there is a scope node selected + /// </summary> + public virtual bool ScopeNodeSelected + { + get { return _selectedNodes != null; } + } - #endregion + /// <summary> + /// Get the set of selected scope nodes. In MMC this always returns 0 or 1 nodes. + /// </summary> + public virtual BaseNode SelectedScopeNodes + { + get { return _selectedNodes; } + } - /// <summary> - /// Add the node to the currently active nodes in the snapin. - /// </summary> - /// <param name="bn">The node to add</param> - internal void AddSelectedNode(BaseNode bn) - { - _currentScopeNode = bn; + /// <summary> + /// returns if there is a view-item selected + /// </summary> + public virtual bool ViewItemSelected + { + get + { + ReportNode rne = _currentScopeNode as ReportNode; + if (rne != null) + { + return rne.GetCurrentSelected().Length != 0; + } + else + { + return false; + } + } + } - _selectedNodes = bn; - } + /// <summary> + /// Get the last selected scope node. This is the node that is currently active, + /// or the last node that was clicked before focus was transfered to the result-pane. + /// </summary> + public virtual BaseNode LastSelectedScopeNode + { + get { return _currentScopeNode; } + } - /// <summary> - /// Remove the given node as active from the snapin. - /// </summary> - /// <param name="bn">The node to remove. (not used, preparing for multiselect)</param> - internal void RemoveSelectedNode(BaseNode bn) - { - _selectedNodes = null; - } + /// <summary> + /// Get all selected items in the result-pane. + /// </summary> + /// <remarks>In the current incarnation of MMCLib/MMCLib2 + /// there is no multiselection possible. This is not a guarantee + /// that it won't be possible to do it in the future though! + /// </remarks> + public ResultViewItem[] SelectedViewItems + { + get + { + ArrayList retval = new ArrayList(); + ReportNode rne = _currentScopeNode as ReportNode; + if (rne != null) + return rne.GetCurrentSelected(); + else + return new ResultViewItem[0]; + } + } - /// <summary> - /// Static function to help with internationalisation - /// </summary> - internal static string Translate(string key) - { - if(_translator == null) - _translator = new ResourceManager("Ironring.MMC.Resources.i18n", - System.Reflection.Assembly.GetExecutingAssembly()); - return _translator.GetString(key); - } + /// <summary> + /// returns the window handle that the control is bound to. + /// </summary> + public IntPtr SnapinHandle + { + get { return _handle; } + } - ////////////////////////////////////////////////////////////////////////// - // - // SnapinBase Implementation - // - #region - /// <summary> - /// Default Constructor - /// </summary> - public SnapinBase() - { - InitializeComponent(); - // Get the window handle and keep it alive, as long as the MMC is. - _handle = Handle; - this.SnapinState = CreateSnapinState(); - System.Diagnostics.Debug.WriteLine("Snapin<init>"); - } + /// <summary> + /// + /// </summary> + public System.Windows.Forms.ContextMenu FilterMenu + { + get { return _filterMenu; } + set { _filterMenu = value; } + } - /// <summary> - /// return the guid for the snapin - dig it out of the Guid attribute in the base class! - /// Gotta love reflection. - /// </summary> - public Guid Guid - { - get - { - object[] attrs = GetType().GetCustomAttributes(typeof(GuidAttribute), true); - if (attrs.Length == 0) - throw new SnapinException("Failed ot find GuidAttribute on SnapinBase class"); + /// <summary> + /// Cached MMCVersion + /// </summary> + public MMC_VERSION MMCVersion + { + get { return _mmcVersion; } + set { _mmcVersion = value; } + } - return new Guid(((GuidAttribute)attrs[0]).Value); - } - } + #endregion - /// <summary> - /// get/set the root node - this starts off the population of the entire - /// namespace. The RootNode is also known as the static node in MMC. It - /// will be queried for its children. - /// </summary> - public BaseNode RootNode - { - get { return (BaseNode)_nodes[0]; } - set { _nodes[0] = value; } - } + /// <summary> + /// Add the node to the currently active nodes in the snapin. + /// </summary> + /// <param name="bn">The node to add</param> + internal void AddSelectedNode(BaseNode bn) + { + _currentScopeNode = bn; - /// <summary> - /// Return the Componenet's console - /// </summary> - public IConsole2 ResultViewConsole - { - get { return _component.Console; } - } + _selectedNodes = bn; + } - /// <summary> - /// Return the cached member variable to get at MMC - /// </summary> - public IConsole2 Console - { - get { return _console; } - } + /// <summary> + /// Remove the given node as active from the snapin. + /// </summary> + /// <param name="bn">The node to remove. (not used, preparing for multiselect)</param> + internal void RemoveSelectedNode(BaseNode bn) + { + _selectedNodes = null; + } - /// <summary> - /// Return the cached member variable to get at MMC - /// </summary> - public IConsoleNameSpace2 ConsoleNameSpace - { - get { return _consoleNameSpace; } - } + /// <summary> + /// Static function to help with internationalisation + /// </summary> + internal static string Translate(string key) + { + if (_translator == null) + _translator = new ResourceManager("Ironring.MMC.Resources.i18n", + System.Reflection.Assembly.GetExecutingAssembly()); + return _translator.GetString(key); + } - /// <summary> - /// Return the cached member variable to get at MMC - /// </summary> - public IHeaderCtrl2 HeaderCtrl - { - get { return (IHeaderCtrl2)_console; } - } + ////////////////////////////////////////////////////////////////////////// + // + // SnapinBase Implementation + // + #region + /// <summary> + /// Default Constructor + /// </summary> + public SnapinBase() + { + InitializeComponent(); + // Get the window handle and keep it alive, as long as the MMC is. + _handle = Handle; + this.SnapinState = CreateSnapinState(); + //added by Harald Binkle [tigerharry] + //create component to be able to add toolbars + IComponent comp; + CreateComponent(out comp); + + System.Diagnostics.Debug.WriteLine("Snapin<init>"); + } - //Added by Alexander Kachalkov - /// <summary> - /// Overridable helper method to GetSelectedItem - /// </summary> - /// <param name="ResultData"></param> - public virtual RESULTDATAITEM GetSelectedItem(IResultData resultData) - { - return GetSelectedItem(resultData, -1); // nIndex == -1 to start at first item - } + /// <summary> + /// return the guid for the snapin - dig it out of the Guid attribute in the base class! + /// Gotta love reflection. + /// </summary> + public Guid Guid + { + get + { + object[] attrs = GetType().GetCustomAttributes(typeof(GuidAttribute), true); + if (attrs.Length == 0) + throw new SnapinException("Failed ot find GuidAttribute on SnapinBase class"); - /// <summary> - /// Overridable helper method to GetSelectedItem - /// </summary> - /// <param name="ResultData"></param> - /// <param name="nIndex"></param> - public virtual RESULTDATAITEM GetSelectedItem(IResultData resultData, int nIndex) - { - RESULTDATAITEM rdi = new RESULTDATAITEM(); + return new Guid(((GuidAttribute)attrs[0]).Value); + } + } - rdi.mask = (uint)RDI.STATE; // nState is valid - rdi.nCol = 0; - rdi.nIndex = nIndex; // nIndex == -1 to start at first item - rdi.nState = (uint)LVIS.SELECTED; // only interested in selected items + /// <summary> + /// get/set the root node - this starts off the population of the entire + /// namespace. The RootNode is also known as the static node in MMC. It + /// will be queried for its children. + /// </summary> + public BaseNode RootNode + { + get { return (BaseNode)_nodes[0]; } + set { _nodes[0] = value; } + } - try - { - resultData.GetNextItem(ref rdi); - } - catch(Exception) - { - // FIXME: (Lesley) - // I get an error while selecting a resultnode - // I think it's because nothing is selected yet - // that's why we catch the exception and won't handle it - // maybe it's better to return null - } - //out - return rdi; - } - /// <summary> - /// find a node with the given cookie in our master index - /// </summary> - /// <param name="cookie"></param> - /// <returns></returns> - public BaseNode FindNode(int cookie) - { - // some nodes use the high order word for item id - // so mask off this word to get the "real" cookie. - int cleanCookie = cookie & 0xffff; - BaseNode node = (BaseNode)_nodes[cleanCookie]; - if (node == null) - throw new SnapinException("Failed to find Node with cookie " + cleanCookie.ToString()); + /// <summary> + /// Return the Componenet's console + /// </summary> + public IConsole2 ResultViewConsole + { + get { return _component.Console; } + } - return node; - } - - /// <summary> - /// find a node by the MMC defined HScopeID - /// </summary> - /// <param name="HScopeID"></param> - /// <returns></returns> - public BaseNode FindNodeByHScope(int hScopeID) - { - foreach(BaseNode node in _nodes.Values) - { - if (node.HScopeItem == hScopeID) - return node; - } - return null; - } + /// <summary> + /// Return the cached member variable to get at MMC + /// </summary> + public IConsole2 Console + { + get { return _console; } + } - /// <summary> - /// called be BaseNode constructor to register itself back here for - /// centralized lookup when MMC want to talk to a Node - /// </summary> - /// <param name="newNode"></param> - /// <returns></returns> - public int Register(BaseNode newNode) - { - // return the index in the array - that is opaque to the node - it shouldn't - // make any assumptions about the value - thats our job in this class. - // We may change the collection strategy in the future if we need to - // support bigger node sets. - int id = _nodeId; - _nodes.Add(id, newNode); - _nodeId++; - return id; - } - - //Added by Alexander Kachalkov - /// <summary> - /// Unregister node - /// </summary> - /// <param name="node"></param> - public void Unregister(BaseNode node) - { - _nodes.Remove(node.Cookie); - //Added by Alexander Ovchinnikov - node.RemovePropertySheet( ); - } + /// <summary> + /// Return the cached member variable to get at MMC + /// </summary> + public IConsoleNameSpace2 ConsoleNameSpace + { + get { return _consoleNameSpace; } + } - /// <summary> - /// Add a string representing the embedded resource name of an icon to - /// the snapin's global image coolection - /// </summary> - /// <param name="iconResourceName"></param> - public int AddImage(string iconResourceName) - { - return _images.Add(iconResourceName); - } - - //Added by Alexander Kachalkov - /// <summary> - /// Add a string representing the embedded resource name of an icon to - /// the snapin's global image coolection - /// </summary> - /// <param name="iconResourceName"></param> - /// <param name="transparentColor">Specifies the TransparentColor of the image to be loaded and appended</param> - /// <returns></returns> - public int AddImage(string iconResourceName, Color transparentColor) - { - return _images.Add(iconResourceName, transparentColor); - } + /// <summary> + /// Return the cached member variable to get at MMC + /// </summary> + public IHeaderCtrl2 HeaderCtrl + { + get { return (IHeaderCtrl2)_console; } + } - /// <summary> - /// Add a loaded and initialized icon to the snapin global image collection - /// </summary> - /// <param name="icon"></param> - public int AddImage(Icon icon) - { - return _images.Add(icon); - } - #endregion - ////////////////////////////////////////////////////////////////////// - // - // IComponentData implementation - // - #region - /// <summary> - /// Called by MMC with the Console interface on startup we do snapin one time init stuff here - /// </summary> - /// <param name="pUnknown">Implements IConsole()2 and IConsoleNameSpace2 interfaces</param> - public void Initialize(Object pUnknown) - { - try - { - // cache references to MMC interfaces - _console = (IConsole2)pUnknown; - _consoleNameSpace = (IConsoleNameSpace2)pUnknown; + //Added by Alexander Kachalkov + /// <summary> + /// Overridable helper method to GetSelectedItem + /// </summary> + /// <param name="ResultData"></param> + public virtual RESULTDATAITEM GetSelectedItem(IResultData resultData) + { + return GetSelectedItem(resultData, -1); // nIndex == -1 to start at first item + } - // alow startup init for each node - foreach(BaseNode node in _nodes.Values) - node.Initialize(); + /// <summary> + /// Overridable helper method to GetSelectedItem + /// </summary> + /// <param name="ResultData"></param> + /// <param name="nIndex"></param> + public virtual RESULTDATAITEM GetSelectedItem(IResultData resultData, int nIndex) + { + RESULTDATAITEM rdi = new RESULTDATAITEM(); - // Now we'll add the images we need for the snapin - IImageList il = null; - _console.QueryScopeImageList(out il); - - // add the snapin - global images to the scope pane - _images.LoadImageList(il); + rdi.mask = (uint)RDI.STATE; // nState is valid + rdi.nCol = 0; + rdi.nIndex = nIndex; // nIndex == -1 to start at first item + rdi.nState = (uint)LVIS.SELECTED; // only interested in selected items - // forward to the root node to see if any nodes care to add their node specific - // icons to the image list - RootNode.OnAddScopePaneImages(il); - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("Initialize failed - " + e.Message); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - throw e; - } - } + try + { + resultData.GetNextItem(ref rdi); + } + catch (Exception) + { + // FIXME: (Lesley) + // I get an error while selecting a resultnode + // I think it's because nothing is selected yet + // that's why we catch the exception and won't handle it + // maybe it's better to return null + } + //out + return rdi; + } + /// <summary> + /// find a node with the given cookie in our master index + /// </summary> + /// <param name="cookie"></param> + /// <returns></returns> + public BaseNode FindNode(int cookie) + { + // some nodes use the high order word for item id + // so mask off this word to get the "real" cookie. + int cleanCookie = cookie & 0xffff; + BaseNode node = (BaseNode)_nodes[cleanCookie]; + if (node == null) + throw new SnapinException("Failed to find Node with cookie " + cleanCookie.ToString()); - // MAM: made virtual. - /// <summary> - /// Give MMC our IComponent implementation when asked - /// </summary> - /// <param name="ppComponent">a pointer to out Component object</param> - public virtual void CreateComponent(out IComponent ppComponent) - { - // Make sure we don't already have a component created - if (_component == null) - _component = new Component(this); + return node; + } - ppComponent = _component; - } + /// <summary> + /// find a node by the MMC defined HScopeID + /// </summary> + /// <param name="HScopeID"></param> + /// <returns></returns> + public BaseNode FindNodeByHScope(int hScopeID) + { + foreach (BaseNode node in _nodes.Values) + { + if (node.HScopeItem == hScopeID) + return node; + } + return null; + } - /// <summary> - /// This notify is primarily responsible for inserting data items into - /// the console namespace. - /// </summary> - /// <param name="lpDataObject">the node to notify</param> - /// <param name="aevent">notification type</param> - /// <param name="arg">optional event context</param> - /// <param name="param">optional event context</param> - /// <returns></returns> - public int Notify(IDataObject lpDataObject, uint aevent, IntPtr arg, IntPtr param) - { - int hr = HRESULT.S_OK; + /// <summary> + /// called be BaseNode constructor to register itself back here for + /// centralized lookup when MMC want to talk to a Node + /// </summary> + /// <param name="newNode"></param> + /// <returns></returns> + public int Register(BaseNode newNode) + { + // return the index in the array - that is opaque to the node - it shouldn't + // make any assumptions about the value - thats our job in this class. + // We may change the collection strategy in the future if we need to + // support bigger node sets. + int id = _nodeId; + _nodes.Add(id, newNode); + _nodeId++; + return id; + } - try - { - DataObject test = (DataObject)lpDataObject; - BaseNode node = (test == null) ? RootNode : test.Node; + //Added by Alexander Kachalkov + /// <summary> + /// Unregister node + /// </summary> + /// <param name="node"></param> + public void Unregister(BaseNode node) + { + _nodes.Remove(node.Cookie); + //Added by Alexander Ovchinnikov + node.RemovePropertySheet(); + } - // TBD: add more events and dispatch to virtual methods instead? or event fire events? + /// <summary> + /// Add a string representing the embedded resource name of an icon to + /// the snapin's global image coolection + /// </summary> + /// <param name="iconResourceName"></param> + public int AddImage(string iconResourceName) + { + return _images.Add(iconResourceName); + } - MMCN_Notify notify = (MMCN_Notify)aevent; + //Added by Alexander Kachalkov + /// <summary> + /// Add a string representing the embedded resource name of an icon to + /// the snapin's global image coolection + /// </summary> + /// <param name="iconResourceName"></param> + /// <param name="transparentColor">Specifies the TransparentColor of the image to be loaded and appended</param> + /// <returns></returns> + public int AddImage(string iconResourceName, Color transparentColor) + { + return _images.Add(iconResourceName, transparentColor); + } - System.Diagnostics.Debug.WriteLine("IComponentData::Notify - " + notify.ToString()); + /// <summary> + /// Add a loaded and initialized icon to the snapin global image collection + /// </summary> + /// <param name="icon"></param> + public int AddImage(Icon icon) + { + return _images.Add(icon); + } + #endregion + ////////////////////////////////////////////////////////////////////// + // + // IComponentData implementation + // + #region + /// <summary> + /// Called by MMC with the Console interface on startup we do snapin one time init stuff here + /// </summary> + /// <param name="pUnknown">Implements IConsole()2 and IConsoleNameSpace2 interfaces</param> + public void Initialize(Object pUnknown) + { + try + { + // cache references to MMC interfaces + _console = (IConsole2)pUnknown; + _consoleNameSpace = (IConsoleNameSpace2)pUnknown; - switch(notify) - { - // If a data item is expanding, we need to tell MMC about it's children. - // Note, this case doesn't necessarily mean the data item is expanding - // visually.... MMC is just requesting information about it. - case MMCN_Notify.EXPAND: - { - if ((int)arg != 0) - { - if (node.HScopeItem == 0) - node.HScopeItem = (int)param; - node.OnExpand(); - } - else - { - node.OnCollapse(); - } - break; - } - //---added by Roman Kiss - case MMCN_Notify.DELETE: - { - node.OnDelete(); - break; - } - //Added by Alexander Kachalkov - case MMCN_Notify.BTN_CLICK: - { - // CmdID of the button equal to a value of the MMC_COMMANDS enum type. - int cmdid = param.ToInt32(); - node.OnBtnClick(cmdid); - break; - } - //Added by Alexander Kachalkov - case MMCN_Notify.RENAME: - { - // can we rename? - if ((int)arg == 0) - { - // can we rename? - if (!node.OnTryRename()) - hr = HRESULT.S_FALSE; - } - // rename editing complete - here is the string - else // arg == 1 - { - // is the renamed value ok? - if (!node.OnRename(Marshal.PtrToStringAuto(param))) - hr = HRESULT.S_FALSE; - } + // alow startup init for each node + foreach (BaseNode node in _nodes.Values) + node.Initialize(); - break; - } - default: - { - // We didn't handle the message - hr = HRESULT.S_FALSE; - break; - } - } - } - - catch(SnapinException) - { - hr = HRESULT.S_FALSE; - } - catch(Exception e) - { - //Added by Lesley van Zijl - //MMC will eat the throw - System.Diagnostics.Debug.WriteLine(e.Message); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - throw e; - - } + // Now we'll add the images we need for the snapin + IImageList il = null; + _console.QueryScopeImageList(out il); - return hr; - } + // add the snapin - global images to the scope pane + _images.LoadImageList(il); - /// <summary> - /// Called by MMC to cleanup - /// TBD: call Dispose - after that pattern is more pervaisivly used - /// </summary> - public virtual void Destroy() - { - } + // forward to the root node to see if any nodes care to add their node specific + // icons to the image list + RootNode.OnAddScopePaneImages(il); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine("Initialize failed - " + e.Message); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + throw e; + } + } - /// <summary> - /// The IComponentData::QueryDataObject method returns a data object that can be used to retrieve - /// the context information for the specified cookie. - /// </summary> - /// <param name="cookie">Specifies the unique identifier for which the data object is required.</param> - /// <param name="type">Specifies the data object as one of the members of the CCT enum</param> - /// <param name="ppDataObject">Pointer to the address of the returned data object</param> - public virtual void QueryDataObject(int cookie, uint type, out IDataObject ppDataObject) - { - if(type == (uint)CCT.SNAPIN_MANAGER && _showSnapinManager) - { - System.Diagnostics.Debug.WriteLine("Asks for Snapin Manager in SnapinBase"); - // false so that it doesn't show up again - _showSnapinManager = false; - this.ShowInitialisationWizard(); - } - ppDataObject = new DataObject(FindNode(cookie)); - } + // MAM: made virtual. + /// <summary> + /// Give MMC our IComponent implementation when asked + /// </summary> + /// <param name="ppComponent">a pointer to out Component object</param> + public virtual void CreateComponent(out IComponent ppComponent) + { + // Make sure we don't already have a component created + if (_component == null) + _component = new Component(this); - #region MMC SNAPIN MANAGER - // This is how it works: - // If you load a snapin in the MMC (so a not saved snapin(.msc)) the mmc sends a msg to the - // Snapin with the question 'do you have a SnapinManager for me?' - // as this happens we set up our wizard, and we make sure that the Wizard is shown once. - // after that we let the base Class handle the QueryDataObject - // - // you could use a SnapinManager for Startup configuration, like the Microsoft Services plugin - // it asks if you want to connect to a remote server or want work on the local machine. - protected virtual void ShowInitialisationWizard() - { - if(this.Managers != null) - { - WizardBase.ShowWizard( this.ManagerTitle, - this.Managers, - new WizardBase.WizardAction(ManagerHandler)); - } - } + ppComponent = _component; + } - public virtual WizardPage[] Managers - { - get{return null;} - } + /// <summary> + /// This notify is primarily responsible for inserting data items into + /// the console namespace. + /// </summary> + /// <param name="lpDataObject">the node to notify</param> + /// <param name="aevent">notification type</param> + /// <param name="arg">optional event context</param> + /// <param name="param">optional event context</param> + /// <returns></returns> + public int Notify(IDataObject lpDataObject, uint aevent, IntPtr arg, IntPtr param) + { + int hr = HRESULT.S_OK; - protected String m_managerTitle; - public virtual String ManagerTitle - { - get{return m_managerTitle;} - set{m_managerTitle = value;} - } + try + { + DataObject test = (DataObject)lpDataObject; + BaseNode node = (test == null) ? RootNode : test.Node; - // This is the method that handles the finish of the Wizard, in this example it does nothing - // but this method could send data to a remote server or could adjust some nodes, be creative :) - protected virtual void ManagerHandler(Ironring.MMC.Wizards.WizardPage[] pages) - { - } - #endregion + // TBD: add more events and dispatch to virtual methods instead? or event fire events? - /// <summary> - /// provides scope pane info to MMC - /// </summary> - /// <param name="sdi"></param> - public virtual void GetDisplayInfo(ref SCOPEDATAITEM sdi) - { - // First let's find this node we want info on.... - BaseNode NodeWeWant = FindNode(sdi.lParam); - NodeWeWant.GetDisplayInfo(ref sdi); - } + MMCN_Notify notify = (MMCN_Notify)aevent; - - /// <summary> - /// This method will compare two data objects based on underlying cookie value - /// that the nodes contain - /// </summary> - /// <param name="lpDataObjectA"></param> - /// <param name="lpDataObjectB"></param> - /// <returns></returns> - public int CompareObjects(IDataObject lpDataObjectA, IDataObject lpDataObjectB) - { - // since this is the only type we hand out it should be the only type - // provided here and the cast should "always" work. + System.Diagnostics.Debug.WriteLine("IComponentData::Notify - " + notify.ToString()); - DataObject doItem1 = (DataObject)lpDataObjectA; - DataObject doItem2 = (DataObject)lpDataObjectB; + switch (notify) + { + // If a data item is expanding, we need to tell MMC about it's children. + // Note, this case doesn't necessarily mean the data item is expanding + // visually.... MMC is just requesting information about it. + case MMCN_Notify.EXPAND: + { + if ((int)arg != 0) + { + if (node.HScopeItem == 0) + node.HScopeItem = (int)param; + node.OnExpand(); + } + else + { + node.OnCollapse(); + } + break; + } + //---added by Roman Kiss + case MMCN_Notify.DELETE: + { + node.OnDelete(); + break; + } + //Added by Alexander Kachalkov + case MMCN_Notify.BTN_CLICK: + { + // CmdID of the button equal to a value of the MMC_COMMANDS enum type. + int cmdid = param.ToInt32(); + node.OnBtnClick(cmdid); + break; + } + //Added by Alexander Kachalkov + case MMCN_Notify.RENAME: + { + // can we rename? + if ((int)arg == 0) + { + // can we rename? + if (!node.OnTryRename()) + hr = HRESULT.S_FALSE; + } + // rename editing complete - here is the string + else // arg == 1 + { + // is the renamed value ok? + if (!node.OnRename(Marshal.PtrToStringAuto(param))) + hr = HRESULT.S_FALSE; + } - // TBD: implement IComparable on Node and compare cookies. + break; + } + default: + { + // We didn't handle the message + hr = HRESULT.S_FALSE; + break; + } + } + } - // These are different objects. We need to return S_FALSE - if (doItem1.Node.Cookie != doItem2.Node.Cookie) - return HRESULT.S_FALSE; + catch (SnapinException) + { + hr = HRESULT.S_FALSE; + } + catch (Exception e) + { + //Added by Lesley van Zijl + //MMC will eat the throw + System.Diagnostics.Debug.WriteLine(e.Message); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + throw e; - return HRESULT.S_OK; - } - #endregion - ////////////////////////////////////////////////////////////////////// - // - // IExtendPropertySheet implementation - // - #region - /// <summary> - /// MMC wants a property sheet created of the given node - /// </summary> - /// <param name="lpProvider"></param> - /// <param name="handle"></param> - /// <param name="lpDataObject"></param> - /// <returns></returns> - public virtual int CreatePropertyPages(IPropertySheetCallback lpProvider, IntPtr handle, IDataObject lpDataObject) - { - DataObject dataObject = (DataObject)lpDataObject; - try - { - if(this.ScopeNodeSelected == false) - { - // Show the property pages for all nodes - ReportNode rpne = (ReportNode)dataObject.Node; - rpne.CreatePropertyPagesForItems(lpProvider, handle); + } - // See comment below! - return HRESULT.S_FALSE; - } - else - { - IMMCSaneNode sane = (IMMCSaneNode)dataObject.Node; - if(sane.PropertyPages.Count == 0) - return HRESULT.S_FALSE; - else - { - // Got pages. - dataObject.Node.PropertyPages.Clear(); - dataObject.Node.CreatePropertyPages(lpProvider, handle); - - // We have created our own property-pages in a separate thread. - // DON'T LET MMC DISPLAY A PROPERTY PAGE TOO! This is needed for - // Winforms to work. - return HRESULT.S_FALSE; - } - } - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("SnapinBaseExt::CreatePropertyPages exception: " + e); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - // don't use the MMC property page facilities - just roll our own. - return HRESULT.S_FALSE; - } + return hr; + } - /// <summary> - /// MMC calls this at initialization time to find out if the node - /// supports property pages - this is the one and only time to respond. - /// This is overriden to get the property-page of the item or node - /// that is currently selected. - /// </summary> - /// <param name="lpDataObject">IdataObject for Node in question</param> - /// <returns></returns> - public virtual int QueryPagesFor(IDataObject lpDataObject) - { - // This snapin does have property pages, so we should return S_OK - // (which will happen automatically). If the snapin didn't have - // any property pages, then we should return S_FALSE + /// <summary> + /// Called by MMC to cleanup + /// TBD: call Dispose - after that pattern is more pervaisivly used + /// </summary> + public virtual void Destroy() + { + } - DataObject dataObject = (DataObject)lpDataObject; - - //---added by Roman Kiss - dataObject.Node.OnQueryProperties(); + /// <summary> + /// The IComponentData::QueryDataObject method returns a data object that can be used to retrieve + /// the context information for the specified cookie. + /// </summary> + /// <param name="cookie">Specifies the unique identifier for which the data object is required.</param> + /// <param name="type">Specifies the data object as one of the members of the CCT enum</param> + /// <param name="ppDataObject">Pointer to the address of the returned data object</param> + public virtual void QueryDataObject(int cookie, uint type, out IDataObject ppDataObject) + { + if (type == (uint)CCT.SNAPIN_MANAGER && _showSnapinManager) + { + System.Diagnostics.Debug.WriteLine("Asks for Snapin Manager in SnapinBase"); + // false so that it doesn't show up again + _showSnapinManager = false; + this.ShowInitialisationWizard(); + } + ppDataObject = new DataObject(FindNode(cookie)); + } - // Let's see if this node has property pages - try - { - // When there are items in the selection, we assume the properties are for those. - if(this.ScopeNodeSelected == false) - { - ReportNode rpne = dataObject.Node as ReportNode; - if(rpne != null) - { - if(rpne.ItemsHavePropertyPages()) - { - return HRESULT.S_OK; - } - } - return HRESULT.S_FALSE; - } - else - { - IMMCSaneNode sane = (IMMCSaneNode)dataObject.Node; - if(sane.PropertyPages.Count != 0) - return HRESULT.S_OK; - } - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("SnapinBase::QueryPagesFor exception: " + e); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } + #region MMC SNAPIN MANAGER + // This is how it works: + // If you load a snapin in the MMC (so a not saved snapin(.msc)) the mmc sends a msg to the + // Snapin with the question 'do you have a SnapinManager for me?' + // as this happens we set up our wizard, and we make sure that the Wizard is shown once. + // after that we let the base Class handle the QueryDataObject + // + // you could use a SnapinManager for Startup configuration, like the Microsoft Services plugin + // it asks if you want to connect to a remote server or want work on the local machine. + protected virtual void ShowInitialisationWizard() + { + if (this.Managers != null) + { + WizardBase.ShowWizard(this.ManagerTitle, + this.Managers, + new WizardBase.WizardAction(ManagerHandler)); + } + } - return HRESULT.S_FALSE; - } - #endregion - ////////////////////////////////////////////////////////////////////// - // - // IExtendContextMenu implementation - // - #region - /// <summary> - /// Add menu items based on MMC's insertion rules - /// </summary> - /// <param name="piDataObject"></param> - /// <param name="piCallback"></param> - /// <param name="pInsertionAllowed"></param> - public void AddMenuItems(IntPtr piDataObject, IContextMenuCallback piCallback, ref int pInsertionAllowed) - { - DataObject item = null; - try - { - //Added by Alexander Kachalkov - IDataObject iDataObject = (IDataObject)Marshal.GetObjectForIUnknown(piDataObject); - - // The piDataObject is really a DataObject in disguise.... - item = (DataObject)iDataObject; + public virtual WizardPage[] Managers + { + get { return null; } + } - if (item.Node != null) - item.Node.AddMenuItems(piCallback, ref pInsertionAllowed); - } - catch(SnapinException e) - { - System.Diagnostics.Debug.WriteLine("SnapinBase::AddMenuItems SnapinException - " + e.ToString()); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - // eat the exception and return s_false indicating that - // we didn't handle the notification - //throw e; - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("SnapinBase::AddMenuItems Exception - " + e.ToString()); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - //throw e; - } - } + protected String m_managerTitle; + public virtual String ManagerTitle + { + get { return m_managerTitle; } + set { m_managerTitle = value; } + } - // FIXME: http://sourceforge.net/tracker/index.php?func=detail&aid=832805&group_id=93348&atid=604010 - // public void AddMenuItems(IntPtr iDataObject, IContextMenuCallback piCallback, ref int pInsertionAllowed) - // { - // if (iDataObject == (IntPtr) DataObject.CUSTOMOCX || iDataObject == (IntPtr)DataObject.CUSTOMWEB) - // { - // } - // else - // { - // - // IDataObject piDataObject = (IDataObject)Marshal.GetObjectForIUnknown(iDataObject); - // - // // The piDataObject is really a DataObject is disguise.... - // - // DataObject item = (DataObject)piDataObject; - // - // if (item.Node != null) - // item.Node.AddMenuItems(piCallback, ref pInsertionAllowed); - // } - // } + // This is the method that handles the finish of the Wizard, in this example it does nothing + // but this method could send data to a remote server or could adjust some nodes, be creative :) + protected virtual void ManagerHandler(Ironring.MMC.Wizards.WizardPage[] pages) + { + } + #endregion + /// <summary> + /// provides scope pane info to MMC + /// </summary> + /// <param name="sdi"></param> + public virtual void GetDisplayInfo(ref SCOPEDATAITEM sdi) + { + // First let's find this node we want info on.... + BaseNode NodeWeWant = FindNode(sdi.lParam); + NodeWeWant.GetDisplayInfo(ref sdi); + } + /// <summary> + /// This method will compare two data objects based on underlying cookie value + /// that the nodes contain + /// </summary> + /// <param name="lpDataObjectA"></param> + /// <param name="lpDataObjectB"></param> + /// <returns></returns> + public int CompareObjects(IDataObject lpDataObjectA, IDataObject lpDataObjectB) + { + // since this is the only type we hand out it should be the only type + // provided here and the cast should "always" work. + DataObject doItem1 = (DataObject)lpDataObjectA; + DataObject doItem2 = (DataObject)lpDataObjectB; + // TBD: implement IComparable on Node and compare cookies. + // These are different objects. We need to return S_FALSE + if (doItem1.Node.Cookie != doItem2.Node.Cookie) + return HRESULT.S_FALSE; - /// <summary> - /// Called when user invokes a menu command - /// </summary> - /// <param name="lCommandID"></param> - /// <param name="piDataObject"></param> - public void Command(int lCommandID, IntPtr piDataObject) - { - DataObject item = null; - try - { - //Added by Alexander Kachalkov - IDataObject iDataObject = (IDataObject)Marshal.GetObjectForIUnknown(piDataObject); - - // The piDataObject is really a DataObject is disguise.... - item = (DataObject)iDataObject; + return HRESULT.S_OK; + } + #endregion + ////////////////////////////////////////////////////////////////////// + // + // IExtendPropertySheet implementation + // + #region + /// <summary> + /// MMC wants a property sheet created of the given node + /// </summary> + /// <param name="lpProvider"></param> + /// <param name="handle"></param> + /// <param name="lpDataObject"></param> + /// <returns></returns> + public virtual int CreatePropertyPages(IPropertySheetCallback lpProvider, IntPtr handle, IDataObject lpDataObject) + { + DataObject dataObject = (DataObject)lpDataObject; + try + { + if (this.ScopeNodeSelected == false) + { + // Show the property pages for all nodes + ReportNode rpne = (ReportNode)dataObject.Node; + rpne.CreatePropertyPagesForItems(lpProvider, handle); - // pass the command on to the node - if (item.Node != null) - item.Node.Command(lCommandID); - } - catch(SnapinException e) - { - System.Diagnostics.Debug.WriteLine("SnapinBase::AddMenuItems SnapinException - " + e.ToString()); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - // eat the exception and return s_false indicating that - // we didn't handle the notification - //throw e; - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("SnapinBase::AddMenuItems Exception - " + e.ToString()); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - //throw e; - } - } - #endregion + // See comment below! + return HRESULT.S_FALSE; + } + else + { + IMMCSaneNode sane = (IMMCSaneNode)dataObject.Node; + if (sane.PropertyPages.Count == 0) + return HRESULT.S_FALSE; + else + { + // Got pages. + dataObject.Node.PropertyPages.Clear(); + dataObject.Node.CreatePropertyPages(lpProvider, handle); - /// <summary> - /// Auto Register the snap-in with MMC - /// </summary> - [ComRegisterFunction()] - public static void RegisterSnapIn(Type t) - { - SnapinRegistrar.Register(t.Assembly); - } + // We have created our own property-pages in a separate thread. + // DON'T LET MMC DISPLAY A PROPERTY PAGE TOO! This is needed for + // Winforms to work. + return HRESULT.S_FALSE; + } + } + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine("SnapinBaseExt::CreatePropertyPages exception: " + e); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } + // don't use the MMC property page facilities - just roll our own. + return HRESULT.S_FALSE; + } - /// <summary> - /// Unregister the snap-in with MMC - /// </summary> - [ComUnregisterFunction()] - public static void UnregisterSnapIn(Type t) - { - SnapinRegistrar.UnRegister(t.Assembly); - } + /// <summary> + /// MMC calls this at initialization time to find out if the node + /// supports property pages - this is the one and only time to respond. + /// This is overriden to get the property-page of the item or node + /// that is currently selected. + /// </summary> + /// <param name="lpDataObject">IdataObject for Node in question</param> + /// <returns></returns> + public virtual int QueryPagesFor(IDataObject lpDataObject) + { + // This snapin does have property pages, so we should return S_OK + // (which will happen automatically). If the snapin didn't have + // any property pages, then we should return S_FALSE - private void InitializeComponent() - { - this.FilterMenu = new System.Windows.Forms.ContextMenu(); - } + DataObject dataObject = (DataObject)lpDataObject; - ////////////////////////////////////////////////////////////////////// - // - // IPersistStream implementation. - // - #region - /// <summary> - /// The state for this snapin. - /// </summary> - protected SnapinStateBase m_SnapinState; - public virtual SnapinStateBase SnapinState - { - get { return this.m_SnapinState; } - set { this.m_SnapinState = value; } - } + //---added by Roman Kiss + dataObject.Node.OnQueryProperties(); - /// <summary> - /// Normaly IPersistStreamInit would be used. This doesn't - /// seem to work though. Instead we fake the init. Our - /// init() will call this method to get a default SnapinState. - /// Override when needed. - /// </summary> - /// <returns></returns> - public virtual SnapinStateBase CreateSnapinState() - { - SnapinStateBase ssb = new SnapinStateBase(); - return ssb; - } - - /// <summary> - /// Get the class-id for this snapin. - /// </summary> - /// <param name="pClassID"></param> - public void GetClassID(out Guid pClassID) - { - System.Diagnostics.Debug.WriteLine("GetClassID"); - pClassID = this.Guid; - } - - /// <summary> - /// Check if the snapin-state is dirty. - /// </summary> - /// <returns></returns> - public int IsDirty( ) - { - System.Diagnostics.Debug.WriteLine("IsDirty"); - if(this.SnapinState != null) - { - if(this.SnapinState.Dirty) - { - return 0; - } - else - { - return 1; - } - } - else - { - return 1; - } - } + // Let's see if this node has property pages + try + { + // When there are items in the selection, we assume the properties are for those. + if (this.ScopeNodeSelected == false) + { + ReportNode rpne = dataObject.Node as ReportNode; + if (rpne != null) + { + if (rpne.ItemsHavePropertyPages()) + { + return HRESULT.S_OK; + } + } + return HRESULT.S_FALSE; + } + else + { + IMMCSaneNode sane = (IMMCSaneNode)dataObject.Node; + if (sane.PropertyPages.Count != 0) + return HRESULT.S_OK; + } + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine("SnapinBase::QueryPagesFor exception: " + e); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } - /// <summary> - /// Delegate back to the snapin-state for de-serializing. - /// </summary> - /// <param name="pStm"></param> - public void Load(IStream pStm) - { - try - { - System.Diagnostics.Debug.WriteLine("Load"); - ComStream cs = new ComStream(pStm); - this.SnapinState.ReadState(cs); - cs.Close(); - System.Diagnostics.Debug.WriteLine("Loaded state: " + this.SnapinState); - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("Exception in load: " + e); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - } + return HRESULT.S_FALSE; + } + #endregion + ////////////////////////////////////////////////////////////////////// + // + // IExtendContextMenu implementation + // + #region + /// <summary> + /// Add menu items based on MMC's insertion rules + /// </summary> + /// <param name="piDataObject"></param> + /// <param name="piCallback"></param> + /// <param name="pInsertionAllowed"></param> + public void AddMenuItems(IntPtr piDataObject, IContextMenuCallback piCallback, ref int pInsertionAllowed) + { + DataObject item = null; + try + { + //Added by Alexander Kachalkov + IDataObject iDataObject = (IDataObject)Marshal.GetObjectForIUnknown(piDataObject); - /// <summary> - /// Delegate back to the snapin-state for serialization. - /// </summary> - /... [truncated message content] |
From: <tig...@us...> - 2008-06-06 14:23:01
|
Revision: 8 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=8&view=rev Author: tigerharry Date: 2008-06-06 07:22:50 -0700 (Fri, 06 Jun 2008) Log Message: ----------- added property ShowRefreshbutton to show the refresh button like on windows event view (F5 to refresh does also work then) Modified Paths: -------------- MMCLib2/Nodes/ReportNode.cs Modified: MMCLib2/Nodes/ReportNode.cs =================================================================== --- MMCLib2/Nodes/ReportNode.cs 2008-06-04 14:45:27 UTC (rev 7) +++ MMCLib2/Nodes/ReportNode.cs 2008-06-06 14:22:50 UTC (rev 8) @@ -24,6 +24,9 @@ // Private vars // #region + //Added by Harald Binkle [tigerharry] + private bool m_ShowRefreshbutton; + //Added by Alexander Kachalkov /// <summary> /// A cached reference to the MMC console @@ -48,6 +51,23 @@ // Properties // #region + //Added by Harald Binkle [tigerharry] + /// <summary> + /// If set to true the standard refresh button will be displayed + /// </summary> + public bool ShowRefreshbutton + { + get + { + return m_ShowRefreshbutton; + } + + set + { + m_ShowRefreshbutton = value; + } + } + //Added by Alexander Kachalkov /// <summary> /// Return the cached member variable to get at MMC @@ -330,6 +350,7 @@ icv.SetVerbState(MMC_CONSOLE_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 0); System.Diagnostics.Debug.WriteLine("Properties disabled"); } + if (m_ShowRefreshbutton) icv.SetVerbState(MMC_CONSOLE_VERB.REFRESH, MMC_BUTTON_STATE.ENABLED, 1);//Added by Harald Binkle [tigerharry] } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2008-06-04 14:45:30
|
Revision: 7 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=7&view=rev Author: tigerharry Date: 2008-06-04 07:45:27 -0700 (Wed, 04 Jun 2008) Log Message: ----------- - added debug info - removed obsolete modifier for Add(image) Modified Paths: -------------- MMCLib2/Core/Component.cs MMCLib2/Core/ImageList.cs Modified: MMCLib2/Core/Component.cs =================================================================== --- MMCLib2/Core/Component.cs 2008-06-04 14:38:49 UTC (rev 6) +++ MMCLib2/Core/Component.cs 2008-06-04 14:45:27 UTC (rev 7) @@ -124,8 +124,9 @@ /// </summary> /// <param name="pConsole"></param> public void Initialize(Object pConsole) - { - IMMCVersionInfo versionInfo = pConsole as IMMCVersionInfo; // doesn't work without platform sdk ? + { + System.Diagnostics.Debug.WriteLine("IComponent::Initialize"); + IMMCVersionInfo versionInfo = pConsole as IMMCVersionInfo; // doesn't work without platform sdk ? IConsole3 testConsole = pConsole as IConsole3; // introduced in mmc2 IColumnData columnData = pConsole as IColumnData; // introduced in mmc1.2 _console = pConsole as IConsole2; // introduced in mmc1.1 @@ -330,7 +331,7 @@ } case MMCN_Notify.INITOCX: { - OnInitOCX(ref hr, ref arg, ref param, ref node); + OnInitOCX(ref hr, ref arg, ref param, ref node); break; } case MMCN_Notify.FILTER_CHANGE: Modified: MMCLib2/Core/ImageList.cs =================================================================== --- MMCLib2/Core/ImageList.cs 2008-06-04 14:38:49 UTC (rev 6) +++ MMCLib2/Core/ImageList.cs 2008-06-04 14:45:27 UTC (rev 7) @@ -399,7 +399,7 @@ /// </summary> /// <param name="image">Specifies the image to be appended. /// </param> - [Obsolete]public override int Add(object image) + public override int Add(object image) { return base.Add(new ImageEntry(image)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2008-06-04 14:38:54
|
Revision: 6 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=6&view=rev Author: tigerharry Date: 2008-06-04 07:38:49 -0700 (Wed, 04 Jun 2008) Log Message: ----------- - now propertypage using size of control - added eventhandle for closing PropertyPage when ESC is pressed Modified Paths: -------------- MMCLib2/PropertyPages/PropertyPage.cs MMCLib2/PropertyPages/PropertySheet.cs Modified: MMCLib2/PropertyPages/PropertyPage.cs =================================================================== --- MMCLib2/PropertyPages/PropertyPage.cs 2007-07-30 14:03:43 UTC (rev 5) +++ MMCLib2/PropertyPages/PropertyPage.cs 2008-06-04 14:38:49 UTC (rev 6) @@ -207,7 +207,7 @@ /// <summary> - /// Generate the actual TabPage that will used in the PropertySheet. + /// Generate the actual TabPage that will be used in the PropertySheet. /// We don't keep re-using the same TabPage each time /// the property page is created because it makes the /// updating of the property pages a little difficult. @@ -222,13 +222,13 @@ UserControl ctrl = MainControl; ctrl.Location = new Point(0, 0); - ctrl.Size = Size; - ctrl.TabIndex = 0; + ctrl.Size = Size; + ctrl.TabIndex = 0; // Parent this control to our user control tp.Controls.Add(ctrl); - tp.Size = Size; + tp.Size = Size; tp.Text = Title; return tp; Modified: MMCLib2/PropertyPages/PropertySheet.cs =================================================================== --- MMCLib2/PropertyPages/PropertySheet.cs 2007-07-30 14:03:43 UTC (rev 5) +++ MMCLib2/PropertyPages/PropertySheet.cs 2008-06-04 14:38:49 UTC (rev 6) @@ -165,7 +165,10 @@ //Added by Alexander Kachalkov //This call is required by the Windows Form Designer. - InitializeComponent(); + InitializeComponent(); + + //Added by Harald Binkle [tigerharry] + this.KeyDown += new KeyEventHandler(PropertySheet_KeyDown); //Added by Alexander Ovchinnikov for close PS after remove node //initialise closeDelegate @@ -173,7 +176,13 @@ { _closeHandle += new OnUserDelegate( ClosePropertySheet ); } - } + } + + //Added by Harald Binkle [tigerharry] to be able to close the property page using ESC button + void PropertySheet_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Escape) FakeClose(); + } /// <summary> /// Prepares the property sheet to be shown and then displays it This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2007-07-30 14:03:48
|
Revision: 5 http://mmclibrary.svn.sourceforge.net/mmclibrary/?rev=5&view=rev Author: tigerharry Date: 2007-07-30 07:03:43 -0700 (Mon, 30 Jul 2007) Log Message: ----------- - added OK as default ok and default cancel if no cancel button there Modified Paths: -------------- MMCLib2/PropertyPages/PropertySheet.cs Modified: MMCLib2/PropertyPages/PropertySheet.cs =================================================================== --- MMCLib2/PropertyPages/PropertySheet.cs 2007-03-15 12:28:35 UTC (rev 4) +++ MMCLib2/PropertyPages/PropertySheet.cs 2007-07-30 14:03:43 UTC (rev 5) @@ -182,7 +182,7 @@ { Controls.Clear(); - + // Figure out how big to make the tab control // by sizing to the largest UserControl @@ -224,8 +224,8 @@ // things, which makes m_tc.ItemSize.Height valid. IntPtr handle = _tc.Handle; - nHeight += _tc.Location.Y + _tc.ItemSize.Height; - + nHeight += _tc.Location.Y + _tc.ItemSize.Height; + nWidth += _tc.Location.X + 8; // calculate the tabcontrol height _tc.Size = new System.Drawing.Size(nWidth, nHeight); nHeight = CalcTabHeight(nHeight); @@ -283,8 +283,10 @@ // We have a 4 pixel margin on each side of the tab control, and a 5 pixel margin // between the buttons and the bottom of the page ClientSize = new System.Drawing.Size(nWidth + 8, nHeight + 5); - this.AcceptButton = _btnOk; - this.CancelButton = _btnCancel; + this.AcceptButton = _btnOk; + if (_btnCancel != null) this.CancelButton = _btnCancel; + //[--added if(!=null), else.. by Harald Binkle (tigerharry) + else this.CancelButton = _btnOk; //Added by Alexander Kachalkov base.Closing += new CancelEventHandler(OnCloseClick); @@ -463,8 +465,8 @@ this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(292, 273); this.Name = SnapinBase.Translate("Properties"); - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - //this.TopMost = true; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + //this.TopMost = true; } @@ -513,7 +515,7 @@ /// Validation Delegate /// </summary> public delegate bool CheckValidation(); - #endregion + #endregion Validate end #region PropertySheetTabControl /// <summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tig...@us...> - 2007-03-15 12:28:39
|
Revision: 4 http://svn.sourceforge.net/mmclibrary/?rev=4&view=rev Author: tigerharry Date: 2007-03-15 05:28:35 -0700 (Thu, 15 Mar 2007) Log Message: ----------- Binkle: added: support for sorting columns on header click Modified Paths: -------------- MMCLib2/Nodes/ReportNode.cs Modified: MMCLib2/Nodes/ReportNode.cs =================================================================== --- MMCLib2/Nodes/ReportNode.cs 2006-09-19 11:55:12 UTC (rev 3) +++ MMCLib2/Nodes/ReportNode.cs 2007-03-15 12:28:35 UTC (rev 4) @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Collections; +using System.Collections.Generic; using System.Threading; using Ironring.MMC.Core; using Ironring.MMC.Nodes.NodeEvents; @@ -12,847 +13,909 @@ namespace Ironring.MMC.Nodes { - // TBD: overridable data binding methods to augment GetDisplayInfo - /// <summary> - /// Configures the resultview as a Listview control. - /// </summary> - public class ReportNode : BaseNode, IMMCSaneNode - { - ////////////////////////////////////////////////////////////////////// - // - // Private vars - // - #region - //Added by Alexander Kachalkov - /// <summary> - /// A cached reference to the MMC console - /// </summary> - private IConsole2 _console = null; - - // MAM: the filtersets that are active. - /// <summary> - /// The currently active filters. The keys are the columns (integer), the values - /// are filter expressions. The expressions are simply matched - /// by testing if they occur anywhere within the value. - /// </summary> - private Hashtable _filters = null; + // TBD: overridable data binding methods to augment GetDisplayInfo + /// <summary> + /// Configures the resultview as a Listview control. + /// </summary> + public class ReportNode : BaseNode, IMMCSaneNode + { + ////////////////////////////////////////////////////////////////////// + // + // Private vars + // + #region + //Added by Alexander Kachalkov + /// <summary> + /// A cached reference to the MMC console + /// </summary> + private IConsole2 _console = null; - private ResultViewItem[] _currentSelectedItems = null; - private ArrayList _items = new ArrayList(); - private ArrayList _columns = new ArrayList(); - #endregion + // MAM: the filtersets that are active. + /// <summary> + /// The currently active filters. The keys are the columns (integer), the values + /// are filter expressions. The expressions are simply matched + /// by testing if they occur anywhere within the value. + /// </summary> + private Hashtable _filters = null; - ////////////////////////////////////////////////////////////////////// - // - // Properties - // - #region - //Added by Alexander Kachalkov - /// <summary> - /// Return the cached member variable to get at MMC - /// </summary> - public IHeaderCtrl2 HeaderCtrl - { - get { return (IHeaderCtrl2)_console; } - } + private ResultViewItem[] _currentSelectedItems = null; + private ArrayList _items = new ArrayList(); + private ArrayList _columns = new ArrayList(); + #endregion - //Added by Alexander Kachalkov - /// <summary> - /// Return the cached member variable to get at MMC - /// </summary> - public IResultData ResultData - { - get { return (IResultData)_console; } - } + ////////////////////////////////////////////////////////////////////// + // + // Properties + // + #region + //Added by Alexander Kachalkov + /// <summary> + /// Return the cached member variable to get at MMC + /// </summary> + public IHeaderCtrl2 HeaderCtrl + { + get { return (IHeaderCtrl2)_console; } + } - /// <summary> - /// Get/set the resultview items. - /// </summary> - public virtual ArrayList Items - { - get {return _items;} - set { _items = value;} - } + //Added by Alexander Kachalkov + /// <summary> + /// Return the cached member variable to get at MMC + /// </summary> + public IResultData ResultData + { + get { return (IResultData)_console; } + } - /// <summary> - /// Get/set the columns for this view. Override for results. - /// </summary> - public virtual ArrayList Columns - { - get { return _columns; } - set { _columns = value;} - } - #endregion + /// <summary> + /// Get/set the resultview items. + /// </summary> + public virtual ArrayList Items + { + get { return _items; } + set { _items = value; } + } - ////////////////////////////////////////////////////////////////////// - // - // Constructors - // - #region /// <summary> - /// ctor takes the snapin to register with - /// </summary> - /// <param name="snapin"></param> - public ReportNode(SnapinBase snapin) : base(snapin) - { - } + /// Get/set the columns for this view. Override for results. + /// </summary> + public virtual ArrayList Columns + { + get { return _columns; } + set { _columns = value; } + } + #endregion - /// <summary> - /// ctor takes the snapin to register with - /// </summary> - /// <param name="snapin">Link back to the SnapinBase</param> - /// <param name="parentNode"></param> - public ReportNode(SnapinBase snapin, BaseNode parentNode) : base(snapin, parentNode) - { - } + ////////////////////////////////////////////////////////////////////// + // + // Constructors + // + #region + /// <summary> + /// ctor takes the snapin to register with + /// </summary> + /// <param name="snapin"></param> + public ReportNode(SnapinBase snapin) + : base(snapin) + { + } - protected internal ReportNode(SnapinBase snapin, String name, bool multiselect) : base(snapin) - { - base.DisplayName = name; - this.MultiSelectMode = multiselect; - } + /// <summary> + /// ctor takes the snapin to register with + /// </summary> + /// <param name="snapin">Link back to the SnapinBase</param> + /// <param name="parentNode"></param> + public ReportNode(SnapinBase snapin, BaseNode parentNode) + : base(snapin, parentNode) + { + } - public ReportNode(SnapinBase snapin, String name, String closedIco, String openIco) : base(snapin, name, closedIco, openIco) - { - } - #endregion - - #region ResultView handling - public override string GetResultViewType(ref int pViewOptions) - { - // Call the base version first and toggle the options later. - string returnValue = base.GetResultViewType(ref pViewOptions); - // Allow multiselect - if(MultiSelectMode) - pViewOptions |= (int)MMC_VIEW_OPTIONS.MULTISELECT; - return returnValue; - } + protected internal ReportNode(SnapinBase snapin, String name, bool multiselect) + : base(snapin) + { + base.DisplayName = name; + this.MultiSelectMode = multiselect; + } - /// <summary> - /// Get the ordinal index of the given item. This does a simple scan - /// on all items and returns the - /// </summary> - /// <param name="item">The item to look for.</param> - /// <returns>The ordinal index, or -1 if the item is not found.</returns> - public virtual int getIndex(ResultViewItem item) - { - ArrayList items = this.Items; - int retval = -1; - int max = items.Count; - for(int i=0; i<max; i++) - { - if(items[i] == item) - { - retval = i; - break; - } - } - return retval; - } - - /// <summary> - /// Check if the given item should be added according to the given filter criteria. - /// </summary> - public virtual bool CheckItem(ResultViewItem item) - { - // Short-circuit the check if there are no filters. - if(this._filters == null) - return true; + public ReportNode(SnapinBase snapin, String name, String closedIco, String openIco) + : base(snapin, name, closedIco, openIco) + { + } + #endregion - // Column-0 is special: it's the display name of the item. - ResultViewColumn col0 = (ResultViewColumn)this.Columns[0]; + #region ResultView handling + public override string GetResultViewType(ref int pViewOptions) + { + // Call the base version first and toggle the options later. + string returnValue = base.GetResultViewType(ref pViewOptions); + // Allow multiselect + if (MultiSelectMode) + pViewOptions |= (int)MMC_VIEW_OPTIONS.MULTISELECT; + return returnValue; + } - // There are filters defined. Column-0 is as it is the display name of the item. - foreach(int i in this._filters.Keys) - { - ResultViewColumn filterColumn = (ResultViewColumn)this.Columns[i]; - String data = (String)this._filters[i]; - String itemValue; - if(filterColumn.Equals(col0)) - itemValue = item.DisplayName; - else - itemValue = (String)item.Details[filterColumn]; + /// <summary> + /// Get the ordinal index of the given item. This does a simple scan + /// on all items and returns the + /// </summary> + /// <param name="item">The item to look for.</param> + /// <returns>The ordinal index, or -1 if the item is not found.</returns> + public virtual int getIndex(ResultViewItem item) + { + ArrayList items = this.Items; + int retval = -1; + int max = items.Count; + for (int i = 0; i < max; i++) + { + if (items[i] == item) + { + retval = i; + break; + } + } + return retval; + } - // When itemValue == null, the column could not be found. - // Assume that a null value does not equal an empty string. A - // null value means we will not filter on the column/item combination, - // an empty string will lead to filtering (and possible rejection of the item). - if(itemValue != null) - { - if(itemValue.IndexOf(data) == -1) - { - // Not found - return false; - } - } - } - return true; - } + /// <summary> + /// Check if the given item should be added according to the given filter criteria. + /// </summary> + public virtual bool CheckItem(ResultViewItem item) + { + // Short-circuit the check if there are no filters. + if (this._filters == null) + return true; - public override void GetDisplayInfo(ref RESULTDATAITEM resultDataItem) - { - bool bCallbase = true; + // Column-0 is special: it's the display name of the item. + ResultViewColumn col0 = (ResultViewColumn)this.Columns[0]; - // the "cell" data - int nRow = (resultDataItem.lParam >> 16) - 1; - int nCol = resultDataItem.nCol; + // There are filters defined. Column-0 is as it is the display name of the item. + foreach (int i in this._filters.Keys) + { + ResultViewColumn filterColumn = (ResultViewColumn)this.Columns[i]; + String data = (String)this._filters[i]; + String itemValue; + if (filterColumn.Equals(col0)) + itemValue = item.DisplayName; + else + itemValue = (String)item.Details[filterColumn]; - ArrayList myColumns = this.Columns; - ArrayList myItems = this.Items; + // When itemValue == null, the column could not be found. + // Assume that a null value does not equal an empty string. A + // null value means we will not filter on the column/item combination, + // an empty string will lead to filtering (and possible rejection of the item). + if (itemValue != null) + { + if (itemValue.IndexOf(data) == -1) + { + // Not found + return false; + } + } + } + return true; + } - string data = DisplayName; - int maxCol = myColumns.Count; - int maxItems = myItems.Count; + public override void GetDisplayInfo(ref RESULTDATAITEM resultDataItem) + { + bool bCallbase = true; - if ((resultDataItem.mask & (uint)RDI.STR) > 0) - { - if (nRow >= 0 && nRow < maxItems && nCol >= 0 && nCol < maxCol) - { - ResultViewItem ri = (ResultViewItem)myItems[nRow]; - if(nCol == 0) - { // get the display name: a special attribute - data = ri.DisplayName; - } - else - { - ResultViewColumn col = (ResultViewColumn)myColumns[nCol]; - data = (String)ri.GetDetail(col); - } - bCallbase = false; - } - resultDataItem.str = Marshal.StringToCoTaskMemUni(data); - } + // the "cell" data + int nRow = (resultDataItem.lParam >> 16) - 1; + int nCol = resultDataItem.nCol; - // the image - requires 2 images in the image list - // small - 0 - // large - 1 - if ((resultDataItem.mask & (uint)RDI.IMAGE) > 0) - { - if (nRow >= 0 && nRow < maxItems && nCol >= 0 && nCol < maxCol) - { - resultDataItem.nImage = GetResultViewImageIndex((ResultViewItem)myItems[nRow]); - bCallbase=false; - } - } - if (bCallbase) - base.GetDisplayInfo(ref resultDataItem); - } + ArrayList myColumns = this.Columns; + ArrayList myItems = this.Items; - /// <summary> - /// prepared for multiselect - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public virtual ResultViewItem[] GetCurrentSelected() - { - ArrayList retval = new ArrayList(); - IConsole2 console = Snapin.ResultViewConsole; - IResultData pResultData = console as IResultData; + string data = DisplayName; + int maxCol = myColumns.Count; + int maxItems = myItems.Count; - RESULTDATAITEM rdi; - int nIndex = -1; - int nIndexCookies = 0; + if ((resultDataItem.mask & (uint)RDI.STR) > 0) + { + if (nRow >= 0 && nRow < maxItems && nCol >= 0 && nCol < maxCol) + { + ResultViewItem ri = (ResultViewItem)myItems[nRow]; + if (nCol == 0) + { // get the display name: a special attribute + data = ri.DisplayName; + } + else + { + ResultViewColumn col = (ResultViewColumn)myColumns[nCol]; + data = (String)ri.GetDetail(col); + } + bCallbase = false; + } + resultDataItem.str = Marshal.StringToCoTaskMemUni(data); + } - // scope items are shown in the resultview too, ignore those - for(int i = 0 + NumChildren, max=this.Items.Count + NumChildren; i < max; i++) - { - try - { - rdi = new RESULTDATAITEM(); - - rdi.mask = 0x8; // RDI_STATE nState is valid - rdi.nIndex = nIndex; // nIndex == -1 to start at first item - rdi.nState = 0x002; // LVIS_SELECTED only interested in selected items + // the image - requires 2 images in the image list + // small - 0 + // large - 1 + if ((resultDataItem.mask & (uint)RDI.IMAGE) > 0) + { + if (nRow >= 0 && nRow < maxItems && nCol >= 0 && nCol < maxCol) + { + resultDataItem.nImage = GetResultViewImageIndex((ResultViewItem)myItems[nRow]); + bCallbase = false; + } + } + if (bCallbase) + base.GetDisplayInfo(ref resultDataItem); + } - // get next selected item - pResultData.GetNextItem(ref rdi); - if (rdi.nIndex != -1) - { - //rdi is the RESULTDATAITEM of a selected item. add its - //lParam to the pCookies array of the pMultiSelectDataObject data object - nIndexCookies++; - nIndex = rdi.nIndex; - retval.Add(Items[rdi.nIndex - NumChildren]); - } - } - catch(Exception) - { - // We can get out of index. Ignore it, it will break MMC when we don't catch. - // This seems to happen sometimes (deep within COM world, so no way that we can debug that). - } - } - return (ResultViewItem[])retval.ToArray(new ResultViewItem().GetType()); - } - #endregion - - ////////////////////////////////////////////////////////////////////// - // - // Selection Handling - // This is done by hand because the events did not propagate as we would like them too. - // - #region - /// <summary> - /// Called when a result item is selected. Sets the property-page flag. - /// </summary> - public override void OnSelectResult() - { - // clear the selected nodes - this.Snapin.RemoveSelectedNode(this); + /// <summary> + /// prepared for multiselect + /// </summary> + /// <param name="index"></param> + /// <returns></returns> + public virtual ResultViewItem[] GetCurrentSelected() + { + ArrayList retval = new ArrayList(); + IConsole2 console = Snapin.ResultViewConsole; + IResultData pResultData = console as IResultData; - System.Diagnostics.Debug.WriteLine("ReportNode::OnSelect"); - this._currentSelectedItems = GetCurrentSelected(); - bool havePropertyPage = false; - for(int i=0; i<this._currentSelectedItems.Length; i++) - { - this._currentSelectedItems[i].OnSelect(); - if(!havePropertyPage && this._currentSelectedItems[i].PropertyPages.Count != 0) - { - havePropertyPage = true; - } - } - - IConsoleVerb icv; - Snapin.ResultViewConsole.QueryConsoleVerb(out icv); + RESULTDATAITEM rdi; + int nIndex = -1; + int nIndexCookies = 0; - // See if we need to enable then property sheets item on the popup menu - if (havePropertyPage) - { - icv.SetVerbState(MMC_CONSOLE_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 1); - System.Diagnostics.Debug.WriteLine("Properties enabled"); - } - else - { - icv.SetVerbState(MMC_CONSOLE_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 0); - System.Diagnostics.Debug.WriteLine("Properties disabled"); - } - } + // scope items are shown in the resultview too, ignore those + for (int i = 0 + NumChildren, max = this.Items.Count + NumChildren; i < max; i++) + { + try + { + rdi = new RESULTDATAITEM(); - /// <summary> - /// Call when the an item is deselected. Deselects the old item. - /// </summary> - /// <remarks>Should this be done like this: it seems a bit slow.</remarks> - public override void OnDeselectResult() - { - System.Diagnostics.Debug.WriteLine("ReportNode::Deselect"); - // Get the new set of selected items. - Hashtable oldItems = new Hashtable(); - Hashtable newItems = new Hashtable(); + rdi.mask = 0x8; // RDI_STATE nState is valid + rdi.nIndex = nIndex; // nIndex == -1 to start at first item + rdi.nState = 0x002; // LVIS_SELECTED only interested in selected items - ResultViewItem[] items = GetCurrentSelected(); - if(items != null) - { - for(int i=0; i<items.Length; i++) - { - newItems.Add(items[i], null); - } - } - for(int i=0; i<this._currentSelectedItems.Length; i++) - { - oldItems.Add(this._currentSelectedItems[i], null); - } + // get next selected item + pResultData.GetNextItem(ref rdi); + if (rdi.nIndex != -1) + { + //rdi is the RESULTDATAITEM of a selected item. add its + //lParam to the pCookies array of the pMultiSelectDataObject data object + nIndexCookies++; + nIndex = rdi.nIndex; + retval.Add(Items[rdi.nIndex - NumChildren]); + } + } + catch (Exception) + { + // We can get out of index. Ignore it, it will break MMC when we don't catch. + // This seems to happen sometimes (deep within COM world, so no way that we can debug that). + } + } + return (ResultViewItem[])retval.ToArray(new ResultViewItem().GetType()); + } + #endregion - for(int i=0; i<items.Length; i++) - { - if(oldItems.ContainsKey(items[i])) - { - // It was selected, and is selected again - } - else - { - // It was not selected, but is selected now - ((ResultViewItem)items[i]).OnSelect(); - } - } + ////////////////////////////////////////////////////////////////////// + // + // Selection Handling + // This is done by hand because the events did not propagate as we would like them too. + // + #region + /// <summary> + /// Called when a result item is selected. Sets the property-page flag. + /// </summary> + public override void OnSelectResult() + { + // clear the selected nodes + this.Snapin.RemoveSelectedNode(this); - for(int i=0; i<this._currentSelectedItems.Length; i++) - { - if(newItems.ContainsKey(this._currentSelectedItems[i])) - { - // It was selected and is selected again - } - else - { - // It was selected, but is not selected now - this._currentSelectedItems[i].OnDeselect(); - } - } + System.Diagnostics.Debug.WriteLine("ReportNode::OnSelect"); + this._currentSelectedItems = GetCurrentSelected(); + bool havePropertyPage = false; + for (int i = 0; i < this._currentSelectedItems.Length; i++) + { + this._currentSelectedItems[i].OnSelect(); + if (!havePropertyPage && this._currentSelectedItems[i].PropertyPages.Count != 0) + { + havePropertyPage = true; + } + } - this._currentSelectedItems = items; - } - + IConsoleVerb icv; + Snapin.ResultViewConsole.QueryConsoleVerb(out icv); - /// <summary> - /// Filters should be cleared onm deselect - /// </summary> - public override void OnDeselectScope() - { - if(_filters !=null ) - this._filters.Clear(); - base.OnDeselectScope(); - } - #endregion + // See if we need to enable then property sheets item on the popup menu + if (havePropertyPage) + { + icv.SetVerbState(MMC_CONSOLE_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 1); + System.Diagnostics.Debug.WriteLine("Properties enabled"); + } + else + { + icv.SetVerbState(MMC_CONSOLE_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 0); + System.Diagnostics.Debug.WriteLine("Properties disabled"); + } + } - ////////////////////////////////////////////////////////////////////// - // - // PropertyPages handling for items - // - #region - /// <summary> - /// This function will create property sheet pages based - /// on the information stored in its m_propertyPages field. - /// It registers the property page along with the callback - /// functions. - /// </summary> - /// <param name="lpProvider"></param> - /// <param name="handle"></param> - public virtual void CreatePropertyPagesForItems(IPropertySheetCallback lpProvider, IntPtr handle) - { - ResultViewItem[] items = GetCurrentSelected(); - for(int i=0; i<items.Length; i++) - { - if(items[i].PropertyPages.Count > 0) - { - if (items[i].PropertySheet == null || items[i].PropertySheet.isClosed) - { - // We need to spin off a new thread for this. - // Why? - // For winforms forms to work correctly (including accelerators, etc) - // we need to use a winforms message pump. We can accomplish that - // by showing our form using Form.ShowDialog(). - // However, this blocks the thread's execution until the dialog - // is dismissed. We'll get around this by spinning off another thread - // to handle the form. - //ThreadPool.QueueUserWorkItem(new WaitCallback(CreatePropertySheetForItems), (object)items[i]); - if (PropertyPageSettings.Instance.ShowModalPropertySheets) - CreatePropertySheetForItems((object)items[i]); - else - ThreadPool.QueueUserWorkItem(new WaitCallback(CreatePropertySheetForItems), (object)items[i]); - } - else - { - items[i].PropertySheet.Activate(); - } - } - } - } + /// <summary> + /// Call when the an item is deselected. Deselects the old item. + /// </summary> + /// <remarks>Should this be done like this: it seems a bit slow.</remarks> + public override void OnDeselectResult() + { + System.Diagnostics.Debug.WriteLine("ReportNode::Deselect"); + // Get the new set of selected items. + Hashtable oldItems = new Hashtable(); + Hashtable newItems = new Hashtable(); - protected virtual void CreatePropertySheetForItems(object item) - { - ResultViewItem m_item = item as ResultViewItem; - m_item.PropertySheet = new PropertySheet(this); + ResultViewItem[] items = GetCurrentSelected(); + if (items != null) + { + for (int i = 0; i < items.Length; i++) + { + newItems.Add(items[i], null); + } + } + for (int i = 0; i < this._currentSelectedItems.Length; i++) + { + oldItems.Add(this._currentSelectedItems[i], null); + } - ArrayList pages = m_item.PropertyPages; + for (int i = 0; i < items.Length; i++) + { + if (oldItems.ContainsKey(items[i])) + { + // It was selected, and is selected again + } + else + { + // It was not selected, but is selected now + ((ResultViewItem)items[i]).OnSelect(); + } + } - foreach(PropertyPage page in pages) - { - m_item.PropertySheet.Pages.Add(page); - } + for (int i = 0; i < this._currentSelectedItems.Length; i++) + { + if (newItems.ContainsKey(this._currentSelectedItems[i])) + { + // It was selected and is selected again + } + else + { + // It was selected, but is not selected now + this._currentSelectedItems[i].OnDeselect(); + } + } - m_item.PropertySheet.Text = m_item.DisplayName + " " + SnapinBase.Translate("Properties"); + this._currentSelectedItems = items; + } - IntPtr ctx = new System.IntPtr(); - if(HasThemes()) - ctx = TurnOnThemes(); + /// <summary> + /// Filters should be cleared on deselect + /// </summary> + public override void OnDeselectScope() + { + if (_filters != null) + this._filters.Clear(); + base.OnDeselectScope(); + } + + /// <summary> + /// Sort items on column click + /// Added by Binkle 15.03.07 + /// </summary> + public override void OnColumnClick(int nCol, bool bAscending) + { + base.OnColumnClick(nCol, bAscending); + + this._items.Sort(new ResultViewItemComparer(bAscending, (ResultViewColumn)this.Columns[nCol], nCol)); + } + #endregion + + ////////////////////////////////////////////////////////////////////// + // + // PropertyPages handling for items + // + #region + /// <summary> + /// This function will create property sheet pages based + /// on the information stored in its m_propertyPages field. + /// It registers the property page along with the callback + /// functions. + /// </summary> + /// <param name="lpProvider"></param> + /// <param name="handle"></param> + public virtual void CreatePropertyPagesForItems(IPropertySheetCallback lpProvider, IntPtr handle) + { + ResultViewItem[] items = GetCurrentSelected(); + for (int i = 0; i < items.Length; i++) + { + if (items[i].PropertyPages.Count > 0) + { + if (items[i].PropertySheet == null || items[i].PropertySheet.isClosed) + { + // We need to spin off a new thread for this. + // Why? + // For winforms forms to work correctly (including accelerators, etc) + // we need to use a winforms message pump. We can accomplish that + // by showing our form using Form.ShowDialog(). + // However, this blocks the thread's execution until the dialog + // is dismissed. We'll get around this by spinning off another thread + // to handle the form. + //ThreadPool.QueueUserWorkItem(new WaitCallback(CreatePropertySheetForItems), (object)items[i]); + if (PropertyPageSettings.Instance.ShowModalPropertySheets) + CreatePropertySheetForItems((object)items[i]); + else + ThreadPool.QueueUserWorkItem(new WaitCallback(CreatePropertySheetForItems), (object)items[i]); + + } + else + { + items[i].PropertySheet.Activate(); + } + } + } + } + + protected virtual void CreatePropertySheetForItems(object item) + { + ResultViewItem m_item = item as ResultViewItem; + m_item.PropertySheet = new PropertySheet(this); + + ArrayList pages = m_item.PropertyPages; + + foreach (PropertyPage page in pages) + { + m_item.PropertySheet.Pages.Add(page); + } + + m_item.PropertySheet.Text = m_item.DisplayName + " " + SnapinBase.Translate("Properties"); + + IntPtr ctx = new System.IntPtr(); + if (HasThemes()) + ctx = TurnOnThemes(); + m_item.PropertySheet.ShowDialog(); - foreach (PropertyPage page in pages) - if(page.Applied) - Snapin.Invoke(((PropertyPageBase)page.MainControl).Action); + foreach (PropertyPage page in pages) + if (page.Applied) + Snapin.Invoke(((PropertyPageBase)page.MainControl).Action); - if(HasThemes()) - ReleaseActCtx(ctx); + if (HasThemes()) + ReleaseActCtx(ctx); - m_item.PropertySheet.Pages.Clear( ); - m_item.PropertySheet = null; - } + m_item.PropertySheet.Pages.Clear(); + m_item.PropertySheet = null; + } - /// <summary> - /// Returns true when an item has a property page. - /// </summary> - /// <returns>True when the item has a property page, false otherwise.</returns> - public virtual bool ItemsHavePropertyPages() - { - bool havePropertyPage = false; - if(_currentSelectedItems != null) - { - for(int i=0; i<this._currentSelectedItems.Length; i++) - { - if(this._currentSelectedItems[i].PropertyPages.Count > 0) - { - havePropertyPage = true; - } - } - } - return havePropertyPage; - } - #endregion + /// <summary> + /// Returns true when an item has a property page. + /// </summary> + /// <returns>True when the item has a property page, false otherwise.</returns> + public virtual bool ItemsHavePropertyPages() + { + bool havePropertyPage = false; + if (_currentSelectedItems != null) + { + for (int i = 0; i < this._currentSelectedItems.Length; i++) + { + if (this._currentSelectedItems[i].PropertyPages.Count > 0) + { + havePropertyPage = true; + } + } + } + return havePropertyPage; + } + #endregion - /// <summary> - /// BaseNode override to populate the treeview control - /// with column information and data - /// </summary> - public override void OnResultShow() - { - _console = Snapin.ResultViewConsole; + /// <summary> + /// BaseNode override to populate the treeview control + /// with column information and data + /// </summary> + public override void OnResultShow() + { + _console = Snapin.ResultViewConsole; - // setup the header for the columns we want to show - OnShowHeader(HeaderCtrl); - - // add the actual data items - OnShowData(ResultData); + // setup the header for the columns we want to show + OnShowHeader(HeaderCtrl); - ResultData.SetViewMode(this.GetViewType()); + // add the actual data items + OnShowData(ResultData); - base.OnResultShow(); - } + ResultData.SetViewMode(this.GetViewType()); - /// <summary> - /// Overrideable method to get the actual type of view for this report-node. - /// Return one of the ViewMode enum. values. - /// </summary> - /// <returns></returns> - public virtual int GetViewType() { - return (int)ViewMode.Report; - } + base.OnResultShow(); + } - //////////////////////////////////////////////////////////////////// - // - // Helper methods - // - #region - public virtual void OnShowHeader(IHeaderCtrl2 header) - { - int idx = 0; - foreach(ResultViewColumn col in this.Columns) - { - header.InsertColumn(idx, col.ColumnName, col.Format, col.Width); - idx++; - } - } + /// <summary> + /// Overrideable method to get the actual type of view for this report-node. + /// Return one of the ViewMode enum. values. + /// </summary> + /// <returns></returns> + public virtual int GetViewType() + { + return (int)ViewMode.Report; + } - public virtual void OnShowData(IResultData resultData) - { - RESULTDATAITEM rdi = new RESULTDATAITEM(); - int nRow = 1; - ArrayList myItems = this.Items; - - int max = myItems.Count; - for(nRow = 1; nRow <=max; nRow++) - { - if(CheckItem((ResultViewItem)myItems[nRow - 1])) - { - // Each item has a String, an Image and the LPARAM field should be kept as our user object. - rdi.mask = (uint)RDI.STR | (uint)RDI.IMAGE | (uint)RDI.PARAM; + //////////////////////////////////////////////////////////////////// + // + // Helper methods + // + #region + public virtual void OnShowHeader(IHeaderCtrl2 header) + { + int idx = 0; + foreach (ResultViewColumn col in this.Columns) + { + header.InsertColumn(idx, col.ColumnName, col.Format, col.Width); + idx++; + } + } - // TBD: what image? - rdi.nImage = -1; - rdi.str = (IntPtr)(-1); // callback for names - rdi.nCol = 0; + public virtual void OnShowData(IResultData resultData) + { + RESULTDATAITEM rdi = new RESULTDATAITEM(); + int nRow = 1; + ArrayList myItems = this.Items; - // The low word contains the cookie for the node, while the high word - // contains the row number + 1 we're inserting - rdi.lParam = Cookie | (nRow << 16); - resultData.InsertItem(ref rdi); - ((ResultViewItem)myItems[nRow - 1]).ItemID = (uint)rdi.itemID; - } - } - } - - /// <summary> - /// Overridable helper method to UpdateItem - /// </summary> - /// <param name="lParam"></param> - public virtual void UpdateItem(int lParam) { - uint pItemID; - //Find ItemID - ResultData.FindItemByLParam(lParam, out pItemID); - ResultData.UpdateItem(pItemID); - } + int max = myItems.Count; + for (nRow = 1; nRow <= max; nRow++) + { + if (CheckItem((ResultViewItem)myItems[nRow - 1])) + { + // Each item has a String, an Image and the LPARAM field should be kept as our user object. + rdi.mask = (uint)RDI.STR | (uint)RDI.IMAGE | (uint)RDI.PARAM; - /// <summary> - /// Overridable helper method to DeleteItem - /// </summary> - /// <param name="lParam"></param> - public virtual void DeleteItem(int lParam) { - uint pItemID; - //Find ItemID - ResultData.FindItemByLParam(lParam, out pItemID); - ResultData.DeleteItem(pItemID, 0); - } + // TBD: what image? + rdi.nImage = -1; + rdi.str = (IntPtr)(-1); // callback for names + rdi.nCol = 0; - /// <summary> - /// Overridable helper method to GetItem - /// </summary> - /// <param name="ResultDataItem"></param> - /// <param name="pItemID"></param> - public virtual void GetItem(out RESULTDATAITEM resultDataItem, uint pItemID) { - RESULTDATAITEM rdi = new RESULTDATAITEM(); + // The low word contains the cookie for the node, while the high word + // contains the row number + 1 we're inserting + rdi.lParam = Cookie | (nRow << 16); + resultData.InsertItem(ref rdi); + ((ResultViewItem)myItems[nRow - 1]).ItemID = (uint)rdi.itemID; + } + } + } - rdi.mask = (uint)RDI.STR; // STR is valid - rdi.itemID = (int)pItemID; - rdi.nCol = 0; + /// <summary> + /// Overridable helper method to UpdateItem + /// </summary> + /// <param name="lParam"></param> + public virtual void UpdateItem(int lParam) + { + uint pItemID; + //Find ItemID + ResultData.FindItemByLParam(lParam, out pItemID); + ResultData.UpdateItem(pItemID); + } - ResultData.GetItem(ref rdi); - - resultDataItem = rdi; - } + /// <summary> + /// Overridable helper method to DeleteItem + /// </summary> + /// <param name="lParam"></param> + public virtual void DeleteItem(int lParam) + { + uint pItemID; + //Find ItemID + ResultData.FindItemByLParam(lParam, out pItemID); + ResultData.DeleteItem(pItemID, 0); + } + /// <summary> + /// Overridable helper method to GetItem + /// </summary> + /// <param name="ResultDataItem"></param> + /// <param name="pItemID"></param> + public virtual void GetItem(out RESULTDATAITEM resultDataItem, uint pItemID) + { + RESULTDATAITEM rdi = new RESULTDATAITEM(); - /// <summary> - /// Overridable helper method to SelectItem - /// </summary> - /// <param name="nRow"></param> - public virtual void SelectItem(int nRow) - { - int lParam = GetItemLParam(nRow); - uint pItemID; + rdi.mask = (uint)RDI.STR; // STR is valid + rdi.itemID = (int)pItemID; + rdi.nCol = 0; - //Find ItemID - ResultData.FindItemByLParam(lParam, out pItemID); + ResultData.GetItem(ref rdi); - //ResultData.SetItem(ref rdi); - ResultData.ModifyItemState(0, pItemID, (uint)LVIS.SELECTED | (uint)LVIS.FOCUSED, 0); - } + resultDataItem = rdi; + } - /// <summary> - /// Overridable helper method to ClearSelection - /// </summary> - public virtual void ClearSelection() - { - ResultViewItem[] rvi = GetCurrentSelected(); - // FIXME: not tested - for(int i=0;i<rvi.Length;i++) - ResultData.ModifyItemState(i,rvi[i].ItemID, 0, (uint)LVIS.SELECTED | (uint)LVIS.FOCUSED); - } + /// <summary> + /// Overridable helper method to SelectItem + /// </summary> + /// <param name="nRow"></param> + public virtual void SelectItem(int nRow) + { + int lParam = GetItemLParam(nRow); + uint pItemID; - /// <summary> - /// Overridable helper method to Set - /// </summary> - /// <param name="nRow"></param> - public virtual void SetFocus(int nRow) - { - int lParam = GetItemLParam(nRow); - uint pItemID; + //Find ItemID + ResultData.FindItemByLParam(lParam, out pItemID); - //Find ItemID - ResultData.FindItemByLParam(lParam, out pItemID); + //ResultData.SetItem(ref rdi); + ResultData.ModifyItemState(0, pItemID, (uint)LVIS.SELECTED | (uint)LVIS.FOCUSED, 0); + } - RESULTDATAITEM rdi = new RESULTDATAITEM(); - rdi.itemID = (int)pItemID; - rdi.mask = (uint)RDI.STATE; - rdi.nState = (uint)LVIS.SELECTED; // select the item - rdi.nCol = 0; + /// <summary> + /// Overridable helper method to ClearSelection + /// </summary> + public virtual void ClearSelection() + { + ResultViewItem[] rvi = GetCurrentSelected(); - ResultData.SetItem(ref rdi); - } + // FIXME: not tested + for (int i = 0; i < rvi.Length; i++) + ResultData.ModifyItemState(i, rvi[i].ItemID, 0, (uint)LVIS.SELECTED | (uint)LVIS.FOCUSED); + } - /// <summary> - /// helper method to get item row ID by lParam - /// </summary> - /// <param name="lParam"></param> - public virtual int GetTableRowID(int lParam) { - return (lParam >> 16) - 1; - } - /// <summary> - /// helper method to get item lParam by nRow - /// The low word contains the cookie for the node, while the high word - /// contains the row number + 1 we're inserting - /// </summary> - /// <param name="nRow"></param> - public virtual int GetItemLParam(int nRow) { - return Cookie | (nRow << 16); - } - #endregion + /// <summary> + /// Overridable helper method to Set + /// </summary> + /// <param name="nRow"></param> + public virtual void SetFocus(int nRow) + { + int lParam = GetItemLParam(nRow); + uint pItemID; - ////////////////////////////////////////////////////////////// - // - // Filtering implementation - // - #region Filtering + //Find ItemID + ResultData.FindItemByLParam(lParam, out pItemID); - // MAM: override the filter-event and do something (only called when the - // view-mode is also filtered). - /// <summary> - /// When we receive a filter event, we construct a full set of filters per column. - /// </summary> - /// <param name="code">The filter-change operator.</param> - /// <param name="col">The column for which the change is.</param> - public override void OnFilterChange(MMC_FILTER_CHANGE_CODE code, int col) - { - switch(code) - { - case MMC_FILTER_CHANGE_CODE.MFCC_DISABLE: - this._filters = null; - break; - case MMC_FILTER_CHANGE_CODE.MFCC_ENABLE: - // ignore - break; - case MMC_FILTER_CHANGE_CODE.MFCC_VALUE_CHANGE: - - try - { - // COM magic. - int bufLen = 1000; - string strData = GetColumnFilter(col, bufLen); - - // Get the column object and set the string - if(this._filters == null) - this._filters = new Hashtable(); - - // Huh? We get a string back: instead of a null-ptr or zero-terminated string - // we get some strange characters. Assume that if we get a really large string an - // empty string is meant. Probably some funky interop is needed to get this - // correct in microsoft parlance. - // TODO: get this verified/looked at by some COM guru. - if (!Regex.IsMatch(strData, @"\w") || strData.Length >= (bufLen / 2)) - this._filters.Remove(col); - else - this._filters[col] = strData; - - // Performance: unset the filter object when no filters are active. - if(this._filters.Count == 0) - this._filters = null; + RESULTDATAITEM rdi = new RESULTDATAITEM(); + rdi.itemID = (int)pItemID; + rdi.mask = (uint)RDI.STATE; + rdi.nState = (uint)LVIS.SELECTED; // select the item + rdi.nCol = 0; - // Do a forced refresh of all items. - RefreshResultConsole(); - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine(e.Message); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - break; - } - base.OnFilterChange(code, col); - } + ResultData.SetItem(ref rdi); + } - //Added by Alexande Kachalkov - /// <summary> - /// Overridable helper method to GetColumnFilter - /// </summary> - /// <param name="col">Filter column</param> - /// <param name="bufLen">Buffer length</param> - /// <returns>string</returns> - public virtual string GetColumnFilter(int col, int bufLen) - { - int retval = 0; - MMC_FILTERDATA data = new MMC_FILTERDATA(); - - try - { - uint type = 0; - // Some arbitrary buffer length. - data.pszText = IntPtr.Zero; - - // COM magic. - data.pszText = Marshal.AllocCoTaskMem(bufLen); - data.cchTextMax = bufLen; - - retval = HeaderCtrl.GetColumnFilter((uint)col, ref type, ref data); - string strData = Marshal.PtrToStringAuto(data.pszText); // the size doesn't change?, data.cchTextMax); - System.Diagnostics.Debug.WriteLine("Got: " + strData + " for column: " + col + " Length of string: " + strData.Length); - - return strData; - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine(e.Message); - //throw e; - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - finally - { - if(! data.pszText.Equals(System.IntPtr.Zero)) - { - Marshal.FreeCoTaskMem(data.pszText); - } - } - return null; - } - - //Added by Alexande Kachalkov - /// <summary> - /// Overridable helper method to SetColumnFilter - /// </summary> - /// <param name="col">Filter column</param> - /// <param name="type">Filter type</param> - /// <param name="text">Filter text</param> - /// <returns></returns> - public virtual int SetColumnFilter(int col, MMC_FILTER_TYPE type, string text) - { - int retval = 0; - MMC_FILTERDATA2 data = new MMC_FILTERDATA2(); - - try - { - data.pszText = text; - - retval = HeaderCtrl.SetColumnFilter((uint)col, (uint)type, data); - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine(e.Message); - //throw e; - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - - return retval; - } + /// <summary> + /// helper method to get item row ID by lParam + /// </summary> + /// <param name="lParam"></param> + public virtual int GetTableRowID(int lParam) + { + return (lParam >> 16) - 1; + } + /// <summary> + /// helper method to get item lParam by nRow + /// The low word contains the cookie for the node, while the high word + /// contains the row number + 1 we're inserting + /// </summary> + /// <param name="nRow"></param> + public virtual int GetItemLParam(int nRow) + { + return Cookie | (nRow << 16); + } + #endregion - #endregion + ////////////////////////////////////////////////////////////// + // + // Filtering implementation + // + #region Filtering - /// <summary> - /// Refreshes the ResultConsole - /// - /// thanks too Arunjeet Singh for the reselecting idea - /// </summary> - public virtual void RefreshResultConsole() - { - if(GetViewType() != (int)ViewMode.Filtered || this._filters == null) - Snapin.SelectScopeNode(this); - else - ResetResultViewConsole(); - } + // MAM: override the filter-event and do something (only called when the + // view-mode is also filtered). + /// <summary> + /// When we receive a filter event, we construct a full set of filters per column. + /// </summary> + /// <param name="code">The filter-change operator.</param> + /// <param name="col">The column for which the change is.</param> + public override void OnFilterChange(MMC_FILTER_CHANGE_CODE code, int col) + { + switch (code) + { + case MMC_FILTER_CHANGE_CODE.MFCC_DISABLE: + this._filters = null; + break; + case MMC_FILTER_CHANGE_CODE.MFCC_ENABLE: + // ignore + break; + case MMC_FILTER_CHANGE_CODE.MFCC_VALUE_CHANGE: - /// <summary> - /// Remove all items from the view and forces a refresh. - /// </summary> - private void ResetResultViewConsole() - { - try - { - IConsole2 console = base.Snapin.ResultViewConsole; - if(console != null) - { - // add the actual data items - IResultData rdata = console as IResultData; - if(rdata != null) - { - rdata.DeleteAllRsltItems(); - this.OnShowData(rdata); - } - else - { - System.Diagnostics.Debug.WriteLine("Rdata cannot be cast"); - } - } - else - { - System.Diagnostics.Debug.WriteLine("Cannot find console"); - } - } - catch(Exception e) - { - System.Diagnostics.Debug.WriteLine("Aaargh: " + e); - ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); - } - } + try + { + // COM magic. + int bufLen = 1000; + string strData = GetColumnFilter(col, bufLen); + // Get the column object and set the string + if (this._filters == null) + this._filters = new Hashtable(); - } + // Huh? We get a string back: instead of a null-ptr or zero-terminated string + // we get some strange characters. Assume that if we get a really large string an + // empty string is meant. Probably some funky interop is needed to get this + // correct in microsoft parlance. + // TODO: get this verified/looked at by some COM guru. + if (!Regex.IsMatch(strData, @"\w") || strData.Length >= (bufLen / 2)) + this._filters.Remove(col); + else + this._filters[col] = strData; + // Performance: unset the filter object when no filters are active. + if (this._filters.Count == 0) + this._filters = null; + // Do a forced refresh of all items. + RefreshResultConsole(); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.Message); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } + break; + } + base.OnFilterChange(code, col); + } + + //Added by Alexande Kachalkov + /// <summary> + /// Overridable helper method to GetColumnFilter + /// </summary> + /// <param name="col">Filter column</param> + /// <param name="bufLen">Buffer length</param> + /// <returns>string</returns> + public virtual string GetColumnFilter(int col, int bufLen) + { + int retval = 0; + MMC_FILTERDATA data = new MMC_FILTERDATA(); + + try + { + uint type = 0; + // Some arbitrary buffer length. + data.pszText = IntPtr.Zero; + + // COM magic. + data.pszText = Marshal.AllocCoTaskMem(bufLen); + data.cchTextMax = bufLen; + + retval = HeaderCtrl.GetColumnFilter((uint)col, ref type, ref data); + string strData = Marshal.PtrToStringAuto(data.pszText); // the size doesn't change?, data.cchTextMax); + System.Diagnostics.Debug.WriteLine("Got: " + strData + " for column: " + col + " Length of string: " + strData.Length); + + return strData; + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.Message); + //throw e; + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } + finally + { + if (!data.pszText.Equals(System.IntPtr.Zero)) + { + Marshal.FreeCoTaskMem(data.pszText); + } + } + return null; + } + + //Added by Alexande Kachalkov + /// <summary> + /// Overridable helper method to SetColumnFilter + /// </summary> + /// <param name="col">Filter column</param> + /// <param name="type">Filter type</param> + /// <param name="text">Filter text</param> + /// <returns></returns> + public virtual int SetColumnFilter(int col, MMC_FILTER_TYPE type, string text) + { + int retval = 0; + MMC_FILTERDATA2 data = new MMC_FILTERDATA2(); + + try + { + data.pszText = text; + + retval = HeaderCtrl.SetColumnFilter((uint)col, (uint)type, data); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.Message); + //throw e; + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } + + return retval; + } + + #endregion + + /// <summary> + /// Refreshes the ResultConsole + /// + /// thanks too Arunjeet Singh for the reselecting idea + /// </summary> + public virtual void RefreshResultConsole() + { + if (GetViewType() != (int)ViewMode.Filtered || this._filters == null) + Snapin.SelectScopeNode(this); + else + ResetResultViewConsole(); + } + + /// <summary> + /// Remove all items from the view and forces a refresh. + /// </summary> + private void ResetResultViewConsole() + { + try + { + IConsole2 console = base.Snapin.ResultViewConsole; + if (console != null) + { + // add the actual data items + IResultData rdata = console as IResultData; + if (rdata != null) + { + rdata.DeleteAllRsltItems(); + this.OnShowData(rdata); + } + else + { + System.Diagnostics.Debug.WriteLine("Rdata cannot be cast"); + } + } + else + { + System.Diagnostics.Debug.WriteLine("Cannot find console"); + } + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine("Aaargh: " + e); + ceh.OnThreadException(this, new ThreadExceptionEventArgs(e)); + } + } + + + } + + /// <summary> + /// Comparer for sorting ResultViewItems on clicking on header columns + /// Added by Binkle 15.03.07 + /// </summary> + public class ResultViewItemComparer : IComparer + { + private ResultViewColumn m_ColToSort; + private int m_nCol; + private bool m_Ascending; + + public ResultViewItemComparer(bool bAscending, ResultViewColumn Col, int nCol) + { + this.m_ColToSort = Col; + this.m_nCol = nCol; + this.m_Ascending = bAscending; + } + + #region IComparer Members + + public int Compare(object x, object y) + { + string strx; + string stry; + if (m_nCol == 0) // colunm 0 is not not a detail in a ResultViewItem + { + strx = ((ResultViewItem)x).DisplayName; + stry = ((ResultViewItem)y).DisplayName; + } + else + { + strx = ((ResultViewItem)x).GetDetail(m_ColToSort); + stry = ((ResultViewItem)y).GetDetail(m_ColToSort); + } + + return m_Ascending ? strx.CompareTo(stry) : stry.CompareTo(strx); + } + + #endregion + + + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |