Qutlook-Beispiel (ActiveQt)
Das Qutlook-Beispiel veranschaulicht die Verwendung von ActiveQt zur Automatisierung von Outlook. Das Beispiel nutzt das Tool „dumpcpp“, um einen C++-Namespace für die Typbibliothek zu generieren, die das Outlook-Objektmodell beschreibt.
Die Projektdatei für das Beispiel sieht wie folgt aus:
TEMPLATE = app
TARGET = qutlook
QT += widgets axcontainer
TYPELIBS = $$system(dumpcpp -getfile {00062FFF-0000-0000-C000-000000000046})
isEmpty(TYPELIBS) {
message("Microsoft Outlook type library not found!")
REQUIRES += Outlook
} else {
HEADERS = addressview.h
SOURCES = addressview.cpp main.cpp
}Die Projektdatei verwendet das Tool „ dumpcpp “, um dem Projekt eine MS Outlook-Typbibliothek hinzuzufügen. Sollte dies fehlschlagen, gibt das generierte Makefile lediglich eine Fehlermeldung aus; andernfalls führt der Build-Schritt nun das Tool „dumpcpp“ auf die Typbibliothek an und generiert eine Header- sowie eine CPP-Datei (in diesem Fall „ msoutl.h “ und „ msoutl.cpp “), die eine benutzerfreundliche API für die Outlook-Objekte deklarieren und implementieren.
class AddressView : public QWidget
{
Q_OBJECT
public:
explicit AddressView(QWidget *parent = nullptr);
protected slots:
void addEntry();
void changeEntry();
void itemSelected(const QModelIndex &index);
void updateOutlook();
protected:
AddressBookModel *model;
QTreeView *m_treeView;
QPushButton *m_addButton;
QPushButton *m_changeButton;
QLineEdit *m_firstName;
QLineEdit *m_lastName;
QLineEdit *m_address;
QLineEdit *m_email;
};Die Klasse „AddressView“ ist eine Unterklasse von „ QWidget “ für die Benutzeroberfläche. Das Widget „ QTreeView “ zeigt den Inhalt des Outlook-Ordners „Kontakte“ an, wie er von der Datei „ model “ bereitgestellt wird.
#include "addressview.h"
#include "msoutl.h"
#include <QtWidgets>
class AddressBookModel : public QAbstractListModel
{
public:
explicit AddressBookModel(AddressView *parent);
virtual ~AddressBookModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex &index, int role) const;
void changeItem(const QModelIndex &index, const QString &firstName, const QString &lastName, const QString &address, const QString &email);
void addItem(const QString &firstName, const QString &lastName, const QString &address, const QString &email);
void update();
private:
Outlook::Application outlook;
Outlook::Items *folderItems = nullptr;
mutable QHash<QModelIndex, QStringList> cache;
};Die Klasse „AddressBookModel“ ist eine Unterklasse von „ QAbstractListModel “, die direkt mit Outlook kommuniziert und dabei ein „ QHash “ zum Zwischenspeichern verwendet.
AddressBookModel::AddressBookModel(AddressView *parent)
: QAbstractListModel(parent)
{
if (!outlook.isNull()) {
Outlook::NameSpace session(outlook.Session());
session.Logon();
Outlook::MAPIFolder *folder = session.GetDefaultFolder(Outlook::olFolderContacts);
folderItems = new Outlook::Items(folder->Items());
connect(folderItems, SIGNAL(ItemAdd(IDispatch*)), parent, SLOT(updateOutlook()));
connect(folderItems, SIGNAL(ItemChange(IDispatch*)), parent, SLOT(updateOutlook()));
connect(folderItems, SIGNAL(ItemRemove()), parent, SLOT(updateOutlook()));
delete folder;
}
}Der Konstruktor initialisiert Outlook. Die verschiedenen Signale, die Outlook zur Benachrichtigung über Inhaltsänderungen bereitstellt, sind mit dem Slot „ updateOutlook() “ verbunden.
AddressBookModel::~AddressBookModel()
{
delete folderItems;
if (!outlook.isNull())
Outlook::NameSpace(outlook.Session()).Logoff();
}Der Destruktor meldet sich von der Sitzung ab.
int AddressBookModel::rowCount(const QModelIndex &) const
{
return folderItems ? folderItems->Count() : 0;
}
int AddressBookModel::columnCount(const QModelIndex & /*parent*/) const
{
return 4;
}Die Implementierung von „ rowCount() “ gibt die von Outlook gemeldete Anzahl der Einträge zurück. „ columnCount “ und „ headerData “ sind so implementiert, dass in der Baumansicht vier Spalten angezeigt werden.
QVariant AddressBookModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
switch (section) {
case 0:
return tr("First Name");
case 1:
return tr("Last Name");
case 2:
return tr("Address");
case 3:
return tr("Email");
default:
break;
}
return QVariant();
}Die Implementierung von „ headerData() “ gibt fest codierte Zeichenfolgen zurück.
QVariant AddressBookModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || role != Qt::DisplayRole)
return QVariant();
QStringList data;
if (cache.contains(index)) {
data = cache.value(index);
} else {
Outlook::ContactItem contact(folderItems->Item(index.row() + 1));
if (contact.Class() == Outlook::OlObjectClass::olContact)
data << contact.FirstName() << contact.LastName() << contact.HomeAddress() << contact.Email1Address();
cache.insert(index, data);
}
if (index.column() < data.size())
return data.at(index.column());
return QVariant();
}Die Implementierung von „ data() “ bildet den Kern des Modells. Befinden sich die angeforderten Daten im Cache, wird der zwischengespeicherte Wert verwendet; andernfalls werden die Daten aus Outlook abgerufen.
void AddressBookModel::changeItem(const QModelIndex &index, const QString &firstName, const QString &lastName, const QString &address, const QString &email)
{
Outlook::ContactItem item(folderItems->Item(index.row() + 1));
if (item.Class() != Outlook::OlObjectClass::olContact)
return; // Not a contact
item.SetFirstName(firstName);
item.SetLastName(lastName);
item.SetHomeAddress(address);
item.SetEmail1Address(email);
item.Save();
cache.take(index);
}Der Slot „ changeItem() “ wird aufgerufen, wenn der Benutzer den aktuellen Eintrag über die Benutzeroberfläche ändert. Der Zugriff auf das Outlook-Element erfolgt über die Outlook-API, und es wird mithilfe der Eigenschaftssetter geändert. Schließlich wird das Element in Outlook gespeichert und aus dem Cache entfernt. Beachten Sie, dass das Modell der Ansicht keine Änderung der Daten signalisiert, da Outlook selbst ein Signal ausgibt.
void AddressBookModel::addItem(const QString &firstName, const QString &lastName, const QString &address, const QString &email)
{
Outlook::ContactItem item(outlook.CreateItem(Outlook::olContactItem));
if (!item.isNull()) {
item.SetFirstName(firstName);
item.SetLastName(lastName);
item.SetHomeAddress(address);
item.SetEmail1Address(email);
item.Save();
}
}Der Slot „ addItem() “ ruft die Methode „CreateItem“ von Outlook auf, um ein neues Kontaktelement zu erstellen, setzt die Eigenschaften des neuen Elements auf die vom Benutzer eingegebenen Werte und speichert das Element.
void AddressBookModel::update()
{
beginResetModel();
cache.clear();
endResetModel();
}Der Slot „ update() “ leert den Cache und sendet das Signal „reset()“, um die Ansicht über die Datenänderung zu informieren, die ein Neuzeichnen des Inhalts erfordert.
AddressView::AddressView(QWidget *parent)
: QWidget(parent)
{
QGridLayout *mainGrid = new QGridLayout(this);
QLabel *firstNameLabel = new QLabel(tr("First &Name"), this);
firstNameLabel->resize(firstNameLabel->sizeHint());
mainGrid->addWidget(firstNameLabel, 0, 0);
QLabel *lastNameLabel = new QLabel(tr("&Last Name"), this);
lastNameLabel->resize(lastNameLabel->sizeHint());
mainGrid->addWidget(lastNameLabel, 0, 1);
QLabel *addressLabel = new QLabel(tr("Add&ress"), this);
addressLabel->resize(addressLabel->sizeHint());
mainGrid->addWidget(addressLabel, 0, 2);
QLabel *emailLabel = new QLabel(tr("&E-Mail"), this);
emailLabel->resize(emailLabel->sizeHint());
mainGrid->addWidget(emailLabel, 0, 3);
m_addButton = new QPushButton(tr("A&dd"), this);
m_addButton->resize(m_addButton->sizeHint());
mainGrid->addWidget(m_addButton, 0, 4);
connect(m_addButton, &QPushButton::clicked, this, &AddressView::addEntry);
m_firstName = new QLineEdit(this);
m_firstName->resize(m_firstName->sizeHint());
mainGrid->addWidget(m_firstName, 1, 0);
firstNameLabel->setBuddy(m_firstName);
m_lastName = new QLineEdit(this);
m_lastName->resize(m_lastName->sizeHint());
mainGrid->addWidget(m_lastName, 1, 1);
lastNameLabel->setBuddy(m_lastName);
m_address = new QLineEdit(this);
m_address->resize(m_address->sizeHint());
mainGrid->addWidget(m_address, 1, 2);
addressLabel->setBuddy(m_address);
m_email = new QLineEdit(this);
m_email->resize(m_email->sizeHint());
mainGrid->addWidget(m_email, 1, 3);
emailLabel->setBuddy(m_email);
m_changeButton = new QPushButton(tr("&Change"), this);
m_changeButton->resize(m_changeButton->sizeHint());
mainGrid->addWidget(m_changeButton, 1, 4);
connect(m_changeButton, &QPushButton::clicked, this, &AddressView::changeEntry);
m_treeView = new QTreeView(this);
m_treeView->setSelectionMode(QTreeView::SingleSelection);
m_treeView->setRootIsDecorated(false);
model = new AddressBookModel(this);
m_treeView->setModel(model);
connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &AddressView::itemSelected);
mainGrid->addWidget(m_treeView, 2, 0, 1, 5);
}
void AddressView::updateOutlook()
{
model->update();
}
void AddressView::addEntry()
{
if (!m_firstName->text().isEmpty() || !m_lastName->text().isEmpty() ||
!m_address->text().isEmpty() || !m_email->text().isEmpty()) {
model->addItem(m_firstName->text(), m_lastName->text(), m_address->text(), m_email->text());
}
m_firstName->clear();
m_lastName->clear();
m_address->clear();
m_email->clear();
}
void AddressView::changeEntry()
{
QModelIndex current = m_treeView->currentIndex();
if (current.isValid())
model->changeItem(current, m_firstName->text(), m_lastName->text(), m_address->text(), m_email->text());
}
void AddressView::itemSelected(const QModelIndex &index)
{
if (!index.isValid())
return;
QAbstractItemModel *model = m_treeView->model();
m_firstName->setText(model->data(model->index(index.row(), 0)).toString());
m_lastName->setText(model->data(model->index(index.row(), 1)).toString());
m_address->setText(model->data(model->index(index.row(), 2)).toString());
m_email->setText(model->data(model->index(index.row(), 3)).toString());
}Der Rest der Datei implementiert die Benutzeroberfläche ausschließlich mithilfe von Qt-APIs, d. h. ohne direkte Kommunikation mit Outlook.
#include "addressview.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
AddressView view;
view.setWindowTitle(QObject::tr("Qt Example - Looking at Outlook"));
view.show();
return a.exec();
}Die Einstiegsfunktion ` main() ` instanziiert schließlich die Benutzeroberfläche und tritt in die Ereignisschleife ein.
Um das Beispiel zu erstellen, müssen Sie zunächst die Bibliothek „ QAxContainer “ erstellen. Führen Sie anschließend Ihr Make-Tool im Verzeichnis „ examples/activeqt/qutlook “ aus und starten Sie die daraus resultierende Datei „ qutlook.exe “.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.