硝子窓ライブラリ

Windows 95 以降のWindowsで透明/半透明のウィンドウを実現

配布条件を変更しました。(2002/05/28)

◆戻る | [硝子窓ライブラリとは?] [ダウンロード] [リンク] [掲示板]

Windows 2000 での画面サンプル
画面例
Windows 95 での画面サンプル

(飾り) 硝子窓ライブラリとは?

◆概要

 Windows 2000 には半透明ウィンドウを作る機能があります。しかし、それ以前のWindowsにはそういう機能はありませんでした。 「硝子窓(がらすまど)ライブラリ」は Windows2000 以前の Windows でその機能を擬似的に実現するためのライブラリです。

あなたのプログラムを半透明にしてみませんか?
このライブラリを使えばWindows2000専用にすることなく半透明機能を提供できます。

 硝子窓ライブラリを使えば、ほとんどのWindowsに対応した半透明アプリケーションをOSの違いを意識することなく開発できます。

◆機能

 このライブラリが提供する透明/半透明の機能は以下の通りです。

ただし、半透明の機能は「完全な半透明」ではなく「擬似的な半透明」を実現するものです。特に次の制限事項があります。
(Windows2000以降で実行した場合はこれらの制限は生じません。) なお、透明(アルファ値=0)の機能はいずれのOSにおいても期待通りに実現されます。

 透明や半透明の効果は、次のようなウィンドウには適用できません。

◆画面サンプル

 サンプルの実行ファイルはこちらからダウンロードできます。

[例1]カラーキー透過の例
[例2]カラーキー透過 + 一定アルファの例
[例3]ピクセル単位アルファブレンディングの例
[元画像1](例1と例2で使用。カラーキーは黒)
[元画像2,3](例3で使用。右がアルファ値(不透明度))

◆特徴

◆OS

 このソフトウェアは Windows 95/ 98/ 98SE/ NT4/ 2000 /Me /XP で動作することを意図して作成されています。

◆言語/コンパイラ

 C++で書かれています。

 Borland C++Builder 5 および Borland C++Compiler 5.5 でコンパイルできることを確認しました。 Visual C++ でもたぶんそのまま使えると思いますが未確認です。

◆注意事項

 このライブラリを使ってアプリケーションを開発するためには、Win32APIによるプログラミングの知識が必要です。

(飾り) ダウンロード

◆公開に当たって [ver 0.12]

 硝子窓ライブラリが提供する機能はとてもシンプルですが、使い方次第でいろいろなアプリケーションに応用できると思います。また、Windows2000以前のWindowsではあたかも OS の基本機能を拡張しているかのような錯覚さえ与えられます。

 しかしながら、このライブラリにはまだまだ改良の余地はありそうです。

 このライブラリはソースコードを公開していますので、誰でも自由に改造したり他のプログラムで利用することができます。どうぞ、気軽にご利用下さい。

◆配布条件など [ver 0.12以降]

 本ソフトウェアはフリーソフトウェアです。

 再配布する場合は、原著作者の署名と連絡先を改変したり削除しないでください。

 また、本ソフトウェアの全部または一部をコピーして他のプログラムのために自由に使用することができます。またそのプログラムを自由に配布できます。

 このソフトウェアの使用または使用不能によるいかなる損害についても、作者は責任を負いません。

◆ダウンロード

<2002/ 5/28> ver 0.12 サンプル実行ファイル (210KB)
ソースコード (196KB)

(飾り) 詳細

◆使い方

 必要な作業は以下の通りです。

 以上の作業により半透明機能が実現します。

 SetImage() を呼び出せばいつでも表示内容を変えることができます。

◆リファレンス

◆クラス TTransparentWindowManager

#include "libgw.h"
class libgw::TTransparentWindowManager;

[説明]
    透明や半透明の機能をウィンドウに適用するマネージャクラス。
    1つの TTransparentWindowManager インスタンスは、1つのウィンドウ
    を透明や半透明にする。
[namespace]
    libgw


◆メンバ関数 TTransparentWindowManager::Init

bool TTransparentWindowManager::Init(HWND handle, UINT timerID);

[機能]
    マネージャを初期化する。
[引数]
    handle    透明や半透明にするウィンドウのハンドル
    timerID   マネージャが内部で使用するためのタイマー識別子
[戻り値]
    成功したらtrueを返す。
[説明]
    timerID にはアプリケーションで使用しない適当なタイマー識別子を
    指定してください。handle引数で指定されるウィンドウがタイマーを
    使用しない場合 timerID 引数には適当に 12345 などを指定できます。


◆メンバ関数 TTransparentWindowManager::OnWindowMessage

void TTransparentWindowManager::OnWindowMessage(
    bool *handled, LRESULT *result,
    UINT msg, WPARAM wParam, LPARAM lParam );

[機能]
    ウィンドウメッセージをマネージャに通知し、必要なら処理させる。
