Использование ActiveX PropertyBags из C # - PullRequest
3 голосов
/ 07 января 2009

Я создал пользовательский элемент управления .NET с интерфейсом ActiveX. Хорошо работает.

Теперь я хочу иметь возможность читать и писать из пакета свойств интерфейса ActiveX.

Как бы я это сделал?

Ответы [ 2 ]

4 голосов
/ 30 октября 2009

Самый простой - использовать клиентский скрипт для передачи значений параметров в ActiveX

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script language="javascript">

    function Rundata(file) 
    {            
        var winCtrl = document.getElementById("YourActiveX");                     
        winCtrl.Option1 = file;             
        winCtrl.WriteToFile();        
    }
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
    <object id="YourActiveX" classid="clsid:6b1bdf22-1c1d-774e-cd9d-1d1aaf7fd88f" 
    width="300px" height="200px">
    <param name="Option1" value="valuetoRetrieve1" />
    </object>

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

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

Если вы не можете использовать клиентский скрипт, вы можете попробовать это так:

Допустим, вы хотите прочитать такой параметр, как:

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

Вам необходимо предоставить следующие COM-интерфейсы в вашем проекте:

[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);
}

Элемент управления ActiveX должен реализовывать эти интерфейсы. Есть один метод, который вам нужно реализовать:

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

Вуаля! параметр должен быть равен "valuetoRetrieve"

3 голосов
/ 18 марта 2010

Я пытался заставить мой C # ActiveX получить свойства PARAM в теге OBJECT.

Я попытался использовать предложенное здесь решение и обнаружил, что IE вылетает при загрузке моего объекта ...

Наконец-то я смог сделать это правильно, используя разные интерфейсы IPropertyBag и IPersistPropertyBag:

[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);
}

Затем я реализовал методы загрузки следующим образом:

#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

И это сработало.

Надеюсь, это поможет кому-то в такой же ситуации.

...