« BCB6とlocale | トップページ | dequeを使うとき。 »

2004年6月13日 (日)

子ウインドウの半透明化はどうやら不可能。

子ウインドウの半透明化をしようと思って挑戦したんですが挫折しました。
その記録まで。

・ウインドウを半透明化するには拡張ウインドウスタイルにWS_EX_LAYEREDを指定します。
これはCreateWindowExの時でもいいですし、作成後やすでにあるウインドウに対してSetWindowLongを行っても構いません。
WS_EX_LAYEREDを指定したらそのウインドウに対してSetLayeredWindowAttributesを実行します。

と、半透明化自体は結構簡単に出来ます。
ただ、子ウインドウに対してWS_EX_LAYEREDを適用しようとすると失敗します。
しかもSetWindowLongはエラーを設定しません。

HWND	hWnd;

	//hWndに対象のウインドウハンドルを取得。

//対象の拡張スタイルを取得
LONG	style = GetWindowLong(hWnd, GWL_EXSTYLE);

	//半透明化フラグを追加。
	style |= WS_EX_LAYERED;

//エラーフラグをクリア
SetLastError(0);

//拡張スタイルをセット
if(!SetWindowLong(hWnd, GWL_EXSTYLE, style))
{
	//戻り値が0。エラーフラグを確認
	if( GetLastError() != 0 )
		assert(0);	//エラーフラグが0以外ならエラー
}

//確認のため
LONG style2 = GetWindowLong(hWnd, GWL_EXSTYLE);

assert( style == style2 );	//…のはず。
上記のソースでassert(0)にはならない(つまりSetWindowLongは成功している)くせにassert( style == style2 );は成立しません。(もともとWS_EX_LAYEREDフラグがたっていないとした場合。)
つまり、SetWindowLongはちゃんと働いたフリをしてるけど実は何もしてないと。

ちなみに
style &= ~WS_EX_CLIENTEDGE;
という風に、他のフラグをいじった場合は普通に動作します。
また、
style &= ~WS_EX_CLIENTEDGE;
style |= WS_EX_LAYERED;
と、他のフラグと一緒にいじると他のフラグごとSetWindowLongは無視します。つまりWS_EX_LAYEREDを子ウインドウに設定しようとするとSetWindowLongは無視するわけです。

|

« BCB6とlocale | トップページ | dequeを使うとき。 »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



« BCB6とlocale | トップページ | dequeを使うとき。 »