home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples.exe / mmc / CComponent.cs < prev    next >
Encoding:
Text File  |  2000-06-23  |  15.7 KB  |  413 lines

  1. //-------------------------------------------------------------
  2. // CComponent.cs
  3. //
  4. // This implements the IComponent, IExtendContextMenu and 
  5. // IExtendControlbar MMC interfaces
  6. //-------------------------------------------------------------
  7. using System;
  8. using System.Runtime.InteropServices;
  9.  
  10.  
  11. namespace Microsoft.SampleMMC
  12. {
  13. public class CComponent: IComponent, IExtendContextMenu, IExtendControlbar
  14. {
  15.     
  16.     private IConsole2     m_Console;        // Holds the MMC Console interface
  17.     private CNode[]       m_Nodes;          // A reference to an array of the Nodes in the snapin
  18.     private IDisplayHelp  m_DisplayHelp;    // Holds the MMC IDisplayHelp interface
  19.     private IToolbar      m_Toolbar;        // Holds the MMC IToolbar interface
  20.     private int           m_hToolbarBMP;    // Holds the bitmap for the toolbar
  21.  
  22.     //-------------------------------------------------
  23.     // CComponent
  24.     //
  25.     // The constructor takes in a reference to the nodes
  26.     // used in the snapin and saves it
  27.     //-------------------------------------------------
  28.     public CComponent(ref CNode[] nodes)
  29.     {
  30.         m_Nodes = nodes;
  31.  
  32.         int hModule = Marshal.GetHINSTANCE(this.GetType().Module);
  33.         
  34.         // Load the bitmap that will be displayed in the menubar
  35.         m_hToolbarBMP = LoadImage(hModule,
  36.                                   "IDB_BLACK",
  37.                                   IMAGE.BITMAP,
  38.                                   16,
  39.                                   16,
  40.                                   0);
  41.     }// CComponent
  42.  
  43.     //-------------------------------------------------
  44.     // Initialize
  45.     //
  46.     // This is where we'll get the interfaces for
  47.     // IConsole2 and IDisplayHelp 
  48.     //-------------------------------------------------
  49.     public void Initialize(Object pConsole)
  50.     { 
  51.         try
  52.         {
  53.           // Let's query for the interfaces needed
  54.             m_Console = (IConsole2)pConsole;
  55.             Marshal.AddRef(Marshal.GetIUnknownForObject(m_Console));
  56.  
  57.  
  58.             m_DisplayHelp = (IDisplayHelp)pConsole;
  59.             Marshal.AddRef(Marshal.GetIUnknownForObject(m_DisplayHelp));
  60.  
  61.  
  62.         }
  63.         catch(Exception e)
  64.         {
  65.           throw new Exception("IComponent::Initialize - Unable to query interfaces. Received: " + e.ToString());
  66.         }
  67.     }// Initialize
  68.     
  69.     //-------------------------------------------------
  70.     // Notify
  71.     //
  72.     // This is where most of the interesting stuff happens.
  73.     // Whenever MMC needs something from the snapin, it will
  74.     // send a message to Notify, and notify is responsible 
  75.     // to take care (or delegate) whatever MMC wants
  76.     //-------------------------------------------------
  77.     public void Notify(IDataObject lpDataObject, uint aevent, int arg, int param)
  78.     {
  79.         CDO Data;    // This will hold the object MMC wants action performed on
  80.  
  81.         // lpDataObject is just a CDO... we're going to obtain the CDO interface.
  82.         // if lpDataObject is null, then there needs to be action performed on the root
  83.         // node.
  84.  
  85.         
  86.         if (lpDataObject != null)
  87.             Data = (CDO)lpDataObject;
  88.         else
  89.             Data = new CDO(ref m_Nodes[0]);
  90.         
  91.         switch(aevent)
  92.         {
  93.             // The selected item needs to show something in the result pane
  94.             case MMCN.SHOW:
  95.                 Data.Node.onShow(m_Console, arg, param);
  96.                 break;
  97.  
  98.             // If an item is selected, we should set flags for verbs available
  99.             // for the item (from the dropdown menu)
  100.             case MMCN.SELECT:
  101.  
  102.                 IConsoleVerb icv;       
  103.                 // Get the IConsoleVerb interface from MMC
  104.                 m_Console.QueryConsoleVerb(out icv);
  105.  
  106.                 Marshal.AddRef(Marshal.GetIUnknownForObject(icv));
  107.                 // See if we need to enable then property sheets item on the popup menu
  108.                 if (Data.Node.HavePropertyPages)
  109.                     icv.SetVerbState(MMC_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 1);
  110.                 else
  111.                     icv.SetVerbState(MMC_VERB.PROPERTIES, MMC_BUTTON_STATE.ENABLED, 0);
  112.  
  113.                 Marshal.ReleaseComObject(icv);
  114.  
  115.  
  116.                 break;
  117.  
  118.             // This is to add images for the result pane
  119.             case MMCN.ADD_IMAGES:
  120.  
  121.                 // arg actually contains the IImageList interface. We need to tell
  122.                 // C# that it is a Object and not a integer.
  123.                 IImageList il = (IImageList)Marshal.GetObjectForIUnknown (arg);
  124.  
  125.                 // param contains the HScopeItem. Let's get the node it represents
  126.                 CNode nLuckyGuy = FindNodeByHScope(param);
  127.  
  128.                 // Add this item's image
  129.                 il.ImageListSetIcon(nLuckyGuy.IconHandle, nLuckyGuy.Cookie);
  130.  
  131.                 // Now add all the children images
  132.                 for(int i=0; i<nLuckyGuy.NumChildren; i++)
  133.                     il.ImageListSetIcon(nLuckyGuy.Child[i].IconHandle, nLuckyGuy.Child[i].Cookie);
  134.  
  135.                 // Now add any images that the node might have for it's listview
  136.                 if (nLuckyGuy.m_oResults != null && nLuckyGuy.m_oResults is IColumnResultView)
  137.                     ((IColumnResultView)nLuckyGuy.m_oResults).AddImages(ref il);
  138.                     
  139.                 break;  
  140.  
  141.             // This is if the user double clicks on the result pane
  142.             case MMCN.DBLCLICK:
  143.                 // We want to expand the item being clicked and select the item
  144.                 m_Console.Expand(Data.Node.HScopeItem, 1);
  145.                 m_Console.SelectScopeItem(Data.Node.HScopeItem);
  146.                 break;
  147.  
  148.                 
  149.             case MMCN.CONTEXTHELP:
  150.                 // If we have context help for this Node, display it
  151.                 if (!Data.Node.HelpSection.Equals(""))
  152.                     m_DisplayHelp.ShowTopic(Data.Node.HelpSection);
  153.                 break;
  154.  
  155.             default:
  156.                 // We don't support the Notification message we got
  157.                 throw new ExternalException("", HRESULT.S_FALSE);
  158.         }
  159.     }// Notify
  160.  
  161.     //-------------------------------------------------
  162.     // Destroy
  163.     //
  164.     // This cleans up whatever needs to be cleaned up.
  165.     //-------------------------------------------------
  166.     public void Destroy(int i)
  167.     {
  168.         Marshal.ReleaseComObject(m_Console);
  169.         Marshal.ReleaseComObject(m_DisplayHelp);
  170.         Marshal.ReleaseComObject(m_Toolbar);
  171.  
  172.         if (m_hToolbarBMP != 0)
  173.             DeleteObject(m_hToolbarBMP);
  174.     }// Destroy
  175.     
  176.     //-------------------------------------------------
  177.     // QueryDataObject
  178.     //
  179.     // When MMC wants a data object for a specific cookie,
  180.     // this function will be called.
  181.     //-------------------------------------------------
  182.     public void QueryDataObject(int cookie, uint type, out IDataObject ppDataObject)
  183.     {
  184.         ppDataObject = new CDO(ref m_Nodes[cookie]); 
  185.     }// QueryDataObject
  186.     
  187.     //-------------------------------------------------
  188.     // GetResultViewType
  189.     //
  190.     // This function is called when MMC needs to display
  191.     // a specific node's information in the result pane.
  192.     //-------------------------------------------------
  193.     public void GetResultViewType(int cookie, out int ppViewType, out int pViewOptions)
  194.     {
  195.         // If this is not null, then we have a HTML page to display in the result pane
  196.         if (m_Nodes[cookie].Result == null)
  197.         {
  198.             ExternalException e = new ExternalException("CComponent::GetResultViewType", HRESULT.S_FALSE);
  199.             throw e;
  200.         }
  201.  
  202.         // Ok, we're displaying a HTML page
  203.         ppViewType=Marshal.StringToCoTaskMemUni(m_Nodes[cookie].Result);
  204.         pViewOptions=0;
  205.     }// GetResultViewType
  206.  
  207.     //-------------------------------------------------
  208.     // GetDisplayInfo
  209.     //
  210.     // This function is called by MMC whenever it needs to
  211.     // display a node in the result view.
  212.     //-------------------------------------------------
  213.     public void GetDisplayInfo(ref RESULTDATAITEM ResultDataItem)
  214.     {
  215.         // The low word in the lParam contains the index of the node
  216.         // we're interested in.
  217.         CNode NodeWeWant = m_Nodes[(int)ResultDataItem.lParam & 0xffff];
  218.  
  219.         // We'll let the node take care of its own Result Data
  220.         NodeWeWant.GetDisplayInfo(ref ResultDataItem);
  221.     }// GetDisplayInfo
  222.     
  223.     //-------------------------------------------------
  224.     // CompareObjects
  225.     //
  226.     // This function will compare two data objects. In this
  227.     // snapin, if the cookies are identical for each data object,
  228.     // then the items are the same
  229.     //-------------------------------------------------
  230.     public void CompareObjects(IDataObject lpDataObjectA, IDataObject lpDataObjectB)
  231.     {
  232.         CDO doItem1, doItem2;
  233.  
  234.         // These data items should be CDO's in disguise.....
  235.         doItem1 = (CDO)lpDataObjectA;
  236.         doItem2 = (CDO)lpDataObjectB;
  237.         
  238.         if (doItem1.Node.Cookie != doItem2.Node.Cookie)
  239.         {
  240.             // These are different objects. We need to return S_FALSE
  241.            ExternalException e = new ExternalException("CComponent::CompareObjects", HRESULT.S_FALSE);
  242.            throw e;
  243.         }
  244.  
  245.         // else we return S_OK automatically
  246.     }// CompareObjects
  247.  
  248.     //-------------------------------------------------------
  249.     // Methods to extend IContextMenu
  250.     //-------------------------------------------------------
  251.  
  252.     //-------------------------------------------------
  253.     // AddMenuItems
  254.     //
  255.     // This function allows us to add items to the context menus
  256.     //-------------------------------------------------
  257.     public void AddMenuItems(IDataObject piDataObject, IContextMenuCallback piCallback, ref int pInsertionAllowed)
  258.     {
  259.         // The piDataObject is really a CDO is disguise....
  260.         CDO item = (CDO)piDataObject;
  261.  
  262.         // We only want to add this menu item for the teams
  263.         if (item.Node.Cookie >= 3)
  264.          // See if we're allowed to insert an item in the "view" section
  265.          if ((pInsertionAllowed & (int)CCM.INSERTIONALLOWED_VIEW) > 0)
  266.          {
  267.             // Let's add "Refresh Page" the the "view" menu
  268.             CONTEXTMENUITEM newitem = new CONTEXTMENUITEM();
  269.  
  270.             newitem.strName = Marshal.StringToCoTaskMemUni("Refresh page");
  271.             newitem.strStatusBarText = Marshal.StringToCoTaskMemUni("Refresh page");
  272.             newitem.lCommandID = 0;
  273.             newitem.lInsertionPointID = CCM.INSERTIONPOINTID_PRIMARY_VIEW;
  274.             newitem.fFlags = 0;
  275.             newitem.fSpecialFlags=0;
  276.  
  277.             // Now add this item through the callback
  278.             piCallback.AddItem(ref newitem);
  279.          }
  280.     }// AddMenuItems
  281.  
  282.     //-------------------------------------------------
  283.     // Command
  284.     //
  285.     // This function is called whenever an item that we
  286.     // added to the context menus is called
  287.     //-------------------------------------------------
  288.     public void Command(int lCommandID, IDataObject piDataObject)
  289.     {
  290.         // Check to see if this is out "Refresh Page" command
  291.         if (lCommandID == 0)
  292.         {
  293.           CDO item = (CDO)piDataObject;
  294.           // To refresh the page, we just need to select it again.
  295.           m_Console.SelectScopeItem(item.Node.HScopeItem);
  296.                
  297.         }
  298.     }// Command
  299.  
  300.     //-------------------------------------------------------
  301.     // Methods for IExtendControlbar
  302.     //-------------------------------------------------------
  303.  
  304.     //-------------------------------------------------
  305.     // SetControlbar
  306.     //
  307.     // This function will add items to the toolbar
  308.     //-------------------------------------------------
  309.      public void SetControlbar(IControlbar pControlbar)
  310.      {
  311.         if (pControlbar != null)
  312.         {
  313.            Object newcontrol;
  314.            // Create a toolbar that we can "integrate" into the default toolbar
  315.            pControlbar.Create(MMC_CONTROL_TYPE.TOOLBAR, this, out newcontrol);
  316.  
  317.            m_Toolbar = (IToolbar)newcontrol;
  318.  
  319.            Marshal.AddRef(Marshal.GetIUnknownForObject(m_Toolbar));
  320.  
  321.            // Add our bitmap to the toolbar's imagelist                                      
  322.            m_Toolbar.AddBitmap(1, m_hToolbarBMP, 16, 16, 0x00FFFFFF);
  323.  
  324.            // Now create the button we'll be adding to the toolbar
  325.            MMCBUTTON    newButton = new MMCBUTTON();
  326.            newButton.nBitmap = 0;
  327.            newButton.idCommand = 1;
  328.            newButton.fsState = TBSTATE.ENABLED;
  329.            newButton.fsType = TBSTYLE.BUTTON;
  330.            newButton.lpButtonText = Marshal.StringToCoTaskMemUni("Go to the Black Page");
  331.            newButton.lpTooltipText = Marshal.StringToCoTaskMemUni("This button will take you to the Black page");
  332.                             
  333.            m_Toolbar.AddButtons(1, ref newButton);
  334.  
  335.            // Now attach the toolbar we just created to MMC's toolbar 
  336.            pControlbar.Attach(MMC_CONTROL_TYPE.TOOLBAR, m_Toolbar);
  337.         }
  338.      }// SetControlbar
  339.  
  340.     //-------------------------------------------------
  341.     // ControlbarNotify
  342.     //
  343.     // This function is called whenever one of our added
  344.     // buttons on the toolbar is click
  345.     //-------------------------------------------------
  346.      public void ControlbarNotify(uint aevent, int arg, int param)
  347.      {
  348.         // If they clicked a button......
  349.         if (aevent == MMCN.BTN_CLICK)
  350.         {
  351.             // Query the Console interface we have for the namespace
  352.             IConsoleNameSpace2 ConsoleNameSpace = (IConsoleNameSpace2)m_Console;
  353.  
  354.             // If they clicked our button we added
  355.             // (This check is unnecessary since we only added one button
  356.             if (param == 1)
  357.             {
  358.                 // We want to open up the tree and center on the black icon.
  359.                 
  360.                 // We'll expand the root node for kicks...
  361.                 ConsoleNameSpace.Expand((uint)m_Nodes[0].HScopeItem);
  362.                 // Now we'll expand each parent node for this guy
  363.                 ConsoleNameSpace.Expand((uint)m_Nodes[1].HScopeItem);
  364.                 // Now let's set the focus on the black node
  365.                 m_Console.SelectScopeItem(m_Nodes[3].HScopeItem);   
  366.             }
  367.         }
  368.         
  369.         // Else we don't handle the event
  370.         else
  371.         {
  372.             ExternalException e = new ExternalException("", HRESULT.S_FALSE);
  373.             throw e;
  374.         }
  375.         
  376.      }// ControlbarNotify
  377.  
  378.     //-------------------------------------------------------
  379.     // Functions that are not a part of any interface
  380.     //-------------------------------------------------------
  381.  
  382.     //-------------------------------------------------
  383.     // FindNodeByHScope
  384.     //
  385.     // This function will look through the array of nodes
  386.     // and look for the node with the matching HScopeID
  387.     //-------------------------------------------------
  388.     private CNode FindNodeByHScope(int HScopeID)
  389.     {
  390.         int i=0;
  391.  
  392.         while(i<m_Nodes.Length && HScopeID != m_Nodes[i].HScopeItem)
  393.             i++;
  394.  
  395.         // If we didn't find a match (we hit the end of the list) return null
  396.         if (i == m_Nodes.Length)
  397.             return null;
  398.  
  399.         return m_Nodes[i];
  400.     }// FindNodeByHScope
  401.  
  402.     //-------------------------------------------------
  403.     // We need to import the Win32 API calls used to deal with
  404.     // image loading.
  405.     //-------------------------------------------------
  406.     [DllImport("user32.dll")]
  407.     public static extern int LoadImage(int hinst, String lpszName,  uint uType, int cxDesired, int cyDesired, uint fuLoad);
  408.     [DllImport("gdi32.dll")]
  409.     public static extern int DeleteObject(int hObject);
  410.  
  411. }// class CComponent
  412. }// namespace Microsoft.SampleMMC
  413.