Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Вместе с тем создание приложений на базе MAPI 1.0 – более трудоемкий процесс, нежели программирование с использованием Simple MAPI. MAPI 1.0 требует от разработчика дополнительной квалификации, в частности знания технологии COM. Перепишем уже имеющийся пример с использованием MAPI 1.0. Для наглядности каждый блок кода сопоставлен с соответствующим фрагментом из предыдущего примера.
// Begin MAPILogon(:);
MAPILogonEx(0, "My Profile", NULL, MAPI_NEW_SESSION, &lpSession);
// End MAPILogon(:);
lpSession->GetMsgStoresTable(0, &StoresTable);
HrQueryAllRows(StoresTable, (LPSPropTagArray)&tagDefaultStore, NULL, NULL, 0, &lpRow);
for(i = 0; i < lpRow -> cRows; i++) {
if (lpRow->aRow[i].lpProps[0].Value.b == TRUE) break;
}
lpSession->OpenMsgStore(0, lpRow->aRow[i].lpProps[1].Value.bin.cb,
(LPENTRYID)lpRow->aRow[i].lpProps[1].Value.bin.lpb, NULL,
MDB_WRITE, &lpMDB);
lpMDB->OpenEntry(lpPropValue->Value.bin.cb, (LPENTRYID)lpPropValue->Value.bin.lpb,
NULL, MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpFolder);
lpFolder->CreateMessage(NULL, 0, &lpMsg);
SInitPropValue MsgProps[] = {
{PR_DELETE_AFTER_SUBMIT, 0, TRUE},
{PR_MESSAGE_CLASS, 0, (ULONG)"IPM.NOTE "},
{PR_SUBJECT, 0, (ULONG)"Greeting"},
{PR_BODY, 0, (ULONG)" Hello Bill!"}
};
lpMsg->SetProps(4, (LPSPropValue)&MsgProps, NULL);
// Begin MAPIResolveName(:);
lpSession->OpenAddressBook(0, NULL, AB_NO_DIALOG, &lpAdrBook);
MAPIAllocateBuffer(CbNewADRLIST(1), (LPVOID*)&lpAdrList);
MAPIAllocateBuffer(2*sizeof(SPropValue), (LPVOID*)&(lpAdrList->aEntries->rgPropVals));
ZeroMemory(lpAdrList->aEntries->rgPropVals, 2*sizeof(SPropValue));
lpAdrList->cEntries = 1;
lpAdrList->aEntries[0].ulReserved1 = 0;
lpAdrList->aEntries[0].cValues = 2;
lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;
lpAdrList->aEntries[0].rgPropVals[0].Value.lpszA = "Bill Gates";
lpAdrList->aEntries[0].rgPropVals[1].ulPropTag = PR_RECIPIENT_TYPE;
lpAdrList->aEntries[0].rgPropVals[1].Value.l = MAPI_TO;
lpAdrBook->ResolveName(0, 0, NULL, lpAdrList);
lpMsg->ModifyRecipients(MODRECIP_ADD, lpAdrList);
// End MAPIResolveName(:);
// Begin MAPISendMail(:);
lpMsg->SubmitMessage(0);
// End MAPISendMail(:);
// Begin MAPILogoff (:);
lpSession->Logoff(0, 0, 0);
// End MAPILogoff (:);
Как видно из этого примера большинство операций, являющихся примитивными для Simple MAPI, в MAPI 1.0 состоят из последовательностей вызовов тех или иных методов различных интерфейсов. Так, для того, чтобы создать сообщение в MAPI 1.0 требуется получить доступ и открыть контейнер с сообщениями, отыскать в нем папку для исходящих сообщений и только потом собственно создать в ней само сообщение и начинить его всей необходимой информацией. В Simple MAPI все эти промежуточные шаги скрыты от разработчика. С другой стороны MAPI 1.0 позволяет создавать сообщения в любой папке (да и не только сообщения, а объекты календаря, задачи и т.д.). Таким образом, взамен простоте использования появляются новые возможности.
Интерфейс MAPI 1.0, в отличие от Simple MAPI можно использовать при создании служб Windows NT. Это очень полезное свойство позволяет создавать различного рода почтовые мониторы. Типичная задача почтового монитора может заключаться в сканировании почтового ящика пользователя на предмет поступающей в него корреспонденции, ее разбор, анализ и последующие действия по результатам этого анализа.
Отдельного обсуждения заслуживает такая возможность MAPI 1.0 как создание всевозможных расширений (extensions) к клиентским программам почтовой системы MS Exchange Server (MS Outlook или MS Exchange Client). Расширения позволяют автоматизировать различные функции обработки сообщений, не реализованные в базовом наборе функций клиентской программы. В частности, механизм расширений позволяет создавать модули для обработки входящих сообщений, так называемые правила (rules), добавлять к клиентской программе дополнительные команды и пункты меню, а также обработчики событий, изменяющие поведение системы при определенных событиях и многое другое.
CDO – разумный компромиссИнтерфейс CDO (Collaboration Data Objects), ранее известный как OLE Messaging и Active Messaging представляет собой библиотеку, обеспечивающую доступ приложений к несколько ограниченному набору функция MAPI 1.0 через вызовы Automation. Функции работы с сообщениями могут быть встроены в приложения, созданные с помощью любого средства разработки, являющегося контроллером Automation. К таковым относятся C/C++, Visual Basic, Visual Basic for Applications, VBScript, Javascript. Использование CDO существенно упрощает разработку приложений, работающих с электронной почтой, вместе с тем оставляя разработчику широкие возможности MAPI. Наибольшее применение CDO находит в скриптовых языках. Так, например, в комбинации с APS использование CDO позволяет достаточно легко создать почтового Web-клиента.
Сухой остатокИтак, мы кратко рассмотрели 3 программных интерфейса, позволяющих встраивать в приложения на платформе Windows функциональность для работы с электронной почтой. У каждого из них есть свои преимущества и недостатки. Ничего универсального не существует – окончательный выбор того или иного средства зависит от конкретной задачи и является прерогативой разработчика. Более подробную информацию на эту тему можно получить на http://msdn.microsoft.com/library/psdk/mapi/.
ВОПРОС-ОТВЕТQ. Как создать окно ввода текста переключаясь в которое устанавливался бы заданный язык. Например, необходим ввод только русских слов в строке, по которой ищется перевод на английский, а язык по умолчанию в виндовс английский. Хотелесь бы при запуске программы, когда пользователь ткнет мышкой в поле ввода, чтобы он не переключал язык по умолчаню на русский.
Alexander ShinkevichA1 Для переключения раскладок необходимо вызвать функцию LoadKeyboardLayout.
Ниже приводится пример ее использования:
1) Добавить в проект с помощью Class Wizard'а новый класс CMyEdit на основе CEdit.
2) Добавить в класс переменную, хранящую предыдущую установленную раскладку клавиатуры:
TCHAR m_PreviousLayout[KL_NAMELENGTH];
3) Добавить обработчики WM_SETFOCUS и WM_KILLFOCUS:
void CMyEdit::OnSetFocus(CWnd* pOldWnd) {
CEdit::OnSetFocus(pOldWnd);
// запоминаем предыдущую раскладку клавиатуры
::GetKeyboardLayoutName(m_PreviousLayout);
// устанавливаем новую раскладку для языка "Русский"
::LoadKeyboardLayout(_T("00000419"), KLF_ACTIVATE);
}
void CMyEdit::OnKillFocus(CWnd* pNewWnd) {
CEdit::OnKillFocus(pNewWnd);
// восстанавливаем предыдущую раскладку клавиатуры
::LoadKeyboardLayout(m_PreviousLayout, KLF_ACTIVATE);
}
4) Использовать CMyEdit вместо CEdit (на примере диалога):
class CMyDlg : public CDialog {
// ...
CMyEdit m_Edit;
// ...
};
void CMyDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestKeyboardDlg)
DDX_Control( pDX, IDC_EDIT, m_Edit );
//}}AFX_DATA_MAP
}
Алексей ГончаровA2 […] Также можно активизировать т.н. keyboard layout (раскладку клавиатуры) с помощью функции ActivateKeyboardLayout, активизирующей раскладку, загруженную предварительно с помощью указанной выше функции LoadKeyboardLayout. Хотя LoadKeyboardLayout сама может активизировать раскладку (при использовании флага KLF_ACTIVATE), но при частой смене языка оптимальнее использовать ActivateKeyboardLayout. Т.е. в начале загрузить раскладку с помощью LoadKeyboardLayout, а многократно переключать язык ввода функцией ActivateKeyboardLayout.
Igor Sukharev В ПОИСКАХ ИСТИНЫQ. Можно ли из моей программы управлять окном которое создано другим приложением (закрывать, сворачивать, нажимать в нем кнопки и т.д.), если да то как?
AlhimА на сегодня это все. До встречи через неделю!
Алекс Jenter [email protected] Красноярск, 2001.Программирование на Visual C++
Выпуск №36 от 11 марта 2001 г.
Здравствуйте!
Ну вот, готова моя первая статья из серии, посвященной межпроцессному обмену данными. Эта статья является обзорной, ее цель – познакомить вас со всем многообразием механизмов Windows для обмена данными между процессами. В последующих статьях я остановлюсь на основных методах поподробнее. Хотя, к сожалению не могу обещать что эти статьи появятся скоро. Вы, однако, можете повлиять на мой выбор тем для подробного рассмотрения, если сообщите мне заранее, какая именно из них вас особенно интересует.
СТАТЬЯ IPC: основы межпроцессного взаимодействия Обзор технологийВведение
Любая операционная система была бы весьма ущербна, если бы замыкала выполняющееся приложение в собственном темном мирке без окон и дверей, без какой-либо возможности сообщить другим программам какую-либо информацию. Если посмотреть внимательно, можно заметить, что далеко не все приложения являются самодостаточными. Очень многим, если не большей части, требуется информация от других приложений, либо они должны эту информацию сообщать. Именно поэтому в операционную систему встраивается множество механизмов, которые обеспечивают т.н. Interproccess Communication (IPC) – то есть межпроцессное взаимодействие.