My application is loading 3rd party DLLs, and some of this DLLs open MessageBox windows.
Is there a way for me to detect when such a window was being opened?
You'll need a CBT hook to receive a notification when a MessageBox window is displayed. You install this by calling the SetWindowsHookEx() function and specifying WH_CBT for the hook ID parameter. The hook callback function will provide you a handle to the MessageBox window, which you can then use to close it.
If you know exactly when to expect the MessageBox is being created and shown, then you can adopt a lighter and simpler approach than a global hook. This would involve calling the FindWindowEx function to get a handle to the MessageBox window, which you can likewise use to close it.
Of course, to close it properly, you will need to know which type of MessageBox it is (that is, which of the standard button choices that it displays) so that you can simulate a click of the desired button. Simply managing to get the MessageBox to disappear off of the screen without providing a valid answer is highly likely to have unexpected results in terms of the library code.
It bears explicit mention that this is really bad behavior on the part of a DLL. Unless absolutely necessary, ditch whatever 3rd party that is foisting such poorly written code upon you. If it is absolutely necessary, well then that's a red flag: work hard to eliminate it as a necessity. You shouldn't have to write and maintain gobs of code to work around their inability to get the big obvious things right.
Related
I want to prevent users from closing a window by Alt + F4 or by clicking the close button.
How to achieve this?
I guess the windows API can do it, but I don't have any experience, and I can't find a specific solution.
Of course, it's good to be able to implement it,don't have to use a specific API.
Background: it is very difficult to find the last place in Word after closing it for a few days. After word2013, word2013 brought with it a way to return to the previous reading position, but that thing is very unstable and often can't be saved. When word is closed, I want to stop closing and pop up a notice to remind me to add a bookmark before exiting.
EDIT: This won't work, as it turned out. At least the message hook won't work because the message is posted and not sent, and about the CBT hook I'm not sure either, and I can't test it at the moment to give an evidence-based statement. The solution is probably to subclass the window but this is also non-trivial and I can't explain it properly and with working examples right now. I can't delete this answer though because it already has a comment. See here for more info. So take it with a grain of salt. I'm turning the answer to community wiki, feel free to edit it and fix/improve the solution!
EDIT2: Seems even subclassing won't be enough because Word is doing things its own way.
You need a windows hook. Either a CBT hook or a getmessage hook will do.
You have to create a DLL for this to work. The hook handler must be located in the DLL. It must have the same bitness as Word (probably 64 Bit). Then you call SetWindowsHookEx to install a global hook.
In the hook, you will have to check whether the current action is a window-closing attempt (in a CBT hook you would check for a HCBT_SYSCOMMAND of SC_CLOSE, in a getmessage hook you would check for a WM_CLOSE message), and whether it is about a Word window (for example using the window class - not sure if it has a recognizable class, you'd have to check - or the process' executable file name which you can get using GetModuleFileName since you will run inside Word's process) and prevent the action (by returning 1 from a CBT hook or returning 0 from a getmessage hook - to allow, call CallNextHookEx).
I am debugging a strange issue with a 3rd party library that displays a formatted message box. The library uses a class based on CDialog and runs the message box dialog with the DoModal() method. Sometimes a message is displayed from a common subroutine that uses the handle of the main window as the parent (type 1), other times from another modal dialog (type 2).
Sometimes a Type 1 call is triggered by an action in a modal dialog and when this happens, the original dialog is no longer modal after the message dialog is dismissed. Changing nothing except the formatted message box with the system default message box and the original dialog stays modal, as expected.
When a Type 2 call is made, the original dialog always remains modal, so I am working to ensure that is how I call the library function, but this looks like it might be a bug in the CDialog itself, so I thought I would ask if anyone knows about this.
I have never worked with these class libraries before (I'm an old school C guy), but it looks like the library is always using EndDialog() to terminate the modal message box and there's no "fancy, low-level" windows stuff that I can find (other than the message formatting). It is probably obvious that I don't really know what I'm asking, so if there is a better place to discuss this, please send me there.
On the other hand, if anything derived from CDialog and DoModal() does this, it would appear to be a bug in the class library, since built-in modal dialogs (like MessageBox) do not have this unwanted effect. I would share the library code, but I am not the original author and I don't have permission, but I am willing to look for things as long as you are willing to have some patience for someone not familiar with C++ code structuring.
I don't know whether my answer will help you a bit.
but there is property for a Dialog box - "System Modal", which makes it System Modal Dialog.
If you set it to True, your Dialog becomes a System Modal Dialog Box.
Our application loads 3rd party DLLs that sometimes pops MessageBoxes.
We've notices that sometimes we can't just use exit(0) when there's an open MessageBox.
How can we still force an exist in such a case?
Thanks
Seems like your ugly DLL calls MessageBox (or whatever) from within DLL_THREAD_DETACH or DLL_PROCESS_DETACH.
If this happens in the same thread (i.e. the thread the calls exit) you may try to call PostQuitMessage right before the application exit. This should abort any message loop. If this happens in another thread - you may call PostThreadMessage.
There's also an option to intercept calls to Win32 API functions by hooking the appropriate module (Exe/Dll) import table. Invented by J.Richter (if I remember correctly). http://www.player.idv.tw/prog/index.php/APIHook
If you want to use brute force you may call the TerminateProcess() function. I'm not sure this is a good idea, you may want to detect if there's an open message box and send a close to it (for example using a FindWindow())
Take a look at MSDN.
According to Using Rich Edit Controls I use RichEdit in such way:
MyControl::OnCreate()
{
handle = LoadLibrary(_T("Riched20.dll"));
}
MyControl::OnDestroy()
{
FreeLibrary(handle);
}
It works fine for win32 but recently I’ve built x64 configuration and now my control fails after the page reload.
I’ve noticed that if do this:
MyControl::OnCreate()
{
handle = LoadLibrary(_T("Riched20.dll"));
FreeLibrary(handle);
handle = LoadLibrary(_T("Riched20.dll"));
}
everything works fine.
I don't wish to put this code into production, so is there any suggestions about better solution/workaround?
Since the reported fault module is Richedit20.dll_unloaded it means you are unloading the DLL while code from it is still in use.
For example, if you still have a richedit window open when you (completely) free the DLL, you can see crashes like that as soon as anything triggers a call to the control's window-proc. This is because the control's window-proc was inside the unloaded DLL code.
It should be safe to call LoadLibrary and FreeLibrary multiple times (so long as the calls balance out), so I doubt that is the problem. It may just be triggering the problem. Also, the problem was there in 32-bit builds; you just got lucky and never triggered it.
OnDestroy is the wrong place to call FreeLibrary. There are several window messages which get sent to a window after WM_DESTROY (e.g. WM_NCDESTROY).
Child windows also still exist when OnDestroy is called. If the richedits are children of your control (rather than the control itself) then moving the FreeLibrary into OnNcDestroy may save you. (Child windows are destroyed by the time WM_NCDESTROY is called.) I'd still say it's not a good place to free the library, however.
So you definitely want to move your FreeLibrary call. I would move both it and the LoadLibrary completely out of the control itself. It's not normal to have controls which load/free libraries whenever an instance of them is created. Instead, have some static init/uninit code somewhere which loads the libraries you need once and for all and frees them when the application is shutting down.
(If your app only rarely uses the control then it might make sense to load/free the library only when windows using the control are active. That situation is rare, though. Usually you're better off just leaving the DLL loaded.)
I'm writing a DLL that is automatically injected on load in a specific application. Because I'd like to run the program while working on it, and my users might want to load the program without it in specific cases (e.g. bug hunting), I sometimes want to prevent loading the DLL.
Currently I do this by checking GetKeyState for VK_LCONTROL, VK_LSHIFT , and VK_LMENU on load, and if all are down, I silently unload myself.
However, it can take quite a few seconds for the program to load and to see if the DLL was loaded or not, so I want to inform the users when we're unloading. I've considered a MessageBox, but that's too disruptive. I've tried MessageBeep, but that didn't seem to do anything on my setup. Currently I'm using a simple dual beep (Beep, Sleep, Beep) to indicate unloading, but that will probably become rather annoying to my co workers. I've also considered a system-tray icon, but that would introduce a lot of code and bug potential, while I'm aiming for a minimal notification as to not introduce any subtle bugs.
Would anyone else know a subtle way (preferably visual) to inform the user that their input has been succesfully received?
Given the limited scope of your goal, this might actually be an appropriate use of a taskbar notification balloon tip.
Edit: Added link the Joe posted in his concurring answer. Thanks, Joe! :)
If your app has a status bar at the bottom, you could place some message text there...
Have you considered a timed messagebox that closes itself?
http://www.codeguru.com/cpp/misc/misc/messageboxhandling/article.php/c203
You could open a window with a short message and close it automatically again after 0.5 seconds or so. It doesn't need user interaction so I don't think it's very disruptive.
Change the window title, then change it back afterwards. Then you can see the change even if the user has Alt-Tabbed over to some other program in the meanwhile, without stealing the focus from the user.
Concur with Greg D.
Look here: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/15cbdc8d-fde3-44ab-bbbc-e50cb2071674/
Two ideas:
Turn it around. Have a visual indication when the DLL is loaded, and have the absence of the indicator let you know that the DLL has been unloaded. Perhaps a suffix in the title bar. That way, you can tell at any time, not just during startup.
FlashWindowEx.