OnPaint Event for Form (1 Viewer)

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:32
Joined
May 21, 2018
Messages
8,463
Call it as you will, but it's annoying as hell. Flash, flicker, the sensation the whole form is blinking... doesn't look very pro :)))
I think you are at the limitation of what you can get in Access. Maybe others have some more ideas to make it better.
As you state, I do not think that would be very doable unbound, The work would be too great IMO for not a lot of benefit. Not that other have not done things this complicated unbound.
If you are going the .Net route PM me and I will help were I can. For fun I took the NorthWind 2010 and recreated it completely with a VB.net front end and access backend. I will tell you it is FAR from trivial. Even if you are already and expert in ADO.NET building this is a lot of work. If you need a book find a used version of ADO.NET by David SCEPPA you will need it. The binding and maintaining the data is the hard part. The .net forms are so robust that the UI you only wish could be done in Access is trivial in .net. Something like this would be trivial in .net, but it is the binding of the data that is not.
 

isladogs

MVP / VIP
Local time
Today, 15:32
Joined
Jan 14, 2017
Messages
18,186
This was one of the first things i tried :D. Unfortunately (or, by design) the moment the Echo becomes True, access repaints everything on the screen, which in turn makes the annoying flicker.
What do you disagree on? On my machine, the semi-flicker is more obvious with CF than with onpaint. :)
I have several forms (& reports) which appear to have formatting which is at least as complex as yours - possibly more so. For example, this form

SENPupilTimetable.gif

... and this report

Exam6StudentResidualGrid.gif


Of course some flicker is inevitable ... perhaps unless you have a super fast PC like @MajP

I find CF both faster & it causes less flicker ... particularly if I switch off screen repainting whilst CF is being done. I have tried the Paint event in my own apps but abandoned it long ago

Good luck with your project
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:32
Joined
May 21, 2018
Messages
8,463
but have you tried the standard method of reducing flicker?
What exactly is that? Just turning off the echo? Which events and where do you turn it on and off? Do you use it in that form you are showing? Can you show the code?
 

isladogs

MVP / VIP
Local time
Today, 15:32
Joined
Jan 14, 2017
Messages
18,186
What exactly is that? Just turning off the echo? Which events and where do you turn it on and off? Do you use it in that form you are showing? Can you show the code?
Either use .Echo False or Me.Painting=False whilst a number of formatting changes are being run or whilst several controls are made visible/hidden, locked/unlocked, enabled/disabled. Also make sure there are no timer events running

I use that in the form itself.
The form in the screenshot is extremely complicated due to the array code used for the timetable display layout as well as the formatting used for each lesson. Posting all the code used would be far too lengthy for a forum thread & would take me too long to be viable. Sorry!
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 11:32
Joined
May 21, 2018
Messages
8,463
Posting all the code used would be far too lengthy for a forum thread & would take me too long to be viable. Sorry!
Sorry, I was not looking for the code just where you are turning on and off the echo. I might be over thinking this, but for CF where are you turning off the echo. In the load and leave it off? I would think you would need to turn in back on somewhere or you are not seeing any updates.
 

isladogs

MVP / VIP
Local time
Today, 15:32
Joined
Jan 14, 2017
Messages
18,186
Oops! I made a silly mistake on post #17 which I've just corrected!
It should of course have read

Code:
Application.Echo False
'the rest of your code here
Application.Echo True

If the CF is done using code rather than the wizard, the CF code would be included in 'the rest of your code here'.
Otherwise, it might be the Form_Load event - but it depends on when the CF wizard code is applied . The TimetableViewer form shown is used for students, teachers & teaching assistants. Different code is used depending on which 'type of' timetable is involved. An array with the appropriate number of lesson for each day is 'built', populated & formatted.

For example:

Code:
Private Sub PupilTimetable()

On Error GoTo Err_Handler

'loads pupil timetable onto screen
    EmptySlots
    PopulateTimetableArrayPupil
    
    FormatNonTimetabledLessons 'CR v4589W
    FormatTimetabledLessons 'CR v4589W
    FormatSupportedLessons
    
Exit_Handler:
    Exit Sub

