PDA

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().