前几天在网上看到一个用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