这个东西在qtcn论坛中多次被问到,今天qt邮件列表中又有人问:“QAxObject在主线程正常,而放入次线程中则不工作”。想想还是整理一下吧
COM使用
首先调用 CoInitialize(NULL) 初始化COM库
CoCreateInstance(....) 创建COM对象并获得接口
使用
使用
释放COM对象
最后 CoUnInitialize() 收回COM库
QAxObject
和 QAxWidget 一样,它封装的是前面提到的中间部分:对象的创建及删除
问题出来了,为什么一般情况下,我们使用QAxObject的时候,都没有调用 CoInitialize 呢?
为什么呢?为什么呢?因为是 QAppliction 的主线程中。
QApplication
为了清楚起见,直接看源码吧
src/gui/kernel/qapplication_win.cpp
先看初始化时做了什么
void qt_init(QApplicationPrivate *priv, int)
{
...
HRESULT r;
r = OleInitialize(0);
if (r != S_OK && r != S_FALSE) {
qWarning("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
}
...
}
再看看退出时做了什么
void qt_cleanup()
{
...
// Deinitialize OLE/COM
OleUninitialize();
}
之所以这样做,是因为windows下拖放操作的实现需要COM的操作。
而这样一来,在QApplication的主线程中,我们也就不需要自己去初始化COM库了。
次线程
当我们在次线程中使用 QAxObject 时,由于QThread不会为我们的次线程做COM初始化的操作,所以就必须自己在次线程中调用这两个函数了。
同样,当我们使用 QCoreApplication 时,也需要自己来初始化。