tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルユーザーコントロールの背景を透明にすると文字がおかしくなる
記事No16276
投稿日: 2017/02/10(Fri) 13:16
投稿者mocky
現在、ラベルコントロールの拡張版のようなものを作成しています。
(Colorプロパティについては先程の投稿で解決しました。ありがとうとざいます)

Labelでは文字を上下方向に中央寄せのような表示ができないため、それを可能とするようにしています。

ほぼ完成していますが、BackStyleを透明にすると、文字の表示がおかしくなってしまいます。

ユーザーコントロールにはLabelがひとつだけ貼り付けています。

コントロールのBackStyleプロパティを透明に設定されるとUserControl、LabelのBackStyleを透明にしています。

すると、LabelのCaptionに設定された文字が一部欠けた状態になって表示されます。

イメージ的にはマスクパターンと、実際の文字列の位置がズレているような感じです。

既存のLabelと入れ替えたいので、できれば動作を合わせておきたいのです。

背景を透明にしても文字をキレイに表示する方法はないでしょうか。

[ツリー表示へ]
タイトルRe: ユーザーコントロールの背景を透明にすると文字がおかしくなる
記事No16277
投稿日: 2017/02/10(Fri) 16:30
投稿者魔界の仮面弁士
> コントロールのBackStyleプロパティを透明に設定されるとUserControl、LabelのBackStyleを透明にしています。

たとえば、このような表示になりますね。
http://www.vb-user.net/junk/replySamples/2017.02.10.14.49/Label1.png


> すると、LabelのCaptionに設定された文字が一部欠けた状態になって表示されます。

https://www.microsoft.com/japan/msdn/vs_previous/vbasic/TechInfo/kb/vb5kbidx/KBBug.htm
https://www.microsoft.com/japan/msdn/vs_previous/vbasic/TechInfo/kb/vb6kbidx/KBBug.htm
上記の
 179052 [VB] 透過コントロール上の透過ラベルの Caption が表示されない
に相当する障害ですね。

現在は該当ページが見えなくなっているようですので、Visual Studio 付属の
MSDN Library で、改正前の文書番号「J046164」「Q179052」を検索してみてください。


> 背景を透明にしても文字をキレイに表示する方法はないでしょうか。

有効な対策は無いと認識しています。

フォームをキャプチャして、それを UserControl の不透明背景に転写するか、
もしくは、フォーム自体に直接描画するなどの対処にするか、あるいは
UserControl は用いず、Label を直接 Form に貼るようにして、
Label の座標を調整して中央寄せのように見せかけるぐらいでしょうか。

その他、UserControl の MaskPicture と MaskColor を使うと言う手がありますが、
透過処理の都合上、TrueType/ClearType フォントのアンチエイリアスに対応できないため、
「透明」背景を使う方法だと、文字のジャギーが残ってしまい、綺麗な表示にはなりません。

[ツリー表示へ]
タイトルRe^2: ユーザーコントロールの背景を透明にすると文字がおかしくなる
記事No16278
投稿日: 2017/02/10(Fri) 19:38
投稿者mocky
魔界の仮面弁士様、いつもありがとうございます。


>  179052 [VB] 透過コントロール上の透過ラベルの Caption が表示されない
> に相当する障害ですね。

MSDNで確認しました。
調査中のまま放置されたようですね・・・。

> フォームをキャプチャして、それを UserControl の不透明背景に転写するか、

ちょっと難易度が高そうですね・・・
背景を透明にしているラベルがどれだけあるか不明ですが、少数であれば背景色を設定するようにします。

背景色の設定だと時間がかかりすぎるようであれば、フォームをキャプチャを考えてみます。


フォームのウィンドウハンドル、DCあたりを取得、コントロールがある場所の範囲をBitBltでコピー・・・とかでしょうか。
やっぱりちょっと難易度が高そう・・・。

[ツリー表示へ]
タイトルRe^3: ユーザーコントロールの背景を透明にすると文字がおかしくなる
記事No16279
投稿日: 2017/02/10(Fri) 23:30
投稿者魔界の仮面弁士
> フォームのウィンドウハンドル、DCあたりを取得、コントロールがある場所の範囲をBitBltでコピー・・・とかでしょうか。
OleDraw API とか BitBlt とかやりようはありますが、親コンテナの内容が
書き換わったら、即座に反映されるような作り込みが必要ですね。



> やっぱりちょっと難易度が高そう・・・。
UserControl 側に背景を描画するのではなく、
Container 側に前景を描画する方向で実装できないかと思案。

ContainerHwnd に対する WM_PAINT を拾い、
標準描画処理が行われた後で、GDI の TextOut API もしくは
GDI+ の GdipDrawString API などで追加描画するとか。

コンテナの AutoRedraw が有効なら、Print メソッドという手も
ありそうですが、その場合、Cls だか RedrawWindow だかで
前回の描画結果を消す処理も必要になりそうな予感。


ひとまず、Image や Label や Shape と同様の、「中層」配置なコントロールにするべく、
Windowless=True な UserControl を使って実験してみましたが、
再描画すべき領域が変動したタイミングを捉えきれませんでした。難しいですね。

 Caption の変更 → UserControl_AmbientChanged
 Height/Width の変更 → UserControl_Resize
 Left/Top の変更 → ???

[ツリー表示へ]
タイトルRe^4: ユーザーコントロールの背景を透明にすると文字がおかしくなる
記事No16281
投稿日: 2017/02/13(Mon) 09:32
投稿者mocky

> ひとまず、Image や Label や Shape と同様の、「中層」配置なコントロールにするべく、
> Windowless=True な UserControl を使って実験してみましたが、
> 再描画すべき領域が変動したタイミングを捉えきれませんでした。難しいですね。


わざわざありがとうございます。
やはりかなり難しそうですね。
ひとまず背景色の透明化は諦めます。

現行アプリでも、透明でないといけない場所はないと思いますので、背景色を指定することで対応します。
どうもありがとうございました。

[ツリー表示へ]