View Full Version : GUI application as DLL. Repaint is blocked.
Grinchman
6th June 2011, 04:29
Hello!
I have Qt4 GUI project. It`s implemented as DLL. The main application which uses my DLL calling interface functions from MainThread. Here is the message loop of main application:
while(buckets_rendered<numRects && events!=0)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
stat = MsgWaitForMultipleObjects(numHandles, handles, FALSE, INFINITE, QS_ALLINPUT);
if(stat == (WAIT_OBJECT_0 + numHandles))
{
continue;
}
else // message comes from the events
{
id = stat - WAIT_OBJECT_0;
--events;
// ...
}
}
All works fine with Qt 4.7.3, but when we use Qt 4.5.3 my DLL is ‘blocked’! When I click some button in my GUI app, nothing happens. But when next I click right mouse button some events occure and I see an effect from the first left mouse button click and an effect from right button click…Why only right mouse button click force repaint? I`m confused…
wysota
6th June 2011, 09:40
Where do you process Qt's events?
Grinchman
6th June 2011, 10:38
Where do you process Qt's events?
I really don`t do any special managment for events. I just have this code for MyApplication class (inherited from QApplication):
bool MyApplication::notify(QObject * obj, QEvent * event) {
try {
return QApplication::notify(obj, event);
}
catch(std::exception & ex) {
handleError(ex.what());
}
catch(...) {
handleError(tr("Critical error: unhandled exception"));
}
return false;
}
Added after 13 minutes:
Maybe it`ll be useful if I show you a code of creating and using MyApplication object.
Main dll function is:
BOOL APIENTRY DllMain(HANDLE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
{
BOOL ret = TRUE;
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
qInstallMsgHandler(myMessageHandler);
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
fBitmapManager *bmmManager = fr_get_bitmap_mgr();
if(bmmManager)
bmmManager->DeleteAllVFBs("defaultvfb");
}
break;
}
return ret;
}
As you see, nothing special...
There is interface functions for my dll:
bool RegisterPlugins(fPluginManager *plugMgr)
{
plugMgr->RegisterPlugin("vfb", "defaultvfb", VFBPluginModel::getInstance,0,0);
return TRUE;
}
bool UnRegisterPlugins(fPluginManager *plugMgr)
{
plugMgr->UnRegisterPlugin("vfb", "defaultvfb");
return TRUE;
}
extern "C" fplug_export fBool initializePlugins(fPluginManager *plugMgr)
{
return RegisterPlugins(plugMgr);
}
extern "C" fplug_export fBool uninitializePlugins(fPluginManager *plugMgr)
{
return UnRegisterPlugins(plugMgr);
}
We interested in VFBPluginModel::getInstance code. This is a singletone wich creates an QApplication object.
Class definition:
class VFBPluginModel : public QObject
{
Q_OBJECT
public:
VFBPluginModel();
virtual ~VFBPluginModel();
static void *getInstance();
...
private:
VFBApplication a;
};
And creating:
VFBPluginModel::VFBPluginModel() : a(i, &name, this)
{
}
Code for VFBApplication class:
class VFBApplication: public QApplication {
Q_OBJECT
public:
VFBApplication(int & argc, char ** argv, VFBPluginModel* plugin);
virtual ~VFBApplication();
virtual bool notify(QObject * obj, QEvent * event);
...
};
VFBApplication::VFBApplication(int & argc, char ** argv, VFBPluginModel* plugin): QApplication(argc, argv) mainWnd_(NULL)
{
mainWnd_ = new MainWindow(appModel_);
mainWnd_->show();
}
wysota
6th June 2011, 10:38
So if you don't process Qt events from within your non-Qt app, then how do you expect them to be handled? Do you have a call to QCoreApplication::exec() or QCoreApplication::processEvents() anywhere?
Grinchman
6th June 2011, 10:49
No, I don`t use it. I little bit confused about using exec() in dll.
But, anyway....my application works fine in Qt 4.7.3...what fundamental difference between 4.7.3 and 4.5.3? (
wysota
6th June 2011, 11:52
Make sure it indeed works fine in Qt 4.7.3 because there is no way for it to work fine if you don't process Qt's events.
Grinchman
7th June 2011, 07:04
Just tested. It works fine in Qt 4.7.3...
My dll originally was a standalone GUI app, and it had main function with app.exec() call. When it migrated into dll I just replaced main function by showed above DLLMain function (without app.exec() call) with several dll_export functions....
wysota
7th June 2011, 07:45
Does your notify() implementation ever get called? Place a debug statement there and find out. Print the object name and event type from the arguments the method receives.
Grinchman
7th June 2011, 08:59
Yeah, it`s always called. And sequences of events are quite common: ApplicationActivate....MouseButtonClicked and so on...And objects are ordinary: QApplication object, MainWindow object, internal widgets, buttons and etc...
wysota
7th June 2011, 11:34
Yeah, it`s always called.
In both 4.5 and 4.7?
And sequences of events are quite common: ApplicationActivate....MouseButtonClicked and so on...And objects are ordinary: QApplication object, MainWindow object, internal widgets, buttons and etc...
Please grep your code for calls to QApplication and QCoreApplication classes and paste them here.
Grinchman
8th June 2011, 07:22
wysota, your tip about processEvent was really helpful. Now non-Qt application is forcing my object QApplication to process events when it gets some windows message and it works! ) So, we may conclude that Qt 4.7 is somehow forcing processEvent without exec() and manualy call of processEvent()...
So, thank you so much for your time and help! ;)
wysota
8th June 2011, 07:28
No, it is not forcing processEvents().
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.