Visual Basic 中学校 掲示板 投稿の管理
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
投稿一覧
bitmapに沢山追加したいです
この投稿へのリンク
https://keijiban.umayadia.com/ThreadDetail.aspx?ThreadId=30686#CommentId84937
この投稿の削除
削除パスワード
削除する
コメント本文
投稿者
魔界の仮面弁士
 (社会人)
投稿日時
2021/12/30 10:52:51
> 御教授頂いた所などを直しましたら、エラーを再現できなくなりました。
> 何十万件でも大丈夫なようでした。
改善されたようで良かったです!
気になる点を指摘しただけのあてずっぽう回答でしたが、
結局何が原因だったのか…ブラシ指定漏れですかね?
http://www.tt.rim.or.jp/~rudyard/torii009.html
> Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, ByVal 0&, MyBMPInf, 0)
> ReDim MyBMPBits(MyBMPInf.bmiHeader.biSizeImage - 1)
> Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, MyBMPBits(0), MyBMPInf, 0)
その表記が許されるのは VBA6 まであり、VBA7 では NG です。
GetDIBits の「LPVOID lpvBits」引数の Declare 宣言を
現状は ByRef lpBits As Any と翻訳しているようなので
#If Win64
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, ByVal 0^, MyBMPInf, 0)
#Else
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, ByVal 0&, MyBMPInf, 0)
#End If
ReDim MyBMPBits(MyBMPInf.bmiHeader.biSizeImage - 1)
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, MyBMPBits(0), MyBMPInf, 0)
と書くのが正しいです。LongPtr 型を示す型宣言文字は存在しないため、
bit 数に応じて LongLong リテラルと Long リテラルを使い分けます。
とはいえ、#If ディレクティブを使うのも煩わしいでしょうから、
'Win32 では As Long = 0& 相当、Win64 では As LongLong = 0^ 相当の定数
Const NullPtr As LongPtr = 0
をあらかじめ用意しておいて、それを用いて
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, ByVal NullPtr, MyBMPInf, 0)
のように呼ぶ方が簡単かと思います。
あるいは別案として、『ByRef lpBits As Any』を『ByVal lpBits As LongPtr』に変更して
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, 0, MyBMPInf, 0)
ReDim MyBMPBits(MyBMPInf.bmiHeader.biSizeImage - 1)
Call GetDIBits(MyDC1, MyBMP, 0, CHEIGHT, VarPtr(MyBMPBits(0)), MyBMPInf, 0)
のように呼び出すのもありです。
もしくはバイナリ指定用の「ByRef lpBits As Byte」版と
NULL 指定用の「ByVal lpBits As LongPtr」版の 2 種類の宣言を Alias 指定して
Call GetDIBitsNull(MyDC1, MyBMP, 0, CHEIGHT, 0, MyBMPInf, 0)
ReDim MyBMPBits(MyBMPInf.bmiHeader.biSizeImage - 1)
Call GetDIBitsByte(MyDC1, MyBMP, 0, CHEIGHT, MyBMPBits(0), MyBMPInf, 0)
などと使い分ける手法もあります。
Office 2016 以降では 64bit 環境が主流となっていますが、ネット上にあるサンプルは
32bit 時代のコードがまだまだ多いですし、VBA7 版でも Win64 対応が不十分なサンプルが
出回っていたりしますので、注意が必要ですね。
そして、似て非なる状況なのがこちら。
> MyDC0 = GetDC(0&)
> Call ReleaseDC(0&, MyDC0)
これも同様に、Win64 環境の場合は 0^ 、Win32 環境の場合は 0& を渡すべきなのですが、
こちらは Any ではなく、『ByVal h As LongPtr』な引数として Declare されていますので、
この場合は暗黙の型変換にお任せして、「0」表記でも「0&」表記でも大丈夫です。私は 0 派です。
極端な話、ここに「"0"」や「0.0」を渡したとしても正常に動作します。
(それが良いコードかどうかは別として!)
ちなみに、ハンドル(HDC とか HWND とか)というデータ型は、
Win32 では 32bit、Win64 では 64bit サイズではありますが、
互換性上の都合から、Win64 でも実際には下位 32bit 部しか
使われていなかったりします。ポインタとハンドルの違いというやつですね。
さらに丁寧に書くなら、Office 2007 以下にも配慮して、#If VBA7 Then ディレクティブを
併用することになりますが…2003 や 2007 等で動かすことが無い場合は冗長になりますね。