[引数]
    handled   マネージャがウィンドウメッセージを処理したかどうかを
              受け取る bool 変数へのポインタ
              処理した場合は true が書き込まれる。
    result    マネージャがウィンドウメッセージを処理した場合の結果
              を受け取る LRESULT 変数へのポインタ
    msg       ウィンドウメッセージ
    wParam    ウィンドウメッセージの WPARAM 引数
    lParam    ウィンドウメッセージの LPARAM 引数
[説明]
    アプリケーションは、ウィンドウへ送られるウィンドウメッセージの
    すべてを OnWindowMessage 関数 によってマネージャに通知する必要
    があります。
    handled が指す bool 変数に true が返された時はアプリケーション
    はそのメッセージの処理を継続してはいけません。その時は、result
    が指す LRESULT 変数に返された値をメッセージの戻り値として下さい。


◆メンバ関数 TTransparentWindowManager::SetImage

bool TTransparentWindowManager::SetImage(
    swinlib::SMemoryBitmap const *foregroundImage,
    bool            enablePerPixelAlpha,
    COLORREF        colorKey,
    bool            enableColorKey,
    BYTE            constantAlpha );

[機能]
    表示内容と透明化/半透明化の機能を指定する。
[引数]
    foregroundImage     表示内容を保持する SMemoryBitmapインスタン
                        スへのポインタ
    enablePerPixelAlpha ピクセル単位アルファブレンディングを使うか
                        どうかのフラグ
    colorKey            カラーキーを指定する COLORREF 構造体
    enableColorKey      colorKey引数を使って透明化するかどうかのフ
                        ラグ
    constantAlpha       ウィンドウ全体に適用する一定のアルファ値
[戻り値]
    成功したらtrueを返す。
[説明]
    foregroundImage は 1ピクセル当たり32ビットのメモリビットマップ
    を格納した SMemoryBitmapインスタンスへのポインタを指定します。
    マネージャはこのポインタを内部に保持して描画のために使用します。
    従って次の SetImage 関数呼び出しによって表示内容を更新するまで
    の間、有効なインスタンスを指している必要があります。
    foregroundImage のピクセル形式は次のようになります。
        
        始めに説明のための構造体表記を示します。
          union Pixel{
            BYTE c[4];
            DWORD d;
          };
        
        * enablePerPixelAlpha == false の場合
          
          c[0]:     c[1]:     c[2]:     c[3]:
          [bbbbbbbb][gggggggg][rrrrrrrr][00000000]
          
          4バイトめ(c[3] )は必ずゼロを格納する事に注意してくださ
          い。
          
          DWORD型でアクセスした場合は次のようになります。
          d:
          MSB                                  LSB
          [00000000  rrrrrrrr  gggggggg  bbbbbbbb]
          
        * enablePerPixelAlpha == true の場合
          
          c[0]:     c[1]:     c[2]:     c[3]:
          [bbbbbbbb][gggggggg][rrrrrrrr][aaaaaaaa]
          
          4バイトめ(c[3] )はアルファ値(0〜255)を格納します。
          0から3バイトめはアルファ値を乗算済みのカラー値です。
          すなわち B <= A && G <= A && R <= A でなければなりません。
          乗算前のARGB形式から乗算済みのARGB形式に変換するには、
          swinlib::MultiplyAlpha 関数を利用できます。
          
          DWORD型でアクセスした場合は次のようになります。
          d:
          MSB                                  LSB
          [aaaaaaaa  rrrrrrrr  gggggggg  bbbbbbbb]
    
    enablePerPixelAlpha 引数が true の場合、アルファ値がゼロである
    ピクセルは透明化されます。
    
    カラーキーによる透明化処理を有効にする場合は、colorKey引数に有
    効なCOLORREF構造体(RGB マクロを使用して作ることができる)を指
    定し enableColorKey 引数に true を指定します。  表示内容の中の
    colorKey で指定される色と一致するピクセルは透明化されます。
    enableColorKey 引数が false の時は colorKey 引数は無視されます。
    
    透明化された領域は背後のウィンドウが完全におもてに見えるように
    なり、その領域におけるマウスクリックなどのメッセージはOSによっ
    て背後のウィンドウへ直接送られるようになります。
    
    enablePerPixelAlpha と enableColorKey には同時に true を指定す
    ることはできません。
    
    constantAlpha に指定するアルファ値は 0から255の範囲の値です。
    0を指定するとウィンドウ全体が見えなくなります。


◆クラス SMemoryBitmap

#include "sbitmap.h"
class swinlib::SMemoryBitmap;

[説明]
    メモリビットマップ(DIBセクション)を生成し保持するクラス。
[namespace]
    swinlib


◆メンバ関数 SMemoryBitmap::Create

void SMemoryBitmap::Create(HDC modelDC,
    SPixelFormat format, int width, int height );

[機能]
    メモリビットマップを生成する。
[説明]
    既に生成済みの場合は自動的に削除されてから新しいメモリビットマ
    ップが生成される。
[例]
    SMemoryBitmap memBitmap;
    memBitmap.Create(NULL, swinlib::pf_32bit, width, height );


◆メンバ関数 SMemoryBitmap::Free

[機能]
    メモリビットマップを破棄する。


