让窗口忽略交互性(Ghost / Overlay窗口)

时间:2013-04-24 03:33:31

标签: .net vb.net winforms

我有一个窗口,其FormBorderStyle为None,其中一个图片框停靠在表单上。因此,基本上所有显示的都是照片。我现在把它设置为Top Most。我想要做的是如果他们点击图像上的某个地方,它将忽略该窗口上的点击并与其下的窗口进行交互。我这样认为它会起作用,但事实并非如此。我猜测点击的速度不足以显示表单,或者我可能必须关闭或最小化表单。

    Me.Hide()
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    Me.Show()

1 个答案:

答案 0 :(得分:2)

在Win32编程模型中,您描述的窗口类型称为“透明”窗口。

请注意,这与不透明度不同,它经常会与之混淆。透明窗口可以看到鼠标点击等事件,但它可能仍然是不透明(即,视觉上不透明)。您可以同时具有命中测试透明度和视觉透明度,或者只有一个,或两者都没有。

要使窗口命中测试透明,您需要在创建窗口时设置WS_EX_TRANSPARENT extended window style

要从VB.NET中执行此操作,请覆盖表单的CreateParams property并添加样式标记,如下所示:

Protected Overrides ReadOnly Property CreateParams As CreateParams
    Get
        Const WS_EX_TRANSPARENT As Integer = &H20

        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
        Return cp
    End Get
End Property

请注意,当您使窗口透明时,您将获得一个完全透明的窗口,就像您提出的那样。这意味着鼠标点击将完全不可见,包括在非客户区域。用户甚至无法单击左上角的关闭框。应用程序必须以编程方式关闭窗口。您需要在设计中考虑到这一点。


打开和关闭样式需要更多代码。您需要P / Invoke Win32函数来检索和设置当前窗口样式。例如:

Imports System
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
' ...etc.

Public Class MyForm : Inherits Form

    ' P/Invoke stuff

    Private Const GWL_EXSTYLE As Integer = -20
    Private Const WS_EX_TRANSPARENT As Integer = &H20

    <DllImport("user32.dll")> _
    Private Shared Function GetWindowLongPtr(hWnd As IntPtr, _
                                             nIndex As Integer) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function SetWindowLongPtr(hWnd As IntPtr, _
                                            nIndex As Integer, _
                                            dwNewLong As IntPtr) As IntPtr                                                
    End Function

    ' Toggling function
    Public Sub ToggleClickTransparency()
        ' Get the form's current extended window styles.
        Dim exStyle As IntPtr = GetWindowLongPtr(Me.Handle, GWL_EXSTYLE)

        ' Determine if the transparency flag is currently set.
        If (exStyle Or WS_EX_TRANSPARENT) = WS_EX_TRANSPARENT Then
            ' Remove the flag.
            exStyle = exStyle And (Not WS_EX_TRANSPARENT)
        Else
            ' Add the flag.
            exStyle = exStyle Or WS_EX_TRANSPARENT
        End If

        ' Update the window's styles.
        SetWindowLongPtr(Me.Handle, GWL_EXSTYLE, exStyle)
    End Sub

    ' Other code
    ' ...

End Class
相关问题