MAPIEx: Updated interface

git-svn-id: svn://ultimatepp.org/upp/trunk@6416 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
koldo 2013-10-11 19:54:08 +00:00
parent 2203d89b08
commit d08dae7b40
18 changed files with 2079 additions and 2054 deletions

View file

@ -1,3 +1,5 @@
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIAppointment.cpp
@ -14,8 +16,8 @@
// Ported to U++ Framework by Koldo. See License.txt file
#include "MapiUtil.h"
#include "MAPIEx.h"
#include "MapiUtil.h"
/////////////////////////////////////////////////////////////
// MAPIAppointment
@ -132,3 +134,4 @@ String MAPIAppointment::GetMeetingUID() {
}
#endif
#endif

View file

@ -1,199 +1,203 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIAttachment.cpp
// Description: MAPI Attachment class wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/MAPIEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
//#include "MAPIExPCH.h"
#include "MAPIEx.h"
/////////////////////////////////////////////////////////////
// MAPIAttachment
MAPIAttachment::MAPIAttachment() {
m_pStream = NULL;
m_nBytesWritten = 0;
}
MAPIAttachment::~MAPIAttachment() {
Close();
}
void MAPIAttachment::Attach(LPATTACH pAttachment) {
Close();
m_pItem = pAttachment;
}
LPATTACH MAPIAttachment::Detach() {
LPATTACH pAttachment = Attachment();
m_pItem = NULL;
return pAttachment;
}
bool MAPIAttachment::Create(LPMESSAGE pMessage) {
Close();
bool bResult = false;
if(pMessage) {
LPATTACH pAttachment;
ULONG ulAttachmentNum=0;
if(pMessage->CreateAttach(NULL, 0, &ulAttachmentNum, &pAttachment) == S_OK) {
m_pItem=pAttachment;
const int nProperties = 2;
SPropValue prop[nProperties];
memset(prop, 0,sizeof(SPropValue)*nProperties);
prop[0].ulPropTag = PR_ATTACH_METHOD;
prop[0].Value.ul = ATTACH_BY_VALUE;
prop[1].ulPropTag = PR_RENDERING_POSITION;
prop[1].Value.l = 1;
if(pAttachment->SetProps(nProperties, prop, NULL) == S_OK)
bResult=true;
}
}
return bResult;
}
bool MAPIAttachment::Open(LPMESSAGE pMessage, int nIndex) {
Close();
bool bResult = false;
LPMAPITABLE pAttachTable;
if(!(nIndex >= 0 && pMessage && pMessage->GetAttachmentTable(0, &pAttachTable) == S_OK))
return false;
enum { PROP_ATTACH_NUM, ATTACH_COLS };
static SizedSPropTagArray(ATTACH_COLS, Columns) = {ATTACH_COLS, PR_ATTACH_NUM };
if(pAttachTable->SetColumns((LPSPropTagArray)&Columns, 0) == S_OK) {
if(pAttachTable->SeekRow(BOOKMARK_BEGINNING, nIndex, NULL) == S_OK) {
LPSRowSet pRows = NULL;
if(pAttachTable->QueryRows(1, 0, &pRows) == S_OK) {
if(pRows->cRows > 0) {
LPATTACH pAttachment;
if(pMessage->OpenAttach(pRows->aRow[0].lpProps[PROP_ATTACH_NUM].Value.ul,
NULL, 0, &pAttachment) == S_OK) {
m_pItem=pAttachment;
bResult=true;
}
}
MAPIEx::FreeProws(pRows);
}
}
}
return bResult;
}
void MAPIAttachment::Close() {
CloseStream();
MAPIObject::Close();
}
String MAPIAttachment::GetDisplayName() {
return GetPropertyString(PR_DISPLAY_NAME);
}
String MAPIAttachment::GetFileName() {
return GetPropertyString(PR_ATTACH_FILENAME);
}
String MAPIAttachment::GetLongFileName() {
return GetPropertyString(PR_ATTACH_LONG_FILENAME);
}
String MAPIAttachment::GetCID() {
return GetPropertyString(PR_ATTACH_CONTENT_ID);
}
bool MAPIAttachment::SetDisplayName(const String &szDisplayName) {
return SetPropertyString(PR_DISPLAY_NAME, szDisplayName);
}
bool MAPIAttachment::SetFileName(const String &szFileName) {
return SetPropertyString(PR_ATTACH_FILENAME, szFileName);
}
bool MAPIAttachment::SetLongFileName(const String &szLongFileName) {
return SetPropertyString(PR_ATTACH_LONG_FILENAME, szLongFileName);
}
bool MAPIAttachment::SetCID(const String &szCID) {
return SetPropertyString(PR_ATTACH_CONTENT_ID, szCID);
}
bool MAPIAttachment::OpenStream(bool bCreate) {
if(m_pItem) {
ULONG ulInterfaceOptions = STGM_READ;
ULONG ulFlags = 0;
if(bCreate) {
ulInterfaceOptions = 0;
ulFlags = MAPI_MODIFY | MAPI_CREATE;
}
return (m_pItem->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, ulInterfaceOptions, ulFlags, (LPUNKNOWN*)&m_pStream)==S_OK);
}
return false;
}
int MAPIAttachment::Read(BYTE* pData, int nCount) {
if(m_pStream) {
ULONG ulRead;
m_pStream->Read(pData, nCount, &ulRead);
return ulRead;
}
return -1;
}
int MAPIAttachment::Write(BYTE* pData, int nCount) {
if(m_pStream) {
ULONG ulWritten;
m_pStream->Write(pData, nCount, &ulWritten);
m_nBytesWritten += ulWritten;
return ulWritten;
}
return -1;
}
void MAPIAttachment::CloseStream() {
if(m_pStream) {
m_pStream->Commit(STGC_DEFAULT);
RELEASE(m_pStream);
SetPropertyValue(PR_ATTACH_SIZE, m_nBytesWritten);
m_nBytesWritten = 0;
}
}
bool MAPIAttachment::LoadAttachment(const String &szPath) {
String file = LoadFile(szPath);
if(file.IsEmpty() || !OpenStream(true))
return false;
Write((BYTE *)file.Begin(), file.GetLength());
return true;
}
bool MAPIAttachment::SaveAttachment(const String &szPath) {
if (!OpenStream(false))
return false;
String file;
const int BUF_SIZE = 4096;
BYTE pData[BUF_SIZE];
ULONG ulRead;
do {
ulRead = Read(pData, BUF_SIZE);
if(ulRead >= 0)
file.Cat(pData, ulRead);
} while(ulRead >= BUF_SIZE);
return SaveFile(szPath, file);
}
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIAttachment.cpp
// Description: MAPI Attachment class wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/MAPIEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
//#include "MAPIExPCH.h"
#include "MAPIEx.h"
/////////////////////////////////////////////////////////////
// MAPIAttachment
MAPIAttachment::MAPIAttachment() {
m_pStream = NULL;
m_nBytesWritten = 0;
}
MAPIAttachment::~MAPIAttachment() {
Close();
}
void MAPIAttachment::Attach(LPATTACH pAttachment) {
Close();
m_pItem = pAttachment;
}
LPATTACH MAPIAttachment::Detach() {
LPATTACH pAttachment = Attachment();
m_pItem = NULL;
return pAttachment;
}
bool MAPIAttachment::Create(LPMESSAGE pMessage) {
Close();
bool bResult = false;
if(pMessage) {
LPATTACH pAttachment;
ULONG ulAttachmentNum=0;
if(pMessage->CreateAttach(NULL, 0, &ulAttachmentNum, &pAttachment) == S_OK) {
m_pItem=pAttachment;
const int nProperties = 2;
SPropValue prop[nProperties];
memset(prop, 0,sizeof(SPropValue)*nProperties);
prop[0].ulPropTag = PR_ATTACH_METHOD;
prop[0].Value.ul = ATTACH_BY_VALUE;
prop[1].ulPropTag = PR_RENDERING_POSITION;
prop[1].Value.l = 1;
if(pAttachment->SetProps(nProperties, prop, NULL) == S_OK)
bResult=true;
}
}
return bResult;
}
bool MAPIAttachment::Open(LPMESSAGE pMessage, int nIndex) {
Close();
bool bResult = false;
LPMAPITABLE pAttachTable;
if(!(nIndex >= 0 && pMessage && pMessage->GetAttachmentTable(0, &pAttachTable) == S_OK))
return false;
enum { PROP_ATTACH_NUM, ATTACH_COLS };
static SizedSPropTagArray(ATTACH_COLS, Columns) = {ATTACH_COLS, PR_ATTACH_NUM };
if(pAttachTable->SetColumns((LPSPropTagArray)&Columns, 0) == S_OK) {
if(pAttachTable->SeekRow(BOOKMARK_BEGINNING, nIndex, NULL) == S_OK) {
LPSRowSet pRows = NULL;
if(pAttachTable->QueryRows(1, 0, &pRows) == S_OK) {
if(pRows->cRows > 0) {
LPATTACH pAttachment;
if(pMessage->OpenAttach(pRows->aRow[0].lpProps[PROP_ATTACH_NUM].Value.ul,
NULL, 0, &pAttachment) == S_OK) {
m_pItem=pAttachment;
bResult=true;
}
}
MAPIEx::FreeProws(pRows);
}
}
}
return bResult;
}
void MAPIAttachment::Close() {
CloseStream();
MAPIObject::Close();
}
String MAPIAttachment::GetDisplayName() {
return GetPropertyString(PR_DISPLAY_NAME);
}
String MAPIAttachment::GetFileName() {
return GetPropertyString(PR_ATTACH_FILENAME);
}
String MAPIAttachment::GetLongFileName() {
return GetPropertyString(PR_ATTACH_LONG_FILENAME);
}
String MAPIAttachment::GetCID() {
return GetPropertyString(PR_ATTACH_CONTENT_ID);
}
bool MAPIAttachment::SetDisplayName(const String &szDisplayName) {
return SetPropertyString(PR_DISPLAY_NAME, szDisplayName);
}
bool MAPIAttachment::SetFileName(const String &szFileName) {
return SetPropertyString(PR_ATTACH_FILENAME, szFileName);
}
bool MAPIAttachment::SetLongFileName(const String &szLongFileName) {
return SetPropertyString(PR_ATTACH_LONG_FILENAME, szLongFileName);
}
bool MAPIAttachment::SetCID(const String &szCID) {
return SetPropertyString(PR_ATTACH_CONTENT_ID, szCID);
}
bool MAPIAttachment::OpenStream(bool bCreate) {
if(m_pItem) {
ULONG ulInterfaceOptions = STGM_READ;
ULONG ulFlags = 0;
if(bCreate) {
ulInterfaceOptions = 0;
ulFlags = MAPI_MODIFY | MAPI_CREATE;
}
return (m_pItem->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, ulInterfaceOptions, ulFlags, (LPUNKNOWN*)&m_pStream)==S_OK);
}
return false;
}
int MAPIAttachment::Read(BYTE* pData, int nCount) {
if(m_pStream) {
ULONG ulRead;
m_pStream->Read(pData, nCount, &ulRead);
return ulRead;
}
return -1;
}
int MAPIAttachment::Write(BYTE* pData, int nCount) {
if(m_pStream) {
ULONG ulWritten;
m_pStream->Write(pData, nCount, &ulWritten);
m_nBytesWritten += ulWritten;
return ulWritten;
}
return -1;
}
void MAPIAttachment::CloseStream() {
if(m_pStream) {
m_pStream->Commit(STGC_DEFAULT);
RELEASE(m_pStream);
SetPropertyValue(PR_ATTACH_SIZE, m_nBytesWritten);
m_nBytesWritten = 0;
}
}
bool MAPIAttachment::LoadAttachment(const String &szPath) {
String file = LoadFile(szPath);
if(file.IsEmpty() || !OpenStream(true))
return false;
Write((BYTE *)file.Begin(), file.GetLength());
return true;
}
bool MAPIAttachment::SaveAttachment(const String &szPath) {
if (!OpenStream(false))
return false;
String file;
const int BUF_SIZE = 4096;
BYTE pData[BUF_SIZE];
ULONG ulRead;
do {
ulRead = Read(pData, BUF_SIZE);
if(ulRead >= 0)
file.Cat(pData, ulRead);
} while(ulRead >= BUF_SIZE);
return SaveFile(szPath, file);
}
#endif