◆メンバ関数 SMemoryBitmap::Bitmap

[機能]
    ハンドル(HBITMAP)を返す。


◆メンバ関数 SMemoryBitmap::DC

[機能]
    デバイスコンテキストを返す。


◆メンバ関数 SMemoryBitmap::BitmapInfo

[機能]
    ビットマップの形式を表す BITMAPINFO 構造体へのポインタを返す。


◆メンバ関数 SMemoryBitmap::Format

[機能]
    ピクセル形式を表す swinlib::SPixelFormat 値を返す。


◆メンバ関数 SMemoryBitmap::Bits

[機能]
    ピクセルデータの先頭(左上の角)へのポインタを返す。


◆メンバ関数 SMemoryBitmap::Width

[機能]
    ビットマップの横のピクセル数を返す。


◆メンバ関数 SMemoryBitmap::Height

[機能]
    ビットマップの縦のピクセル数を返す。


◆メンバ関数 SMemoryBitmap::Stride

[機能]
    ピクセルデータにおけるあるラインの左端から次のラインの左端まで
    のバイト数を返す。


◆メンバ関数 SMemoryBitmap::ScanLine

void* SMemoryBitmap::ScanLine(int row)const;

[機能]
    Y座標 row のラインの左端のピクセルデータへのポインタを返す。

◆技術的な詳細

 硝子窓ライブラリは以下の2つの内部モードを持っています。

モードはライブラリによって自動的に選択され、機能の違いはライブラリが可能な限り吸収するので、ライブラリのユーザはこれらのモードの違いを特別扱いすることなくアプリケーションを開発できます。

◆Win9x互換モード

 Win9x互換モードでは、 ウィンドウによって隠されている背景のイメージを実時間では取得できないというOSの制限があるため、半透明を実現するためには背景が隠される前になんとかしてそのイメージを取得する必要があります。

 そこで硝子窓ライブラリでは、ウィンドウが最初に画面に表示される直前にその背景のイメージを取得して保持します。その後、ウィンドウが移動やサイズ変更するときは、その移動が実際に画面に反映される直前に、移動によって新たに隠される画面領域のイメージを取得して、保持しているイメージに継ぎ足します。移動によっておもてに出る部分の背景イメージはすぐに破棄します。これにより常に、ウィンドウの後ろに隠されている背景のイメージをできるだけ最新の状態でしかも無駄なく保持し続ける仕組みになっています。

 背景の取得は GetDesktopWindow() --> GetWindowDC() --> BitBlt()で行います。ただしこれだけでは、描画が終わっていない不完全な背景イメージを取得してしまう可能性があります。この問題を解決するため、硝子窓ライブラリでは、 BitBlt() を行う直前にその領域にあるウィンドウに対して UpdateWindow() を呼び出すことで描画を完成させます。これにより描きかけではない背景イメージを最短の時間で取得します。

 Win9x互換モードにおいて、透明(アルファ値=0 )なピクセルはリージョン機能によって実現されます。

◆Win2kモード

 Win2kモードでは、レイヤードウィンドウAPIを使用します。

 リージョン機能は使用しません。Windows2000 でリージョン機能を使うと極端にパフォーマンスが低下するためです。

◆既知の問題

 Win2kモードでカラーキー透過と255未満の一定アルファ値を組み合わせると、画面の色数、カラーキー、などによってはうまく透過しない。(Windows2000 の問題あるいは仕様と思われる)
カラーキーとして完全な黒( RGB(0,0,0) )を使用すればうまく行くようです。

 Win9xモードではウィンドウの背景は隠された瞬間に固定されるので、見えているものは最新とは限らない。(仕様)

 Win9xモードではウィンドウの背景は正しく取得できないこともある。(仕様)

(飾り) 開発履歴

2000/ 5/12ver 0.01 最初の実装
2000/ 5/20ver 0.02 Windows2000のAPIが使えるなら使うようにした。
2001/ 5/24ver 0.03 Per-Pixel,ColorKey,ConstantAlphaの組み合わせに対応
2001/ 6/ 2ver 0.10 最初の公開バージョン
2001/ 6/10ver 0.11 - Win32APIのみによるサンプルを追加
 (フリーのBorland C++Compiler5.5で確認)
- AutoSizeプロパティを追加
- SBitmap::Pixel 関数を追加
- 不要な警告メッセージを削減
- BitmapARGBFromHBitmap関数の仕様を変更
(ピクセル単位アルファブレンディングのサンプルで使用しているので、
 サンプルをコピーした場合は注意してください。
 ssurfacetools.hを参照)
- swin2kapi.hのバグフィックス(#ifdef --> #ifndef)
2002/ 5/28ver 0.12 配布条件を変更

(飾り) リンク

窓立て2
窓立て2は硝子窓ライブラリによって半透明化を実現しています。

画面例
(Windows 95 使用 2003/01/26)

(飾り) 掲示板

 ご意見、感想などは「窓立て掲示板」をご利用下さい。(硝子窓ライブラリは一応、窓立て関連ソフトです(^^;)