Results 1 to 10 of 10

Thread: Can I trust in this function?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2013
    Posts
    113

    Can I trust in this function?

    Goodmorning

    I need in one of my projects to use the DoEvents statement. Many programmers said me that is not a good way use it for vary reasons, but as I need it into a function, I thought that there might be another better solution. With a Google query, I found this code:
    Code:
    Option Explicit
    
    Private Type POINTAPI
            x As Long
            y As Long
    End Type
    
    Private Type MSG
        hwnd As Long         'hwnd  della finestra di destinazione del messaggio
        message As Long      'numero che identifica il tipo di messaggio
        wParam As Long       'parametro del messaggio (tipo e valore cambiano in funzione del tipo di messaggio inviato)
        lParam As Long       'altro parametro del messaggio che varia sempre in funzione del messaggio
        time As Long         'l'ora in cui è stato inviato il messaggio
        pt As POINTAPI       'posizione del cursore al momento dell'invio del messaggio
    End Type
    
    'La funzione PeekMessage cerca e recupera un messaggio in coda e lascia immediatamente il controllo al programma
    'Se il messaggio viene recuperato la funzione restituisce TRUE, in caso contrario restituisce FALSE.
    'La funzione prevede un parametro (wRemoveMsg) che indica se rimuovere il messaggio recuperato dalla coda o di lasciarlo dove si trova.
    Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" ( _
        lpMsg As MSG, _
        ByVal hwnd As Long, _
        ByVal wMsgFilterMin As Long, _
        ByVal wMsgFilterMax As Long, _
        ByVal wRemoveMsg As Long) As Long
    Private Const PM_REMOVE = &H1 'indica alla funzione PeekMessage di rimuovere il messaggio in coda
        
    'La funzione TranslateMessage codifica alcuni messaggi arrivati dalla tastiera in modo da renderli opportunamente eleborabili.
    Private Declare Function TranslateMessage Lib "user32" (lpMsg As MSG) As Long
    
    'La funzione DispatchMessage richiama la corretta procedura che deve elaborare il messaggio in base al valore del campo hwnd della struttura MSG
    'N.B.: l'omissione di questa funzione porterebbe alla mancata elaborazione dei messaggi e, quindi, al probabile blocco del sistema.
    Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageA" (lpMsg As MSG) As Long
    
    
    Private Const lMaxCounter  As Long = 100000
    
    Private Sub MyDoEvents() 'funzione alternativa alla funzione di VB "DoEvents"
        Dim CurrMsg As MSG
        
        'Questo loop recupera (e cancella) tutti i messaggi dalla coda e li invia alla finestra di destinazione
        Do While PeekMessage(CurrMsg, 0, 0, 0, PM_REMOVE) <> 0
            TranslateMessage CurrMsg
            DispatchMessage CurrMsg
        Loop
    End Sub
    It seems work well and faster than the DoEvents statement. But can I really trust in this code lines? Can I be sure that if I replace all the DoEvents calls with MyDoEvents any problems won't be raised?

    Thank you for all your opinions and suggestions,

  2. #2
    Frenzied Member
    Join Date
    Dec 2008
    Location
    Melbourne Australia
    Posts
    1,487

    Re: Can I trust in this function?

    If it ain't broke, don't fix it.
    I do not sprinkle DoEvents everywhere.
    But if I see something is 'living in the past', and the controls Refresh command does not help, then it cops a DoEvents.
    I reckon if you are judicious about your use of DoEvents, just stick with that.
    Rob
    PS I will be getting donations from the other post that I just made, so that will help build a fund, in case anyone sues me over this advice.

  3. #3
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Can I trust in this function?

    It appears that the code you found originated from NirSoft's DoEvents alternative function. It also looks like somebody else downloaded the same code and has asked the same question as you did in the "MyDoEvents" vs DoEvents? thread. There were 16 responses in that thread so far.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Mar 2013
    Posts
    113

    Re: Can I trust in this function?

    I don't remember what the source was and I didn't know there already was a thread like this. However, reading the answers, I think that I should continue to use the VB's DoEvents statement.

    Thanks,

  5. #5
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Can I trust in this function?

    The DoEvents() function lived on in VB6 for a reason, sometimes it is necessary.

    However most of the reasons people use it are incorrect. It is only really safe in certain circumstances for a few specific purposes. Because a newb will reach for it far too often (and then come back posting a question about why their programs blow up, lose data, corrupt data, etc.) a DoEvents is evil mantra came about.

    The VB6 manuals (and the soft copy contained in the MSDN Library CDs providing VB6's online Help) discuss DoEvents and the preferred alternatives in several chapters.

    So choosing whether to use it or not depends entirely on where and why you are considering using it. There is no simple answer, and why would you expect there to be one? Programming isn't a cookbook endeavor.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Mar 2013
    Posts
    113

    Re: Can I trust in this function?

    I use DoEvents in several cases, i.e. into a Delay function (to let a fluid refresh or to allow users to move the Form) or to stop a loop with a click on a button, but more in general, I use it when I don't want that a long operation (once launched) monopolizes my project.

    My question is more about to know if there is a way to emulate DoEvents statement avoiding a code come-back. Try this code:
    Code:
    Private Sub Delay(ByVal Seconds As Single)
        Seconds = (Timer + Seconds)
        Do While Timer < Seconds
            DoEvents
        Loop
    End Sub
    
    Private Sub Quit()
        Dim f As Form
    
        For Each f In Forms
            Unload f
        Next f
    End Sub
    
    Private Sub Form_Load()
        Me.Show
        Me.Refresh
        Delay 10
        MsgBox "App slept for 2 seconds"
    End Sub
    
    Private Sub Command1_Click()
       Quit
    End If
    If you click on the command button before MsgBox appears, the form won't be unloaded and it still remains into the running processes. And this is not good. The only way to escape is to use End to finish the app. But if I need only to close one form, calling End statement will close the whole program.

    Don't tell me to use a Timer control instead, because into unless loops neither Timer's ticks are fired if you don't put (into the loop) a DoEvents.

  7. #7
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Can I trust in this function?

    Did you know that DoEvents is a very Frequently Asked Question? Searching this forum alone turned up 180 hits. In fact, in this recent thread, two methods were proposed that eventually led to the resolution of the nested looping problem. Your given example is a simpler form of the problem discussed there, namely, unloading a Form while in the middle of a loop (made possible by use of DoEvents). The Interrupting Background Processing article talks about ways of implementing long-running tasks.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  8. #8
    Frenzied Member
    Join Date
    Dec 2008
    Location
    Melbourne Australia
    Posts
    1,487

    Re: Can I trust in this function?

    I would not be messing around in the Form_Load event.

  9. #9

    Thread Starter
    Lively Member
    Join Date
    Mar 2013
    Posts
    113

    Re: Can I trust in this function?

    I thought the title of this thread was clear enough... I didn't want to know about VB's DoEvents function. My question was (and is still now): the code I posted, is it 100% safe? Does it really do all it promises to do (run faster than DoEvents function and let OS to process all messages)?

    About the speediness, that's true: MyDoEvents function is faster. But what about the else? Does it really processess all the messages? After I've read this thread, I think to have understood that MyDoEvents runs my own thread messages only (and if it so, that's how it runs faster than DoEvents, which has to manage all system messages). Now, if this is right, I think that there surely are unexpected effects if something goes wrong.

    And that's all, there's nothing else that I wanted to know.

  10. #10
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Can I trust in this function?

    I think the deeper issue is, why do you need to use DoEvents or its (faster) alternatives? Can't you re-design your code so that you won't have to use DoEvents, etc. anymore? As you have found out, DoEvents, et al. have re-entrancy issues which are messy to deal with. The alternative proposed by MSDN is by using the Timer control's Timer event to divide the task in chunks that can be processed intermittently.

    BTW, DoEvents and its alternatives all have the same goal, and unfortunately, the same side-effects.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width