×

vb.net实现Windows关机渐淡效果

Kalet Kalet 发表于2009-03-20 12:00:14 浏览256 评论0

抢沙发发表评论

前几天在网上看到一个用VC++实现的模拟关机的效果.用VB.net也能实现同样的效果.


无论是C++及VB.net实现,思想都是先获得屏幕图像,然后处理这个图像.


处理这个图像有两种方法,一种是用GetPixes及SetPixes对每个像素进行操作.这种操作由于是由.net托管实现的,所以速度很慢.在1024*768的情况下处理一帧竟然用了6秒.我自己都以为死机了,何况是用户?.我顶你个肺啊.真受不了.

vb.net实现Windows关机渐淡效果

另外一种就是使用BitmapData.实现后的效果及速度和Windows一样.


Public Class MainWindow
    Inherits System.Windows.Forms.Form


#Region " Windows 窗体设计器生成的代码 "


    Public Sub New()
        MyBase.New()
        System.Windows.Forms.Application.EnableVisualStyles()
        System.Windows.Forms.Application.DoEvents()
        setstyle(ControlStyles.DoubleBuffer, True)
        UpdateStyles()
        '该调用是 Windows 窗体设计器所必需的。
        InitializeComponent()
        '在 InitializeComponent() 调用之后添加任何初始化


    End Sub


    '窗体重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub


    'Windows 窗体设计器所必需的
    Private components As System.ComponentModel.IContainer


    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改此过程。
    '不要使用代码编辑器修改它。
    Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu
    Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem
    Friend WithEvents MenuItem2 As System.Windows.Forms.MenuItem
    Friend WithEvents MenuItem3 As System.Windows.Forms.MenuItem
    Friend WithEvents CloseWindow As System.Windows.Forms.MenuItem
    Friend WithEvents ClosingTimer As System.Windows.Forms.Timer
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.MainMenu1 = New System.Windows.Forms.MainMenu
        Me.MenuItem1 = New System.Windows.Forms.MenuItem
        Me.MenuItem2 = New System.Windows.Forms.MenuItem
        Me.MenuItem3 = New System.Windows.Forms.MenuItem
        Me.CloseWindow = New System.Windows.Forms.MenuItem
        Me.ClosingTimer = New System.Windows.Forms.Timer(Me.components)
        '
        'MainMenu1
        '
        Me.MainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem1})
        '
        'MenuItem1
        '
        Me.MenuItem1.Index = 0
        Me.MenuItem1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem2, Me.MenuItem3, Me.CloseWindow})
        Me.MenuItem1.Text = "文件(&F)"
        '
        'MenuItem2
        '
        Me.MenuItem2.Index = 0
        Me.MenuItem2.Text = "打开"
        '
        'MenuItem3
        '
        Me.MenuItem3.Index = 1
        Me.MenuItem3.Text = "-"
        '
        'CloseWindow
        '
        Me.CloseWindow.Index = 2
        Me.CloseWindow.Shortcut = System.Windows.Forms.Shortcut.CtrlQ
        Me.CloseWindow.Text = "退出(X)"
        '
        'ClosingTimer
        '
        Me.ClosingTimer.Interval = 700
        '
        'MainWindow
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
        Me.ClientSize = New System.Drawing.Size(592, 385)
        Me.Menu = Me.MainMenu1
        Me.Name = "MainWindow"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
        Me.Text = "Form1"


    End Sub


#End Region



