Welcome to Dream.In.Code
Getting VB.NET Help is Easy!

Join 136,479 VB.NET Programmers for FREE! Get instant access to thousands of VB.NET experts, tutorials, code snippets, and more! There are 1,662 people online right now. Registration is fast and FREE... Join Now!




Screen refresh speed is not fast enough

 
Reply to this topicStart new topic

Screen refresh speed is not fast enough

Devan
3 Jul, 2008 - 12:33 PM
Post #1

New D.I.C Head
*

Joined: 3 Jul, 2008
Posts: 3

I am looking for help on how to speed up VB.NET (or C#) screen refresh speed. Specifically I need to update many controls and then refresh them on the screen all at once.

I am in charge of writing a .NET interface for an older legacy program. Because this needs to run on slow legacy machines I did a performance test and discovered the screen refresh speeds of VB6 is faster then .NET. huh.gif In VB6 there is barely a flicker as controls change across the entire form all at once. In VB.NET you can see controls change moving across the form like a wave. I must be doing something wrong...

To do a head to head comparison I put together equivalent VB6 and VB.NET programs, each with a maximized form and 48 labels. Clicking on any label changes the background color of all the labels on the form. To really see the problem it is best to try the following code on a slower machine (1GHz etc.)

In VB6 create a project MyProject and add a form MyForm with the following properties
CODE
Caption = "Screen Refresh test VB6"
BackColor = Black
WindowState = Maximized


On that form add a label MyLabel with the following properties:
CODE
Index = 0
Caption = "Hello World"
BackColor = Cyan


In the form add the following code:
CODE
Option Explicit

Const ROWS  As Integer = 8
Const COLS  As Integer = 6
Const PAD   As Integer = 75   ' 5 pixels at 15 twips per pixel

Private colors(0 To 2) As Long
Private color As Integer

Private Sub Form_Load()
   Dim index As Integer
  
   colors(0) = vbCyan
   colors(1) = vbYellow
   colors(2) = vbGreen
  
   For index = 1 To ROWS * COLS - 1
      Call Load(MyLabel(index))
      MyLabel(index).Caption = MyLabel(index).Caption & " " & CStr(index)
      MyLabel(index).Visible = True
   Next index
   MyLabel(0).Caption = MyLabel(0).Caption & " 0"
End Sub

Private Sub Form_Resize()
   Dim width   As Single
   Dim height  As Single
   Dim row     As Integer
   Dim col     As Integer
   Dim index   As Integer
  
   width = (Me.width - 60 - PAD * (COLS + 1)) \ COLS
   height = (Me.height - 450 - PAD * (ROWS + 1)) \ ROWS
  
   For col = 0 To COLS - 1
      For row = 0 To ROWS - 1
         index = col * ROWS + row
         Call MyLabel(index).Move(PAD + col * (width + PAD), PAD + row * (height + PAD), width, height)
      Next row
   Next col
End Sub

Private Sub MyLabel_Click(index As Integer)
   color = (color + 1) Mod 3
  
   For index = 0 To ROWS * COLS - 1
      MyLabel(index).BackColor = colors(color)
   Next index
End Sub


The VB.NET program is virtually identical. Just create a windows project and past in the following code. This code defines a form and is self sufficient. It does not need the auto generated form code.
CODE
Public Class MyForm
   Inherits System.Windows.Forms.Form

   Private Const _ROWS As Integer = 8
   Private Const _COLS As Integer = 6
   Private Const _PAD As Integer = 5
   Private _myLabel(_ROWS * _COLS - 1) As System.Windows.Forms.Label

   Private _colors() As System.Drawing.Color = {Color.Cyan, Color.Magenta, Color.Yellow}
   Private _color As Integer

   Public Sub New()
      Me.SuspendLayout()

      For index As Integer = 0 To _ROWS * _COLS - 1

         Me._myLabel(index) = New System.Windows.Forms.Label
         Me._myLabel(index).BackColor = System.Drawing.Color.Cyan
         Me._myLabel(index).Name = "MyLabel" & CStr(index)
         Me._myLabel(index).TabIndex = index
         Me._myLabel(index).Text = "Hello World " & CStr(index)
         Me._myLabel(index).TextAlign = System.Drawing.ContentAlignment.MiddleCenter

         AddHandler Me._myLabel(index).Click, AddressOf MyLabel_Click

         Me.Controls.Add(Me._myLabel(index))
      Next

      Me.ClientSize = New System.Drawing.Size(292, 273)
      Me.StartPosition = FormStartPosition.CenterScreen
      Me.WindowState = FormWindowState.Maximized
      Me.BackColor = Color.Black
      Me.Name = "MyForm"
      Me.Text = "Screen Refresh Test VB.NET"

      Me.ResumeLayout(False)

   End Sub

   Private Sub MyForm_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
      Dim resize As System.Drawing.Size = _
         New System.Drawing.Size _
            ( _
               (Me.ClientRectangle.Width - (_PAD * _COLS + 1)) \ _COLS, _
               (Me.ClientRectangle.Height - (_PAD * _ROWS + 1)) \ _ROWS _
            )

      Me.SuspendLayout()

      For col As Integer = 0 To _COLS - 1
         For row As Integer = 0 To _ROWS - 1
            With Me._myLabel(col * _ROWS + row)
               .Size = resize
               .Location = New System.Drawing.Point(_PAD + col * (.Width + _PAD), _PAD + row * (.Height + _PAD))
            End With
         Next
      Next

      Me.ResumeLayout()
   End Sub

   Private Sub MyLabel_Click(ByVal sender As Object, ByVal e As System.EventArgs)
      _color = (_color + 1) Mod _colors.Length
      For index As Integer = 0 To _ROWS * _COLS - 1
         Me._myLabel(index).BackColor = _colors(_color)
      Next
   End Sub
End Class

User is offlineProfile CardPM
+Quote Post

djkitt
RE: Screen Refresh Speed Is Not Fast Enough
3 Jul, 2008 - 01:56 PM
Post #2

D.I.C Head
**

Joined: 22 May, 2008
Posts: 128



Thanked: 13 times
My Contributions
Check out this link to George Shepherd's Windows FAQ:

http://www.syncfusion.com/faq/windowsforms...c95c.aspx#q637q


The sample discussed here is in C# but you can download a sample in vb.net that should do the trick for you.

This post has been edited by djkitt: 3 Jul, 2008 - 01:56 PM
User is offlineProfile CardPM
+Quote Post

Devan
RE: Screen Refresh Speed Is Not Fast Enough
8 Jul, 2008 - 05:19 AM
Post #3

New D.I.C Head
*

Joined: 3 Jul, 2008
Posts: 3

Well it turns out that did not work. Suspending control updates with the WM_SETREDRAW windows message requires using a refresh command afterward. When the refresh is used all the sub-controls update the same way as before. In a visible wave across the form.

Are there any more suggestions on how to get multiple sub-controls to all update on the screen at the same time?
User is offlineProfile CardPM
+Quote Post

WayneSpangler
RE: Screen Refresh Speed Is Not Fast Enough
8 Jul, 2008 - 07:05 AM
Post #4

D.I.C Head
**

Joined: 22 Mar, 2008
Posts: 102



Thanked: 8 times
My Contributions
Try setting the form's DoubleBuffer to true.
User is offlineProfile CardPM
+Quote Post

Devan
RE: Screen Refresh Speed Is Not Fast Enough
8 Jul, 2008 - 10:10 AM
Post #5

New D.I.C Head
*

Joined: 3 Jul, 2008
Posts: 3

Thank you, but I have tried double buffering. It works with graphics and drawing on a single control but sub-controls still get updated independently of each other and their container. So the wave update across the screen still happens.
User is offlineProfile CardPM
+Quote Post

djkitt
RE: Screen Refresh Speed Is Not Fast Enough
23 Jul, 2008 - 08:18 AM
Post #6

D.I.C Head
**

Joined: 22 May, 2008
Posts: 128



Thanked: 13 times
My Contributions
QUOTE(Devan @ 8 Jul, 2008 - 01:10 PM) *

Thank you, but I have tried double buffering. It works with graphics and drawing on a single control but sub-controls still get updated independently of each other and their container. So the wave update across the screen still happens.


So, I know it has been a while, but I was just running through some old code and I got to thinking about this problem again. I think I have a way to make things at least look a little smoother, without double buffering and such...(At least it does on my PC)

Try swapping your order you change the labels properties. Change the position(Top,Left) before you change the size (Height,Width).

Good luck,


User is offlineProfile CardPM
+Quote Post

djkitt
RE: Screen Refresh Speed Is Not Fast Enough
23 Jul, 2008 - 09:59 AM
Post #7

D.I.C Head
**

Joined: 22 May, 2008
Posts: 128



Thanked: 13 times
My Contributions
So, scratch that last one. I think I have a better answer.

I tried this and it seems to work well on my box.

Step 1. Take a picture of the panel.
Step 2. Make that image the background for the form.
Step 3. Set panel.Visible to False
Step 4. Redraw the labels.
Step 5. Make the panel visible again.
Step 6. Clean up the graphics.

Here it is in C# (I'm a C# kind of guy)
csharp

private void RedrawPanel()
{
if (RedrawResize == true)
{
// Step 1. Take a picture of the panel.
Graphics g = panel1.CreateGraphics();
Bitmap img = new Bitmap(panel1.Width, panel1.Height, g);
Rectangle rect = new Rectangle(0, 0, panel1.Width, panel1.Height);
panel1.DrawToBitmap(img, rect);

// Step 2. Make that image the background for the form.
this.BackgroundImage = img;

// Step 3. Set panel.Visible to False
panel1.Visible = false;
RedrawResize = false;

// Step 4. Redraw the labels.
Label l;
int lwidth = panel1.Width / col;
int lheight = panel1.Height / row;

for (int r = 0; r < row; r++)
for (int c = 0; c < col; c++)
{
l = (Label)(panel1.Controls["Batch" + r.ToString() + c.ToString()]);
resizeLabel(l, lwidth, lheight, r, c);
}

// Step 5. Make the panel visible again.
panel1.Visible = true;

// Step 6. Clean up the graphics.
this.BackgroundImage = null;
g.Dispose();
}
}

// Edit: I was using the RedrawResize variable when I was messing with using a timer
// to see if that would help smooth things out. It didn't seem to matter though...



Hope this helps,


This post has been edited by djkitt: 23 Jul, 2008 - 10:02 AM
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/2/08 06:33PM

Live VB.NET Help!

VB.NET Tutorials

Reference Sheets

VB.NET Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month