How to detect Windows is Closing Down / System Shutdown?

I have an EXE that I want to close when the user is closing down the Windows OS (Alt+F4, Shutdown or Restart).

Do we have that ability to query an EVENT in an ACCEPT loop that would allow the program to unload itself if the OS is shutting down?

I am not seeing anything in my code that I have created over the years to do this.

Not exactly what you’re asking, but there’s a “FrameExtension Template” in current Clarion versions that has a checkbox to allow the app to close down when Windows shuts down (so you don’t get the popup from Windows saying that it can’t shut down.)

But I use Capesoft’s Winevent which shuts down apps that don’t have an app frame: https://www.capesoft.com/docs/winevent5/WinEvent.htm#AutoShutdownFunctions

1 Like

Thanks for the reply, Jane!

I code hand-coded projects and don’t use templates. I am using C10 at the moment and was hoping there is some code I can query using the Event() call. Or, something along that line.

The included FrameExtension Template Jane mentions is probably the easiest.

If you want more control … Windows sends 2 messages (events). You have to subclass the frame to get them. For more info search the web for WM_QUERYENDSESSION and WM_ENDSESSION. If you answer YES your Frame will get an EVENT:CloseDown and it will send that to all Children.

WM_QUERYENDSESSION EQUATE(0011h) !Windows is asking if we would shutdown, True says YES
WM_ENDSESSION EQUATE(0016h) !Windows IS shutting down, we say YES and will get EVENT:CloseDown next

This template has the code. You can add it to an APP and generate to see the code it adds.

Excellent, Carl! Thanks, as always.

I will have a look at that and will come back if I have any other further questions! :nerd_face:

I found this Repo with the code:

       MODULE('WIN API PROTOTYPES')                        ! ABC Free apiSubclass template
                    CallWindowProc(LONG,UNSIGNED,UNSIGNED,UNSIGNED,LONG),LONG,PASCAL,NAME('CallWindowProcA') ! apiSubclass (ABC Free)          
       END  

...
SubClassMain          (UNSIGNED,UNSIGNED,UNSIGNED,LONG),LONG,PASCAL
...
  SELF.Open(AppFrame)                                      ! Open window
                                                           ! ABC Free apiSubclass template
  SC::WindowMain=AppFrame{Prop:WndProc}      ! Save address of code that handles window messages
  AppFrame{Prop:WndProc}=ADDRESS(SubClassMain)  ! Re-assign address of code that handles window messages
...
SubClassMain FUNCTION(LOC:hWnd,LOC:usMsg,LOC:WParam,LOC:LParam) ! ABC Free apiSubclass template

LOC:WM_QUERYENDSESSION EQUATE(0011h)                       ! apiSubclass (ABC Free)
LOC:WM_ENDSESSION      EQUATE(0016h)                       ! apiSubclass (ABC Free)
LOC:WM_PAINT           EQUATE(000Fh)                       ! apiSubclass (ABC Free)
LOC:WM_ERASEBKGND      EQUATE(0014h)                       ! apiSubclass (ABC Free)
LOC:WM_HOTKEY          EQUATE(0312H)                       ! apiSubclass (ABC Free)

LOC:SaveResults        UNSIGNED                            ! apiSubclass (ABC Free)
LOC:iParam             LONG,OVER(LOC:LParam)               ! apiSubclass (ABC Free)

    CODE                                                   ! apiSubclass (ABC Free)
    CASE LOC:usMsg                                         ! apiSubclass (ABC Free)
    OF LOC:WM_QUERYENDSESSION                              ! apiSubclass (ABC Free)
      RETURN(True)                                         ! apiSubclass (ABC Free)
    OF LOC:WM_ENDSESSION                                   ! apiSubclass (ABC Free)
      POST(Event:CloseDown)                                ! apiSubclass (ABC Free)
      RETURN(True)                                         ! apiSubclass (ABC Free)
    ! Other Windows Messages can be accessed here
    END                                                    ! apiSubclass (ABC Free)
    RETURN(CallWindowProc(SC::WindowMain,LOC:hWnd,LOC:usMsg,LOC:WParam,LOC:LParam)) ! apiSubclass (ABC Free)


1 Like

That looks like that is everything I should need to include in my project! Thanks again, Carl! Much obliged.

Many things changed in Vista, I found this page noting some of the changes to the Shutdown. E.g. a program without a visible UI can no longer block shutdown.

You can call ShutdownBlockReasonCreate() to specify a reason that will appear on the List of Apps that are blocking, seems useful for a long process e.g. “File Rebuild in Process - Do NOT Shutdown”. When done can call ShutdownBlockReasonDestroy().

image


Also new is you can call RegisterApplicationRestart() to register to have Windows Restart your EXE when the system reboots. For a utility or monitor seems nice that at Shutdown your programs closes without bother, then opens on Restart.

More on Shutdown…

1 Like

Also, remember that a template just generates code. You can create a sample app and add the template functionality and look at the generated code. Then incorporate that into your hand-coded project.
That would work using the SV solution or WinEvent’s.

2 Likes

Right… Thanks for reminding me that Rick. I haven’t generated code from a template in… fifteen years. I have so much other hand-coded code floating around that I usually just copy and paste what I need to get the job done. Thanks, Rick!

1 Like

Just remember that the message box is modal and wont respond to any OS shutdown request you send to it. Its why Capesoft rolled their own message box addon, which could respond to an OS shutdown et al request.

The template if you are looking for one is an ABC template called CleanCloseDown and uses threads and notify to post event closedowns to each top window.

When I was messing around with the subclassing in a clarion app years ago, I think the main frame window basically got most of the messages and then the runtime sent them to the appropriate thread but this might have changed in later runtimes becuase I noticed C11 handles mdi child windows differently. It would explain how the template works using notify though.

I have a template which subclasses every window, automatically and allows daisy chaining of subclass procedures so modifying the template to handle a particular win msg like this is like a 30min to 1hr job for all apps now and in the future, so I find handcoding intriguing because it tends to be more unstructured and thus requiring more work but it does have less of learning curve to begin with. I’m not saying templates are the way to go, because I have source procedures, but I do find the structured nature of the templates to be quite efficient and productive generally.

hth.

1 Like

i am running an application. if the user end the application via the windows task manager, can this extension able to detect it and perform some code?
@CarlBarnes

I do not believe you can execute something in your code if the process is killed via task manager or taskkill.exe.