#Region "MainMenu1菜单事件"
    ''引用APIvb.net实现Windows关机渐淡效果
    '创建内存上下文设备用来装箱指定句柄的上下文设备
    Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer
    '创建Bitmap用来装箱特定上下文设备
    Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer
    '将Object装入指定的上下文设备
    Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer
    '将源上下文设备的色彩数据装入目标上下文设备
    Private Declare Function BitBlt Lib "GDI32" (ByVal srchDC As Integer, ByVal srcX As Integer, ByVal srcY As Integer, ByVal srcW As Integer, ByVal srcH As Integer, ByVal desthDC As Integer, ByVal destX As Integer, ByVal destY As Integer, ByVal op As Integer) As Integer
    '删除指定的上下文设备
    Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer
    '释放指定设备的所有资源
    Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer
    '返回指定句柄的显示上下文设备
    Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
    Private Const SRCCOPY As Integer = &HCC0020


    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    Private Declare Function ShowWindow Lib "User32" (ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As Integer
    Private Const SW_HIDE = 0
    Private Const SW_SHOW = 5


    Private myBitmap As Bitmap
    Private myBitmapCount As Single = 0.75
    Private myClosing As New ClosingWindow
    Private T0 As Single = 0.001
    Private T1 As Single = 0.287
    Private T2 As Single = 0.712
    '退出整个程序将引发类似于Windows关机时颜色变淡的效果
    Private Sub CloseWindow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseWindow.Click
        Dim hDC, hMDC As Integer
        Dim hBMP, hBMPOld As Integer
        Dim sw, sh As Integer
        hDC = GetDC(0) '获取整个屏幕的上下文设备
        hMDC = CreateCompatibleDC(hDC) '为整个屏幕上下文设备创建内存上下文设备
        sw = Screen.PrimaryScreen.Bounds.Width
        sh = Screen.PrimaryScreen.Bounds.Height
        hBMP = CreateCompatibleBitmap(hDC, sw, sh) '创建Bitmap用来装箱屏幕上下文设备
        hBMPOld = SelectObject(hMDC, hBMP) '将hBMP装入内存上下文设备,得到一个句柄
        BitBlt(hMDC, 0, 0, sw, sh, hDC, 0, 0, SRCCOPY) '将整个屏幕的色彩信息装入hMDC
        hBMP = SelectObject(hMDC, hBMPOld) '装hBMPOld装入hMDC
        myBitmap = Bitmap.FromHbitmap(New IntPtr(hBMP))
        DeleteDC(hDC)
        DeleteDC(hMDC)
        DeleteObject(hBMP)
        myClosing.BackgroundImage = myBitmap
        If myClosing Is Nothing Or myClosing.IsDisposed Then
            Dim tmpClosingWindow As New ClosingWindow
            myClosing = tmpClosingWindow
        End If
        myClosing.Show()
        Me.ClosingTimer.Start()
    End Sub
    Private Sub ExitProgram()
        Dim myBitmapData As System.Drawing.Imaging.BitmapData = myBitmap.LockBits(New Rectangle(0, 0, myBitmap.Width, myBitmap.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
        Dim i, j As Integer
        Dim tBlue As Byte
        Dim tGreen As Byte
        Dim tRed As Byte
        Dim p(2) As Byte
        For i = 0 To myBitmap.Height - 1
            For j = 0 To myBitmap.Width - 1
                tBlue = System.Runtime.InteropServices.Marshal.ReadByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j))
                tGreen = System.Runtime.InteropServices.Marshal.ReadByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j + 1))
                tRed = System.Runtime.InteropServices.Marshal.ReadByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j + 2))
                p(0) = T0 * tRed + T1 * tGreen + T2 * tBlue
                p(1) = T1 * tRed + T2 * tGreen + T0 * tBlue
                p(2) = T2 * tRed + T0 * tGreen + T1 * tBlue
                System.Runtime.InteropServices.Marshal.WriteByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j), p(0))
                System.Runtime.InteropServices.Marshal.WriteByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j + 1), p(1))
                System.Runtime.InteropServices.Marshal.WriteByte(myBitmapData.Scan0, myBitmapData.Stride * i + (3 * j + 2), p(2))
            Next
        Next
        myBitmap.UnlockBits(myBitmapData)
        myClosing.BackgroundImage = Nothing
        myClosing.BackgroundImage = myBitmap
        Me.Invalidate()
    End Sub


    Private Sub ClosingTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ClosingTimer.Tick
        If T2 > 0.2 Then
            T0 += 0.02
            T1 += 0.02
            T2 = 1 - T0 - T1
            ExitProgram()
        Else
            Me.ClosingTimer.Stop()
        End If
    End Subvb.net实现Windows关机渐淡效果
#End Region
End Class


群贤毕至

访客