Err_Handler:
    'create error message & log
    strProc = Application.VBE.ActiveCodePane.CodeModule.ProcOfLine(Application.VBE.ActiveCodePane.TopLine, 0)
    PopulateErrorLog
    Resume Exit_Handler
    
End Sub

Each of those 5 code lines loads a separate procedure with the last three applying different formatting depending on the circumstances.

Not sure whether that makes things any clearer
 

Adelina_RO

Member
Local time
Today, 17:32
Joined
Apr 9, 2021
Messages
42
I have several forms (& reports) which appear to have formatting which is at least as complex as yours - possibly more so. For example, this form

View attachment 94895
... and this report

View attachment 94894

Of course some flicker is inevitable ... perhaps unless you have a super fast PC like @MajP

I find CF both faster & it causes less flicker ... particularly if I switch off screen repainting whilst CF is being done. I have tried the Paint event in my own apps but abandoned it long ago

Good luck with your project
i don't think it has a lot to do with how complicated the code behind is, but more with how many controls access has to redraw. For a few (under 20) i remember being super fast and with almost no flashing. But my forms have around 26x12 for the small one and 26x20 for the big one. I think that reports work different as there is no Painting done after the initial view. The Format event for the Reports works way faster. Besides, i forgot to mention: each click on my rows connects to a MariaDB server and retrieves some data (not a lot) from there. The connection is through a VPN, so that's laggy as well. I was thinking of using a subreport instead of a subform, but it's a lot of code change and in the end there are less options for that.
The thing is, my client is coming from a shared excel file, which was extremely slow and got stuck for minutes after each update, so what i gave them is like a tommy-gun in the dark ages. The obsession with flickering is from my part, as they have never complained, even when the code was way shitter and less optimized.
Thank you for everything!
 

Attachments

  • Untitled.png
    Untitled.png
    265.1 KB · Views: 85

Adelina_RO

Member
Local time
Today, 17:32
Joined
Apr 9, 2021
Messages
42
I think you are at the limitation of what you can get in Access. Maybe others have some more ideas to make it better.
As you state, I do not think that would be very doable unbound, The work would be too great IMO for not a lot of benefit. Not that other have not done things this complicated unbound.
If you are going the .Net route PM me and I will help were I can. For fun I took the NorthWind 2010 and recreated it completely with a VB.net front end and access backend. I will tell you it is FAR from trivial. Even if you are already and expert in ADO.NET building this is a lot of work. If you need a book find a used version of ADO.NET by David SCEPPA you will need it. The binding and maintaining the data is the hard part. The .net forms are so robust that the UI you only wish could be done in Access is trivial in .net. Something like this would be trivial in .net, but it is the binding of the data that is not.
I just might take you up on that, especially since learning from books is not my strong suite... i'm more of a trial and error type of gal' :p
I have had two tries before to work with Ado.net, but always with an access backend, so now i'm going to go with an ADO mariadb connection. i imagine it will be difficult, but i love that. it helps me learn :D
actually, i would love learning c#, but the difference between vba and c# are huge and in the words of Danny Glover: "i'm too old for this shit"
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 15:32
Joined
Sep 12, 2006
Messages
15,614
Rather than explicitly "paint", you might find that putting DoEvents in your code achieves the same thing. Some updates happen in the background and don't always cause an immediate repaint. DoEvents allows all pending events to catch up. Adding DoEvents to a loop also allows you to break into a code loop in the event that you think the loop might be infinite and not terminating.
 

Isaac

Lifelong Learner
Local time
Today, 08:32
Joined
Mar 14, 2017
Messages
8,738
Adding DoEvents to a loop also allows you to break into a code loop in the event that you think the loop might be infinite and not terminating.
Hi Dave, this caught my attention.

Sometimes while code is running, Ctrl+PauseBreak will effectively break into it, and other times, not so much, until I hit it 100 times, or do the rain dance or something.

Does your comment mean that DoEvents affects how Ctrl+PauseBreak works? Or were you talking about some other trigger for Break?
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 15:32
Joined
Sep 12, 2006
Messages
15,614
Yes. DoEvents will (should) let you break into a loop, as it will allow the keyboard interrupt to be intercepted and processed.
Especially useful when you haven't saved the code, and forgot to increment a loop variable so the loop runs forever.

