home *** CD-ROM | disk | FTP | other *** search
- //-------------------------------------------------------------
- // CComponent.cs
- //
- // This implements the IComponent, IExtendContextMenu and
- // IExtendControlbar MMC interfaces
- //-------------------------------------------------------------
- using System;
- using System.Runtime.InteropServices;
-
-
- namespace Microsoft.SampleMMC
- {
- public class CComponent: IComponent, IExtendContextMenu, IExtendControlbar
- {
-
- private IConsole2 m_Console; // Holds the MMC Console interface
- private CNode[] m_Nodes; // A reference to an array of the Nodes in the snapin
- private IDisplayHelp m_DisplayHelp; // Holds the MMC IDisplayHelp interface
- private IToolbar m_Toolbar; // Holds the MMC IToolbar interface
- private int m_hToolbarBMP; // Holds the bitmap for the toolbar
-
- //-------------------------------------------------
- // CComponent
- //
- // The constructor takes in a reference to the nodes
- // used in the snapin and saves it
- //-------------------------------------------------
- public CComponent(ref CNode[] nodes)
- {
- m_Nodes = nodes;
-
- int hModule = Marshal.GetHINSTANCE(this.GetType().Module);
-
- // Load the bitmap that will be displayed in the menubar
- m_hToolbarBMP = LoadImage(hModule,
- "IDB_BLACK",
- IMAGE.BITMAP,
- 16,
- 16,
- 0);
- }// CComponent
-
- //-------------------------------------------------
- // Initialize
- //
- // This is where we'll get the interfaces for
- // IConsole2 and IDisplayHelp
- //-------------------------------------------------
- public void Initialize(Object pConsole)
- {
- try
- {
- // Let's query for the interfaces needed
- m_Console = (IConsole2)pConsole;
- Marshal.AddRef(Marshal.GetIUnknownForObject(m_Console));
-
-
- m_DisplayHelp = (IDisplayHelp)pConsole;
- Marshal.AddRef(Marshal.GetIUnknownForObject(m_DisplayHelp));
-
-
- }
- catch(Exception e)
- {
- throw new Exception("IComponent::Initialize - Unable to query interfaces. Received: " + e.ToString());
- }
- }// Initialize
-
- //-------------------------------------------------
- // Notify
- //
- // This is where most of the interesting stuff happens.
- // Whenever MMC needs something from the snapin, it will
- // send a message to Notify, and notify is responsible
- // to take care (or delegate) whatever MMC wants
- //-------------------------------------------------
- public void Notify(IDataObject lpDataObject, uint aevent, int arg, int param)
- {
- CDO Data; // This will hold the object MMC wants action performed on
-
- // lpDataObject is just a CDO... we're going to obtain the CDO interface.
- // if lpDataObject is null, then there needs to be action performed on the root
- // node.
-
-
- if (lpDataObject != null)
- Data = (CDO)lpDataObject;
- else
- Data = new CDO(ref m_Nodes[0]);
-
- switch(aevent)
- {
- // The selected item needs to show something in the result pane
- case MMCN.SHOW:
- Data.Node.onShow(m_Console, arg, param);
- break;
-
- // If an item is selected, we should set flags for verbs available
- // for the item (from the dropdown menu)
- case MMCN.SELECT:
-
- IConsoleVerb icv;
- // Get the IConsoleVerb interface from MMC
- m_Console.QueryConsoleVerb(out icv);
-
- Marshal.AddRef(Marshal.GetIUnknownForObject(icv));
- // See if we need to enable then property sheets item on the popup menu
- if (Data.Node.HavePropertyPages)
- icv.SetVerbState(MMC_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 1);
- else
- icv.SetVerbState(MMC_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 0);
-
- Marshal.ReleaseComObject(icv);
-
-
- break;
-
- // This is to add images for the result pane
- case MMCN.ADD_IMAGES:
-
- // arg actually contains the IImageList interface. We need to tell
- // C# that it is a Object and not a integer.
- IImageList il = (IImageList)Marshal.GetObjectForIUnknown (arg);
-
- // param contains the HScopeItem. Let's get the node it represents
- CNode nLuckyGuy = FindNodeByHScope(param);
-
- // Add this item's image
- il.ImageListSetIcon(nLuckyGuy.IconHandle, nLuckyGuy.Cookie);
-
- // Now add all the children images
- for(int i=0; i<nLuckyGuy.NumChildren; i++)
- il.ImageListSetIcon(nLuckyGuy.Child[i].IconHandle, nLuckyGuy.Child[i].Cookie);
-
- // Now add any images that the node might have for it's listview
- if (nLuckyGuy.m_oResults != null && nLuckyGuy.m_oResults is IColumnResultView)
- ((IColumnResultView)nLuckyGuy.m_oResults).AddImages(ref il);
-
- break;
-
- // This is if the user double clicks on the result pane
- case MMCN.DBLCLICK:
- // We want to expand the item being clicked and select the item
- m_Console.Expand(Data.Node.HScopeItem, 1);
- m_Console.SelectScopeItem(Data.Node.HScopeItem);
- break;
-
-
- case MMCN.CONTEXTHELP:
- // If we have context help for this Node, display it
- if (!Data.Node.HelpSection.Equals(""))
- m_DisplayHelp.ShowTopic(Data.Node.HelpSection);
- break;
-
- default:
- // We don't support the Notification message we got
- throw new ExternalException("", HRESULT.S_FALSE);
- }
- }// Notify
-
- //-------------------------------------------------
- // Destroy
- //
- // This cleans up whatever needs to be cleaned up.
- //-------------------------------------------------
- public void Destroy(int i)
- {
- Marshal.ReleaseComObject(m_Console);
- Marshal.ReleaseComObject(m_DisplayHelp);
- Marshal.ReleaseComObject(m_Toolbar);
-
- if (m_hToolbarBMP != 0)
- DeleteObject(m_hToolbarBMP);
- }// Destroy
-
- //-------------------------------------------------
- // QueryDataObject
- //
- // When MMC wants a data object for a specific cookie,
- // this function will be called.
- //-------------------------------------------------
- public void QueryDataObject(int cookie, uint type, out IDataObject ppDataObject)
- {
- ppDataObject = new CDO(ref m_Nodes[cookie]);
- }// QueryDataObject
-
- //-------------------------------------------------
- // GetResultViewType
- //
- // This function is called when MMC needs to display
- // a specific node's information in the result pane.
- //-------------------------------------------------
- public void GetResultViewType(int cookie, out int ppViewType, out int pViewOptions)
- {
- // If this is not null, then we have a HTML page to display in the result pane
- if (m_Nodes[cookie].Result == null)
- {
- ExternalException e = new ExternalException("CComponent::GetResultViewType", HRESULT.S_FALSE);
- throw e;
- }
-
- // Ok, we're displaying a HTML page
- ppViewType=Marshal.StringToCoTaskMemUni(m_Nodes[cookie].Result);
- pViewOptions=0;
- }// GetResultViewType
-
- //-------------------------------------------------
- // GetDisplayInfo
- //
- // This function is called by MMC whenever it needs to
- // display a node in the result view.
- //-------------------------------------------------
- public void GetDisplayInfo(ref RESULTDATAITEM ResultDataItem)
- {
- // The low word in the lParam contains the index of the node
- // we're interested in.
- CNode NodeWeWant = m_Nodes[(int)ResultDataItem.lParam & 0xffff];
-
- // We'll let the node take care of its own Result Data
- NodeWeWant.GetDisplayInfo(ref ResultDataItem);
- }// GetDisplayInfo
-
- //-------------------------------------------------
- // CompareObjects
- //
- // This function will compare two data objects. In this
- // snapin, if the cookies are identical for each data object,
- // then the items are the same
- //-------------------------------------------------
- public void CompareObjects(IDataObject lpDataObjectA, IDataObject lpDataObjectB)
- {
- CDO doItem1, doItem2;
-
- // These data items should be CDO's in disguise.....
- doItem1 = (CDO)lpDataObjectA;
- doItem2 = (CDO)lpDataObjectB;
-
- if (doItem1.Node.Cookie != doItem2.Node.Cookie)
- {
- // These are different objects. We need to return S_FALSE
- ExternalException e = new ExternalException("CComponent::CompareObjects", HRESULT.S_FALSE);
- throw e;
- }
-
- // else we return S_OK automatically
- }// CompareObjects
-
- //-------------------------------------------------------
- // Methods to extend IContextMenu
- //-------------------------------------------------------
-
- //-------------------------------------------------
- // AddMenuItems
- //
- // This function allows us to add items to the context menus
- //-------------------------------------------------
- public void AddMenuItems(IDataObject piDataObject, IContextMenuCallback piCallback, ref int pInsertionAllowed)
- {
- // The piDataObject is really a CDO is disguise....
- CDO item = (CDO)piDataObject;
-
- // We only want to add this menu item for the teams
- if (item.Node.Cookie >= 3)
- // See if we're allowed to insert an item in the "view" section
- if ((pInsertionAllowed & (int)CCM.INSERTIONALLOWED_VIEW) > 0)
- {
- // Let's add "Refresh Page" the the "view" menu
- CONTEXTMENUITEM newitem = new CONTEXTMENUITEM();
-
- newitem.strName = Marshal.StringToCoTaskMemUni("Refresh page");
- newitem.strStatusBarText = Marshal.StringToCoTaskMemUni("Refresh page");
- newitem.lCommandID = 0;
- newitem.lInsertionPointID = CCM.INSERTIONPOINTID_PRIMARY_VIEW;
- newitem.fFlags = 0;
- newitem.fSpecialFlags=0;
-
- // Now add this item through the callback
- piCallback.AddItem(ref newitem);
- }
- }// AddMenuItems
-
- //-------------------------------------------------
- // Command
- //
- // This function is called whenever an item that we
- // added to the context menus is called
- //-------------------------------------------------
- public void Command(int lCommandID, IDataObject piDataObject)
- {
- // Check to see if this is out "Refresh Page" command
- if (lCommandID == 0)
- {
- CDO item = (CDO)piDataObject;
- // To refresh the page, we just need to select it again.
- m_Console.SelectScopeItem(item.Node.HScopeItem);
-
- }
- }// Command
-
- //-------------------------------------------------------
- // Methods for IExtendControlbar
- //-------------------------------------------------------
-
- //-------------------------------------------------
- // SetControlbar
- //
- // This function will add items to the toolbar
- //-------------------------------------------------
- public void SetControlbar(IControlbar pControlbar)
- {
- if (pControlbar != null)
- {
- Object newcontrol;
- // Create a toolbar that we can "integrate" into the default toolbar
- pControlbar.Create(MMC_CONTROL_TYPE.TOOLBAR, this, out newcontrol);
-
- m_Toolbar = (IToolbar)newcontrol;
-
- Marshal.AddRef(Marshal.GetIUnknownForObject(m_Toolbar));
-
- // Add our bitmap to the toolbar's imagelist
- m_Toolbar.AddBitmap(1, m_hToolbarBMP, 16, 16, 0x00FFFFFF);
-
- // Now create the button we'll be adding to the toolbar
- MMCBUTTON newButton = new MMCBUTTON();
- newButton.nBitmap = 0;
- newButton.idCommand = 1;
- newButton.fsState = TBSTATE.ENABLED;
- newButton.fsType = TBSTYLE.BUTTON;
- newButton.lpButtonText = Marshal.StringToCoTaskMemUni("Go to the Black Page");
- newButton.lpTooltipText = Marshal.StringToCoTaskMemUni("This button will take you to the Black page");
-
- m_Toolbar.AddButtons(1, ref newButton);
-
- // Now attach the toolbar we just created to MMC's toolbar
- pControlbar.Attach(MMC_CONTROL_TYPE.TOOLBAR, m_Toolbar);
- }
- }// SetControlbar
-
- //-------------------------------------------------
- // ControlbarNotify
- //
- // This function is called whenever one of our added
- // buttons on the toolbar is click
- //-------------------------------------------------
- public void ControlbarNotify(uint aevent, int arg, int param)
- {
- // If they clicked a button......
- if (aevent == MMCN.BTN_CLICK)
- {
- // Query the Console interface we have for the namespace
- IConsoleNameSpace2 ConsoleNameSpace = (IConsoleNameSpace2)m_Console;
-
- // If they clicked our button we added
- // (This check is unnecessary since we only added one button
- if (param == 1)
- {
- // We want to open up the tree and center on the black icon.
-
- // We'll expand the root node for kicks...
- ConsoleNameSpace.Expand((uint)m_Nodes[0].HScopeItem);
- // Now we'll expand each parent node for this guy
- ConsoleNameSpace.Expand((uint)m_Nodes[1].HScopeItem);
- // Now let's set the focus on the black node
- m_Console.SelectScopeItem(m_Nodes[3].HScopeItem);
- }
- }
-
- // Else we don't handle the event
- else
- {
- ExternalException e = new ExternalException("", HRESULT.S_FALSE);
- throw e;
- }
-
- }// ControlbarNotify
-
- //-------------------------------------------------------
- // Functions that are not a part of any interface
- //-------------------------------------------------------
-
- //-------------------------------------------------
- // FindNodeByHScope
- //
- // This function will look through the array of nodes
- // and look for the node with the matching HScopeID
- //-------------------------------------------------
- private CNode FindNodeByHScope(int HScopeID)
- {
- int i=0;
-
- while(i<m_Nodes.Length && HScopeID != m_Nodes[i].HScopeItem)
- i++;
-
- // If we didn't find a match (we hit the end of the list) return null
- if (i == m_Nodes.Length)
- return null;
-
- return m_Nodes[i];
- }// FindNodeByHScope
-
- //-------------------------------------------------
- // We need to import the Win32 API calls used to deal with
- // image loading.
- //-------------------------------------------------
- [DllImport("user32.dll")]
- public static extern int LoadImage(int hinst, String lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad);
- [DllImport("gdi32.dll")]
- public static extern int DeleteObject(int hObject);
-
- }// class CComponent
- }// namespace Microsoft.SampleMMC
-