透過されたpng画像

タグの編集
投稿者 Lyuigi  (中学生) 投稿日時 2009/1/22 01:26:10
初めて質問させてもらいます。
趣味でプログラミングをしている中学二年生です。

MyTrashCanというフリーソフトを知っていますか?
あのソフトのように透過されたpng画像を表示するにはどうすればいいのでしょうか。
FormのBackColorプロパティにTransparentを設定することができないので困っています。
TransparencyKeyなども試してみましたがどうもうまくいきません。
VBではできないのでしょうか?

ご教授してくださる方がいたらよろしくお願いします。
投稿者 るしぇ  (社会人) 投稿日時 2009/1/22 01:51:44
> MyTrashCanというフリーソフトを知っていますか?
検索したらゴミ箱のアイコン変更ツールでした。

> あのソフトのように透過されたpng画像を表示
アイコンファイルじゃないの?

> TransparencyKeyなども試してみましたがどうもうまくいきません。
[DOBON.NET フォームウィンドウの特定の色を透明にする]
http://dobon.net/vb/dotnet/form/transparencykey.html
『うまくいきません』ではどういう結果が得られたのかが
伝わりませんので、どういった情報が必要なのか分かりません。
とりあえず、上記リンクの
> うまくいかない場合は?
に該当するなら、それ以降のコードを試してみてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/1/22 01:54:10
フォームの Region プロパティについて調べてみてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/1/22 02:40:55
枠の無いフォームが表示されますので、そこに背景透過なGIF/PNGファイルをドロップしてみてください。
巨大な画像は処理に時間がかかるので注意。
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Class Form1

    Private oldRegion, newRegion As Region
    Private oldImage, newImage As Image

    Private Sub Form1_DoubleClick(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.DoubleClick
        Me.Close()
    End Sub

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        Me.AllowDrop = True
        Me.TopMost = True
        oldRegion = Me.Region
        oldImage = Me.BackgroundImage
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As ObjectByVal e As FormClosedEventArgs) Handles Me.FormClosed
        If newRegion IsNot Nothing Then
            Me.Region = oldRegion
            newRegion.Dispose()
        End If
        If newImage IsNot Nothing Then
            Me.BackgroundImage = oldImage
            newImage.Dispose()
        End If
    End Sub


    Private Sub Form1_DragOver(ByVal sender As ObjectByVal e As DragEventArgs) Handles Me.DragOver
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            e.Effect = DragDropEffects.Copy
        End If
    End Sub

    Private Sub Form1_DragDrop(ByVal sender As ObjectByVal e As DragEventArgs) Handles Me.DragDrop
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then
            Me.AllowDrop = False

            Dim dropFiles() As String = e.Data.GetData(DataFormats.FileDrop)
            newImage = New Bitmap(dropFiles(0))
            Me.ClientSize = newImage.Size
            Me.BackgroundImage = newImage

            ' http://smdn.invisiblefulmoon.net/mnemorepos/20040229-00.html 
            newRegion = CreateRegionFromImage(newImage, Color.Transparent)

            Me.BackgroundImage = newImage
            Me.Region = newregion
        End If
    End Sub
End Class
投稿者 Lyuigi  (中学生) 投稿日時 2009/1/22 03:51:13
説明が分かりにくくてすいません。
画像を用意しました。こういうことです。
http://quartzcrystal3.web.fc2.com/
(上がMyTrashCan。
 下は[DOBON.NET フォームウィンドウの特定の色を透明にする]を使ったもの。)

ところでMyTrashCanはアイコン変更ツールではないと思うのですが・・・
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/1/23 07:18:47
MyTrashCan の動作を見る限り、レイヤード ウィンドウ(※1)が使われているようですが、
これは API を使わねばならないので、難易度が高いですよ。

.NET でレイヤード ウィンドウといえば、Form.TransparecyKey / Form.Opacity プロパティが
該当しますが、これらのプロパティは SetLayeredWindowAttributes API (※2)に相当する物であり、
今回のように部分的に透過率を変えたいような場合には利用できません。

同じ画面上に透過度の違うエリアを作りたい場合は、UpdateLayeredWindow API (※3)を
使わねばなりませんが、これに相当する機能は .NET Framework には用意されていないようなので、
Declare ステートメント(もしくは、DllImport 属性)を用いて、この API を
直接呼び出すコードを書く必要があります (※4, ※5)。


-----------------------------------------------------------------
(※1)レイヤード ウィンドウという言葉を聞いた事が無ければ、下記を参照してください。
http://msdn.microsoft.com/ja-jp/library/ms997507.aspx

(※2) SetLayeredWindowAttributes API の仕様について。
http://msdn.microsoft.com/ja-jp/library/cc411043.aspx

(※3) UpdateLayeredWindow API の仕様について。
http://msdn.microsoft.com/ja-jp/library/cc364847.aspx

(※4) C# での実装サンプル。main.exe を起動し、そこに png 画像をドロップしてみましょう。
http://www.codeproject.com/KB/GDI-plus/perpxalpha_sharp.aspx

(※5) VB での実装ヒント。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41225&forum=7