11 connect(wmp, SIGNAL(PositionChange(double, double)),
12 this, SLOT(onPositionChange(double, double)));
После вызова QAxWidget::setControl мы вызываем функцию QObject::setProperty для установки свойства ShowControls (отображать элементы управления) элемента управления Media Player системы Windows на значение false, поскольку мы предоставляем свои собственные кнопки для работы с компонентом. Функция QObject::setProperty может использоваться как для свойств СОМ, так и для обычных свойств Qt. Ее второй параметр имеет тип QVariant.
Затем мы вызываем функцию setSizePolicy, чтобы элемент управления ActiveX мог занять все имеющееся в менеджере компоновки пространство, и мы подсоединяем три события ActiveX компонента СОМ к трем слотам.
13 stopButton = new QToolButton;
14 stopButton->setText(tr("&Stop"));
15 stopButton->setEnabled(false);
16 connect(stopButton, SIGNAL(clicked), wmp, SLOT(Stop));
17 …
18 }
Остальная часть конструктора PlayerWindow следует обычному образцу, за исключением того, что мы подсоединяем некоторые сигналы Qt к слотам объекта COM (Play, Pause и Stop). Мы показали здесь реализацию только кнопки Stop, поскольку другие кнопки реализуются аналогично.
01 void PlayerWindow::timerEvent(QTimerEvent *event)
02 {
03 if (event->timerId == updateTimer) {
04 double curPos = wmp->property("CurrentPosition").toDouble;
05 onPositionChange(-1, curPos);
06 } else {
07 QWidget::timerEvent(event);
08 }
09 }
Функция timerEvent вызывается через определенные интервалы времени во время проигрывания мультимедийного клипа. Мы используем ее для продвижения ползунка. Это делается путем вызова функции property для элемента управления ActiveX, чтобы получить значение свойства CurrentPosition (текущая позиция) в виде объекта типа QVariant и вызова функции toDouble для преобразования его в тип double. Мы затем вызываем функцию onPositionChange для обновления положения ползунка.
Мы не будем рассматривать остальную часть программного кода, поскольку большая часть его не имеет непосредственного отношения к ActiveX и не содержит ничего такого, что мы уже не обсуждали ранее. Данный программный код имеется на компакт-диске.
В файле .pro нам необходимо задать элемент для связи с модулем QAxContainer.
CONFIG += qaxcontainer
При работе с объектами СОМ одной из часто возникающих потребностей является необходимость непосредственного вызова метода СОМ (вместо подсоединения его к сигналу Qt). Наиболее просто это сделать путем вызова функции QAxBase::dynamicCall с указанием имени и сигнатуры метода в первом параметре и аргументов метода в дополнительных параметрах. Например:
wmp->dynamicCall("TitlePlay(uint)", 6);
Функция dynamicCall принимает до восьми параметров типа QVariant и возвращает объект типа QVariant. Если нам необходимо передавать таким образом IDispatch * или IUnknown *, мы можем инкапсулировать компонент в QAxObject и вызвать для него функцию asVariant для преобразования его в тип QVariant. Если нам необходимо вызвать метод СОМ, который возвращает IDispatch * или IUnknown *, или если нам необходимо осуществлять доступ к свойству СОМ одного из этих типов, мы можем вместо этого использовать функцию querySubObject:
QAxObject *session = outlook.querySubObject('"Session");
QAxObject *defaultContacts =
session->querySubObject("GetDefaultFolder(01DefaultFolders)",
"olFolderContacts");