Sunday 19 June 2011

A very strange Aero - VB6 - Crystal Reports bug.

As I have already written, one of the joys of my job is maintaining a rather large VB6 app (in the hope of moving it to a more contemporary developement system,one day). Last week I've encountered a quaint bug with a combination of VB6 Form, Crystal Reports preview form, and Windows 7.

Take a rather crowded VB6 form, not impossibly crowded, a few frames, several buttons and textbox, a SSTab, two DataGrids. Take a standard Crystal Reports (version 9) print report preview (the aforementioned app has literally hundreds of such reports) . Take a Windows 7 (32 or 64 bit, probably even Vista) with Aero (not Basic, not Classic) themes. After the preview is closed, regardeless of the fact that the report is printed or not, the calling crowded form remains half painted. The controls are still there, they're just not updated. If you click on them, they're repainted. Clearly it's some strange combination of VB6 components and the Crystal Reports preview, but 1) it only happens with Aero themes 2) it doesn't happen in other similar forms, so far. The culprit is probably a compatibility bug with aero (Vista had worse problems) but in order to work around the problem the solution lies in redrawing all the controls after the preview is called. You might cycle through all the controls and call their Refresh method (a single Refresh on 'Me' dosen't cut it) but i found a simpler, "cleaner" trick to refresh the form more rapidly. It's simply a matter of creating an empty frame at runtime, displaying for a moment, and then turning it off and destroying it. Here's a self-explanatory sub.


Public Sub RedrawForm(ByRef frm As Form)
Dim frmRefresh As Control
Set frmRefresh = frm.Controls.Add("VB.Frame", "frmRefresh")
frmRefresh.BorderStyle = 0
frmRefresh.Top = 0
frmRefresh.Left = 0
frmRefresh.Width = frm.Width
frmRefresh.Height = frm.Height
frmRefresh.Caption = ""
frmRefresh.ZOrder
frmRefresh.Visible = True
frm.Refresh
frmRefresh.Visible = False
frm.Refresh
frm.Controls.Remove ("frmRefresh")
Set frmRefresh = Nothing
End Sub

1 comment:

  1. can u give an example and screenshot ?
    I'm attracted

    ReplyDelete