Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to prevent vertical flickering while moving a form at runtime? 1

Status
Not open for further replies.

WomanPro

Programmer
Nov 1, 2012
180
GR
I have this code on a form class so that to prevent it to be movable out of the bounds of the working area during runtime. I don't know why, but when I move the form vertically I get a flickering. This form is TeachingFrm. I also have a central form which is the enviroment with a strech background image layout picture, it's not mdi parent, but it is always maximized and unmovable as I want it. The TeachingFrm changes at height every time I click on the next exercise only if the text is bigger than the previous exercise. Anyway, are there any suggestions how to prevent the vertical flickering? Any help will be much appreciated. Thank you so much in advanced.

Private Const WM_MOVING As Integer = &H216
Private Const [TRUE] As Integer = 1
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer

Public Overrides Function ToString() As String
Return String.Format("{{Left={0},Top={1},Right={2},Bottom={3}}}",
Me.Left, Me.Top, Me.Right, Me.Bottom)
End Function
End Structure
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_MOVING Then
'The current bounds of the form.
Dim currentFormBounds As Rectangle = Me.Bounds

'The proposed new bounds of the form after the move.
Dim newFormBounds = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(RECT)), RECT)

'The bounds of the primary monitor.
Dim screenBounds As Rectangle = Screen.PrimaryScreen.WorkingArea
screenBounds.Y = CentralFrm.Location.Y + TeachingFrmToolStrip.Height
screenBounds.Height = screenBounds.Height - screenBounds.Y

'screenBounds.Height = CentralFrmHeight
'screenBounds.Width = CentralFrmWdth
'Don't let the form move beyond the bounds of the screen in a horizontal direction.
If newFormBounds.Left < screenBounds.Left OrElse
newFormBounds.Right > screenBounds.Right Then
newFormBounds.Left = currentFormBounds.Left
newFormBounds.Right = currentFormBounds.Right
End If

'Don't let the form move beyond the bounds of the screen in a vertical direction.
If newFormBounds.Top < screenBounds.Top OrElse
newFormBounds.Bottom > screenBounds.Bottom Then
newFormBounds.Top = currentFormBounds.Top
newFormBounds.Bottom = currentFormBounds.Bottom + Me.Height
End If

'Replace the proposed bounds with the calculated bounds.

Marshal.StructureToPtr(newFormBounds,
m.LParam,
False)

m.Result = New IntPtr([TRUE])

End If

'Pass the message on.
MyBase.WndProc(m)
End Sub
 
Do you have Me.DoubleBuffered = True in the form's load event?

I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day!
 
I have checked the DoubleBuffered property in the MS documentation, and found that a Form has none of it...
What am I missing?

Regards,

Ilya
 
Well, DoubleBuffered is indeed a property of a Form object. The mouse-over text of DoubleBuffered reads: "Gets or sets a value indicating whether this control should redraw its surface using a secondary buffer to reduce or prevent flicker."

Here's a couple of links I found:





I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day!
 
Not at all. DoubleBuffered is false and I haven't change it through source code.
 
I'm sorry, I wasn't clear before. You *should* set Me.DoubleBuffered = True - it might help with the flickering. Set it in Form_Load, before anything else.

I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day!
 
Mr Jebension thank you so much. It happens something strange if I run it to Windows 10, it runs without flickering, but if I run it in Windows XP, flickering still remains. I am trying to find an explanation. All the code is the same, form properties too. Is there a way to solve or doesn't have an matter because Windows XP are not supported anymore?
 
The problem here may be the change in graphics architecture that took place between XP and Vista.

XP uses a stacking window manager which comprises a single display buffer to which all programs write, whilst the Desktop Window Manager used by Vista onwards is a compositing window manager, which means that each program has a buffer that it writes data to and DWM then composites each program's buffer into a final image. The job of repainting and refreshing the screen when windows are moved is handled by DWM, unlike in XP where it is the application's responsibility.

As a result, repainting a window as it moves is likely to be more susceptible to flickering under XP than on W10

Given the fairly simple subclassing you are doing I think the issue is with XP and not your code, so there's little you can do about it. (and DoubleBuffered won't help on XP since that leverages DWM, and XP does not have DWM)

 
So I let it as it is. I wish I could do something to prevent it. Thank you so much in advanced.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top