.bfOffBitsと.bfSizeが反転?

ActiveBasicのバグと思われる不具合を発見された方は、こちらから知らせていただけると助かります。
返信する
メッセージ
作成者
Uhsp

.bfOffBitsと.bfSizeが反転?

#1 投稿記事 by Uhsp »

 4.10台のバージョンからビットマップファイルを書き込むと
.bfOffBitsと.bfSizeが反転してしまいます。

下記コードを実行してファイルを確認すると
 .bfOffBits = 30360000 .... 00003036
 .bfSize = 00360000 .... 00000036
なので上下を入れ替えないとビットマップとして表示されません。

 突然ビットマップが作成できなくなったので半日悩みましたバグではない
かも知れませんが調査していただけると嬉しいです。

コード: 全て選択


 Dim hFile as LONG
 Dim htDC  as HDC
 Dim htBmp as HBITMAP
 Dim Bmf   as BITMAPFILEHEADER
 Dim Bmi   as BITMAPINFO
 Dim Dsz   as DWORD
 Dim Dps   as BytePtr
 Dim Wtp   as LONG
     Bmi.bmiHeader.biSize           =  40
     Bmi.bmiHeader.biWidth          =  64
     Bmi.bmiHeader.biHeight         =  64
     Bmi.bmiHeader.biPlanes         =   1
     Bmi.bmiHeader.biBitCount       =  24
     Bmi.bmiHeader.biCompression    =  BI_RGB
     Bmi.bmiHeader.biSizeImage      =   0
     Bmi.bmiHeader.biXPelsPerMeter  =   0
     Bmi.bmiHeader.biYPelsPerMeter  =   0
     Bmi.bmiHeader.biClrUsed        =   0
     Bmi.bmiHeader.biClrImportant   =   0

     Dsz  =  ((24*Bmi.bmiHeader.biWidth+31)\32)*4*Abs(Bmi.bmiHeader.biHeight)

     Bmf.bfType       =  &H4D42
     Bmf.bfReserved1  =  0
     Bmf.bfReserved2  =  0
     Bmf.bfOffBits    = 54
     Bmf.bfSize       =  Dsz+Bmf.bfOffBits

     Dps   =  GlobalAlloc(GPTR, Dsz)
     htDC  =  CreateCompatibleDC(0)
     htBmp  = CreateCompatibleBitmap(htDC,64,64)
     SelectObject(htDC, Binfo[Cbuf].hmBmp)
     GetDIBits(htDC,htBmp,0,64,Dps,Bmi,DIB_RGB_COLORS)
     DeleteDC(htDC)

     hFile =  CreateFile(FN,GENERIC_WRITE,0,ByVal NULL,
                         CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)
     WriteFile(hFile,VarPtr(Bmf),14,VarPtr(Wtp),ByVal NULL)
     WriteFile(hFile,VarPtr(Bmi),Bmf.bfOffBits-14,VarPtr(Wtp),ByVal NULL)
     WriteFile(hFile,Dps,Dsz,VarPtr(Wtp),ByVal NULL)
     CloseHandle(hFile)
     GlobalFree(Dps)
Uhsp

Re: .bfOffBitsと.bfSizeが反転?

#2 投稿記事 by Uhsp »

訂正です。
>  .bfOffBits = 30360000 .... 00003036
>  .bfSize = 00360000 .... 00000036

 .bfSize = 30360000 .... 00003036
.bfOffBits = 00360000 .... 00000036
すみません。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#3 投稿記事 by マティ »

最新版(4.11.03)を使用して
include\api_gdi.sbpのBITMAPFILEHEADERを以下のように書き換えると
動作するでしょうか?

コード: 全て選択


' Bitmap file header struct
'Type BITMAPFILEHEADER
Type Align(1) BITMAPFILEHEADER	'Alignを追加
	bfType As Integer
	bfSize As Long
	bfReserved1 As Integer
	bfReserved2 As Integer
	bfOffBits As Long
End Type
Uhsp

#4 投稿記事 by Uhsp »

> 最新版(4.11.03)を使用して
> include\api_gdi.sbpのBITMAPFILEHEADERを以下のように
> 書き換えると動作するでしょうか?

ありがとうございます。
動作しましたこれも「PRINTDLG」の時と同じ原因だったのですね
「BITMAPFILEHEADER」は使用頻度が高い気がしていたので修正されていると
思い込んでいました、他にもありそうなので次回から最初に
構造体を疑ってみます。:特にINTEGERを含むものを
山本
Site Admin
記事: 535
登録日時: 2005年5月30日(月) 15:08
連絡する:

#5 投稿記事 by 山本 »

ご報告ありがとうございます。次回のバージョンアップで修正します。

BITMAPFILEHEADERは、.bmpファイルの先頭に含まれる構造体なんですよね。これは、16ビット時代(Windows3.1時代)から使われていたものなんでしょうか??だとしたら、4バイト境界でアラインメントを作るわけにはいかないですな。

他にもこういう構造体を見つけた方がいらっしゃいましたら、ご一報いただけると助かります。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#6 投稿記事 by マティ »

山本さまの疑問にお答えします。(もう大昔の話なので、うる覚えですが・・・)

GDI系の構造体はOS/2 Ver1.?のPM(プレゼンテーションマネージャだったかな?、GUIを管理するシステム)までさかのぼります。
当時のOS/2がターゲットとしていたCPUは286ですので、必然的に構造体のアライメントは2バイト境界となります。

その後、MSとIBMがそれぞれの道を進む事になった際に、Win3.1とOS/2 Ver2へと別々の道を進んでいきます。
GUI系のAPI(名称は別として)は座標の原点が左上か左下の違いしかありませんでした。
Win9x系のディスプレイドライバでGDIを処理するコードは16ビットセグメントで実行します。(DirectX系は32Bitです)
また、WinNT系でもAPIはWin9x系と互換なので過去を引きずっています。(ディスプレイドライバーは32ビット化済みです。)

GDI系のAPIに関しては、こんな感じです。
山本
Site Admin
記事: 535
登録日時: 2005年5月30日(月) 15:08
連絡する:

#7 投稿記事 by 山本 »

マティさん、情報ありがとうございます。入り込んだ話になってきましたので、「構造体のアラインメントについて」のトピックで議論をすすめましょう。

http://www.discoversoft.net/forum/viewtopic.php?t=477
返信する