DOBON.NET DOBON.NETプログラミング掲示板過去ログ

VBAのLenBとVarPtr

  • 題名: VBAのLenBとVarPtr
  • 著者: kei2
  • 日時: 2014/09/17 21:50:03
  • ID: 32615
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[VB.NET2008]
分類:[.NET]

Fuji XEROXのDocuWorksというソフトにbmpを貼り付けたいのですが、
参考になるプログラムがEXCEL VBAのものしか見つけられなかったので、
これをVB.NETに変換してるのですが、エラーが解決されないので2点質問があります。

参照にしたサイト
http://tokidokidokin.com/2011/04/vba%E3%81%A7docuworks%E3%81%AE%E5%85%A8%E3%81%A6%E3%81%AE%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E3%82%8B/

476行の
myAaBMPData.common.nSize = LenB(myAaBMPData) '構造体のバイト数。


With myAaBMPData '構造体
.common = myAaInitialData
.szImagePath
End With

myAaBMPData.common.nSize = System.Text.Encoding.GetEncoding(932).GetByteCount(myAaBMPData)
だと、”これらの引数で呼び出される、アクセス可能な'GetByteCount'がないため、オーバーロードの解決に失敗しました。”になります。

構造体のバイト数を取得するには、どのようにすればいいでしょうか?

もう1つが、
470行の
MsgBox XDW_AddAnnotation(lngHandle, myXDW_AID, lngPage, lngHorPos, lngVerPos, VarPtr(myAaBMPData), lngHandleAnnotation, vbNullString)

で、

'2.1 XDW_AddAnnotation アノテーションを貼り付ける
Private Declare Function XDW_AddAnnotation Lib "C:\Windows\system32\xdwapi.dll" _
(ByVal handle As Long, ByVal nAnnotationType As Long, ByVal nPage As Long, ByVal nHorPos As Long, ByVal nVerPos As Long, _
ByRef pInitialData As XDW_AA_FUSEN_INITIAL_DATA, ByRef phNewAnnotation As Long, ByVal reserved As String) As Long

Private Structure XDW_AA_FUSEN_INITIAL_DATA
' common As Long '共通情報。構造体のバイト数とアノテーションの種類を指定する。
Public common As XDW_AA_INITIAL_DATA '共通情報。構造体のバイト数とアノテーションの種類を指定する。
Public nWidth As Long '付箋アノテーションの幅。単位は1/100mm。
Public nHeight As Long '付箋アノテーションの高さ。単位は1/100mm。
End Structure


'XDW_AddAnnotation用の構造体定義
Private Structure XDW_AA_INITIAL_DATA
Public nSize As Long '構造体のバイト数。
Public nAnnotationType As Long 'アノテーションの種類。
Public nReserved1 As Long '予約メンバ。0でなければならない。
Public nReserved2 As Long '予約メンバ。0でなければならない。
End Structure


Dim gch As GCHandle = GCHandle.Alloc(myAaBMPData, GCHandleType.Pinned)
Dim address As Integer = gch.AddrOfPinnedObject().ToInt32()
XDW_AddAnnotation(lngHandle, myXDW_AID, lngPage, lngHorPos, lngVerPos, address, lngHandleAnnotation, vbNullString)

gch.Free()
で、address の部分が"型'Integer'の値を'XDW_AA_FUSEN_INITIAL_DATA'に変換出来ません。
になります。

2点、よろしくおねがいします。
■No32615に返信(kei2さんの記事)
> myAaBMPData.common.nSize = System.Text.Encoding.GetEncoding(932).GetByteCount(myAaBMPData)
> だと、”これらの引数で呼び出される、アクセス可能な'GetByteCount'がないため、オーバーロードの解決に失敗しました。”になります。
それは、文字列を「Shift_JIS データとしてエンコードした時のバイト数を得る方法」であって、
「構造体(VBA で言うところのユーザー定義型)のサイズを得る方法」ではないからです。



> 構造体のバイト数を取得するには、どのようにすればいいでしょうか?
可変サイズでは無いでしょうから、固定値を渡してしまって良いと思います。
XDW_DOCUMENT_INFO 型なら、40バイトですね。

コードで計測したいのであれば、Marshal クラスの SizeOf メソッドを使って下さい。


それはそうと、そもそもデータ型の扱いを間違えているようです。
大前提として、VBA の Long を VB.NET の Long にしてはいけません。

基本的には、以下のように置き換えることになります。
 「VBA の Integer 型 」= 16bit 符号付き整数型 =「VB2008 の Short 型 (System.Int16 構造体)」
 「VBA の Long 型」  = 32bit 符号付き整数型 =「VB2008 の Integer 型(System.Int32 構造体)」
 「VBA の LongLong 型」= 64bit 符号付き整数型 =「VB2008 の Long 型  (System.Int64 構造体)」
 「VBA の LongPtr 型」 = 32 or 64bit ポインタ =「VB2008 の System.IntPtr 構造体」

また、VBA でポインタとして、ByVal As Long に対して VarPtr(何某) を
渡している個所は、多くの場合、
 (a) ByVal As IntPtr にして受け渡す。
 (b) ByRef As 何某 にして受け渡す。
のいずれかに変更することで対処できます。

たとえば、VBA で、「ByVal As Long」に「VarPtr(ユーザー定義型)」を渡していたなら、
VB2008 では「ByRef As 構造体」で宣言し、そこに「構造体」を直接渡せば OK です。

なお、VBA で「ByRef As ユーザー定義型」を渡していた箇所は、
「ByVal As クラス」あるいは「ByRef As 構造体」に置き換えることができます。



> Dim gch As GCHandle = GCHandle.Alloc(myAaBMPData, GCHandleType.Pinned)
> Dim address As Integer = gch.AddrOfPinnedObject().ToInt32()

IntPtr 値を、むやみに ToInt32 や ToInt64 するべきではありません。
アドレスやハンドルとして扱われる IntPtr 値は、IntPtr 型のまま扱って下さい。
(それ以前に、GCHandle が必要かどうかという話もありますが…)
  • 題名: Re[2]: VBAのLenBとVarPtr
  • 著者: kei2
  • 日時: 2014/09/19 20:51:54
  • ID: 32629
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
> 可変サイズでは無いでしょうから、固定値を渡してしまって良いと思います。
> XDW_DOCUMENT_INFO 型なら、40バイトですね。
こちらは固定値を渡しました。

> それはそうと、そもそもデータ型の扱いを間違えているようです。
> 大前提として、VBA の Long を VB.NET の Long にしてはいけません。
ご指摘の点、修正しました。

> また、VBA でポインタとして、ByVal As Long に対して VarPtr(何某) を
> 渡している個所は、多くの場合、
>  (a) ByVal As IntPtr にして受け渡す。
>  (b) ByRef As 何某 にして受け渡す。
> のいずれかに変更することで対処できます。
>
> たとえば、VBA で、「ByVal As Long」に「VarPtr(ユーザー定義型)」を渡していたなら、
> VB2008 では「ByRef As 構造体」で宣言し、そこに「構造体」を直接渡せば OK です。

ByRef As に置き換えて、
XDW_AddAnnotation(lngHandle, myXDW_AID, lngPage, lngHorPos, lngVerPos, myAaBMPData, lngHandleAnnotation, vbNullString)

で、エラーは消えました。が、まだbmp貼り付けはうまくいかなくて・・・
もう少し勉強してみます。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板