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

  1. //-------------------------------------------------------------
  2. // CDO.cs
  3. //
  4. // This implements the object that is responsible for transfering
  5. // data about nodes to the MMC.
  6. //-------------------------------------------------------------
  7. using System;
  8. using System.Runtime.InteropServices;
  9.  
  10.  
  11. namespace Microsoft.SampleMMC
  12. {
  13.  
  14. public class CDO : IDataObject
  15. {
  16.     private ushort      m_cfDisplayName; // Clipboard format # for Display Name
  17.     private ushort      m_cfNodeType;    // Clipboard format # for NodeType
  18.     private ushort      m_cfSZNodeType;  // Clipboard format # for SZNodeType
  19.     private ushort      m_cfSnapinClsid; // Clipboard format # for SnapinClsid
  20.     
  21.     private CNode       m_NodeData;      // The node that this Data object is
  22.                                          // responsible for
  23.  
  24.     //-------------------------------------------------
  25.     // CDO
  26.     //
  27.     // The constructor is responsible for loading the about images
  28.     // that will be displayed in the MMC
  29.     //-------------------------------------------------
  30.     public CDO(ref CNode initData)
  31.     {
  32.         // Set the Node this Data Object will be responsible for
  33.         m_NodeData = initData;
  34.  
  35.         // Get the Clipboard Format Numbers for these various items.
  36.         // MMC should have already registered these Clipboard Formats,
  37.         // so this call just gives us the id assigned for each format.
  38.         
  39.         m_cfDisplayName = RegisterClipboardFormat("CCF_DISPLAY_NAME");
  40.         m_cfNodeType = RegisterClipboardFormat("CCF_NODETYPE");
  41.         m_cfSZNodeType = RegisterClipboardFormat("CCF_SZNODETYPE");
  42.         m_cfSnapinClsid = RegisterClipboardFormat("CCF_SNAPIN_CLASSID");
  43.     }// CDO
  44.     
  45.     //-------------------------------------------------
  46.     // Node
  47.     //
  48.     // Provides access to the Data Object's Node
  49.     //-------------------------------------------------
  50.     public CNode Node
  51.     {
  52.         get
  53.         {
  54.             return m_NodeData;
  55.         }
  56.     }// Node
  57.     
  58.     //-------------------------------------------------
  59.     // GetDataHere
  60.     //
  61.     // This function will send certain data to the MMC. Note
  62.     // this function uses the "unsafe" context... we need to
  63.     // send a pointer to a byte array to IStream:Write, and this
  64.     // is the easiest way to do it.
  65.     //-------------------------------------------------
  66.     public unsafe void GetDataHere(ref FORMATETC pFormatEtc, ref STGMEDIUM pMedium)
  67.     {
  68.         IStream         pStream=null;   
  69.         byte[]           bDataToSend;
  70.         int             iLengthOfData;
  71.         uint             iDataSent=0;
  72.         
  73.         try
  74.         {
  75.         // We'll send this array if we don't know what to send
  76.         byte[] Nothing = {0x0, 0x0};
  77.  
  78.         ushort cf = (ushort)pFormatEtc.cfFormat;
  79.  
  80.         CreateStreamOnHGlobal(pMedium.hGlobal, 0, out pStream );
  81.  
  82.         // If we couldn't open a global handle....
  83.         if (pStream == null)
  84.         {
  85.             throw new ExternalException("CDO::GetDataHere - Fail on CreateStreamOnHGlobal");
  86.         }
  87.  
  88.         Marshal.AddRef(Marshal.GetIUnknownForObject(pStream));
  89.  
  90.         // Let's determine what data we need to send.
  91.         if (cf == m_cfDisplayName)
  92.            bDataToSend = m_NodeData.bDisplayName;
  93.         else if (cf == m_cfNodeType)
  94.            bDataToSend= m_NodeData.bGuid;
  95.         else if (cf == m_cfSZNodeType)
  96.            bDataToSend = Nothing;
  97.         else if (cf == m_cfSnapinClsid)
  98.         {
  99.             // The GUID for this snapin
  100.             byte[] CLSID =  {9,4,0xb,9,0xd, 5, 1, 0xf, 
  101.                                       0xc, 8, 7, 4,
  102.                                       4, 0xd, 0xa, 0,
  103.                                       0xb, 0xc, 1, 3, 
  104.                                       0xf, 0xd, 0xa, 9, 4, 0xc, 0xb, 0xf, 7, 2, 0xd, 0xe};
  105.             bDataToSend = CLSID;
  106.  
  107.         }
  108.         else // We don't know what to send
  109.            bDataToSend = Nothing;
  110.  
  111.         iLengthOfData = bDataToSend.Length;
  112.  
  113.         // NOTE: the use of pointers is only possible because the function was marked
  114.         // unsafe. Also, pData will only point to a valid address inside the "fixed"
  115.         // block... outside of the "fixed" block the GC could move our memory around, resulting
  116.         // in pData pointing to garbage.
  117.         fixed(byte* pData = bDataToSend)
  118.         {
  119.             pStream.Write((int)pData, (uint)iLengthOfData, out iDataSent);
  120.         }
  121.  
  122.         // Close/Flush the stream
  123.         Marshal.ReleaseComObject(pStream);
  124.  
  125.         // We'll create a object so unmanaged code won't try to free this memory.
  126.         pMedium.pUnkForRelease = new Object();
  127.  
  128.         }
  129.         catch(Exception)
  130.         {
  131.             if (pStream != null)
  132.                 Marshal.ReleaseComObject(pStream);
  133.         }
  134.     }// GetDataHere
  135.  
  136.     //-------------------------------------------------
  137.     // Other IDataObject Methods
  138.     //
  139.     // We don't need to implement any of these other 
  140.     // methods, so if they are called, we'll just return
  141.     // E_NOTIMPL
  142.     //-------------------------------------------------
  143.  
  144.     public void GetData(ref FORMATETC a, ref STGMEDIUM b)
  145.     {
  146.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  147.     }// GetData
  148.  
  149.     public void QueryGetData(ref FORMATETC a)
  150.     {
  151.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  152.     }// QueryGetData
  153.  
  154.     public void GetCanonicalFormatEtc(ref FORMATETC a, out FORMATETC b)
  155.     {
  156.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  157.     }// GetCanonicalFormatEtc
  158.  
  159.     public void SetData(ref FORMATETC a, ref userFLAG_STGMEDIUM b, int c)
  160.     {
  161.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  162.     }// SetData
  163.     
  164.     public void EnumFormatEtc(uint a, out Object b)
  165.     {
  166.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  167.     }// EnumFormatEtc
  168.     
  169.     public void DAdvise(ref FORMATETC a, uint b, ref Object c, out uint d)
  170.     {
  171.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  172.     }// DAdvise
  173.  
  174.     public void DUnadvise(uint a)
  175.     {
  176.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  177.     }// DUnadvise
  178.  
  179.     public void EnumDAdvise(out Object a)
  180.     {
  181.         throw new ExternalException("", HRESULT.E_NOTIMPL);
  182.     }// EnumDAdvise
  183.  
  184.     //-------------------------------------------------
  185.     // We need to import the Win32 API calls used to deal with
  186.     // clipboard formats and HGlobal streams.
  187.     //-------------------------------------------------
  188.  
  189.     [DllImport("ole32.dll")]
  190.     public static extern int CreateStreamOnHGlobal(int hGlobal, int fDeleteOnRelease, out IStream ppstm);
  191.  
  192.     // All the MMC stuff is done in Unicode, which is why we're using
  193.     // that character set here
  194.   
  195.     [DllImport("user32.dll", CharSet=CharSet.Unicode)]
  196.     public static extern ushort RegisterClipboardFormat(String format);
  197.     
  198. }// class CDO
  199. }// namespace Microsoft.SampleMMC
  200.