询问者
难啊!vb.net 的autoredraw问题

问题
-
Imports System.Threading Imports System.ComponentModel Imports System.Drawing.Imaging Public Class Form1 Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer 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 Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Integer, ByVal hdc As Integer) As Integer Const SRCCOPY As Integer = &HCC0020 Dim g2, o1, o2, g3 As Graphics Dim bgimage As Bitmap Dim xp1 As Bitmap = New Bitmap(My.Resources.g) Public Function SaveCurPic() As Bitmap Dim bmp As Bitmap = Nothing 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, 568, 405) hBMPOld = SelectObject(hMDC, hBMP) BitBlt(hMDC, 0, 0, sw, sh, hDC, 0, 0, SRCCOPY) hBMP = SelectObject(hMDC, hBMPOld) bmp = Image.FromHbitmap(New IntPtr(hBMP)) ReleaseDC(0, hDC) ' DeleteDC(hDC) DeleteDC(hMDC) DeleteObject(hBMP) Return bmp End Function Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.SetDesktopLocation(0, 0) Me.TopMost = True bgimage = New Bitmap(PictureBox1.Width, PictureBox1.Height) '创建相同大小的内存位图 PictureBox1.Image = bgimage g2 = Graphics.FromImage(bgimage) g2.DrawImage(My.Resources.bb, 0, 0) g3 = Graphics.FromImage(bgimage) o1 = Graphics.FromImage(bgimage) o2 = Graphics.FromImage(bgimage) End Sub Private Sub thread1() While True Randomize() Dim tempbmp As Bitmap = New Bitmap(SaveCurPic()) Dim x As Integer = CInt(Int((PictureBox1.Width * Rnd()) + 1)) Dim y As Integer = CInt(Int((PictureBox1.Height * Rnd()) + 1)) g2.DrawImage(My.Resources.g, New Rectangle(x, y, My.Resources.g.Width, My.Resources.g.Height), _ New Rectangle(0, 0, My.Resources.g.Width, My.Resources.g.Height), GraphicsUnit.Pixel) Threading.Thread.Sleep(200) g2.DrawImage(tempbmp, New Rectangle(x, y, My.Resources.g.Width, My.Resources.g.Height), New Rectangle(x, y, My.Resources.g.Width, My.Resources.g.Height), GraphicsUnit.Pixel) ' g2.DrawString("test1", New Font("", 10, FontStyle.Bold), Brushes.Blue, x + 10, y - 10) End While End Sub Private Sub thread2() CheckForIllegalCrossThreadCalls = False While True Randomize() Dim tempbmp As Bitmap = New Bitmap(SaveCurPic()) Dim x As Integer = CInt(Int((PictureBox1.Width * Rnd()) + 1)) Dim y As Integer = CInt(Int((PictureBox1.Height * Rnd()) + 1)) g3.DrawImage(My.Resources.blueg, New Rectangle(x, y, My.Resources.blueg.Width, My.Resources.blueg.Height), _ New Rectangle(0, 0, My.Resources.blueg.Width, My.Resources.blueg.Height), GraphicsUnit.Pixel) PictureBox1.Invalidate() Application.DoEvents() Threading.Thread.Sleep(200) g3.DrawImage(tempbmp, New Rectangle(x, y, My.Resources.blueg.Width, My.Resources.blueg.Height), New Rectangle(x, y, My.Resources.blueg.Width, My.Resources.blueg.Height), GraphicsUnit.Pixel) ' g2.DrawString("test1", New Font("", 10, FontStyle.Bold), Brushes.Blue, x + 10, y - 10) End While End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick PictureBox1.Invalidate() End Sub End Class
求教各位高手,本人想在vb.net中实现autoredraw功能,如果用上面的timer来实现,将timer1的interval调到足够小的时候,能够勉强实现上面的动画效果,但cpu将高达60%占用,而且画面还不流畅。请问有什么办法能不用timer1而实现上面的动画效果。我上面这个例子只是临时写的。因为我现在的程序中有十多个线程在同时操作界面上的元素实现动画效果。我在CSDN上也提出了这个问题。但并没有得到解答。参见:
http://topic.csdn.net/u/20110217/19/e36e6525-a089-48a0-9ede-88752cb9d07f.html
http://topic.csdn.net/u/20110301/00/c636ab6e-f66a-495a-8660-1623703dc47d.html
有什么办法,在不改动上面example太多的情况下实现我要的效果呢。有什么可以代替timer1来实现。。。。谢谢了。
全部回复
-
你是整个重画,试试只重画需要更新的一部分
http://feiyun0112.cnblogs.com/ -
你是整个重画,试试只重画需要更新的一部分
http://feiyun0112.cnblogs.com/
非常感谢楼上的指点,但我画的时候是只重画局部啊。drawimage都是使用destrect 和sourcerect这样的参数来重画的啊。我现在是可以实现,但是是依靠timer不停的调用picturebox的invalidate来刷新实现的。我是想有什么办法能解决不用timer而让drawimage后自动更新到界面上