Qutlookの例(ActiveQt)
Qutlookのサンプルは、Outlookを自動化するためのActiveQtの使用を示しています。この例では、Outlookオブジェクト・モデルを記述するタイプ・ライブラリのC++名前空間を生成するためにdumpcppツールを使用しています。
この例のプロジェクト・ファイルは次のようになっています:
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 }
このプロジェクト・ファイルでは、dumpcpp
ツールを使用して MS Outlook タイプ・ライブラリをプロジェクトに追加します。これが失敗した場合、生成されたmakefileはエラーメッセージを表示するだけです。そうでない場合、ビルドステップは型ライブラリに対してdumpcppツールを実行し、Outlookオブジェクトへの使いやすいAPIを宣言して実装するヘッダーとcppファイル(この場合、msoutl.h
とmsoutl.cpp
)を生成します。
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; };
AddressViewクラスは、ユーザー・インターフェース用のQWidget サブクラスです。QTreeView ウィジェットは、model
によって提供される Outlook の Contact フォルダの内容を表示します。
#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; };
AddressBookModel クラスはQAbstractListModel のサブクラスで、キャッシュのためにQHash を使用して Outlook と直接通信します。
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; } }
コンストラクタはOutlookを初期化します。コンテンツの変更を通知するためにOutlookが提供するさまざまなシグナルは、updateOutlook()
スロットに接続されています。
AddressBookModel::~AddressBookModel() { delete folderItems; if (!outlook.isNull()) Outlook::NameSpace(outlook.Session()).Logoff(); }
デストラクタはセッションからログオフする。
int AddressBookModel::rowCount(const QModelIndex &) const { return folderItems ? folderItems->Count() : 0; } int AddressBookModel::columnCount(const QModelIndex & /*parent*/) const { return 4; }
rowCount()
の実装は、Outlookによって報告されたエントリ数を返す。columnCount
とheaderData
は、ツリービューに4つの列を表示するように実装されている。
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(); }
headerData()
の実装はハードコードされた文字列を返す。
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(); }
data()
の実装はモデルの中核である。要求されたデータがキャッシュにある場合はキャッシュ値が使用され、そうでない場合はOutlookからデータが取得されます。
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); }
changeItem()
スロットは、ユーザーがユーザーインターフェイスを使用して現在の項目を変更するときに呼び出されます。Outlookアイテムは、Outlook APIを使用してアクセスされ、プロパティ・セッターを使用して変更されます。最後に、項目はOutlookに保存され、キャッシュから削除されます。Outlookはそれ自身でシグナルを発するので、モデルはデータ変更のシグナルをビューに送らないことに注意してください。
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(); } }
addItem()
スロットは、OutlookのCreateItemメソッドを呼び出して新しいコンタクトアイテムを作成し、新しいアイテムのプロパティをユーザによって入力された値に設定し、アイテムを保存します。
void AddressBookModel::update() { beginResetModel(); cache.clear(); endResetModel(); }
update()
スロットはキャッシュをクリアし、reset() シグナルを発信して、内容の再描画を必要とするデータ変更についてビューに通知します。
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()); }
ファイルの残りの部分では、Qt APIのみを使用して、つまり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(); }
main()
のエントリーポイント関数は、最後にユーザーインターフェースをインスタンス化し、イベントループに入ります。
このサンプルをビルドするには、まずQAxContainer ライブラリをビルドする必要があります。次に、examples/activeqt/qutlook
でmakeツールを実行し、その結果のqutlook.exe
を実行します。
© 2025 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.