最終更新日 :
VB Tips

MFCの関数をVBに(その1-1)
第2回目ですが、早速C/C++コードを実際にVBに移植してみましょう。習うより慣れろです。

MFCのソースから取ってきた、CDC::DrawDragRectという関数をVBに移植してみます。以下は、そのソースです(一部省略)。

void CDC::DrawDragRect(LPCRECT lpRect, SIZE size,
LPCRECT lpRectLast, SIZE sizeLast, CBrush* pBrush, CBrush* pBrushLast)
{
// first, determine the update region and select it
CRgn rgnNew;
CRgn rgnOutside, rgnInside;
rgnOutside.CreateRectRgnIndirect(lpRect);
CRect rect = *lpRect;
rect.InflateRect(-size.cx, -size.cy);
rect.IntersectRect(rect, lpRect);
rgnInside.CreateRectRgnIndirect(rect);
rgnNew.CreateRectRgn(0, 0, 0, 0);
rgnNew.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);

CBrush* pBrushOld = NULL;
if (pBrush == NULL)
pBrush = CDC::GetHalftoneBrush();
if (pBrushLast == NULL)
pBrushLast = pBrush;

CRgn rgnLast, rgnUpdate;
if (lpRectLast != NULL)
{
// find difference between new region and old region
rgnLast.CreateRectRgn(0, 0, 0, 0);
rgnOutside.SetRectRgn(lpRectLast);
rect = *lpRectLast;
rect.InflateRect(-sizeLast.cx, -sizeLast.cy);
rect.IntersectRect(rect, lpRectLast);
rgnInside.SetRectRgn(rect);
rgnLast.CombineRgn(&rgnOutside, &rgnInside, RGN_XOR);

// only diff them if brushes are the same
if (pBrush->m_hObject == pBrushLast->m_hObject)
{
rgnUpdate.CreateRectRgn(0, 0, 0, 0);
rgnUpdate.CombineRgn(&rgnLast, &rgnNew, RGN_XOR);
}
}
if (pBrush->m_hObject != pBrushLast->m_hObject && lpRectLast != NULL)
{
// brushes are different -- erase old region first
SelectClipRgn(&rgnLast);
GetClipBox(&rect);
pBrushOld = SelectObject(pBrushLast);
PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);
SelectObject(pBrushOld);
pBrushOld = NULL;
}

// draw into the update/new region
SelectClipRgn(rgnUpdate.m_hObject != NULL ? &rgnUpdate : &rgnNew);
GetClipBox(&rect);
pBrushOld = SelectObject(pBrush);
PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATINVERT);

// cleanup DC
if (pBrushOld != NULL)
SelectObject(pBrushOld);
SelectClipRgn(NULL);
}


この関数をVBで書き直してみましょう。ここで簡単のために、ブラシはハーフトーンブラシに固定にしますので、引数は減ります。
まずは関数の宣言部分です。void型の関数であるので、VBではSubプロシージャです。よって、プロシージャの宣言はこうなります。

Public Sub DrawDragRect(ByVal hdc As Long, NewRect As RECT, NewSize As SIZE, OldRect As RECT, OldSize As SIZE)

VBにはCDCクラスなど存在しないので、引数にデバイスコンテキストのハンドルが必要です。次は変数の宣言です。VBではプロシージャの途中で変数宣言することはあまりありません。 途中で宣言しようと最初にしようとReDimステートメント以外はプロシージャ実行時に変数が確保されてしまうからです。また、まだ書いてなかったでしょうが、初期値代入はできません。
この関数で使用する変数はRECT構造体と、リージョンハンドルが何個か、それとブラシのハンドルです。これを実際宣言すると、

Dim rgnNew As Long, rgnOutside As Long, rgnInside As Long
Dim rgnOld As Long, rgnUpdate As Long
Dim brsOld As Long, brsNew As Long
Dim rc As RECT


rcは、変換前の変数rectの代わりです。同名で宣言するのはまずいですから。

続きはまた次の機会にしましょう。→

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