Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Timed Message Box

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Timed Message Box

    Code:
    '------------------------------------------------
    ' Timed MessageBox
    '
    ' Don't remember where I got this one from. A POFFS
    ' search turned up nothing so I thought I would post
    ' it for those folks that need a MessageBox that will
    ' kill itself after a predefined time. If it's yours,
    ' speak up.
    '
    '    Platform: WinNT 4.0 SP6a/post 6a Hotfixes
    '
    ' Language(s): PB/DLL V6 and PB/CC V2
    '
    '      Author: Unknown
    '     Revised: March 15, 2001
    '
    ' POFFS: indespensable tool from Borje Hagsten
    '------------------------------------------------
    '
    #COMPILE EXE
    #DIM ALL
    #REGISTER NONE
    #INCLUDE "Win32API.inc"
    
    '=========================================================
    FUNCTION MessageBoxTimer(BYVAL hWnd AS DWORD, BYVAL uiMsg AS DWORD, _
             BYVAL idEvent AS DWORD, BYVAL dwTime AS DWORD) AS LONG
      '
      PostQuitMessage 0
      FUNCTION = 0
    END FUNCTION
    
    '=========================================================
    FUNCTION TimedMessageBox(BYVAL hWnd AS DWORD, ptszMessage AS ASCIIZ, _
             ptszTitle AS ASCIIZ, BYVAL flags AS DWORD) AS DWORD
      '
      DIM iResult       AS LONG
      DIM Msg           AS tagMsg
      DIM TimerProcPtr  AS DWORD
      DIM Delay         AS LONG
      '
      Delay = 10000      'milliseconds to wait before killing the MsgBox
      '
      TimerProcPtr = CODEPTR(MessageBoxTimer)
      SetTimer %NULL, 1, Delay, TimerProcPtr
      FUNCTION = MessageBox(%NULL, ptszMessage, ptszTitle, flags)
      KillTimer %NULL, 1
      iResult= PeekMessage(Msg, %NULL, %WM_QUIT, %WM_QUIT, %PM_REMOVE)
      IF iResult THEN FUNCTION = 0
    END FUNCTION
    
    '=========================================================
    FUNCTION PBMAIN() AS LONG
        LOCAL Msg   AS ASCIIZ * 256
        LOCAL Title AS ASCIIZ * 256
        '
        Msg = "If you wait long enough this message box will disapear on it's own." & $CRLF
        Msg = Msg & "Or just click the OK button to make it go away now." & $CRLF
        Title = "Timed MessageBox..."
        TimedMessageBox %NULL, _                                            'No Parent
                        Msg, _                                              'Message to display
                        Title, _                                            'Title
                        %MB_OK OR %MB_TASKMODAL OR %MB_ICONINFORMATION      'How to display it
    END FUNCTION

    ------------------


    [This message has been edited by John McWilliams (edited July 07, 2004).]

  • #2
    I've been using this for a while and have a problem I can't solve.

    If you put it into a loop with a short delay between, the first one or two times, the message box will come up for the specified period of time. After that, it just briefly flashes on the screen then disappears.

    It's obvious a variable needs to be reset but I'll be ding-dong if I can figure out what.

    Any help?
    There are no atheists in a fox hole or the morning of a math test.
    If my flag offends you, I'll help you pack.

    Comment


    • #3
      The timer is not being killed.
      Pass the return value from SetTimer.
      http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx

      KillTimer Function

      Parameters
      hWnd [in, optional] HWND A handle to the window associated with the specified timer. This value must be the same as the hWnd value passed to the SetTimer function that created the timer.
      uIDEvent [in] UINT_PTR The timer to be destroyed. If the window handle passed to SetTimer is valid, this parameter must be the same as the nIDEvent value passed to SetTimer. If the application calls SetTimer with hWnd set to NULL, this parameter must be the timer identifier returned by SetTimer.
      Return Value

      BOOL
      If the function succeeds, the return value is nonzero.


      Code:
      FUNCTION TimedMessageBox(BYVAL hWnd AS DWORD, ptszMessage AS ASCIIZ, _
               ptszTitle AS ASCIIZ, BYVAL flags AS DWORD) AS DWORD
        '
        DIM iResult       AS LONG
        DIM Msg           AS tagMsg
        DIM TimerProcPtr  AS DWORD
        DIM Delay         AS LONG
        LOCAL TimerResult AS LONG
        LOCAL KillResult  AS LONG
        '
        Delay = 5000      'milliseconds to wait before killing the MsgBox
        '
        TimerProcPtr = CODEPTR(MessageBoxTimer)
       
        [B]TimerResult[/B] = SetTimer(%NULL, 1, Delay, TimerProcPtr)
        FUNCTION = MessageBox(%NULL, ptszMessage, ptszTitle, flags)
        [COLOR=red]REM KillTimer %NULL, 1 'incorrect[/COLOR]
        KillResult = KillTimer(%NULL,[B]TimerResult[/B])
        iResult= PeekMessage(Msg, %NULL, %WM_QUIT, %WM_QUIT, %PM_REMOVE)
        IF iResult THEN FUNCTION = 0
      END FUNCTION
      Last edited by Mike Doty; 21 Jun 2010, 04:00 PM.

      Comment


      • #4
        There seems to be a misunderstanding of what the second parameter of SetTimer does. It is, in fact, ignored if the first parameter is set to NULL.

        If the first parameter is set to NULL then the second parameter of KillTimer should be the return value of SetTimer.

        So, if the first parameter of SetTimer is NULL then we should use something like this:

        Local TimerID As Long
        ...
        ...
        ...
        TimerID = SetTimer( %NULL, 0, Delay, TimerProcPtr )
        ...
        ...
        ...
        KillTimer %NULL, TimerID

        This may solve your problem, Mel, but then, it may not.

        BTW, instead of

        iResult= PeekMessage(Msg, %NULL, %WM_QUIT, %WM_QUIT, %PM_REMOVE)
        IF iResult THEN FUNCTION = 0

        I use [No longer true: 26 June 2010]

        Do Until PeekMessage( Msg, %Null, 0, 0, %PM_REMOVE ) = 0: Loop

        Perhaps this will help you, Mel.

        Added: You got in before me Mike. I decided to make a cup of tea half way through.
        Last edited by David Roberts; 28 Jun 2010, 05:45 AM.

        Comment


        • #5
          Hello,

          There is a function in user32.dll : messageboxtimeout
          Maybe this can help...

          Code:
          '
          'Roger Remblain
          '06/22/2010
          'PBWin 9.04.0122
          '
          #COMPILE EXE
          #DIM ALL
          %MB_TIMEDOUT = &h7D00
          '
          DECLARE FUNCTION MessageBoxTimeout LIB "user32.dll" ALIAS "MessageBoxTimeoutA" (BYVAL hwnd AS DWORD,lptext AS ASCIIZ, lpcaption AS ASCIIZ, BYVAL utype AS DWORD, BYVAL wlangageid AS WORD, BYVAL dwmilliseconds AS DWORD) AS LONG
          FUNCTION PBMAIN () AS LONG
          LOCAL utype AS DWORD
          LOCAL lpresult AS LONG
                   utype= %MB_YESNO OR %MB_SETFOREGROUND OR %MB_SYSTEMMODAL OR %MB_ICONINFORMATION
                   LOCAL t1,t2 AS ASCIIZ*30
                   '
                   t1="caption"
                   t2="title"
                   '
                   lpresult=MessageBoxTimeout(0,t1,t2,utype,0,2000)
                   '
                   SELECT CASE AS LONG lpresult
                        CASE %mb_timedout
                            ?"timeout"
                        CASE %IDYES
                            ?"yes"
                        CASE %IDNO
                            ?"no"
                   END SELECT
           
          END FUNCTION

          Comment


          • #6
            Actually, this subject got a good airing here. I mentioned MessageBoxTimeoutA in post #4 but did warn that is was undocumented.

            Comment


            • #7
              Thank you for that example, Roger. It took a while to figure out how to put it into a working function but after I did, it works brilliantly.
              There are no atheists in a fox hole or the morning of a math test.
              If my flag offends you, I'll help you pack.

              Comment


              • #8
                I have been using a variant of the above (John's initial post) for sometime without problem. However, each and every use has been in conjunction with 'If (CB.wParam And &HFFF0) = %SC_CLOSE Then'.

                Today I included it in a form not associated with a %SC_CLOSE and the parent window locked up on the time out. It was not locking up if I 'got in' before the time out.

                The problem was solved with the assignment 'hTimedMsgBoxParent = CB.Hndl' just before the TimedMessageBox call and where hTimedMsgBoxParent is declared as a global long.

                All we need to do now is to include one line in the MessageBoxTimer function as follows:

                Code:
                Function MessageBoxTimer() As Long
                  
                  [COLOR="Blue"]If hTimedMsgBoxParent <> %HWND_DESKTOP Then EnableWindow(hTimedMsgBoxParent, %TRUE)[/COLOR]
                  PostQuitMessage 0
                
                End Function
                Obviously, the parent must be enabled by windows when the message box is destroyed in the 'normal' course of events.

                Added: %HWND_DESKTOP test added - if we are coming from PBMain then we don't need to EnableWindow
                Last edited by David Roberts; 24 Jun 2010, 06:30 AM.

                Comment

                Working...
                X