Reputation: 9492
I've written a few ATL COM objects that are used for drag-and-drop within my C++ Builder application.
Due to reasons beyond my control, my application still has active COM objects when the user attempts to close it. This is because other COM clients that use my objects seem to cache my COM objects and don't release them - as a result, my COM objects still have a reference count greater than zero when the user clicks the "X" to close my program. This results in the user getting an unfriendly message like this:
I would like my application to silently terminate and not ask the user this annoying question.
How do I suppress this message?
Upvotes: 2
Views: 4080
Reputation: 597490
The popup message is displayed by the the TATLModule::AutomationTerminateProc()
callback function in atlmod.h. It is registered by the TATLModule::InitATLServer()
callback, which calls the VCL's AddTerminateProc()
function. When the TForm::Close()
method is called, it calls CallTerminationProcs()
to see if the app can safely close, which then calls TATLModule::AutomationTerminateProc()
.
The TATLModule
constructor calls InitATLServer()
if you do not provide your own initialization callback. So to avoid the popup, simply pass in a custom callback in your project's main .cpp file that does everything TATLModule::InitATLServer()
normally does other than call AddTerminateProc()
, eg:
void __fastcall MyInitATLServer();
TComModule _ProjectModule(&MyInitATLServer); // <-- here
TComModule &_Module = _ProjectModule;
BEGIN_OBJECT_MAP(ObjectMap)
...
END_OBJECT_MAP()
void __fastcall MyInitATLServer()
{
if (TComModule::SaveInitProc)
TComModule::SaveInitProc();
_Module.Init(ObjectMap, Sysinit::HInstance);
_Module.m_ThreadID = ::GetCurrentThreadId();
_Module.m_bAutomationServer = true;
_Module.DoFileAndObjectRegistration();
// AddTerminationProc(AutomationTerminationProc); // <-- no more popup!
}
Upvotes: 3
Reputation: 9492
I found a workaround for this. I'll leave this question open in case anyone posts a better method, since this one is dependent on undocumented internal implementation details of C++ Builder's ATL/VCL libraries.
In the main form, place:
extern TComModule &_Module;
void __fastcall TMainAppForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
_Module.m_nLockCnt = 0;
VCL appears to check the lock count and display this annoying message after the close query event is raised. It only displays the message if the lock count is 0. Therefore, I set the lock count to 0 which causes the message to not be shown. I think it's harmless to do, because I searched the ATL/VCL source code for places where the lock count is used, and I didn't find anything other than the code that checks whether to display this message.
Upvotes: 1
Reputation: 43331
Try
TerminateProcess(GetCurrentProcess(), 0);
Of course, if there is no better way.
Upvotes: 0