Announcement

Collapse
No announcement yet.

Is there a way to intercept the "X" (close) button...

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

  • Is there a way to intercept the "X" (close) button...

    ...so I can do some cleanup before the program actually ends?
    Thanks.


    ------------------
    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.

  • #2
    Code:
    #DIM ALL
    #INCLUDE "win32api.inc"
    '
    DECLARE FUNCTION ConsoleHandler(BYVAL dwEvent AS DWORD) AS LONG
    FUNCTION PBMAIN () AS LONG
      SetConsoleCtrlHandler CODEPTR(ConsoleHandler), 1
      WAITKEY$
      SetConsoleCtrlHandler CODEPTR(ConsoleHandler), 0
    END FUNCTION
    '
    FUNCTION ConsoleHandler(BYVAL dwEvent AS DWORD) AS LONG
      BEEP
      'Alt + F4 not trapped here, Ctrl-C not working either
      SELECT CASE dwEvent
        CASE %CTRL_C_EVENT
          PRINT "Ctrl-C pressed.  Never got this to work."
        CASE %CTRL_BREAK_EVENT
          PRINT "Ctrl-Break pressed"
        CASE %CTRL_CLOSE_EVENT
          PRINT "[x] Close clicked"
        CASE %CTRL_LOGOFF_EVENT
          PRINT "User logging off or restarting"
        CASE %CTRL_SHUTDOWN_EVENT
          PRINT "System shutting down"
      END SELECT
      SLEEP 1000
    END FUNCTION
    ------------------
    The world is full of apathy, but who cares?

    Comment


    • #3
      Originally posted by Mike Doty:
      Code:
          PRINT "Ctrl-C pressed.  Never got this to work."
      This will never work, because RB console returns a chr$(3) in inkey$.
      I also suggest to set the ConsoleHandler value %TRUE, then the control will
      be handed back to the program if the [X]Close is clicked.
      Here is my version.
      Note: To be exact: we need to determine whether F4 or Alt-F4 is pressed, so
      an (inshift and 3) would come in handy.
      Code:
      #compile exe
      #dim all
      #include "WIN32API.INC"
      
      declare function Breakhandler(byval dwEvent as dword) as long
      
      global gEventType as dword
      global gEventFlag as long
      
      function pbmain as long
          local lTemp as long
          local sTemp as string
          stdout "<Esc> will stop this little program"
          SetConsoleCtrlHandler codeptr(Breakhandler),1
          while %TRUE
            if gEventFlag then
               select case gEventType
                 case %CTRL_BREAK_EVENT
                   print "Ctrl-Break pressed"
                 case %CTRL_CLOSE_EVENT
                   print "[x] Close clicked"
                 case %CTRL_LOGOFF_EVENT
                   print "User logging off or restarting"
                 case %CTRL_SHUTDOWN_EVENT
                   print "System shutting down"
               end select
               gEventFlag=%FALSE
            end if
            sTemp=inkey$
            if len(sTemp) then
               select case sTemp
                 case chr$(3)
                   print "Ctrl-C pressed"
                 case chr$(0)+chr$(62)
                   print "Alt-F4 pressed"
                 case chr$(27)
                   print "Escape pressed - exiting program"
                   exit function
                 case else
                   for lTemp=1 to len(sTemp)
                       stdout format$(asc(mid$(sTemp,lTemp)))+" ";
                   next lTemp
                   stdout""
               end select
            end if
            sleep 2
          wend
          SetConsoleCtrlHandler codeptr(Breakhandler),0
      end function
      
      function Breakhandler(byval dwEvent as dword) as long
          gEventType=dwEvent
          gEventFlag=%TRUE
          function=%TRUE
      end function
      Best regards
      Albert

      ------------------
      Albert Richheimer
      http://consulting.richheimer.org
      http://www.chlohn.ch

      [This message has been edited by Albert Richheimer (edited October 29, 2006).]
      „Let the machine do the dirty work.“
      The Elements of Programming Style, Brian W. Kernighan, P. J. Plauger 1978

      Comment


      • #4
        I think I can work with that, Mike. Thanks.


        ------------------
        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


        • #5
          Code:
          #DIM ALL
          #INCLUDE "win32api.inc"
          'Anyone know how to trap all events in ConsoleHandler?
          'This should cover the bases
          'SetConsoleMode might be used
          '
          DECLARE FUNCTION ConsoleHandler(BYVAL dwEvent AS DWORD) AS LONG
          DECLARE FUNCTION ShutDown AS LONG
          FUNCTION PBMAIN () AS LONG
            LOCAL result AS LONG
          
            'Can't get this to work, probably don't want anyway
            result = SetConsoleMode(CONSHNDL,%Enable_Processed_Input)    'can't get to work
            IF result = 0 THEN PRINT "Can't SetConsoleMode"              'can't get to work
            
            result = SetConsoleCtrlHandler(CODEPTR(ConsoleHandler), 1)   'add handler, true
            IF result = 0 THEN PRINT "Can't add handler"
            
            result = ASC(RIGHT$(WAITKEY$,1))  'could be 2 characters
            IF result = 3 THEN
              PRINT "Ctrl+C didn't work so shut down here"
            ELSEIF result = 62 THEN
              PRINT "Alt+F4 didn't work, so shut down here"
            ELSE
                PRINT "result" ; result
            END IF
            ShutDown
            result = SetConsoleCtrlHandler(CODEPTR(ConsoleHandler), 0)  'remove handler, false
            IF result = 0 THEN
               PRINT "Didn't end handler cleanly"
            ELSE
              PRINT "Handler shutdown correctly"
            END IF
            SLEEP 2000
          END FUNCTION
          
          FUNCTION ConsoleHandler(BYVAL dwEvent AS DWORD) AS LONG
            PRINT "ConsoleHandler"
            'Alt + F4 not trapped here, Ctrl-C not working either
            SELECT CASE dwEvent
              CASE %CTRL_C_EVENT
                PRINT "Ctrl-C pressed."                    'does NOT get called here
                ShutDown
              CASE %CTRL_BREAK_EVENT                       'does NOT get called here
                PRINT "Ctrl-Break pressed"
                ShutDown
              CASE %CTRL_CLOSE_EVENT                       'works
                PRINT "[x] %CTRL_CLOSE_EVENT"
                ShutDown
              CASE %CTRL_LOGOFF_EVENT                      'works
                PRINT "User logging off or restarting"
                ShutDown
              CASE %CTRL_SHUTDOWN_EVENT                    'works
                PRINT "System shutting down"
                ShutDown
            CASE ELSE
                PRINT "dwEvent was something else" + STR$(dwEvent)
                ShutDown
            END SELECT
            SLEEP 1000
          END FUNCTION
          
          FUNCTION ShutDown AS LONG
            STATIC AlreadyShutDown AS LONG
            IF AlreadyShutDown THEN
               BEEP
               PRINT "ShutDown: Already Shutdown, have never seen this"
               SLEEP 500
               EXIT FUNCTION
            END IF
            PRINT "ShutDown:"
            AlreadyShutDown = 1
            SLEEP 500
          END FUNCTION
          ------------------
          The world is full of apathy, but who cares?

          Comment


          • #6
            Albert,
            Code:
            CASE %CTRL_CLOSE_EVENT                       'works
                  PRINT "[x] %CTRL_CLOSE_EVENT"
                  ShutDown
            If FUNCTION = 1 is added above, windows opens a dialog box
            saying the system needs more time to end (in my code.)"


            ------------------
            The world is full of apathy, but who cares?

            Comment


            • #7
              Originally posted by Mike Doty:
              Albert,
              If FUNCTION = 1 is added above, windows opens a dialog box
              saying the system needs more time to end (in my code.)"
              Right. This is the reason for the return value = 1. If you want to close down
              the program immediately you may return 0.

              Best regards
              Albert


              ------------------
              Albert Richheimer
              http://consulting.richheimer.org
              http://www.chlohn.ch
              „Let the machine do the dirty work.“
              The Elements of Programming Style, Brian W. Kernighan, P. J. Plauger 1978

              Comment

              Working...
              X