View file

@ -1,3 +1,5 @@
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIContact.cpp
@ -14,9 +16,11 @@
// Ported to U++ Framework by Koldo. See License.txt file
#include <MapiUtil.h>
#include "MAPIEx.h"
String Tokenize(const String &str, const String &token, int &pos);
#include "MapiUtil.h"
#include <Functions4U/Functions4U.h>
#define CATEGORIES_PROPERTY "Keywords"
@ -659,14 +663,14 @@ bool MAPIContact::SetCategories(const String &szCategories) {
nCount = 0;
nIndex = 0;
int nLen = 0;
strCategory=Tokenize(strCategories, ";", nIndex);
strCategory = Tokenize(strCategories, ";", nIndex);
do {
nLen = strCategory.GetLength();
if(nLen > 0) {
arCategories[nCount] = new TCHAR[nLen+1];
memcpy(arCategories[nCount], (LPCTSTR)strCategory, nLen*sizeof(TCHAR));
arCategories[nCount++][nLen] = (TCHAR)0;
strCategory=Tokenize(strCategories, ";", nIndex);
strCategory = Tokenize(strCategories, ";", nIndex);
}
} while(nLen);
@ -711,3 +715,5 @@ bool MAPIContact::SetPicture(const String &szPath) {
return bPicture;
#endif
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
#include <Core/Core.h>
using namespace Upp;
#undef CY
#define CY tagCY
@ -118,6 +118,7 @@ protected:
ULONG GetMessageStoreSupport();
bool OpenFolder(unsigned long ulFolderID, MAPIFolder &folder);
public: ////////
static String ValidateString(LPCTSTR s);
IMAPISession* GetSession() {return m_pSession;}
LPMDB GetMessageStore() {return m_pMsgStore;}

View file

@ -4,7 +4,7 @@ uses
Core,
Functions4U;
library(GCC) "mapi32 kernel32";
library(GCC WIN32) "mapi32 kernel32";
file
MAPIAppointment.cpp,

View file

@ -1,321 +1,325 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIFolder.cpp
// Description: MAPI Folder class wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/CMapiEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
#include <MapiUtil.h>
#include "MAPIEx.h"
/////////////////////////////////////////////////////////////
// MAPIFolder
MAPIFolder::MAPIFolder() {
Init();
}
MAPIFolder::MAPIFolder(MAPIEx* pMAPI, LPMAPIFOLDER pFolder, String szName) {
Init();
m_entryID.cb=0;
Attach(pMAPI, pFolder, szName);
}
MAPIFolder::~MAPIFolder() {
Close();
}
void MAPIFolder::Init() {
m_pHierarchy = NULL;
m_pContents = NULL;
m_nMaxRowsSize = DEFAULT_FOLDER_BUFFER_SIZE;
m_pRows = NULL;
ClearBuffer();
}
void MAPIFolder::Close() {
ClearBuffer();
RELEASE(m_pHierarchy);
RELEASE(m_pContents);
MAPIObject::Close();
}
void MAPIFolder::SetBufferSize(int nSize) {
m_nMaxRowsSize = max(1, nSize);
}
void MAPIFolder::ClearBuffer() {
if(m_pRows) {
FreeProws(m_pRows);
m_pRows = NULL;
}
m_nRowsIndex = 0;
}
bool MAPIFolder::Attach(MAPIEx* pMAPI, LPMAPIFOLDER pFolder, String szName) {
Close();
m_pMAPI = pMAPI;
m_pItem = pFolder;
m_strName = szName;
LPSPropValue pProp;
if(GetProperty(PR_ENTRYID, pProp) == S_OK) {
SetEntryID(&pProp->Value.bin);
MAPIFreeBuffer(pProp);
return true;
} else {
SetEntryID(NULL);
return false;
}
}
LPMAPIFOLDER MAPIFolder::Detach() {
LPMAPIFOLDER pFolder = Folder();
m_pItem = NULL;
return pFolder;
}
String MAPIFolder::GetName() {
return m_strName;
}
LPMAPITABLE MAPIFolder::GetHierarchy() {
RELEASE(m_pHierarchy);
if(Folder()->GetHierarchyTable(0, &m_pHierarchy) != S_OK)
return NULL;
const int nProperties = 2;
SizedSPropTagArray(nProperties, Columns)={nProperties,{PR_DISPLAY_NAME, PR_ENTRYID}};
if(m_pHierarchy->SetColumns((LPSPropTagArray)&Columns, 0) != S_OK) {
RELEASE(m_pHierarchy);
return NULL;
}
return m_pHierarchy;
}
// High Level function to open a sub folder by iterating recursively (DFS) over all folders
bool MAPIFolder::OpenSubFolder(const String &subFolderName, MAPIFolder &subFolder,
bool fullPath, String path) {
if(!GetHierarchy())
return NULL;
String strFolder;
MAPIFolder folder;
MAPIFolder* pSubFolder = NULL;
while(GetNextSubFolder(folder, strFolder)) {
bool retSubFolder;
if (fullPath)
strFolder = path + "/" + strFolder;
if(!CompareNoCase(strFolder, subFolderName))
retSubFolder = subFolder.Attach(m_pMAPI, folder.Detach());
else
retSubFolder = folder.OpenSubFolder(subFolderName, subFolder, fullPath, strFolder);
if(retSubFolder)
return true;
}
return false;
}
// Creates a sub-folder under pFolder, opens the folder if it already exists
bool MAPIFolder::CreateSubFolder(const String &subFolderName, MAPIFolder &subFolder) {
LPMAPIFOLDER pSubFolder = NULL;
ULONG ulFolderType=FOLDER_GENERIC;
ULONG ulFlags=OPEN_IF_EXISTS | MAPIEx::cm_nMAPICode;
Folder()->CreateFolder(ulFolderType, (LPTSTR)(subFolderName.Begin()), NULL, NULL, ulFlags,
&pSubFolder);
subFolder.Attach(m_pMAPI, pSubFolder);
return pSubFolder;
}
// Deletes a sub-folder and ALL sub folders/messages
bool MAPIFolder::DeleteSubFolder(const String &subFolderName) {
if(GetHierarchy()) {
String strFolder;
MAPIFolder folder;
while(GetNextSubFolder(folder, strFolder)) {
if(!CompareNoCase(strFolder, subFolderName))
return DeleteSubFolder(folder);
}
}
return false;
}
// Deletes a sub-folder and ALL sub folders/messages
bool MAPIFolder::DeleteSubFolder(MAPIFolder &subFolder) {
if(!subFolder.IsOpened())
return false;
LPSPropValue props = NULL;
ULONG cValues=0;
ULONG rgTags[]={ 1, PR_ENTRYID };
if(subFolder.Folder()->GetProps((LPSPropTagArray) rgTags, MAPIEx::cm_nMAPICode,
&cValues, &props) == S_OK) {
HRESULT hr = Folder()->DeleteFolder(props[0].Value.bin.cb,
(LPENTRYID)props[0].Value.bin.lpb, 0, NULL,DEL_FOLDERS|DEL_MESSAGES);
MAPIFreeBuffer(props);
return (hr == S_OK);
}
return false;
}
LPMAPITABLE MAPIFolder::GetContents() {
RELEASE(m_pContents);
if(Folder()->GetContentsTable(MAPIEx::cm_nMAPICode, &m_pContents)!=S_OK)
return NULL;
const int nProperties = MESSAGE_COLS;
SizedSPropTagArray(nProperties, Columns) = {nProperties,{PR_MESSAGE_FLAGS, PR_ENTRYID }};
if(m_pContents->SetColumns((LPSPropTagArray)&Columns, 0)!=S_OK) {
RELEASE(m_pContents);
return NULL;
}
return m_pContents;
}
int MAPIFolder::GetCount() {
ULONG ulCount;
if(!m_pContents || m_pContents->GetRowCount(0, &ulCount) != S_OK)
return -1;
return ulCount;
}
bool MAPIFolder::SortContents(ULONG ulSortParam, ULONG ulSortField) {
if(!m_pContents)
return false;
SizedSSortOrderSet(1, SortColums) = {1, 0, 0, {{ulSortField, ulSortParam}}};
return (m_pContents->SortTable((LPSSortOrderSet)&SortColums, 0) == S_OK);
}
bool MAPIFolder::SetUnreadOnly(bool bUnreadOnly) {
if(bUnreadOnly) {
SRestriction res;
res.rt = RES_BITMASK;
res.res.resBitMask.relBMR = BMR_EQZ;
res.res.resBitMask.ulPropTag = PR_MESSAGE_FLAGS;
res.res.resBitMask.ulMask = MSGFLAG_READ;
return SetRestriction(&res);
}
return SetRestriction(NULL);
}
bool MAPIFolder::SetRestriction(SRestriction* pRestriction) {
return (m_pContents && m_pContents->Restrict(pRestriction, 0)==S_OK);
}
bool MAPIFolder::QueryRows() {
ClearBuffer();
if(m_pContents) {
if(m_pContents->QueryRows(m_nMaxRowsSize, 0, &m_pRows) == S_OK) {
return true;
}
m_pRows = NULL;
}
return false;
}
SRow* MAPIFolder::GetNextRow() {
if(m_pRows == NULL || m_nRowsIndex >= m_pRows->cRows) {
if(!QueryRows())
return NULL;
}
if(m_pRows->cRows==0) {
ClearBuffer();
return NULL;
}
return &m_pRows->aRow[m_nRowsIndex++];
}
bool MAPIFolder::GetNextMessage(MAPIMessage& message) {
SRow* pRow = GetNextRow();
return pRow ? message.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
}
bool MAPIFolder::GetNextContact(MAPIContact& contact) {
#ifdef _WIN32_WCE
return m_poom.GetNextContact(m_pMAPI, contact);
#else
SRow* pRow = GetNextRow();
return pRow ? contact.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
#endif
}
bool MAPIFolder::GetNextAppointment(MAPIAppointment& appointment) {
#ifdef _WIN32_WCE
return m_poom.GetNextAppointment(m_pMAPI,appointment);
#else
SRow* pRow=GetNextRow();
return pRow ? appointment.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
#endif
}
bool MAPIFolder::GetNextSubFolder(MAPIFolder& folder, String& strFolder) {
if(!m_pHierarchy)
return NULL;
folder.Close();
DWORD dwObjType;
LPSRowSet pRows = NULL;
LPMAPIFOLDER pSubFolder = NULL;
if(m_pHierarchy->QueryRows(1, 0, &pRows) == S_OK) {
if(pRows->cRows) {
if(S_OK == Folder()->OpenEntry(pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.cb,
(LPENTRYID)pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.lpb,
NULL, MAPI_MODIFY, &dwObjType, (LPUNKNOWN*)&pSubFolder)) {
strFolder = MAPIEx::GetValidString(pRows->aRow[0].lpProps[0]);
folder.Attach(m_pMAPI, pSubFolder, strFolder);
}
}
FreeProws(pRows);
}
if (!pSubFolder)
return false;
folder.GetHierarchy();
folder.GetContents();
return true;
}
bool MAPIFolder::DeleteMessage(MAPIMessage& message) {
return DeleteObject(message);
}
bool MAPIFolder::CopyMessage(MAPIMessage& message, MAPIFolder &folderDest) {
ENTRYLIST entries = { 1, message.GetEntryID() };
HRESULT hr = Folder()->CopyMessages(&entries, NULL, folderDest.Folder(), 0, NULL, 0);
return (hr == S_OK);
}
bool MAPIFolder::MoveMessage(MAPIMessage& message, MAPIFolder &folderDest) {
if(!folderDest.IsOpened())
return false;
ENTRYLIST entries = { 1, message.GetEntryID() };
HRESULT hr = Folder()->CopyMessages(&entries, NULL, folderDest.Folder(), 0, NULL,MESSAGE_MOVE);
return (hr == S_OK);
}
bool MAPIFolder::DeleteContact(MAPIContact& contact) {
return DeleteObject(contact);
}
bool MAPIFolder::DeleteAppointment(MAPIAppointment& appointment) {
return DeleteObject(appointment);
}
bool MAPIFolder::DeleteObject(MAPIObject& object) {
ENTRYLIST entries={ 1, object.GetEntryID() };
HRESULT hr = Folder()->DeleteMessages(&entries, 0, NULL, 0);
return (hr==S_OK);
}
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIFolder.cpp
// Description: MAPI Folder class wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/CMapiEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
#include "MAPIEx.h"
#include "MapiUtil.h"
/////////////////////////////////////////////////////////////
// MAPIFolder
MAPIFolder::MAPIFolder() {
Init();
}
MAPIFolder::MAPIFolder(MAPIEx* pMAPI, LPMAPIFOLDER pFolder, String szName) {
Init();
m_entryID.cb=0;
Attach(pMAPI, pFolder, szName);
}
MAPIFolder::~MAPIFolder() {
Close();
}
void MAPIFolder::Init() {
m_pHierarchy = NULL;
m_pContents = NULL;
m_nMaxRowsSize = DEFAULT_FOLDER_BUFFER_SIZE;
m_pRows = NULL;
ClearBuffer();
}
void MAPIFolder::Close() {
ClearBuffer();
RELEASE(m_pHierarchy);
RELEASE(m_pContents);
MAPIObject::Close();
}
void MAPIFolder::SetBufferSize(int nSize) {
m_nMaxRowsSize = max(1, nSize);
}
void MAPIFolder::ClearBuffer() {
if(m_pRows) {
FreeProws(m_pRows);
m_pRows = NULL;
}
m_nRowsIndex = 0;
}
bool MAPIFolder::Attach(MAPIEx* pMAPI, LPMAPIFOLDER pFolder, String szName) {
Close();
m_pMAPI = pMAPI;
m_pItem = pFolder;
m_strName = szName;
LPSPropValue pProp;
if(GetProperty(PR_ENTRYID, pProp) == S_OK) {
SetEntryID(&pProp->Value.bin);
MAPIFreeBuffer(pProp);
return true;
} else {
SetEntryID(NULL);
return false;
}
}
LPMAPIFOLDER MAPIFolder::Detach() {
LPMAPIFOLDER pFolder = Folder();
m_pItem = NULL;
return pFolder;
}
String MAPIFolder::GetName() {
return m_strName;
}
LPMAPITABLE MAPIFolder::GetHierarchy() {
RELEASE(m_pHierarchy);
if(Folder()->GetHierarchyTable(0, &m_pHierarchy) != S_OK)
return NULL;
const int nProperties = 2;
SizedSPropTagArray(nProperties, Columns)={nProperties,{PR_DISPLAY_NAME, PR_ENTRYID}};
if(m_pHierarchy->SetColumns((LPSPropTagArray)&Columns, 0) != S_OK) {
RELEASE(m_pHierarchy);
return NULL;
}
return m_pHierarchy;
}
// High Level function to open a sub folder by iterating recursively (DFS) over all folders
bool MAPIFolder::OpenSubFolder(const String &subFolderName, MAPIFolder &subFolder,
bool fullPath, String path) {
if(!GetHierarchy())
return NULL;
String strFolder;
MAPIFolder folder;
MAPIFolder* pSubFolder = NULL;
while(GetNextSubFolder(folder, strFolder)) {
bool retSubFolder;
if (fullPath)
strFolder = path + "/" + strFolder;
if(!CompareNoCase(strFolder, subFolderName))
retSubFolder = subFolder.Attach(m_pMAPI, folder.Detach());
else
retSubFolder = folder.OpenSubFolder(subFolderName, subFolder, fullPath, strFolder);
if(retSubFolder)
return true;
}
return false;
}
// Creates a sub-folder under pFolder, opens the folder if it already exists
bool MAPIFolder::CreateSubFolder(const String &subFolderName, MAPIFolder &subFolder) {
LPMAPIFOLDER pSubFolder = NULL;
ULONG ulFolderType=FOLDER_GENERIC;
ULONG ulFlags=OPEN_IF_EXISTS | MAPIEx::cm_nMAPICode;
Folder()->CreateFolder(ulFolderType, (LPTSTR)(subFolderName.Begin()), NULL, NULL, ulFlags,
&pSubFolder);
subFolder.Attach(m_pMAPI, pSubFolder);
return pSubFolder;
}
// Deletes a sub-folder and ALL sub folders/messages
bool MAPIFolder::DeleteSubFolder(const String &subFolderName) {
if(GetHierarchy()) {
String strFolder;
MAPIFolder folder;
while(GetNextSubFolder(folder, strFolder)) {
if(!CompareNoCase(strFolder, subFolderName))
return DeleteSubFolder(folder);
}
}
return false;
}
// Deletes a sub-folder and ALL sub folders/messages
bool MAPIFolder::DeleteSubFolder(MAPIFolder &subFolder) {
if(!subFolder.IsOpened())
return false;
LPSPropValue props = NULL;
ULONG cValues=0;
ULONG rgTags[]={ 1, PR_ENTRYID };
if(subFolder.Folder()->GetProps((LPSPropTagArray) rgTags, MAPIEx::cm_nMAPICode,
&cValues, &props) == S_OK) {
HRESULT hr = Folder()->DeleteFolder(props[0].Value.bin.cb,
(LPENTRYID)props[0].Value.bin.lpb, 0, NULL,DEL_FOLDERS|DEL_MESSAGES);
MAPIFreeBuffer(props);
return (hr == S_OK);
}
return false;
}
LPMAPITABLE MAPIFolder::GetContents() {
RELEASE(m_pContents);
if(Folder()->GetContentsTable(MAPIEx::cm_nMAPICode, &m_pContents)!=S_OK)
return NULL;
const int nProperties = MESSAGE_COLS;
SizedSPropTagArray(nProperties, Columns) = {nProperties,{PR_MESSAGE_FLAGS, PR_ENTRYID }};
if(m_pContents->SetColumns((LPSPropTagArray)&Columns, 0)!=S_OK) {
RELEASE(m_pContents);
return NULL;
}
return m_pContents;
}
int MAPIFolder::GetCount() {
ULONG ulCount;
if(!m_pContents || m_pContents->GetRowCount(0, &ulCount) != S_OK)
return -1;
return ulCount;
}
bool MAPIFolder::SortContents(ULONG ulSortParam, ULONG ulSortField) {
if(!m_pContents)
return false;
SizedSSortOrderSet(1, SortColums) = {1, 0, 0, {{ulSortField, ulSortParam}}};
return (m_pContents->SortTable((LPSSortOrderSet)&SortColums, 0) == S_OK);
}
bool MAPIFolder::SetUnreadOnly(bool bUnreadOnly) {
if(bUnreadOnly) {
SRestriction res;
res.rt = RES_BITMASK;
res.res.resBitMask.relBMR = BMR_EQZ;
res.res.resBitMask.ulPropTag = PR_MESSAGE_FLAGS;
res.res.resBitMask.ulMask = MSGFLAG_READ;
return SetRestriction(&res);
}
return SetRestriction(NULL);
}
bool MAPIFolder::SetRestriction(SRestriction* pRestriction) {
return (m_pContents && m_pContents->Restrict(pRestriction, 0)==S_OK);
}
bool MAPIFolder::QueryRows() {
ClearBuffer();
if(m_pContents) {
if(m_pContents->QueryRows(m_nMaxRowsSize, 0, &m_pRows) == S_OK) {
return true;
}
m_pRows = NULL;
}
return false;
}
SRow* MAPIFolder::GetNextRow() {
if(m_pRows == NULL || m_nRowsIndex >= m_pRows->cRows) {
if(!QueryRows())
return NULL;
}
if(m_pRows->cRows==0) {
ClearBuffer();
return NULL;
}
return &m_pRows->aRow[m_nRowsIndex++];
}
bool MAPIFolder::GetNextMessage(MAPIMessage& message) {
SRow* pRow = GetNextRow();
return pRow ? message.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
}
bool MAPIFolder::GetNextContact(MAPIContact& contact) {
#ifdef _WIN32_WCE
return m_poom.GetNextContact(m_pMAPI, contact);
#else
SRow* pRow = GetNextRow();
return pRow ? contact.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
#endif
}
bool MAPIFolder::GetNextAppointment(MAPIAppointment& appointment) {
#ifdef _WIN32_WCE
return m_poom.GetNextAppointment(m_pMAPI,appointment);
#else
SRow* pRow = GetNextRow();
return pRow ? appointment.Open(m_pMAPI, pRow->lpProps[PROP_ENTRYID].Value.bin) : false;
#endif
}
bool MAPIFolder::GetNextSubFolder(MAPIFolder& folder, String& strFolder) {
if(!m_pHierarchy)
return NULL;
folder.Close();
DWORD dwObjType;
LPSRowSet pRows = NULL;
LPMAPIFOLDER pSubFolder = NULL;
if(m_pHierarchy->QueryRows(1, 0, &pRows) == S_OK) {
if(pRows->cRows) {
if(S_OK == Folder()->OpenEntry(pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.cb,
(LPENTRYID)pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.lpb,
NULL, MAPI_MODIFY, &dwObjType, (LPUNKNOWN*)&pSubFolder)) {
strFolder = MAPIEx::GetValidString(pRows->aRow[0].lpProps[0]);
folder.Attach(m_pMAPI, pSubFolder, strFolder);
}
}
FreeProws(pRows);
}
if (!pSubFolder)
return false;
folder.GetHierarchy();
folder.GetContents();
return true;
}
bool MAPIFolder::DeleteMessage(MAPIMessage& message) {
return DeleteObject(message);
}
bool MAPIFolder::CopyMessage(MAPIMessage& message, MAPIFolder &folderDest) {
ENTRYLIST entries = { 1, message.GetEntryID() };
HRESULT hr = Folder()->CopyMessages(&entries, NULL, folderDest.Folder(), 0, NULL, 0);
return (hr == S_OK);
}
bool MAPIFolder::MoveMessage(MAPIMessage& message, MAPIFolder &folderDest) {
if(!folderDest.IsOpened())
return false;
ENTRYLIST entries = { 1, message.GetEntryID() };
HRESULT hr = Folder()->CopyMessages(&entries, NULL, folderDest.Folder(), 0, NULL,MESSAGE_MOVE);
return (hr == S_OK);
}
bool MAPIFolder::DeleteContact(MAPIContact& contact) {
return DeleteObject(contact);
}
bool MAPIFolder::DeleteAppointment(MAPIAppointment& appointment) {
return DeleteObject(appointment);
}
bool MAPIFolder::DeleteObject(MAPIObject& object) {
ENTRYLIST entries={ 1, object.GetEntryID() };
HRESULT hr = Folder()->DeleteMessages(&entries, 0, NULL, 0);
return (hr==S_OK);
}
#endif

View file

@ -1,3 +1,5 @@
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPIMessage.cpp
@ -12,8 +14,10 @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <MapiUtil.h>
// Ported to U++ Framework by Koldo. See License.txt file
#include "MAPIEx.h"
#include "MapiUtil.h"
#include <imessage.h>
const GUID CLSID_MailMessage={ 0x00020D0B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
@ -25,8 +29,10 @@ const GUID CLSID_MailMessage={ 0x00020D0B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x0
#include <MAPIGuid.h>
#endif
extern "C" {
STDAPI_(void) CloseIMsgSession(LPMSGSESS lpMsgSess);
}
// Ported to U++ Framework by Koldo. See License.txt file
/////////////////////////////////////////////////////////////
// MAPIMessage
@ -486,4 +492,6 @@ bool MAPIMessage::SaveToFile(const String &fileName) {
RELEASE(pStorage);
return true;
#endif
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,54 +1,57 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPISink.cpp
// Description: MAPI Advise Sink Wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/CMapiEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
#include "MAPIEx.h"
#include "MAPISink.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MAPISink
MAPISink::MAPISink(LPNOTIFCALLBACK lpfnCallback, LPVOID lpvContext) {
m_lpfnCallback = lpfnCallback;
m_lpvContext = lpvContext;
m_nRef = 0;
}
HRESULT MAPISink::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) {
if(riid == IID_IUnknown) {
*ppvObj = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG MAPISink::AddRef() {
return InterlockedIncrement(&m_nRef);
}
ULONG MAPISink::Release() {
ULONG ul = InterlockedDecrement(&m_nRef);
if(!ul)
delete this;
return ul;
}
ULONG MAPISink::OnNotify(ULONG cNotification, LPNOTIFICATION lpNotifications) {
if(m_lpfnCallback)
m_lpfnCallback(m_lpvContext, cNotification, lpNotifications);
return 0;
}
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: MAPISink.cpp
// Description: MAPI Advise Sink Wrapper
//
// Copyright (C) 2005-2011, Noel Dillabough
//
// This source code is free to use and modify provided this notice remains intact and that any enhancements
// or bug fixes are posted to the CodeProject page hosting this class for the community to benefit.
//
// Usage: see the CodeProject article at http://www.codeproject.com/internet/CMapiEx.asp
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Ported to U++ Framework by Koldo. See License.txt file
#include "MAPIEx.h"
#include "MAPISink.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MAPISink
MAPISink::MAPISink(LPNOTIFCALLBACK lpfnCallback, LPVOID lpvContext) {
m_lpfnCallback = lpfnCallback;
m_lpvContext = lpvContext;
m_nRef = 0;
}
HRESULT MAPISink::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) {
if(riid == IID_IUnknown) {
*ppvObj = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG MAPISink::AddRef() {
return InterlockedIncrement(&m_nRef);
}
ULONG MAPISink::Release() {
ULONG ul = InterlockedDecrement(&m_nRef);
if(!ul)
delete this;
return ul;
}
ULONG MAPISink::OnNotify(ULONG cNotification, LPNOTIFICATION lpNotifications) {
if(m_lpfnCallback)
m_lpfnCallback(m_lpvContext, cNotification, lpNotifications);
return 0;
}
#endif

View file

@ -682,15 +682,17 @@ int CMAPIEx::ShowAddressBook(LPADRLIST& pAddressList, LPCTSTR szCaption)
adrparm.lpszCaption=(LPTSTR)szNarrowCaption;
}
#endif
adrparm.cDestFields=1;
adrparm.lppszDestTitles=(LPTSTR*)lppszDestTitles;
adrparm.lpulDestComps=lpulDestComps;
adrparm.cDestFields = 1;
adrparm.lppszDestTitles = (LPTSTR*)lppszDestTitles;
adrparm.lpulDestComps = lpulDestComps;
HWND hDesktop=::GetDesktopWindow();
HRESULT hr=pAddressBook->Address((ULONG_PTR*)&hDesktop, &adrparm, &pAddressList);
HWND hDesktop = ::GetDesktopWindow();
HRESULT hr = pAddressBook->Address((ULONG_PTR*)&hDesktop, &adrparm, &pAddressList);
RELEASE(pAddressBook);
if(hr==S_OK) return IDOK;
if(hr==MAPI_E_USER_CANCEL) return IDCANCEL;
if(hr == S_OK)
return IDOK;
if(hr == MAPI_E_USER_CANCEL)
return IDCANCEL;
}
#endif
return FALSE;

View file

@ -510,7 +510,7 @@ BOOL CMAPIMessage::SaveAsMsg(LPCTSTR szPath)
CString strPath=szPath;
if(strPath.GetLength()<4 || strPath.Right(4).CompareNoCase(".msg")) strPath+=".msg";
#ifdef _WIN32_WCE
return FALSE;
return FALSE;
#else
LPSTORAGE pStorage;
DWORD dwFlags=STGM_READWRITE | STGM_TRANSACTED | STGM_CREATE;
@ -524,14 +524,11 @@ BOOL CMAPIMessage::SaveAsMsg(LPCTSTR szPath)
{
LPMSGSESS pMsgSession;
LPMALLOC pMalloc = MAPIGetDefaultMalloc();
if(OpenIMsgSession(pMalloc, 0, &pMsgSession) == S_OK)
{
if(OpenIMsgSession(pMalloc, 0, &pMsgSession) == S_OK) {
LPMESSAGE pIMsg;
if(OpenIMsgOnIStg(pMsgSession, MAPIAllocateBuffer, MAPIAllocateMore, MAPIFreeBuffer, pMalloc, NULL, pStorage, NULL, 0, 0, &pIMsg) == S_OK)
{
if(OpenIMsgOnIStg(pMsgSession, MAPIAllocateBuffer, MAPIAllocateMore, MAPIFreeBuffer, pMalloc, NULL, pStorage, NULL, 0, 0, &pIMsg) == S_OK) {
// client must support CLSID_MailMessage as the compound document
if(WriteClassStg(pStorage, CLSID_MailMessage) == S_OK)
{
if(WriteClassStg(pStorage, CLSID_MailMessage) == S_OK) {
// exclude these properties from the copy operation to speed things up
SizedSPropTagArray ( 7, excludeTags );
excludeTags.cValues=7;
@ -543,8 +540,7 @@ BOOL CMAPIMessage::SaveAsMsg(LPCTSTR szPath)
excludeTags.aulPropTag[5]=PR_RTF_SYNC_PREFIX_COUNT;
excludeTags.aulPropTag[6]=PR_RTF_SYNC_TRAILING_COUNT;
if(Message()->CopyTo(0, NULL, (LPSPropTagArray)&excludeTags, NULL, NULL, (LPIID)&IID_IMessage, pIMsg, 0, NULL ) == S_OK)
{
if(Message()->CopyTo(0, NULL, (LPSPropTagArray)&excludeTags, NULL, NULL, (LPIID)&IID_IMessage, pIMsg, 0, NULL ) == S_OK) {
pIMsg->SaveChanges(KEEP_OPEN_READWRITE);
pStorage->Commit(STGC_DEFAULT);
}
@ -553,7 +549,6 @@ BOOL CMAPIMessage::SaveAsMsg(LPCTSTR szPath)
}
CloseIMsgSession(pMsgSession);
}
RELEASE(pStorage);
return TRUE;
}

View file

@ -1,7 +1,3 @@
TOPIC("aa$en-us")
#include "aa$en-us.tppi"
END_TOPIC
TOPIC("MAPIAppointment$en-us")
#include "MAPIAppointment$en-us.tppi"
END_TOPIC
@ -26,3 +22,7 @@ TOPIC("MAPIMessage$en-us")
#include "MAPIMessage$en-us.tppi"
END_TOPIC
TOPIC("aa$en-us")
#include "aa$en-us.tppi"
END_TOPIC

View file

@ -1,9 +0,0 @@
topic "News and changes Log";
[ $$0,0#00000000000000000000000000000000:Default]
[a83;*R6 $$1,0#31310162474203024125188417583966:caption]
[{_}%EN-US
[s0; [*R+184 MAPIEx. News and changes log]&]
[s0;%- &]
[ {{1441:8559f0;g0;^t/25b/25 [s0;# [2 2011/04/20]]
:: [s0;# [2 Package created.]]}}&]
[s0; ]

View file

@ -27,4 +27,4 @@ ucian Wischik MAPI Utils][2 . Its license is:]&]
[s0; [C+75 This code (c) 2002`-2006 Lucian Wischik.]&]
[s0;C+75 &]
[s0; [C+75 The code is free and anyone can do with it whatever they
like, including incorporating it in commercial products.]]
like, including incorporating it in commercial products.]]]

View file

@ -1,6 +1,6 @@
TITLE("MAPIEx License")
COMPRESSED
120,156,149,147,107,79,219,48,20,134,255,202,145,96,19,163,144,91,175,43,154,166,209,49,9,13,16,2,170,125,168,10,54,142,155,120,56,118,100,59,52,101,218,127,223,113,82,208,214,21,77,235,151,186,245,185,188,239,57,143,103,176,187,27,29,68,59,209,63,62,227,207,124,65,43,233,230,51,58,234,30,237,95,13,48,47,198,188,110,220,141,163,120,144,244,134,189,36,234,70,73,47,78,250,241,104,212,139,135,253,81,247,253,96,48,102,180,116,66,171,249,236,199,221,207,55,39,23,135,211,107,152,217,232,8,102,251,87,157,120,212,131,243,79,151,167,39,53,156,9,198,149,229,243,183,115,127,155,64,251,13,179,228,57,96,74,58,164,3,199,244,137,82,3,37,101,15,52,227,32,44,44,42,41,87,112,79,45,79,65,40,152,207,110,115,231,74,50,38,33,9,151,203,37,9,138,42,37,1,163,36,108,11,145,224,73,148,183,9,92,104,46,225,179,144,146,222,235,42,203,97,210,94,207,177,99,0,167,206,130,108,21,97,143,241,95,170,38,157,97,31,38,186,92,25,145,
229,14,246,38,239,32,137,162,62,57,76,162,56,58,216,172,189,78,111,146,254,168,112,147,163,1,171,43,195,56,48,157,182,126,12,231,224,52,84,216,154,170,20,10,157,138,197,10,74,163,31,69,138,30,157,207,81,218,161,58,48,188,160,66,89,244,237,40,115,77,184,203,169,63,172,128,171,156,42,198,11,174,208,139,54,112,95,101,176,16,53,183,64,13,135,82,91,231,139,105,76,224,232,36,229,151,70,127,231,88,164,244,115,205,241,90,168,172,109,198,36,181,168,11,107,248,88,166,139,162,82,194,173,124,242,61,87,124,33,92,240,170,195,169,197,114,99,176,222,211,70,35,106,208,131,68,147,14,252,198,198,161,95,87,224,199,80,182,17,120,46,66,180,198,141,226,46,156,156,211,82,156,212,1,181,229,22,72,190,104,41,245,242,69,242,243,238,168,148,192,112,14,25,218,206,233,35,71,193,92,225,216,74,109,214,246,217,203,18,115,45,83,110,130,45,4,253,166,201,255,40,72,248,245,152,132,167,151,228,89,20,241,170,106,242,177,176,25,249,208,29,13,7,81,47,38,
59,117,189,62,214,53,242,118,221,140,0,181,249,209,55,148,109,177,177,134,16,85,225,70,253,102,27,42,22,70,23,91,100,45,133,101,185,120,88,75,146,21,9,81,100,102,104,81,112,67,194,2,149,145,187,202,9,105,73,144,187,66,162,134,179,138,9,170,224,91,155,216,188,44,152,250,136,255,160,190,97,182,145,181,199,26,234,19,79,125,52,216,40,254,58,18,55,249,6,236,30,91,36,86,43,252,31,11,164,26,150,194,229,32,28,44,17,102,254,200,27,240,86,40,237,129,31,32,235,76,86,169,223,52,158,180,193,77,210,6,85,12,199,231,239,233,228,6,133,72,255,98,210,138,57,27,204,231,191,0,77,128,153,55,
120,156,149,147,107,79,219,48,20,134,255,202,145,96,19,163,144,91,175,43,154,166,209,49,9,13,16,2,170,125,168,2,54,142,219,120,56,118,100,59,52,101,218,127,223,113,82,208,214,21,77,235,151,186,245,185,188,239,57,143,103,176,187,27,29,68,59,209,63,62,227,207,124,78,43,233,210,25,29,117,143,246,175,6,152,23,99,94,55,238,198,81,60,72,122,195,94,18,117,163,164,23,39,253,120,52,234,197,195,254,168,251,126,48,24,51,90,58,161,85,58,251,113,247,243,205,201,197,225,244,26,102,54,58,130,217,254,85,39,30,245,224,252,211,229,233,73,13,103,130,113,101,121,250,54,245,183,9,180,223,48,75,158,3,166,164,67,58,112,76,159,40,53,80,82,246,64,23,28,132,133,121,37,229,10,238,169,229,25,8,5,233,236,54,119,174,36,99,18,146,112,185,92,146,160,168,50,18,48,74,194,182,16,9,158,68,121,155,192,133,230,18,62,11,41,233,189,174,22,57,76,218,235,20,59,6,112,234,44,200,86,17,246,24,255,165,106,210,25,246,97,162,203,149,17,139,
220,193,222,228,29,36,81,212,39,135,73,20,71,7,155,181,215,233,77,210,31,21,110,114,52,96,117,101,24,7,166,179,214,143,225,28,156,134,10,91,83,149,65,161,51,49,95,65,105,244,163,200,208,163,243,57,74,59,84,7,134,23,84,40,139,190,29,101,174,9,119,57,245,135,21,112,149,83,197,120,193,21,122,209,6,238,171,5,204,69,205,45,80,195,161,212,214,249,98,26,19,56,58,201,248,165,209,223,57,22,41,253,92,115,188,22,106,209,54,99,146,90,212,133,53,124,44,211,69,81,41,225,86,62,249,158,43,62,23,46,120,213,225,212,98,185,49,88,239,105,163,17,53,232,65,162,73,7,126,99,227,208,175,43,240,99,40,219,8,60,23,33,90,227,70,113,23,78,206,105,41,78,234,128,218,114,11,36,95,180,148,122,249,34,249,121,119,84,74,96,56,135,5,218,206,233,35,71,193,92,225,216,74,109,214,246,217,203,18,115,45,51,110,130,45,4,253,166,201,255,40,72,248,245,152,132,167,151,228,89,20,241,170,106,242,177,176,11,242,161,59,26,14,162,94,76,
118,234,122,125,172,107,228,237,186,25,1,106,243,163,111,40,219,98,99,13,33,170,194,141,250,205,54,84,204,141,46,182,200,90,10,203,114,241,176,150,36,43,18,162,200,133,161,69,193,13,9,11,84,70,238,42,39,164,37,65,238,10,137,26,206,42,38,168,130,111,109,98,243,178,96,234,35,254,131,250,134,217,70,214,30,107,168,79,60,245,209,96,163,248,235,72,220,228,27,176,123,108,145,88,173,240,127,44,144,105,88,10,151,131,112,176,68,152,249,35,111,192,91,161,180,7,126,128,172,51,89,101,126,211,120,210,6,55,73,27,84,49,28,159,191,167,147,27,20,34,253,139,201,42,230,108,144,166,233,47,231,20,153,148,

View file

@ -3,4 +3,4 @@ topic "ToDo list";
[{_}%EN-US
[s0; [*R+184 MAPIEx. ToDo list]&]
[s0;2 &]
[s0;i150;O0;~~~608; [2 MinGW compatibility.]]
[s0;i150;O0;~~~608; [2 MinGW compatibility.]]]

View file

@ -1,4 +1,4 @@
TITLE("ToDo list")
COMPRESSED
120,156,139,86,80,81,49,208,49,80,54,32,0,172,92,82,211,18,75,115,74,98,163,171,227,107,85,93,253,116,67,131,21,162,139,13,172,21,162,181,130,180,13,45,76,20,124,29,3,60,93,43,244,20,66,242,93,242,21,114,50,139,75,98,213,98,65,10,140,20,32,116,166,161,169,129,181,191,129,117,93,93,157,153,129,5,80,159,145,130,111,102,158,123,184,66,114,126,110,65,98,73,102,82,102,78,102,73,165,94,108,44,0,103,174,40,73,
120,156,139,86,80,81,49,208,49,80,54,32,0,172,92,82,211,18,75,115,74,98,163,171,227,107,85,93,253,116,67,131,21,162,139,13,172,21,162,181,130,180,13,45,76,20,124,29,3,60,93,43,244,20,66,242,93,242,21,114,50,139,75,98,213,98,65,10,140,20,32,116,166,161,169,129,181,191,129,117,93,93,157,153,129,5,80,159,145,130,111,102,158,123,184,66,114,126,110,65,98,73,102,82,102,78,102,73,165,94,108,108,44,0,144,84,40,166,