Microsoft DirectX 8.0 (Visual Basic)

フラグの使い方

Microsoft® DirectX® for Microsoft Visual Basic® の多くのオブジェクト メソッドでは、flags、またはそれに似た名前を持つ長整数型 (Long) のパラメータが使用される。また、型の中にはフラグ メンバを持つものもある。これらの "フラグ フィールド" を使用すると、多数のオプションから簡単に選択できる。多くの場合、フラグ フィールドはメソッドの動作を正確に指定するときに使用される。たとえば、DirectInput8.GetDevicesBySemantics flags パラメータを使用してオプションの 1 つを選択すると、列挙の範囲を定義できる。

フラグは、はい/いいえを表す 1 ビットの情報である。フラグ フィールドの中で、整数の各ビットは、独立した情報を表す異なるフラグに対応する。ビットを設定した場合、フラグは有効になる。ビットを 0 にした場合、フラグは無効になる。一般に、フラグ フィールドには、列挙により表される一組の関連したフラグが含まれる。通常、列挙の各メンバの数値はフラグ フィールドの異なる 1 ビットを表す。しかし、メンバによっては複数のフラグの組み合わせを表すことがある。

通常、フラグ フィールドを使用すると、さまざまなオプションの 1 つを選択できる。それには、フラグ パラメータに適切な列挙値を代入することが多い。しかし、各フラグは異なるビットに対応するため、フラグ フィールドを使用して、リストから複数のオプションを選択することもできる。それには、Or 演算子を使用し、選択したフラグの列挙値を組み合わせて、関連するビットをすべて設定する。たとえば、DirectInputDevice8.SetCooperativeLevel メソッドには、デバイスの協調レベルの指定に使用されるフラグ フィールドがある。次のコード例では、DISCL_FOREGROUND フラグと DISCL_EXCLUSIVE フラグを組み合わせて、フォアグラウンドと排他協調レベルを選択する。

' diDevice は DirectInputDevice8 オブジェクトで、hwnd はウィンドウ ハンドルである。
diDevice.SetCooperativeLevel(hwnd, _
    DISCL_FOREGROUND Or DISCL_EXCLUSIVE)

  リファレンス ページをよく調べ、フラグ フィールドの使用方法を確認すること。1 つのフラグしか設定できないフラグ フィールドに複数のフラグを設定すると、予想外の結果が発生することがある。

Or 演算子の代わりに、加算演算子を使用して、フラグを組み合わせないこと。2 つの演算は等価なことが多いが、間違った結果に達することがある。特に、一方のフラグが複数のフラグの組み合わせを表す場合、2 つの演算子は等価ではないことが多い。次の例では、CF_PURPLE フラグは CF_RED と CF_BLUE の組み合わせを表している。

Enum COLORFLAGS
    CF_RED    = 1
    CF_BLUE   = 2
    CF_PURPLE = 3
    CF_GREEN  = 4
End Enum
 
Dim Color As Integer
Color = CF_RED Or CF_PURPLE

ここで、Color の値は 3 である。CF_RED のビットは CF_PURPLE により既に設定されているため、CF_RED はエフェクトを持たない。

一方、次の演算では不正な値が設定される。

' 次のコードは間違いである。
Color = CF_RED + CF_PURPLE

2 つのフラグの値を加えると、Color は 4 に設定され、CF_GREEN と等価になる。

フラグの値を取得したら、And 演算子を使用してフラグ フィールドのフラグの値を組み合わせ、個々のフラグが設定されているかどうかを確認できる。フラグ フィールドにフラグ定数が表すビットが設定されている場合、And 演算により、フラグが "オン" であることを示す 0 以外の値が返される。And 演算で 0 が返された場合、フラグは "オフ" である。たとえば、DirectInputDevice8.GetCapabilities メソッドの caps パラメータは、デバイスの能力が格納された DIDEVCAPS 型を返す場合に使用される。この型の lFlags メンバは、CONST_DIDEVCAPSFLAGS 列挙セットで指定された 1 つまたは複数のフラグを設定できるフラグ フィールドである。DIDC_ATTACHED フラグが設定された場合、デバイスはシステムに物理的にアタッチされている。次のコード例は、lFlags メンバと DIDC_ATTACHED を組み合わせる And 演算の値を調べることで、デバイスがアタッチされているかどうかを判定する方法を示している。

Dim IsAttached As Boolean
IsAttached = diDevCaps.lFlags And DIDC_ATTACHED 

lFlags が DIDC_ATTACHED と等価であるかどうかを単純にテストしてはならない。このフラグ フィールドには、複数のフラグ セットが含まれている可能性がある。複数のフラグが設定されている場合、DIDC_ATTACHED が設定されていても、次のテストは失敗する。

' 次のコードは間違いである。
IsAttached = (diDevCaps.lFlags = DIDC_ATTACHED)