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.
|