Windows message application close

Closing the Window

When the user closes a window, that action triggers a sequence of window messages.

The user can close an application window by clicking the Close button, or by using a keyboard shortcut such as ALT+F4. Any of these actions causes the window to receive a WM_CLOSE message. The WM_CLOSE message gives you an opportunity to prompt the user before closing the window. If you really do want to close the window, call the DestroyWindow function. Otherwise, simply return zero from the WM_CLOSE message, and the operating system will ignore the message and not destroy the window.

Here is an example of how a program might handle WM_CLOSE.

In this example, the MessageBox function shows a modal dialog that contains OK and Cancel buttons. If the user clicks OK, the program calls DestroyWindow. Otherwise, if the user clicks Cancel, the call to DestroyWindow is skipped, and the window remains open. In either case, return zero to indicate that you handled the message.

If you want to close the window without prompting the user, you could simply call DestroyWindow without the call to MessageBox. However, there is a shortcut in this case. Recall that DefWindowProc executes the default action for any window message. In the case of WM_CLOSE, DefWindowProc automatically calls DestroyWindow. That means if you ignore the WM_CLOSE message in your switch statement, the window is destroyed by default.

When a window is about to be destroyed, it receives a WM_DESTROY message. This message is sent after the window is removed from the screen, but before the destruction occurs (in particular, before any child windows are destroyed).

In your main application window, you will typically respond to WM_DESTROY by calling PostQuitMessage.

We saw in the Window Messages section that PostQuitMessage puts a WM_QUIT message on the message queue, causing the message loop to end.

Here is a flow chart showing the typical way to process WM_CLOSE and WM_DESTROY messages:

Window Messages (Get Started with Win32 and C++)

A GUI application must respond to events from the user and from the operating system.

  • Events from the user include all the ways that someone can interact with your program: mouse clicks, key strokes, touch-screen gestures, and so on.
  • Events from the operating system include anything «outside» of the program that can affect how the program behaves. For example, the user might plug in a new hardware device, or Windows might enter a lower-power state (sleep or hibernate).

These events can occur at any time while the program is running, in almost any order. How do you structure a program whose flow of execution cannot be predicted in advance?

To solve this problem, Windows uses a message-passing model. The operating system communicates with your application window by passing messages to it. A message is simply a numeric code that designates a particular event. For example, if the user presses the left mouse button, the window receives a message that has the following message code.

Some messages have data associated with them. For example, the WM_LBUTTONDOWN message includes the x-coordinate and y-coordinate of the mouse cursor.

To pass a message to a window, the operating system calls the window procedure registered for that window. (And now you know what the window procedure is for.)

The Message Loop

An application will receive thousands of messages while it runs. (Consider that every keystroke and mouse-button click generates a message.) Additionally, an application can have several windows, each with its own window procedure. How does the program receive all these messages and deliver them to the correct window procedure? The application needs a loop to retrieve the messages and dispatch them to the correct windows.

For each thread that creates a window, the operating system creates a queue for window messages. This queue holds messages for all the windows that are created on that thread. The queue itself is hidden from your program. You cannot manipulate the queue directly. However, you can pull a message from the queue by calling the GetMessage function.

This function removes the first message from the head of the queue. If the queue is empty, the function blocks until another message is queued. The fact that GetMessage blocks will not make your program unresponsive. If there are no messages, there is nothing for the program to do. If you have to perform background processing, you can create additional threads that continue to run while GetMessage waits for another message. (See Avoiding Bottlenecks in Your Window Procedure.)

Читайте также:  Как открывать папки одним щелчком мыши windows 10

The first parameter of GetMessage is the address of a MSG structure. If the function succeeds, it fills in the MSG structure with information about the message. This includes the target window and the message code. The other three parameters let you filter which messages you get from the queue. In almost all cases, you will set these parameters to zero.

Although the MSG structure contains information about the message, you will almost never examine this structure directly. Instead, you will pass it directly to two other functions.

The TranslateMessage function is related to keyboard input. It translates keystrokes (key down, key up) into characters. You do not really have to know how this function works; just remember to call it before DispatchMessage. The link to the MSDN documentation will give you more information, if you are curious.

The DispatchMessage function tells the operating system to call the window procedure of the window that is the target of the message. In other words, the operating system looks up the window handle in its table of windows, finds the function pointer associated with the window, and invokes the function.

For example, suppose that the user presses the left mouse button. This causes a chain of events:

  1. The operating system puts a WM_LBUTTONDOWN message on the message queue.
  2. Your program calls the GetMessage function.
  3. GetMessage pulls the WM_LBUTTONDOWN message from the queue and fills in the MSG structure.
  4. Your program calls the TranslateMessage and DispatchMessage functions.
  5. Inside DispatchMessage, the operating system calls your window procedure.
  6. Your window procedure can either respond to the message or ignore it.

When the window procedure returns, it returns back to DispatchMessage. This returns to the message loop for the next message. As long as your program is running, messages will continue to arrive on the queue. Therefore, you must have a loop that continually pulls messages from the queue and dispatches them. You can think of the loop as doing the following:

As written, of course, this loop would never end. That is where the return value for the GetMessage function comes in. Normally, GetMessage returns a nonzero value. When you want to exit the application and break out of the message loop, call the PostQuitMessage function.

The PostQuitMessage function puts a WM_QUIT message on the message queue. WM_QUIT is a special message: It causes GetMessage to return zero, signaling the end of the message loop. Here is the revised message loop.

As long as GetMessage returns a nonzero value, the expression in the while loop evaluates to true. After you call PostQuitMessage, the expression becomes false and the program breaks out of the loop. (One interesting result of this behavior is that your window procedure never receives a WM_QUIT message. Therefore, you do not have to have a case statement for this message in your window procedure.)

The next obvious question is when to call PostQuitMessage. We’ll return to this question in the topic Closing the Window, but first we have to write our window procedure.

Posted Messages versus Sent Messages

The previous section talked about messages going onto a queue. Sometimes, the operating system will call a window procedure directly, bypassing the queue.

The terminology for this distinction can be confusing:

  • Posting a message means the message goes on the message queue, and is dispatched through the message loop (GetMessage and DispatchMessage).
  • Sending a message means the message skips the queue, and the operating system calls the window procedure directly.

For now, the difference is not very important. The window procedure handles all messages. However, some messages bypass the queue and go directly to your window procedure. However, it can make a difference if your application communicates between windows. You can find a more thorough discussion of this issue in the topic About Messages and Message Queues.

Application. Exit Method

Definition

Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.

Overloads

Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.

Читайте также:  Linux archive log files

Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.

Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed.

Examples

The following code example lists numbers in a list box on a form. Each time you click button1 , the application adds another number to the list.

The Main method calls Run to start the application, which creates the form, listBox1 , and button1 . When the user clicks button1 , the button1_Click method adds numbers one to three to the list box, and displays a MessageBox. If the user clicks No on the MessageBox, the button1_Click method adds another number to the list. If the user clicks Yes, the application calls Exit, to process all remaining messages in the queue and then to quit.

The example requires that listBox1 and button1 have been instantiated and placed on a form.

Remarks

The Exit method stops all running message loops on all threads and closes all windows of the application. This method does not necessarily force the application to exit. The Exit method is typically called from within a message loop, and forces Run to return. To exit a message loop for the current thread only, call ExitThread.

Exit raises the following events and performs the associated conditional actions:

A FormClosing event is raised for every form represented by the OpenForms property. This event can be canceled by setting the Cancel property of their FormClosingEventArgs parameter to true .

If one of more of the handlers cancels the event, then Exit returns without further action. Otherwise, a FormClosed event is raised for every open form, then all running message loops and forms are closed.

The Exit method does not raise the Closed and Closing events, which are obsolete as of .NET Framework 2.0.

Closing Applications

What is best practice when closing a C# application?

I have read that you can use:

But what is the difference?

Furthermore, with regards to Environment.Exit(0), I have used exit codes before when working with Java but have never fully understood their purpose. What role do they play when exiting an application in C#?

4 Answers 4

System.Windows.Forms.Application.Exit() — Informs all message pumps that they must terminate, and then closes all application windows after the messages have been processed. This method stops all running message loops on all threads and closes all windows of the application. This method does not force the application to exit. The Exit() method is typically called from within a message loop, and forces Run() to return. To exit a message loop for the current thread only, call ExitThread() . This is the call to use if you are running a Windows Forms application. As a general guideline, use this call if you have called System.Windows.Forms.Application.Run() .

System.Environment.Exit(exitCode) — Terminates this process and gives the underlying operating system the specified exit code. This call requires that you have SecurityPermissionFlag.UnmanagedCode permissions. If you do not, a SecurityException error occurs. This is the call to use if you are running a console application.

I hope it is best to use Application.Exit

See also these links:

Application.Exit is for Windows Forms applications — it informs all message pumps that they should terminate, waits for them to finish processing events and then terminates the application. Note that it doesn’t necessarily force the application to exit.

Environment.Exit is applicable for all Windows applications, however it is mainly intended for use in console applications. It immediately terminates the process with the given exit code.

In general you should use Application.Exit in Windows Forms applications and Environment.Exit in console applications, (although I prefer to let the Main method / entry point run to completion rather than call Environment.Exit in console applications).

For more detail see the MSDN documentation.

Close programs from the command line (Windows)

What is the proper way to close/exit programs from command line, similar to pressing the «X» close button in the corner of the window?

Im trying to close chrome under 3 different versions of windows: win7 ultimate, win7 home, winXP

Under Ultimate and XP: TSKILL chrome

Under Home: TASKKILL /IM chrome.exe

(It closes chrome, no cmd errors,
but chrome error restore when relaunch it)

TASKKILL /IM chrome.exe :

(It closes chrome, no chrome errors when relaunch it,
but errors in cmd: «impossible to terminate child processes(about 4-5), only by force with /F «)

Читайте также:  Как подготовить загрузочную флешку windows 10 uefi

Should I ignore cmd child errors if on relaunch chrome show me no errors?

5 Answers 5

The proper way to close/exit a program ultimately depends upon the software. However, generally the best practice is for Windows programs to close whenever they receive the WM_CLOSE message. Properly releasing memory and closing handles. There are other messages that can signal the close of the application, but it is up to the author of the software how each message is handled.

taskkill sends the WM_CLOSE message and it is then up to the application whether to properly close. You may also want to use the /T option to also signal child processes.

Only use the /F option if you want to force the termination of the process.

Other options would include sending the Alt+F4 keys, using PowerShell, or 3rd party applications.

Update to Updated Question

Ignore, the errors. Chrome generates many processes. The errors are caused when an process does not acknowledge the WM_CLOSE message that TASKKILL sends. Only processes with a message loop will be able to receive the message, therefore, the processes that do not have a message loop will generate that error. Most likely, these processes are the chrome extensions and plugins.

To hide the errors capture the output

Summary: TASKKILL is the proper way via command line to close applications per its WM_CLOSE implementation and the Microsoft KB that I linked.

It has «closeprocess» command which is designed to close processes gracefully. As per its document, it does not terminate apps but sends WM_CLOSE to all top-level windows of the target process.

If this doesn’t work, I bet your application has an unusual cleanup procedure. I would like to see what happens inside so please let me know what your target application is.

The answer to that question can be found here (Microsoft link).

You can send WM_CLOSE messages to any window you wish to close. Many windows handle WM_CLOSE to prompt the user to save documents.

A tool that does this correctly is @Kill . Look also SendMsg.

I do not know how to do this in batch, but you could use the vbscript for this. Simulating the Alt + F4 keys (equates to signal WM_CLOSE ).

Run and look at the behavior of this script below.

Here is the list key names for SendKeys.

When you run the script, the notepad is open, some words are written and then a signal to close the program is delivered, see picture below.

Additional Questions

Can I start a program minimized, or background with vbscript?

Yes. Use the following code:

For more information check the Run Method .

Can chrome go to some url in vbscript?

If chrome is the default, use:

Is there a way to bring focus to specific application (chrome.exe)?

I want to send alt+f4 ONLY to chrome, independently of i’m doing with other windows.

The following code works on Windows 8.

There are some command-line utilities that can send a suitable WM_SYSCOMMAND message (with SC_CLOSE as the command) to a program’s top-level window. I’m sure that at least one will be mentioned shortly. (Then someone will mention AutoIt. Then there’ll be an answer showing how to do it with PowerShell and CloseMainWindow() .)

The command-line utility that comes as a built-in command in JP Software’s TCC, a command interpreter and command script processor for Windows, is called TASKEND .

Alright, Not going to lie. I saw this on stackoverflow and thought it was a challenging question. Soooo I just spent the last 2 hours writing some code. And here it is.

After following the steps below, you can type «TaskClose notepad.exe» after hitting «Start» and it will auto save all undocumented notepad files into desktop. It will auto-close chrome.exe and save the restoration settings.

You can add and remove additional settings for other applications under the if conditions. For instance:

The vbs and batch files performs the following procedures:

  • Collects the executable.
  • Queries the executable application names off of the tasklist.
  • Performs an «Alt+TAB(x)» procedure until it has verified the window is open.
  • Then Executes the rolling commands whether it be «Alt+F4» or even in extreme cases
  • Alt+F4
  • Activate Save
  • AutoIncrememnt Filename
  • Exit application.

ReturnAppList.bat : install in «C:\windows\system32\»

TaskClose.bat : install in «C:\windows\system32\» AND «C:\Users\YourUserName\»

TaskClose.vbs : install in «C:\windows\system32\»

This was alot of fun to write and I’m more happy about finishing it than actually showing the answer. Have a great week!

Оцените статью