As it happens, I just had to use this to very thing to break into a loop to check that it was running correctly.
 
Last edited:

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 10:32
Joined
Feb 28, 2001
Messages
27,004
@Isaac - Yes, DoEvents can trigger behavioral changes in code. The CTRL/BREAK function requires something to be able to accept it, and if you have a nasty loop that is improperly terminated, you might have to wait for a while before Access "comes up for air" to check on input signals.


The article is about Excel VBA but the problem is similar. I'm not sure which events will actually break in, but remember that Access is by its nature totally synchronous. So if your loop is particularly ugly, you might have to wait for a moment when the system takes control again and checks for some extraneous action. If nothing else detects this BREAK key, you might catch it when the Windows internal scheduler encounters what is called a "task switch" (having to do with the Windows Scheduler's "fairness" problem.)
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 15:32
Joined
Sep 12, 2006
Messages
15,614
if you have this sort of thing

Code:
while not rst.eof
     'statements to process the current record
     rst.movenext
     DoEvents
wend

Then the DoEvents will allow an interrupt to trigger, and halt the code at that line, so you can then step through the code with F8
It would also allow you to interact with the database, and open other forms while this process continues.
 

Adelina_RO

Member
Local time
Today, 17:32
Joined
Apr 9, 2021
Messages
42
Rather than explicitly "paint", you might find that putting DoEvents in your code achieves the same thing. Some updates happen in the background and don't always cause an immediate repaint. DoEvents allows all pending events to catch up. Adding DoEvents to a loop also allows you to break into a code loop in the event that you think the loop might be infinite and not terminating.
I understand your point, but the thing is there is no place to put the DoEvents in my code as i have no loop structure. I mean, there is one, as the OnPaint runs for every row in a continuous form, but there is only one procedure. So that doesn't make sense in this situation. but i'll keep that in mind :)
 

Isaac

Lifelong Learner
Local time
Today, 08:32
Joined
Mar 14, 2017
Messages
8,738
Yes. DoEvents will (should) let you break into a loop, as it will allow the keyboard interrupt to be intercepted and processed.
Especially useful when you haven't saved the code, and forgot to increment a loop variable so the loop runs forever.

As it happens, I just had to use this to very thing to break into a loop to check that it was running correctly.
Thanks, Dave.
I currently have a database with no DoEvents anywhere in the code. Ctrl+PauseBreak works occasionally, but not very often - it seemed a bit random to me.

I'll have to remember this, it seems like a nice thing to throw in sometimes - thanks!
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 15:32
Joined
Sep 12, 2006
Messages
15,614
I understand your point, but the thing is there is no place to put the DoEvents in my code as i have no loop structure. I mean, there is one, as the OnPaint runs for every row in a continuous form, but there is only one procedure. So that doesn't make sense in this situation. but i'll keep that in mind :)

sorry - what does the on paint actually do/achieve?
I could see that repainting a form might cause an awful lot of flickering. (as others have pointed out)
Have you posted a sample database?
 

Adelina_RO

Member
Local time
Today, 17:32
Joined
Apr 9, 2021
Messages
42
sorry - what does the on paint actually do/achieve?
I could see that repainting a form might cause an awful lot of flickering. (as others have pointed out)
Have you posted a sample database?
I have. It's at the beginning of this thread. What the onpaint achieves (especially for continuous forms) it that it offers a way to handle each control formatting in a way that delivers more options then CF and, for me at least, in a faster and less flicker-prone manner. As you probably know, in a continuous form, there is only one set of controls, usually bound to some fields. What i used to do (and eventually did it again) was to use CF to paint each runtime control, but with the onpaint i can set more things than only background, foreground and enable settings. for instance, i let the users define their own set of colors for different conditions, and with CF that would mean i would have to rebuild the entire set of conditions each time the user opens the form, as i have no idea if he changed his colors. With the onpaint, which is run for each record, i can simply store the code color and condition and apply it as the form is painted...
i don't know if it makes sense, but try the database i attached. in the form header there is a check box which demonstrates both CF and onpaint functionality
 

Users who are viewing this thread

Top Bottom