VB.net点阅表格

问题描述 投票:1回答:5

我正在尝试为深夜注视编写程序,我需要笔记本电脑的屏幕只有红色,所以我想制作一个充当红色滤镜的程序。它将覆盖整个屏幕,并且为透明+红色。用户可以单击它,就像在屏幕前面放一块透明的红色塑料一样。

到目前为止,我的表单可以将其大小调整为您的屏幕大小,然后将其移动到左上角。它略带透明和红色。

我需要使表单上的所有点击都通过,因为我最终会使表单透明和红色,但是我不希望用户能够与它进行交互。

程序被称为“ Red_Filter”

Public Class Form1

Dim Screens As Array
Dim TotalWidth As Integer
Dim TotalHeight As Integer
Dim Heights As List(Of Integer) = New List(Of Integer)

'Load / Close
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Screens = Screen.AllScreens

    For I As Integer = 0 To UBound(Screens)

        TotalWidth += Screens(I).Bounds.Width
        Heights.Add(Screens(I).Bounds.Height)

    Next

    TotalHeight = Heights.Max()

    Me.Width = TotalWidth
    Me.Height = TotalWidth

    Me.Location = New Point(0, 0)

    Me.BackColor = Color.Red
    Me.Opacity = 0.5
    Me.TopMost = True

    'Make it click through
    SetWindowLong(Me.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT)
End Sub


'Click Through Functionality
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Const GWL_EXSTYLE = -20
Const WS_EX_TRANSPARENT = &H20

End Class

这是我到目前为止在网上找到的“'点击后功能”部分,但是,它给了我这个错误:

A call to PInvoke function 'Red Filter!Red_Filter.Form1::SetWindowLong' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我不知道我在网上找到的代码是如何工作的,但是错误发生在表单的load事件的最后一行。

有人知道如何点击表单吗?

vb.net forms click transparent
5个回答
3
投票

我从此代码项目帖子中剥离了代码:http://www.codeproject.com/Articles/12877/Transparent-Click-Through-Forms

这是一个具有所有注释优势的复杂版本:

Imports System.Runtime.InteropServices

Public Class Form1

Private InitialStyle As Integer
Dim PercentVisible As Decimal

Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ' Grab the Extended Style information
    ' for this window and store it.
    InitialStyle = GetWindowLong(Me.Handle, GWL.ExStyle)
    PercentVisible = 0.8

    ' Set this window to Transparent
    ' (to the mouse that is!)

    ' This creates a new Extended Style
    ' for our window, which takes effect
    ' immediately upon being set, that
    ' combines the initial style of our window
    ' (saved in Form.Load) and adds the ability
    ' to be Transparent to the mouse.
    ' Both Layered and Transparent must be
    ' turned on for this to work AND have
    '  the window render properly!
    SetWindowLong(Me.Handle, GWL.ExStyle, InitialStyle Or WS_EX.Layered Or WS_EX.Transparent)

    ' Don't forget to set the Alpha
    ' for the window or else you won't be able
    ' to see the window! Possible values
    ' are 0 (visibly transparent)
    ' to 255 (visibly opaque). I'll set
    ' it to 70% visible here for show.
    ' The second parameter is 0, because
    ' we're not using a ColorKey!
    SetLayeredWindowAttributes(Me.Handle, 0, 255 * PercentVisible, LWA.Alpha)

    ' Just for giggles, set this window
    ' to stay on top of all others so we
    ' can see what's happening.
    Me.TopMost = True
    Me.BackColor = Color.Red
End Sub

Public Enum GWL As Integer
    ExStyle = -20
End Enum

Public Enum WS_EX As Integer
    Transparent = &H20
    Layered = &H80000
End Enum

Public Enum LWA As Integer
    ColorKey = &H1
    Alpha = &H2
End Enum

<DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
Public Shared Function GetWindowLong( _
    ByVal hWnd As IntPtr, _
    ByVal nIndex As GWL _
        ) As Integer
End Function

<DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
Public Shared Function SetWindowLong( _
    ByVal hWnd As IntPtr, _
    ByVal nIndex As GWL, _
    ByVal dwNewLong As WS_EX _
        ) As Integer
End Function

<DllImport("user32.dll", _
  EntryPoint:="SetLayeredWindowAttributes")> _
Public Shared Function SetLayeredWindowAttributes( _
    ByVal hWnd As IntPtr, _
    ByVal crKey As Integer, _
    ByVal alpha As Byte, _
    ByVal dwFlags As LWA _
        ) As Boolean
End Function
End Class

这是我使用的简化版本,对我来说更有意义:

Imports System.Runtime.InteropServices

Public Class Form1

Private InitialStyle As Integer
Dim PercentVisible As Decimal

Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    InitialStyle = GetWindowLong(Me.Handle, -20)
    PercentVisible = 0.8

    SetWindowLong(Me.Handle, -20, InitialStyle Or &H80000 Or &H20)

    SetLayeredWindowAttributes(Me.Handle, 0, 255 * PercentVisible, &H2)

    Me.BackColor = Color.Red
    Me.TopMost = True
End Sub

<DllImport("user32.dll", EntryPoint:="GetWindowLong")> Public Shared Function GetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
End Function

<DllImport("user32.dll", EntryPoint:="SetWindowLong")> Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function

<DllImport("user32.dll", EntryPoint:="SetLayeredWindowAttributes")> Public Shared Function SetLayeredWindowAttributes(ByVal hWnd As IntPtr, ByVal crKey As Integer, ByVal alpha As Byte, ByVal dwFlags As Integer) As Boolean
End Function

End Class

0
投票

使用VS 2012,我创建了一个简单的程序,没有您的Screens对象,像这样:

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Me.BackColor = Color.Red
        Me.Opacity = 0.5
        Me.TopMost = True

        SetWindowLong(Me.Handle.ToInt64(), GWL_EXSTYLE, WS_EX_TRANSPARENT)

    End Sub

    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Const GWL_EXSTYLE = -20
    Const WS_EX_TRANSPARENT = &H20
End Class

注意对SetWindowLong的呼叫:

SetWindowLong(Me.Handle.ToInt64(), GWL_EXSTYLE, WS_EX_TRANSPARENT)

这是正在运行的程序的屏幕快照:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9HNU9oZy5wbmcifQ==” alt =“在此处输入图像描述”>

已编辑添加

请注意,您无需调用SetWindowLong就可以获得相同的效果。


0
投票

在下课后添加:

    Private Const WS_EX_TRANSPARENT As Integer = &H20

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
            Return cp
        End Get
    End Property

然后运行它。它应该工作。从我所知,它也不适用于非透明形式。


0
投票

尝试一下:

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Const WS_EX_TRANSPARENT As Integer = &H20 'Check if it can
        Dim params As CreateParams = MyBase.CreateParams
        params.ExStyle = params.ExStyle Or WS_EX_TRANSPARENT
        Return params 'return
    End Get
End Property

-1
投票

具有最新的Declare语法的幽灵形式的小变体(您可以通过它查看并单击它!)。感谢邮递员提供有用的帖子。

Imports System.Runtime.InteropServices

Public Class GhostForm

    Private InitialStyle As Integer
    Private PercentVisible As Decimal

    Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As System.IntPtr, ByVal nIndex As Integer) As Integer
    Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As System.IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
    Declare Function SetLayeredWindowAttributes Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal crKey As Integer, ByVal alpha As Byte, ByVal dwFlags As Integer) As Boolean

    Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        InitialStyle = GetWindowLong(Me.Handle, -20)
        PercentVisible = 0.5
        SetWindowLong(Me.Handle, -20, InitialStyle Or &H80000 Or &H20)
        SetLayeredWindowAttributes(Me.Handle, 0, 255 * PercentVisible, &H2)
        Me.BackColor = Color.Green
        Me.TopMost = True

    End Sub
End Class
© www.soinside.com 2019 - 2024. All rights reserved.