最終更新日 :
VB Tips

MFCの関数をVBに(その1-3)
大変遅れまして申し訳ありませんでした。今回も前回・前々回の続き、MFCのソースから取ってきたCDC::DrawDragRectという関数の移植で、その中でも中心となるCDC::GetHalftoneBrushを解説したいと思います。
前回でメイン関数CDC::DrawDragRectの流れの説明を終えましたが、今回はその中でもハーフトーンブラシ取得関数の流れです。

CBrush* PASCAL CDC::GetHalftoneBrush()
{
if (halftoneBrush == NULL)
{
WORD grayPattern[8];
for (int i = 0; i < 8; i++)
grayPattern[i] = (WORD)(0x5555 << (i & 1));
HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
if (grayBitmap != NULL)
{
halftoneBrush = ::CreatePatternBrush(grayBitmap);
DeleteObject(grayBitmap);
}
}
return CBrush::FromHandle(halftoneBrush);
}


このC++コードをVBで書き換えるとどうなるでしょうか。こうなります。

Dim iDither(7) As Integer, i As Integer, hbmGray As Long

For i = 0 To 7
iDither(i) = CInt("&H" & Hex$(&H5555 * (2 ^ (i And 1))))
Next
hbmGray = CreateBitmap(8, 8, 1, 1, iDither(0))
If hbmGray Then
GetHalftoneBrush = CreatePatternBrush(hbmGray)
DeleteObject hbmGray
Else
GetHalftoneBrush = 0
End If


さて、順を追って説明していきましょう。

iDither(i) = CInt("&H" & Hex$(&H5555 * (2 ^ (i And 1))))

"grayPattern[i] = (WORD)(0x5555 << (i & 1));"を変換したものですが、ここには"<<"とかいう見慣れない演算子が登場しています。 これは、左シフト演算子というもので左のオペランド(引数)を右のオペランド分だけ左にずらします。
例えば&H5555 = 101010101010101(2)を1ビットだけ左にシフトすると、1010101010101010(2) = &HAAAA というように、左に1ビットだけずれます。逆に右に1ビットずらす(右シフト演算)と、10101010101010(2) = &H2AAA になります。
これは、実は単純に2の「ずらすビット」乗を掛けたり、それで割ったり(あまりは無視)しているだけです。そうすると上のようになります。不思議に思う方は他の数字でやってみるといいでしょう。
それで、これによってなにが得られるかと言いますと、ビットマップ(にする予定の配列)の中身が、
0101010101010101
1010101010101010
0101010101010101
1010101010101010
0101010101010101
1010101010101010
0101010101010101
1010101010101010
というようになるわけでして、これを次のCreateBitmap()に渡すのです。

hbmGray = CreateBitmap(8, 8, 1, 1, iDither(0))

これで、モノクロのビットマップを8x8のサイズで作成するようにしています。モノクロビットマップなので、黒か白、つまり配列の中身は0 or 1でよく、先ほどの配列を指定すれば黒と白がディザになっているビットマップを得ることができます。

GetHalftoneBrush = CreatePatternBrush(hbmGray)

そして最後にビットマップの作成に成功した場合、それを用いてブラシを作成します。Windows3.1/95/98では、パターンブラシはビットマップの左上8ピクセルx8ピクセルしか適用されないことになっています(95以上はビットマップ全体が適用されるとリファレンスには記述されていますが)。
何はともあれ、これで網がけ模様を描画するためのハーフトーンブラシが作成されました。後はこれを使ってPatBlt()APIで指定したクリップリージョン内を埋め尽くすだけです。埋め尽くすときに、vbPatInvertを引数に与えていますが、 これを指定することによって、白の部分は透明に、黒の部分はカラー反転で描画するようになります。わかりやすく言えば、ブラシの中の白の部分はなにも影響を与えていないだけです。ちょうどペイントブラシの消しゴムで対象色指定したときのような感じです。

最後になって本当に申し訳ないですが、このコードの利用例をファイルに収めました。参考にしてください。(最初の回に公開すべきだったと思います。)

Copyright (C) 2000 Satoshi Tadaフィードバックはこちら
Home