C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: VistaとXpの違い。透過フォームについて


(過去ログ 58 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■32952 / inTopicNo.1)  VistaとXpの違い。透過フォームについて
  
□投稿者/ chana (5回)-(2009/02/18(Wed) 09:42:41)

分類:[VB.NET/VB2005 以降] 

おはようございます。
WindowsVista+VB2005で開発しております。

メインフォーム上に透明なフォームを出して、見た目ではメインフォーム上に線を引く様なソフトを作成しました。
透明なフォームにPictureboxを貼ってマウスによる線引きをしています。

Vistaでは問題なく動くのですが、XPでテストしたところ透明なフォームにすると
透明なフォームにフォーカスが入って来なくなります。
当然ですがMouseDown、MouseMoveも来ないので線が引けません。
試しに透過を止めるとフォーカスは入ってきます。

ちなみに、Opacityで薄くしてやってみましたが線は引けますが全部が薄いのでNGでした。

OSによる違いはあるかと思いますが、この問題を解決するにはどんな手があるか知恵を貸して頂けませんでしょうか?


Public frmP As New frmPaint() ---->透明なフォーム

<Main Form_Load>
Me.AddOwnedForm(frmP)
'フォームをモードレスで表示する
frmP.Show()



<frmP Form_Load>
'フォームの境界線をなくす
Me.FormBorderStyle = FormBorderStyle.None
'大きさを適当に変更
Me.Size = New Size(frm1X, frm1Y)
Me.Location = New Point(frmPicPoint.X, frmPicPoint.Y)

'画像を読み込む
Dim bmp As New Bitmap("form.bmp")
'透明にする色
Dim transColor As Color = bmp.GetPixel(0, 0)
'画像を透明にする
bmp.MakeTransparent(transColor)
'背景画像を指定する
Me.BackgroundImage = bmp
'背景色を指定する
Me.BackColor = transColor
'透明を指定する
Me.TransparencyKey = transColor --->ここをコメントにすればフォーカスは来ますが透明で無くなってしまいます。



どうぞ宜しくお願いします。


引用返信 編集キー/
■32958 / inTopicNo.2)  Re[1]: VistaとXpの違い。透過フォームについて
□投稿者/ 魔界の仮面弁士 (998回)-(2009/02/18(Wed) 10:34:16)
No32952 (chana さん) に返信
> ちなみに、Opacityで薄くしてやってみましたが線は引けますが全部が薄いのでNGでした。

もしも API を使っても良いのであれば、UpdateLayeredWindow API を使うと言うのはどうでしょうか。
(Opacity や TransparencyKey は、SetLayeredWindowAttributes API の動作に相当します)

UpdateLayeredWindow を使ったレイヤード ウィンドウは、部分的に半透明な状態を作り出せますので、
フォーム全体は、ほぼ完全透過に近い半透明にし、描画部分だけは完全不透明という状況を作り出せます。
引用返信 編集キー/
■32983 / inTopicNo.3)  Re[2]: VistaとXpの違い。透過フォームについて
□投稿者/ chana (6回)-(2009/02/18(Wed) 13:49:40)
No32958 (魔界の仮面弁士 さん) に返信
> ■No32952 (chana さん) に返信
>>ちなみに、Opacityで薄くしてやってみましたが線は引けますが全部が薄いのでNGでした。
>
> もしも API を使っても良いのであれば、UpdateLayeredWindow API を使うと言うのはどうでしょうか。
> (Opacity や TransparencyKey は、SetLayeredWindowAttributes API の動作に相当します)
>
> UpdateLayeredWindow を使ったレイヤード ウィンドウは、部分的に半透明な状態を作り出せますので、
> フォーム全体は、ほぼ完全透過に近い半透明にし、描画部分だけは完全不透明という状況を作り出せます。

魔界の仮面弁士さん
どうもありがとうございます。
早速レイヤードウィンドウで試していますが、まだレイヤードウィンドウ自体できない状態です。
じっくりやってみたいと思います。


引用返信 編集キー/
■32987 / inTopicNo.4)  Re[3]: VistaとXpの違い。透過フォームについて
□投稿者/ りょう (5回)-(2009/02/18(Wed) 14:23:35)
.Net 1.0の時代に、全く同じような事をした経験があります。


確か、
Formだけを透過させた場合
Formの上にPictureBoxを張り付けて透過させた場合、
この2つの挙動が違った記憶があります。。。。

MouseDownが透過するとかしないとか・・・
.Netのバグ?だとかで、MSに問い合わせた記憶があるような無いような・・。


最終的には、マウスフックを行い、マウスイベントを貰って、
それを透明画面に流し込んで解決しました。


参考になるか分かりませんが、情報として・・・。
引用返信 編集キー/
■32990 / inTopicNo.5)  Re[3]: VistaとXpの違い。透過フォームについて
□投稿者/ 魔界の仮面弁士 (1000回)-(2009/02/18(Wed) 14:32:51)
2009/02/18(Wed) 14:34:37 編集(投稿者)

> メインフォーム上に透明なフォームを出して
フォームの上にフォームを出すというのが、どういう状況を
指しているのか、良くわかりませんでした。


No32983 (chana さん) に返信
> 早速レイヤードウィンドウで試していますが、まだレイヤードウィンドウ自体できない状態です。
> じっくりやってみたいと思います。

