C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.99868 の関連記事表示

<< 0 >>
■99868  Re[9]: IHTMLDocumentオブジェクトの取得に関して
□投稿者/ 魔界の仮面弁士 -(2022/06/13(Mon) 20:19:43)
    以下、蛇足情報。
    解決済みチェックは付けたままにしておきます。
    
    ■No99864 (はなみ さん) に返信
    >> IHTMLDocument 〜 IHTMLDocument8 の各インターフェイスの定義は、こちらを参照してみてください。
    >> https://docs.microsoft.com/ja-jp/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa752574%28v%3dvs.85%29
    > 
    > 先日ご紹介いただいた docs.microsoft.comのページを見ていた際に、
    > IHTMLDocument8のみが IUnknownから継承されていて、他は IDispatchから継承と
    > 書かれており、IDispatchは IUnknownから継承とあったので
    
    すべての COM インターフェイスは IUnknown を継承しています。
    IHTMLDocument8 もそうですし、IDispatch や IDispatchEx もそうです。
    
    《OAIdl.h》より抜粋
    MIDL_INTERFACE("00020400-0000-0000-C000-000000000046")
    IDispatch : public IUnknown
    
    《DispEx.h》より抜粋
    MIDL_INTERFACE("A6EF9860-C720-11d0-9337-00A0C90DCAA9")
    IDispatchEx : public IDispatch
    
    
    > 「逆なのでは?」と疑問に感じました。
    いずれもデュアルインターフェイスですね。
    IHTMLDocument8 もまた、他と同様にディスパッチインターフェイスを持ちます。
    宣言を見る限り、IHTMLDocument2 だけは IHTMLDocument から引き継がれるようですが。
    
    ちなみにマネージの System.Windows.Forms.HtmlDocument クラスも、
    内部では COM の IHTMLDocument2 インターフェイスを利用しています。
    
    
    《MsHTML.h》もしくは《Mshtmlc.h》より抜粋
    
    MIDL_INTERFACE("626FC520-A41E-11cf-A731-00A0C9082637")
    IHTMLDocument : public IDispatch
    
    MIDL_INTERFACE("332c4425-26cb-11d0-b483-00c04fd90119")
    IHTMLDocument2 : public IHTMLDocument
    
    MIDL_INTERFACE("3050f485-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument3 : public IDispatch
    
    MIDL_INTERFACE("3050f69a-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument4 : public IDispatch
    
    MIDL_INTERFACE("3050f80c-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument5 : public IDispatch
    
    MIDL_INTERFACE("30510417-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument6 : public IDispatch
    
    MIDL_INTERFACE("305104b8-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument7 : public IDispatch
    
    MIDL_INTERFACE("305107d0-98b5-11cf-bb82-00aa00bdce0b")
    IHTMLDocument8 : public IDispatch
    
    
    完全に蛇足ですが、 VB.NET の CallByName は DispId 呼び出しに対応しています。
    
     Dim doc As Object = GetHTMLDocument(hWnd_IE_Server)
    
     'Option Strict Off なら、オブジェクトのメンバーに実行時にアクセスできる
     Debug.WriteLine( doc.location.href )
    
     'Option Strict Off では、IHTMLLocation の Default Method を呼び出すために、このような書き方ができる
     Debug.WriteLine( CObj(doc.location)() )
    
     'Option Strict On でも、CallByName を使えばディスパッチインターフェイスで呼び出せる
     Debug.WriteLine(CallByName(CallByName(doc, "location", CallType.Get), "href", CallType.Get))
     Debug.WriteLine(CallByName(CallByName(doc, "location", CallType.Get), "", CallType.Get))
    
     'DispId で呼び出すこともできる
     Debug.WriteLine(CallByName(CallByName(doc, "[DispID=1026]", CallType.Get), "[DispId=0]", CallType.Get))
    
    
    そして上記の DispID は《MsHtmdid.h》にて得ることができます。
    
    #define DISPID_NORMAL_FIRST                     1000
    #define DISPID_OMDOCUMENT                       DISPID_NORMAL_FIRST
    #define DISPID_IHTMLDOCUMENT2_LOCATION          DISPID_OMDOCUMENT+26
    #define DISPID_IHTMLLOCATION_HREF               DISPID_VALUE
    
    
    
    > これです! このイメージでした!
    > …ただ StrPtr(IID_IHTMLDocumentX) と指定している部分を AddrOfPinnedObjectで
    > 取得したアドレスに置き換えようとしましたが、
    
    その対応が間違っていると思います。
    
    VBA における VarStr と StrPtr の違いは御存知なのですよね。
    LPCSTR と LPCOLESTR の違いは把握されていますか?
    http://hanatyan.sakura.ne.jp/logbbs1/wforum.cgi?mode=allread&no=1785&page=0#1805
    
    
    TextOutA API などの LPCSTR であれば、VBA からは ByVal As String で渡せば良いですが、
    CLSIDFromString が求める LPCOLESTR の場合は、StrPtr を使って渡すことになります。
    
    
    さて、.NET から呼び出す場合はどうかというと…属性指定するのが一般的です。
    
    http://www5b.biglobe.ne.jp/~yone-ken/VBNET/special/sp06_GetPrivateProfileString.html
    https://docs.microsoft.com/en-us/dotnet/framework/interop/marshalling-strings
    https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshalling-for-strings
    https://docs.microsoft.com/en-us/dotnet/standard/native-interop/best-practices#string-parameters
    
    というわけで、CLSIDFromString の VB.NET からの宣言例はこんな感じになります。
    
    <DllImport("ole32.dll")>
    Private Function CLSIDFromString(<MarshalAs(UnmanagedType.BStr)> ByVal lpsz As String, <Out> ByRef guid As Guid) As Integer
        ' 実際には Guid.ParseExact / Guid.Parse メソッドを使った方が手っ取り早い
    End Function
    
    
    どうしても明示的に BSTR を IntPtr として扱う必要がある場合は、
    GCHandle クラスではなく Marshal クラスを使ってみてください。
    
    BSTR の場合はこのあたりです。
     Marshal.StringToBSTR メソッド
     Marshal.PtrToStringBSTR メソッド
     Marshal.FreeBSTR メソッド
    
    C 形式の文字列の場合はこのあたりです。
     Marshal.StringToHGlobalAnsi/Auto/Uni メソッド
     Marshal.StringToCoTaskMemAnsi/Auto/Uni/UTF8 メソッド
     Marshal.PtrToStringAnsi/Auto/Uni/UTF8 メソッド
     Marshal.FreeHGlobal メソッド
     Marshal.FreeCoTaskMem メソッド
    
    注).NET Framework は UTF8 系メソッドをサポートしていません。
記事No.99815 のレス / END /過去ログ174より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -