Aborting an MFC-based C++ without a dialog pop-up - c++

We have an old MFC-based C++ gui app (Visual Studio 6.0) which often does not terminate correctly. So I would like to be able to use a instruction like "abort();" to immediately end it.
However, the abort() instruction causes a dialog box to pop up, rather than ending immediately. Using "exit(int)" doesn't work.
Is there a way to eliminate the abort dialog, or is there a better termination method?

One obvious way to abort without anything else happening ahead of time would be for it to call the Windows ExitProcess function:
ExitProcess(exitCode);
If you want to kill it from some external program, you'd do that with TerminateProcess. To do that, you'll need a handle to the process, which typically means getting its process ID. If you're doing this from a program that spawned the one you want to kill, you'll probably get a handle to it when you create it. Otherwise, you'll probably need to use something like FindWindow to find its window, then GetWindowThreadProcessId to find the ID of that window's process. Once you have that, you call OpenProcess to get a handle, and finally TerminateProcess to actually kill it.

If it is a dialog box based app, then you can use EndDialog(IDOK) method.

Related

click close console window to end a c++ console program is proper way?

I have just got this problem for a few days. Before, I've always thought that letting the program exit by returning from main and clicking close the console window is the same way to end the program.
However, I've found that they are different. Since my program opens a camera which is an object. And closing the console windows does not destroy or clean up the object. So the next time I have error to open the camera again
I just need a confirm if this is true?
Then why only until now I can see the problem?
Closing a console window in Windows, kills the running program (or stack of running programs). Unless it has registered a handler for this event, it gets no chance to clean up. If you want solution, register a handler.
Hm, consulting the documentation, wait a few secs…
OK, look up SetConsoleCtrlHandler.
Closing a running console application will kill the process, not giving you the chance for any clean up code. I guess you could hook a windows message loop to trap the WM_CLOSE message and do proper cleanup, but at the end of the day, you just shouldn't kill the process.

How to automatically close my GUI application from within?

Let me explain my question with an example. In my app, I need to provide a way to automatically close it from within "itself." (An example of such function is when an installer/updater of my app needs it to close before installing an update. Another example is when my app performs actions on schedule and needs to automatically close once it's done.)
I picture that in the simplest situation posting the WM_CLOSE message to the own window will accomplish this task, but there're the following cases that will not work with just that:
My app may be displaying an arbitrary number of child dialog windows.
My app may be displaying a common control window, such as Open File dialog:
or this one, but there could be others:
And lastly what could one do if the close button is not even available:
At the current point, I simply resort to terminating my process (either with the exit() method from within, or with TerminateProcess from outside.)
But I'm curious, if there's a more graceful way of closing my GUI app (from within)?
There is no single answer, it depends on your app's architecture and what it's doing. I don't quite understand why you would want to force close your application while it is in a common dialog, but if you do, then exit() is safe. In that case the process is actually shutdown from the operating system's perspective as opposed to a forced termination (TerminateProcess). In theory TerminateProcess might leave objects in the OS (DLL global data and such) in an inconsistent state, and exit() will be cleaner in that regard.
Generally though I'd avoid having visible UI that is up for the user just disappear and instead close the windows in reaction to some user choice.
But, exit() will work.
You can use exit() but a safer way to close the window would be:
SomewWindow->ShowWindow(SW_HIDE);
You could then destroy the window object or show the window later.

How to exit Win32 application via API?

I have a C++ Win32 application written using Win32 API and I wish to force it to exit in one of functions. Is there something like Exit() or Destroy() or Abort() something similar that would just terminate it?
Aiiieeeeeeeeeeee. Don't do ANY of these things!
exit() and ExitProcess are the equivalent of taking a gun and shooting the process in the face. I hope I don't have to explain why that isn't nice, especially for processes that are holding shared objects like database handles that might be system-wide. I know that's the norm in Android, but this is Windows and we don't do that 'round here.
Calling PostQuitMessage() directly can cause memory leaks. PostQuitMessage() is intended to be called from WM_DESTROY. It is NOT NOT NOT a message intended to be used to ask a window to close. It's a callback mechanism for applications to post their exit code back to the shell. It is intended to populate WM_QUIT with the application exit code. If you call PostQuitMessage() directly, you will bypass WM_DESTROY entirely. This is problematic because many windows--and child widgets--very correctly perform their clean-up in WM_DESTROY. If you skip this message by lying to the window, you will deny components the chance to clean up.
And since we're on the topic, don't call WM_DESTROY directly either. Raymond Chen of Microsoft has a wonderful article where he explains "Sending a window a WM_DESTROY message is like prank calling somebody pretending to be the police". It's sort of the evil-twin of PostQuitMessage. Instead of exiting without cleaning up, you're asking the window to clean up without exiting. The window manager never knows to remove the components, and you're left with a dead orphan window in memory. Sigh.
The correct answer is to post WM_CLOSE. Anything using the default window procedure will correctly notify the window manager to destroy the window which will cascade on to WM_DESTROY then to WM_QUIT as intended.
If you need different behavior than the standard close, the other alternative is to create a WM_USER or WM_APP message. If your window has a "fancy" WM_CLOSE--say, for example, you give the user a prompt "Are you sure you want to exit?"--and you want to skip that, you may define a custom message with WM_USER or WM_APP and call that in its place. Your app-defined message would implement the default close behavior, and the WM_CLOSE that's tied to the system gadgets performs your fancy behavior.
I hope that helps!
PostQuitMessage() is the standard, graceful way of quitting a windowed application.
It will not immediately quit but rather post a quit message that will get parsed by your main loop (if done correctly) and then quit the application.
If you're using a Win32 application with a proper window procedure, you can use the function PostQuitMessage.
If you're working with visual C++, then use:
PostQuitMessage()
ExitProcess is the function to use, else you can use exit, note that neither insure the integrity of the shutdown (ie: you many leak handles etc and threaded operations will be terminated, even if they are halfway through an operation, like a db commit)
Yes, it's exit()
http://www.cplusplus.com/reference/clibrary/cstdlib/exit/
Just return from the WinMain function. If you have a message loop, use PostQuitMessage to break out. Don't try to exit the process in the middle of execution; it's sloppy.

Closing a MessageBox automatically

I have a third party encryption library, which may create a MessageBox if key creation fails. The failure can be caused by bad random number generation or other rarities, and in most cases, trying again will result in success. My code will attempt key creation up to three times before deciding it failed.
Now, the issue is that the program may be used with automation. If a MessageBox is created during automation, it will block the process forever, because there's nobody to click the 'OK' button.
Does anyone know of a way to catch when this message box is created and automatically close it?
Anything is fair game, as long as it's not something that will make security suites angry. This means no hooking or code tunneling.
In summary, I need to catch when a MessageBox is created and close it. The MessageBox's creation is outside of my control. Modifying the code at runtime is not acceptable.
Also, I've noticed there are some other similar questions, but they don't have the same requirements.
EDIT: Additional note, I can find the message box via searching through all windows until I find one with a matching title and then send it a WM_CLOSE message, but I don't think this is a great solution. I also have no guarantee that the message box has been/will be displayed, or how long after my call it will be displayed. It could display instantly, it could display 1200 ms later, or it could not display at all.
Just before you begin the encryption process, install a WH_CBT hook, and in its callback watch for an nCode of HCBT_CREATEWND. If you get a matching class name ('#32770 (Dialog)' ?) and a matching title either return a nonzero value from the callback, or if that doesn't work post a WM_CLOSE (or a BM_CLICK to a relevant button if selecting an option is necessary). Uninstall the hook after the process for not messing with every possible dialog your application pops up.
That sounds like bad design on the part of that library. Generally any sort of utility library (like encryption) has no business invoking any kind of GUI (unless you explicitly ask it to).
Is there possibly some configuration or setting in this library that could disable its use of message boxes?
If not, I'd suggest that you might want to investigate using a different library. After all, if the designers of this library have already made this kind of poor design decision once, then there may be other unfortunate surprises lurking in there.
You can hope that it will be found by GetForegroundWindow, but this may catch other applications. The more brute force way is to iterate over all windows with EnumWindows looking for something that has a caption or text equal to this shown by the library.
I have once "remote controlled" an application by sending mouse click events to some controls. I guess you would have to do this in a separate thread that is watching for Events if a window is opened. Pretty ugly but working...
Create a new thread. If your function fails and a Message Box is opened, obtain a handle to the message box by looping through the windows (GetTopWindow, GetNextWindow) and comparing the window's process id to the one returned from GetCurrentProcessId().
Or, you can avoid all the hard work and just hook the MessageBox API with detours. It's not very hard, and if you don't want to pay for detours, you can do it manually.
Call VirtualProtect and set the memory protection at MessageBox at PAGE_EXECUTE_READWRITE
Create a naked function, and use it as a trampoline.
Create a function identical in parameters to MessageBox (this will be your hook)
Create a jump from MessageBox to your hook function.

Globally intercept window movement

I am having trouble getting a global system hook to work. I want to be notified whenever a window is moving, as early as possible, and change the window size. This means the CBT hook HCBT_MOVESIZE won't cut it, it only happens after the window has been moved. I want to hook the actual movement of the window, and be able to change the window size during the move.
The hooks are set from a DLL, and the callback function is within that DLL. This is what I've tried.
WH_CALLWNDPROC. It does alert me when a window is moved (WM_MOVING is received for windows from other applications), but I cannot change the contents of the message.
WH_CALLWNDPROCRET Same as WH_CALLWNDPROC.
CBT hook HCBT_MOVESIZE. Event happens to late.
WH_GETMESSAGE. Never receive WM_MOVE, WM_MOVING or WM_WINDOWPOSCHANGING. This hook would allow me to change the messages.
Update: Windows event hooks seem to allow me to capture it:
hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc,
0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
However, this creates a different problem: changing the size of the window using SetWindowPos() does not work (it changes size alright, but immediately changes back to its previous size), even though I use SWP_NOSENDCHANGING. Ideas?
Update 2: Subclassing seems to work, however Visual Studio crashes after each program run (so does a lot of other windows). It works well if I place breakpoints and walk through the "unsubclassing", but not when I let the program run by itself. Ideas?
I have a CBT hook (it was there from earlier), and whenever HCBT_ACTIVATE is sent for a new window, I remove any previous subclassing using SetWindowLongPtr() (this has to run on 64-bit as well), and then subclass the new window. If I put a breakpoint anywhere, and immediately resume the session when it breaks, everything works fine. However, when I do not have any breakpoints, Visual Studio crashes when the program exits.
Hm, I would've thought that HCBT_MOVESIZE is precisely what you want, given that the MSDN says this about CBT hooks:
The system calls this function before activating, creating, destroying,
minimizing, maximizing, moving, or sizing a window.
and in particular:
HCBT_MOVESIZE
A window is about to be moved or sized.
(these quotes were taken from http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx)
...so I'd have thought that you get the HCBT_MOVESIZE call in time. The hook function which handles HCBT_MOVESIZE is also allowed to return an integer so that the system can determine whether the operation is allowed or should be prevented. Hence, given that the HCBT_MOVESIZE hook should get an option to prevent the operation, I'd say it's called before the move event occurred.
Are you really sure the hook function is called after the move event? If you do a GetWindowRect call on the particular handle within your hook function, does the returned rect equal the rectangle which is passed to the hook function?
Hooks are pretty heavy. You only want to use them when you absolutely have to.
That said, you could use one of the basic hooks simply as a way to get into the process. Once in the process, you could subclass the window you're interested in and handle the sizing messages in your subclass proc rather than trying to catch everything at the hook level.
Depending on what you want to do in response to the resize, you might need some interprocess communication.