【问题标题】:Alpha transparent window formAlpha透明窗口窗体
【发布时间】:2012-05-22 09:18:06
【问题描述】:

我得到以下代码,将带有 alpha 通道的 PNG 加载到表单上,并重塑表单以匹配 alpha 通道。

Public Function applyAlphaForm(ByVal f As Form, ByVal bitmap As Bitmap, Optional ByVal opacity As Byte = 255) As Boolean
    f.FormBorderStyle = FormBorderStyle.None
    Dim style As Long
    style = Win32.GetWindowLong(f.Handle, Win32.GWL_EXSTYLE)
    If Not (style And Win32.WS_EX_LAYERED = Win32.WS_EX_LAYERED) Then
        style = style Or Win32.WS_EX_LAYERED
        Win32.SetWindowLong(f.Handle, Win32.GWL_EXSTYLE, style)
    End If
    Return SetBitmap(f, bitmap, opacity)
End Function

Public Function SetBitmap(ByVal f As Form, ByVal bitmap As Bitmap, ByVal opacity As Byte) As Boolean
    f.Height = bitmap.Height
    f.Width = bitmap.Width
    If bitmap.PixelFormat <> PixelFormat.Format32bppArgb Then
        f.BackgroundImage = bitmap
        f.TransparencyKey = bitmap.GetPixel(0, 0)
        Return True
    End If

    Dim screenDC As IntPtr = Win32.GetDC(IntPtr.Zero)
    Dim memDC As IntPtr = Win32.CreateCompatibleDC(screenDC)
    Dim hBitmap As IntPtr = IntPtr.Zero
    Dim oldBitmap As IntPtr = IntPtr.Zero

    Try
        hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)) 'grab a GDI handle from this GDI+ bitmap
        oldBitmap = Win32.SelectObject(memDC, hBitmap)

        Dim size As Win32.Size = New Win32.Size(bitmap.Width, bitmap.Height)
        Dim pointSource As Win32.Point = New Win32.Point(0, 0)
        Dim topPos As Win32.Point = New Win32.Point(f.Left, f.Top)
        Dim blend As Win32.BLENDFUNCTION = New Win32.BLENDFUNCTION()
        blend.BlendOp = Win32.AC_SRC_OVER
        blend.BlendFlags = 0
        blend.SourceConstantAlpha = opacity
        blend.AlphaFormat = Win32.AC_SRC_ALPHA

        Win32.UpdateLayeredWindow(f.Handle, screenDC, topPos, size, memDC, pointSource, 0, blend, Win32.ULW_ALPHA)

    Catch ex As Exception
    Finally
        Win32.ReleaseDC(IntPtr.Zero, screenDC)
        If hBitmap <> IntPtr.Zero Then
            Win32.SelectObject(memDC, oldBitmap)
            Win32.DeleteObject(hBitmap)
        End If
        Win32.DeleteDC(memDC)
    End Try
    Return True
End Function

很好很简单,但是如果我在表单上放置一些控件(按钮、文本框...),它们就会消失。我邀请 UpdateLayeredWindow 将在表单 hDC 上进行绘制,因此我们看不到它后面的任何内容。那么如何在表单上绘制一些表单控件呢?在调用 api 之前,我尝试遍历所有控件并渲染为 png 位图,但这将是静态图像。

【问题讨论】:

  • 为什么不直接将位图转换为 32bpp 并去掉该代码?
  • 糟糕!我找到了解决方案:stackoverflow.com/questions/2979125/… :(
  • @Hans Passant:我想要来自 PNG 的半透明数据(一些不透明区域)...

标签: vb.net winforms vb.net-2010 windows-applications


【解决方案1】:

所以我来宾我必须创建两个,一个是 alpha 透明的背景表单,一个是带有控件的前景表单。控制窗体只会显示控制区域。

【讨论】:

    猜你喜欢
    • 2012-12-27
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 2013-02-21
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多