mshtml - GETBLOCKFMTS

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Zentner

    mshtml - GETBLOCKFMTS

    I have a weird problem...

    A while ago I wrote some code in VB.NET which gets the block formats from
    mshtml like shown below. I am now converting this into C# and I have the
    problem that the IOleCommandTarg et.Exec function doesn't return the
    supported formats - in VB it works fine. (sorry code is long)

    Thanks for helping
    Peter

    VB code:

    Imports System.Runtime. InteropServices
    ' OLECMD
    <StructLayout(L ayoutKind.Seque ntial)> _
    Public Structure OLECMD
    Public cmdID As Int32
    Public cmdf As Int32
    End Structure
    ' OLECMDTEXT
    <StructLayout(L ayoutKind.Seque ntial, CharSet:=CharSe t.Unicode)> _
    Public Class OLECMDTEXT
    Public cmdtextf As OLECMDTEXTF
    Public cwActual As Int32
    Private cwBuf As Int32 = 256 'Make sure this is the same as SizeConst
    below
    <MarshalAs(Unma nagedType.ByVal TStr, SizeConst:=256) > _
    Public text As String
    End Class

    Public Enum OLECMDTEXTF
    OLECMDTEXTF_NON E = 0
    OLECMDTEXTF_NAM E = 1
    OLECMDTEXTF_STA TUS = 2
    End Enum

    ' IOleCommandTarg et interface
    <ComVisible(Tru e), ComImport(),
    Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), _
    InterfaceType(C omInterfaceType .InterfaceIsIUn known)> _
    Public Interface IOleCommandTarg et
    <PreserveSig( )> Function QueryStatus(ByR ef pguidCmdGroup As Guid, ByVal
    cCmds As Int32, _
    <InAttribute( ), Out(), MarshalAs(Unman agedType.LPArra y,
    SizeParamIndex: =1)> ByVal prgCmds() As OLECMD, _
    <InAttribute( ), Out()> ByVal pCmdText As OLECMDTEXT) As Integer

    <PreserveSig( )> Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdId
    As Int32, _
    ByVal nCmdExecOpt As Int32, ByVal pvaIn As OLEVARIANT, ByVal pvaOut As
    OLEVARIANT) As Integer
    End Interface

    <StructLayout(L ayoutKind.Expli cit)> _
    Public Class OLEVARIANT
    <FieldOffset(0) > Public vt As System.Int16
    <FieldOffset(2) > Public wReserved1 As System.Int16
    <FieldOffset(4) > Public wReserved2 As System.Int16
    <FieldOffset(6) > Public wReserved3 As System.Int16
    <FieldOffset(8) > Public lVal As Integer
    <FieldOffset(8) > Public iVal As Short
    <FieldOffset(8) > Public bstrVal As IntPtr
    <FieldOffset(8) > Public pUnkVal As IntPtr
    <FieldOffset(8) > Public pArray As IntPtr
    <FieldOffset(8) > Public pvRecord As IntPtr
    <FieldOffset(12 )> Public pRecInfo As IntPtr

    Public Sub Clear()
    VariantClear(Me )
    End Sub 'Clear

    Public Sub LoadString(ByVa l Value As String)
    bstrVal = Marshal.StringT oBSTR(Value)
    End Sub

    Public Function ToNativeObject( ) As Object
    Dim p As IntPtr

    Try
    'Allocate a buffer to hold the data in this OLEVARIANT
    p = Marshal.AllocCo TaskMem(Marshal .SizeOf(Me.GetT ype()))
    Marshal.Structu reToPtr(Me, p, False)
    Return Marshal.GetObje ctForNativeVari ant(p)
    Finally
    'Called no matter what
    Marshal.FreeCoT askMem(p)
    End Try
    End Function

    <DllImport("Ole aut32.dll", PreserveSig:=Fa lse)> _
    Private Shared Sub VariantClear(By Val var As OLEVARIANT)
    ' Leave this blank. Call will be redirected to external DLL.
    End Sub
    End Class 'OLEVARIANT

    Get the formats...

    Dim oOut As New OLEVARIANT()
    Dim oIn As OLEVARIANT
    Dim cmdt As IOleCommandTarg et

    Try
    Dim pguidCmdGroup As System.Guid = New
    Guid("DE4BA900-59CA-11CF-9592-444553540000")
    cmdt = DirectCast(Html Editor1.Documen t, IOleCommandTarg et)
    cmdt.Exec(pguid CmdGroup, cmdID,
    onlyconnect.OLE CMDEXECOPT.OLEC MDEXECOPT_DONTP ROMPTUSER, oIn, oOut)
    Catch ex As Exception
    Throw New Exception("Exec Command: " & ex.Message)
    End Try

    C# code:

    using System;
    using System.Runtime. InteropServices ;

    [StructLayout(La youtKind.Sequen tial)]
    public struct OLECMD
    {
    public long cmdID;
    public long cmdf;
    }

    [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Unicode)]
    public class OLECMDTEXT
    {
    public OLECMDTEXTF cmdtextf;
    public long cwActual;
    private long cwBuf = 256; // make sure this is the same as SizeConst
    below
    [MarshalAs(Unman agedType.ByValT Str, SizeConst=256)]
    public String text;
    }

    public enum OLECMDTEXTF
    {
    OLECMDTEXTF_NON E = 0,
    OLECMDTEXTF_NAM E,
    OLECMDTEXTF_STA TUS
    }

    [ComVisible(true ), ComImport(),
    Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
    InterfaceType(C omInterfaceType .InterfaceIsIUn known)]
    public interface IOleCommandTarg et
    {
    [PreserveSig()]
    int QueryStatus(ref Guid pguidCmdGroup, long cCmds, [In, Out]OLECMD
    prgCmds, [In, Out]OLECMDTEXT pCmdText);

    [PreserveSig()]
    int Exec(ref Guid pguidCmdGroup, long nCmdId, long nCmdExecOpt,
    OLEVARIANT pvaIn, OLEVARIANT pvaOut);
    }

    [StructLayout(La youtKind.Explic it)]
    public class OLEVARIANT
    {
    [FieldOffset(0)]public int vt;
    [FieldOffset(2)]public int wReserved1;
    [FieldOffset(4)]public int wReserved2;
    [FieldOffset(6)]public int wReserved3;
    [FieldOffset(8)]public long lVal;
    [FieldOffset(8)]public int iVal;
    [FieldOffset(8)]public IntPtr bstrVal;
    [FieldOffset(8)]public IntPtr bUnkVal;
    [FieldOffset(8)]public IntPtr pArray;
    [FieldOffset(8)]public IntPtr pvRecord;
    [FieldOffset(12)]public IntPtr pRecInfo;

    public void Clear()
    {
    VariantClear(th is);
    }

    public void LoadString(Stri ng Value)
    {
    bstrVal = Marshal.StringT oBSTR(Value);
    }

    public object ToNativeObject( )
    {
    IntPtr p = IntPtr.Zero;
    try
    {
    // allocate a buffer to hold the data in this OLEVARIANT
    p = Marshal.AllocCo TaskMem(Marshal .SizeOf(this.Ge tType()));
    Marshal.Structu reToPtr(this, p, false);
    return Marshal.GetObje ctForNativeVari ant(p);
    }
    finally
    {
    // called no matter what
    Marshal.FreeCoT askMem(p);
    }
    }

    [DllImport("Olea ut32.dll", PreserveSig=fal se)]
    private static extern void VariantClear(OL EVARIANT var);
    }


  • Leonhardt Wille

    #2
    Re: mshtml - GETBLOCKFMTS

    Well I don't know C# - but I think there's no need to work with the raw
    interfaces :) The MFC contain a wrapper class for MSHTML, the
    CHtmlEditCtrlBa se class (afxhtml.h) which implements retrieval of
    blockformats as follows: (sorry code is also long, but at least readable
    :P )
    Hope this helps you, I don't know whether the code can be ported to C#
    or whether there's an equivalent class in C#.

    HRESULT GetBlockFormatN ames(CStringArr ay &sa) const
    {
    CComVariant vaRet;
    HRESULT hr = E_FAIL;
    long lStatus = QueryStatus(IDM _GETBLOCKFMTS);
    if (lStatus & OLECMDF_ENABLED || lStatus & OLECMDF_LATCHED )
    {
    if (S_OK == ExecCommand(IDM _GETBLOCKFMTS, OLECMDEXECOPT_D ODEFAULT,
    NULL, &vaRet))
    {
    if(vaRet.vt & VT_ARRAY)
    {
    USES_CONVERSION ;
    SAFEARRAY *psa = vaRet.parray;

    long lBound = 0,uBound = 0;
    if(S_OK == SafeArrayGetLBo und(psa,1,&lBou nd) &&
    S_OK == SafeArrayGetUBo und(psa,1,&uBou nd) )
    {
    for(long i=lBound; i<uBound; i++)
    {
    CComBSTR bstrElem;
    if( (S_OK == SafeArrayGetEle ment(psa, &i, &bstrElem) ))
    {
    sa.Add(CString( bstrElem));
    }
    }
    hr = S_OK;
    }
    }
    }
    }

    if (vaRet.vt == VT_ERROR)
    hr = V_ERROR(&vaRet) ;

    return hr;
    }

    regards, Leo

    Peter Zentner wrote:[color=blue]
    > I have a weird problem...
    >
    > A while ago I wrote some code in VB.NET which gets the block formats from
    > mshtml like shown below. I am now converting this into C# and I have the
    > problem that the IOleCommandTarg et.Exec function doesn't return the
    > supported formats - in VB it works fine. (sorry code is long)
    >
    > Thanks for helping
    > Peter
    >
    > VB code:
    >
    > Imports System.Runtime. InteropServices
    > ' OLECMD
    > <StructLayout(L ayoutKind.Seque ntial)> _
    > Public Structure OLECMD
    > Public cmdID As Int32
    > Public cmdf As Int32
    > End Structure
    > ' OLECMDTEXT
    > <StructLayout(L ayoutKind.Seque ntial, CharSet:=CharSe t.Unicode)> _
    > Public Class OLECMDTEXT
    > Public cmdtextf As OLECMDTEXTF
    > Public cwActual As Int32
    > Private cwBuf As Int32 = 256 'Make sure this is the same as SizeConst
    > below
    > <MarshalAs(Unma nagedType.ByVal TStr, SizeConst:=256) > _
    > Public text As String
    > End Class
    >
    > Public Enum OLECMDTEXTF
    > OLECMDTEXTF_NON E = 0
    > OLECMDTEXTF_NAM E = 1
    > OLECMDTEXTF_STA TUS = 2
    > End Enum
    >
    > ' IOleCommandTarg et interface
    > <ComVisible(Tru e), ComImport(),
    > Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), _
    > InterfaceType(C omInterfaceType .InterfaceIsIUn known)> _
    > Public Interface IOleCommandTarg et
    > <PreserveSig( )> Function QueryStatus(ByR ef pguidCmdGroup As Guid, ByVal
    > cCmds As Int32, _
    > <InAttribute( ), Out(), MarshalAs(Unman agedType.LPArra y,
    > SizeParamIndex: =1)> ByVal prgCmds() As OLECMD, _
    > <InAttribute( ), Out()> ByVal pCmdText As OLECMDTEXT) As Integer
    >
    > <PreserveSig( )> Function Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdId
    > As Int32, _
    > ByVal nCmdExecOpt As Int32, ByVal pvaIn As OLEVARIANT, ByVal pvaOut As
    > OLEVARIANT) As Integer
    > End Interface
    >
    > <StructLayout(L ayoutKind.Expli cit)> _
    > Public Class OLEVARIANT
    > <FieldOffset(0) > Public vt As System.Int16
    > <FieldOffset(2) > Public wReserved1 As System.Int16
    > <FieldOffset(4) > Public wReserved2 As System.Int16
    > <FieldOffset(6) > Public wReserved3 As System.Int16
    > <FieldOffset(8) > Public lVal As Integer
    > <FieldOffset(8) > Public iVal As Short
    > <FieldOffset(8) > Public bstrVal As IntPtr
    > <FieldOffset(8) > Public pUnkVal As IntPtr
    > <FieldOffset(8) > Public pArray As IntPtr
    > <FieldOffset(8) > Public pvRecord As IntPtr
    > <FieldOffset(12 )> Public pRecInfo As IntPtr
    >
    > Public Sub Clear()
    > VariantClear(Me )
    > End Sub 'Clear
    >
    > Public Sub LoadString(ByVa l Value As String)
    > bstrVal = Marshal.StringT oBSTR(Value)
    > End Sub
    >
    > Public Function ToNativeObject( ) As Object
    > Dim p As IntPtr
    >
    > Try
    > 'Allocate a buffer to hold the data in this OLEVARIANT
    > p = Marshal.AllocCo TaskMem(Marshal .SizeOf(Me.GetT ype()))
    > Marshal.Structu reToPtr(Me, p, False)
    > Return Marshal.GetObje ctForNativeVari ant(p)
    > Finally
    > 'Called no matter what
    > Marshal.FreeCoT askMem(p)
    > End Try
    > End Function
    >
    > <DllImport("Ole aut32.dll", PreserveSig:=Fa lse)> _
    > Private Shared Sub VariantClear(By Val var As OLEVARIANT)
    > ' Leave this blank. Call will be redirected to external DLL.
    > End Sub
    > End Class 'OLEVARIANT
    >
    > Get the formats...
    >
    > Dim oOut As New OLEVARIANT()
    > Dim oIn As OLEVARIANT
    > Dim cmdt As IOleCommandTarg et
    >
    > Try
    > Dim pguidCmdGroup As System.Guid = New
    > Guid("DE4BA900-59CA-11CF-9592-444553540000")
    > cmdt = DirectCast(Html Editor1.Documen t, IOleCommandTarg et)
    > cmdt.Exec(pguid CmdGroup, cmdID,
    > onlyconnect.OLE CMDEXECOPT.OLEC MDEXECOPT_DONTP ROMPTUSER, oIn, oOut)
    > Catch ex As Exception
    > Throw New Exception("Exec Command: " & ex.Message)
    > End Try
    >
    > C# code:
    >
    > using System;
    > using System.Runtime. InteropServices ;
    >
    > [StructLayout(La youtKind.Sequen tial)]
    > public struct OLECMD
    > {
    > public long cmdID;
    > public long cmdf;
    > }
    >
    > [StructLayout(La youtKind.Sequen tial, CharSet=CharSet .Unicode)]
    > public class OLECMDTEXT
    > {
    > public OLECMDTEXTF cmdtextf;
    > public long cwActual;
    > private long cwBuf = 256; // make sure this is the same as SizeConst
    > below
    > [MarshalAs(Unman agedType.ByValT Str, SizeConst=256)]
    > public String text;
    > }
    >
    > public enum OLECMDTEXTF
    > {
    > OLECMDTEXTF_NON E = 0,
    > OLECMDTEXTF_NAM E,
    > OLECMDTEXTF_STA TUS
    > }
    >
    > [ComVisible(true ), ComImport(),
    > Guid("b722bccb-4e68-101b-a2bc-00aa00404770"),
    > InterfaceType(C omInterfaceType .InterfaceIsIUn known)]
    > public interface IOleCommandTarg et
    > {
    > [PreserveSig()]
    > int QueryStatus(ref Guid pguidCmdGroup, long cCmds, [In, Out]OLECMD
    > prgCmds, [In, Out]OLECMDTEXT pCmdText);
    >
    > [PreserveSig()]
    > int Exec(ref Guid pguidCmdGroup, long nCmdId, long nCmdExecOpt,
    > OLEVARIANT pvaIn, OLEVARIANT pvaOut);
    > }
    >
    > [StructLayout(La youtKind.Explic it)]
    > public class OLEVARIANT
    > {
    > [FieldOffset(0)]public int vt;
    > [FieldOffset(2)]public int wReserved1;
    > [FieldOffset(4)]public int wReserved2;
    > [FieldOffset(6)]public int wReserved3;
    > [FieldOffset(8)]public long lVal;
    > [FieldOffset(8)]public int iVal;
    > [FieldOffset(8)]public IntPtr bstrVal;
    > [FieldOffset(8)]public IntPtr bUnkVal;
    > [FieldOffset(8)]public IntPtr pArray;
    > [FieldOffset(8)]public IntPtr pvRecord;
    > [FieldOffset(12)]public IntPtr pRecInfo;
    >
    > public void Clear()
    > {
    > VariantClear(th is);
    > }
    >
    > public void LoadString(Stri ng Value)
    > {
    > bstrVal = Marshal.StringT oBSTR(Value);
    > }
    >
    > public object ToNativeObject( )
    > {
    > IntPtr p = IntPtr.Zero;
    > try
    > {
    > // allocate a buffer to hold the data in this OLEVARIANT
    > p = Marshal.AllocCo TaskMem(Marshal .SizeOf(this.Ge tType()));
    > Marshal.Structu reToPtr(this, p, false);
    > return Marshal.GetObje ctForNativeVari ant(p);
    > }
    > finally
    > {
    > // called no matter what
    > Marshal.FreeCoT askMem(p);
    > }
    > }
    >
    > [DllImport("Olea ut32.dll", PreserveSig=fal se)]
    > private static extern void VariantClear(OL EVARIANT var);
    > }
    >
    >[/color]

    Comment

    Working...