views:

597

answers:

3

I have created a .NET user control with an ActiveX interface. It works well.

Now, I want to be able to read and write from the property bag for the ActiveX interface.

How would I do this?

+1  A: 

The easiest is to use client script to pass the parameters values to the ActiveX

<html xmlns="http://www.w3.org/1999/xhtml" >

    function Rundata(file) 
    {            
        var winCtrl = document.getElementById("YourActiveX");                     
        winCtrl.Option1 = file;             
        winCtrl.WriteToFile();        
    }

    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

    <asp:Button runat="server" ID="Button1" OnClientClick="javascript:Rundata('valuetoRetrieve2');" />
</div>
</form>

If you can't use client script, you can try that way:

Let's say you want to read a parameter such as:

<object id="YourActiveX" classid="clsid:6b1bdf22-1c1d-774e-cd9d-1d1aaf7fd88f" 
 width="300px" height="200px">
 <param name="option1" value="valuetoRetrieve" />
 </object>

You need to expose the following COM interfaces in your project:

[ComImport]
[Guid("55272A00-42CB-11CE-8135-00AA004BB851")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyBag
{
    void Write([InAttribute] string propName, [InAttribute] ref Object ptrVar);
    void Read([InAttribute] string propName, out Object ptrVar, int errorLog);
}

[ComImport]
[Guid("37D84F60-42CB-11CE-8135-00AA004BB851")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersistPropertyBag
{

    [PreserveSig]
    void InitNew();

    [PreserveSig]
    void Load(IPropertyBag propertyBag, int errorLog);

    [PreserveSig]
    void Save(IPropertyBag propertyBag, [InAttribute] bool clearDirty, [InAttribute] bool saveAllProperties);

    [PreserveSig]
    void GetClassID(out Guid classID);
}

Your activeX control should implement these interfaces. There's one method you need to implement :

void IPersistPropertyBag.Load(IPropertyBag propertyBag, int errorLog) 
    {
        object value; 
        propertyBag.Read("option1", out value, errorLog);  
        string parameter = (string)value;
    }

Voilà! parameter should be equal to "valuetoRetrieve"

teebot.be
+1  A: 

I was trying to make my C# ActiveX receive the PARAM properties in an OBJECT tag.

I tried to use the solution proposed here, and I found IE crashing when loading my object...

Finally I could get it right using different IPropertyBag and IPersistPropertyBag interfaces:

[ComVisible(true), ComImport, 
Guid("0000010C-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersist
{
    [PreserveSig]
    int GetClassID([Out] out Guid pClassID);
}

[ComVisible(true), ComImport,
Guid("37D84F60-42CB-11CE-8135-00AA004BB851"),//Guid("5738E040-B67F-11d0-BD4D-00A0C911CE86"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPersistPropertyBag : IPersist
{
    #region IPersist
    [PreserveSig]
    new int GetClassID([Out] out Guid pClassID);
    #endregion

    [PreserveSig]
    int InitNew();

    [PreserveSig]
    int Load(
    [In] IPropertyBag pPropBag,
    [In, MarshalAs(UnmanagedType.Interface)] object pErrorLog
    );

    [PreserveSig]
    int Save(
    IPropertyBag pPropBag,
    [In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty,
    [In, MarshalAs(UnmanagedType.Bool)] bool fSaveAllProperties
    );
}

[ComVisible(true), ComImport,
Guid("55272A00-42CB-11CE-8135-00AA004BB851"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyBag
{
    [PreserveSig]
    int Read(
    [In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
    [In, Out, MarshalAs(UnmanagedType.Struct)]    ref    object pVar,
    [In] IntPtr pErrorLog);

    [PreserveSig]
    int Write(
    [In, MarshalAs(UnmanagedType.LPWStr)] string pszPropName,
    [In, MarshalAs(UnmanagedType.Struct)] ref object pVar);
}

Then I implemented the load methods like this:

#region IPropertyBag Members

    public int Read(string pszPropName, ref object pVar, IntPtr pErrorLog)
    {
        pVar = null;
        switch (pszPropName)
        {
            case "FileType": pVar = _fileType; break;
            case "WebServiceUrl": pVar = _webServiceUrl; break;
            case "Language": pVar = _language; break;
        }

        return 0;
    }

    public int Write(string pszPropName, ref object pVar)
    {
        switch (pszPropName)
        {
            case "FileType": _fileType = (string)pVar; break;
            case "WebServiceUrl": _webServiceUrl = (string)pVar; break;
            case "Language": _language = (string)pVar; break;
        }

        return 0;
    }

    #endregion

    #region IPersistPropertyBag Members

    public int GetClassID(out Guid pClassID)
    {
        throw new NotImplementedException();
    }

    public int InitNew()
    {
        return 0;
    }

    public int Load(IPropertyBag pPropBag, object pErrorLog)
    {
        object val = null;

        pPropBag.Read("FileType", ref val, IntPtr.Zero);
        Write("FileType", ref val);

        pPropBag.Read("WebServiceUrl", ref val, IntPtr.Zero);
        Write("WebServiceUrl", ref val);

        pPropBag.Read("Language", ref val, IntPtr.Zero);
        Write("Language", ref val);

        return 0;
    }

    public int Save(IPropertyBag pPropBag, bool fClearDirty, bool fSaveAllProperties)
    {
        return 0;
    }

    #endregion

And it worked.

Hope this can help someone in the same situation.

Juan Calero
A: 

Hi, I was too looking for a way to be able to retrieve the values from the <PARAM> tags in order to use them from within my control, and I'm confident your solution works... however, I have no idea how to call the load method... :(

The code I'm using to start loading the parameters is:

IPropertyBag myBag;
Object errorLog;
Load(myBag, errorLog);

I get two errors since these two variables must be set to something I can't figure out since I'm not that familiar with interfaces. I must be doing something really silly... please help!!!

The source code seems very well organized, but there are almost no comments and so I can't understand it fully.

Please, can you give an actual example on how to call the load method, and explain at least briefly how this solution works?

Best Regards, Miguel Guzman

Miguel Guzman