You'd like to be able to control what happens once you quit your applications: you may want to shut down Windows at the same time, or perhaps even reboot the machine. How can you do that from within Access?
The Windows API provides an ExitWindowsEx function that grants you control over exiting Windows, and you have a choice of three different things you can do: log off and await a new login; shut down to the point at which it's safe to turn off the computer's power; or reboot the computer. This solution demonstrates these simple functions.
To try closing Windows under program control, load and run frmExitWindows from 11-06.MDB. This sample form, shown in Figure 11-7, allows you to choose from the three options. Make your choice and click on the Go button, which will execute the code necessary to quit in the manner you've specified.
To use this functionality within your own applications, follow these steps:
Import the module basExitWindows from 11-06.MDB.
Call the function from Table 11-4 that best suits your needs. In each case, if the function returns at all, it indicates that some Windows process wasn't able to shut down and that your function call failed. This won't happen often.
For example, to reboot your computer:
intRetval = acbReboot( )
Shuts down all processes running in the security context of the process that called the function, then logs off the user. Depending on the operating system, you may find that all applications get the shutdown message except the one that called this function. Check the behavior of your target operating system.
Reboots the computer.
Shuts down the system to a point at which it is safe to turn off the power. All file buffers are flushed to disk, and all running processes are stopped.
Normally, when you shut down Windows, it sends a message to check with every running application before shutting down. If other applications have any unsaved data files that require user intervention, you'll usually be asked if it's okay to save the files. Once all the applications have agreed to shut down, Windows shuts itself down.
Windows follows the same shutdown procedures when you use any of the functions listed in Table 11-4. The only difference is what happens after Windows shuts down.
The basExitWindows module is simple: it merely calls directly into the ExitWindowsEx API function. The entire module looks like this:
Declare Function acb_apiExitWindowsEx Lib "user32" Alias "ExitWindowsEx" _ (ByVal uFlags As Long, ByVal dwReserved As Long) As Long ' EWX_FORCE ' Forces processes to terminate. Instead of bringing up the ' "application not responding" dialog for the user, this value ' forces an application to terminate if it does not respond. ' EWX_LOGOFF ' Shuts down all processes running in the security context ' of the process that called the ExitWindowsEx function, then ' logs off the user. ' EWX_REBOOT ' Shuts down the system, then restarts the system. ' EWX_SHUTDOWN ' Shuts down the system to a point at which it is safe to turn off ' the power. All file buffers have been flushed to disk, and all ' running processes have stopped. Const EWX_LOGOFF = 0 Const EWX_SHUTDOWN = 1 Const EWX_REBOOT = 2 Const EWX_FORCE = 4 Public Function acbReboot( ) acbReboot = acb_apiExitWindowsEx(EWX_REBOOT, 0) End Function Public Function acbShutDown( ) acbShutDown = acb_apiExitWindowsEx(EWX_SHUTDOWN, 0) End Function Public Function acbLogOff( ) acbLogOff = acb_apiExitWindowsEx(EWX_LOGOFF, 0) ' This is actually necessary only in some operating systems, ' but it can't hurt. Application.Quit acExit End Function
Each function listed in Table 11-4 has its own role. You're most likely to use acbShutDown when your application is meant for users who use only Access. When they're done with your application, they're done with Windows. The other functions are more useful in utility applications other than Access; use your imagination! There may be reasons why you'd need to reboot; for example, perhaps you've changed a setting in the Windows registry for the user and you want it to take effect immediately.
Certainly, these are not functions that every application will need or that you will use every day. But if you need to control what happens once your application has done its work, they are valuable indeed.