以前、私が(C#で)やった時には、こんな手順で実装していました。

(0) CreateParams をオーバーライドして、ExStyle に WS_EX_LAYERED を追加しておく。
(1) 透明度情報(Alpha)を持った PNG 画像を用意しておく。
(2) 1 を読み込んだ Bitmap クラスから、GetHbitmap で HBITMAP を得る。
(3) GetDC(IntPtr.Zero) で HDC を得る。
(4) 3 の HDC を CreateCompatibleDC して、メモリDC を得る。
(5) SelectObject で、4 のメモリ DC に 2 の HBITMAP を割り当て、以前の HBITMAP を得る。
(6) UpdateLayeredWindow を ULW_ALPHA 指定で呼び出す。
(7) ReleaseDC で 3 の HDC を解放。
(8) SelectObject で、4 のメモリ DC に 5 の旧 HBITAMP を割り当てなおす。
(9) DeleteObject で、2 の HBITMAP を解放。
(10) DeleteDC で、3 の HDC を解放。
引用返信 編集キー/
■32992 / inTopicNo.6)  Re[4]: VistaとXpの違い。透過フォームについて
□投稿者/ chana (7回)-(2009/02/18(Wed) 14:56:23)
りょうさん

アドバイスありがとうございます。

> 確か、
> Formだけを透過させた場合
> Formの上にPictureBoxを張り付けて透過させた場合、
> この2つの挙動が違った記憶があります。。。。

やっとレイヤードウィンドウで透過する事ができました。
Pictureboxは透過しませんでした。それ以上追及しておりませんが・・
そこでフォームに直接描画しようとやってみましたが
透過されているところはマウスも透過されているようですね。

>
> 最終的には、マウスフックを行い、マウスイベントを貰って、
> それを透明画面に流し込んで解決しました。

マウスフックですか。。
私も同様の事をしないとできそうもありませんね・・・
mainFormで監視すればいいのでしょうか?
調べてみます。


引用返信 編集キー/
■32993 / inTopicNo.7)  Re[4]: VistaとXpの違い。透過フォームについて
□投稿者/ chana (8回)-(2009/02/18(Wed) 15:01:39)
>
> (0) CreateParams をオーバーライドして、ExStyle に WS_EX_LAYERED を追加しておく。
> (1) 透明度情報(Alpha)を持った PNG 画像を用意しておく。
> (2) 1 を読み込んだ Bitmap クラスから、GetHbitmap で HBITMAP を得る。
> (3) GetDC(IntPtr.Zero) で HDC を得る。
> (4) 3 の HDC を CreateCompatibleDC して、メモリDC を得る。
> (5) SelectObject で、4 のメモリ DC に 2 の HBITMAP を割り当て、以前の HBITMAP を得る。
> (6) UpdateLayeredWindow を ULW_ALPHA 指定で呼び出す。
> (7) ReleaseDC で 3 の HDC を解放。
> (8) SelectObject で、4 のメモリ DC に 5 の旧 HBITAMP を割り当てなおす。
> (9) DeleteObject で、2 の HBITMAP を解放。
> (10) DeleteDC で、3 の HDC を解放。

魔界の仮面弁士さん
ありがとうございます。
レイヤードを調べている時の魔界の仮面弁士さんの記事を見つけまして参考にさせて頂きました。


引用返信 編集キー/
■33087 / inTopicNo.8)  Re[5]: VistaとXpの違い。透過フォームについて
□投稿者/ chana (9回)-(2009/02/20(Fri) 13:00:04)
レイヤードウィンドウ+マウスフックをしてみましたが、MouseDownが入ってこないのは一緒でした。
別の方法を探します。
解決済み
引用返信 編集キー/
■33090 / inTopicNo.9)  Re[6]: VistaとXpの違い。透過フォームについて
□投稿者/ 魔界の仮面弁士 (1010回)-(2009/02/20(Fri) 13:26:45)
2009/02/20(Fri) 13:59:32 編集(投稿者)

# 元が解決済みになっているので、解決チェックをつけた状態にしておきます。
## と思ったら No33091 で解決チェックが解除されたので、再々編集して未解決状態に戻しておきます。

No33087 (chana さん) に返信
> レイヤードウィンドウ+マウスフックをしてみましたが、MouseDownが入ってこないのは一緒でした。

Vista で試していないので分かりませんが、
全透過ならともかく、半透過でも触れなくなる物なのかな…。
(少なくとも、手元の XP では MouseDown を認識しているので)

> 別の方法を探します。

DirectInput で、マウス押下を検出するのはどうでしょうか。
それで駄目なら、MousePosition / MouseButtons を Timer で監視すれば、
フォームの状態に関係なく、マウス位置を取得できるのではないかと。
引用返信 編集キー/
■33091 / inTopicNo.10)  Re[7]: VistaとXpの違い。透過フォームについて
□投稿者/ chana (11回)-(2009/02/20(Fri) 13:29:20)
chana さんの Web サイト
No33090 (魔界の仮面弁士 さん) に返信
> ■No33087 (chana さん) に返信
>>レイヤードウィンドウ+マウスフックをしてみましたが、MouseDownが入ってこないのは一緒でした。
>
> Vista で試していないので分かりませんが、
> 全透過ならともかく、半透過でも触れなくなる物なのかな…。
>
>
>>別の方法を探します。
>
> DirectInput で、マウス押下を検出するのはどうでしょうか。
> それで駄目なら、MousePosition / MouseButtons を Timer で監視すれば、
> フォームの状態に関係なく、マウス位置を取得できるのではないかと。

魔界の仮面弁士さん

いつもお世話になります。

半透明ですか!それはやって無かったですね。
早速試してみます。



引用返信 編集キー/
■33093 / inTopicNo.11)  Re[8]: VistaとXpの違い。透過フォームについて
□投稿者/ 魔界の仮面弁士 (1011回)-(2009/02/20(Fri) 13:57:52)
全文引用は避けましょう。

No33091 (chana さん) に返信
> 半透明ですか!それはやって無かったですね。

その前の No32958 で、「ほぼ完全透過に近い半透明」という案を出していたり。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -