Hi,

I am trying to implement a custom command in a C3PO that allows users to "Send & Store" a message. The idea is that when composing a new message, they invoke the command, which sends it, then stores a representation of the sent message in a 3rd party database.

Simple enough? Possibly, but I'm having a heck of a time trying to make it work! The main problem is trying to identify the message AFTER it has been sent.

The starting point is a draft message('X00'). At the moment, I am saving the message to the 'Work In Progress' folder, then accessing the corresponding IGWMessage object. I then try to add a user defined field (UDF) to that message through the IGWMessage interface. The idea is that I can then use the UDF to find the message in the 'Sent Items' folder after it has been sent.

Problem is, when I try to add the UDF, IGWFields-Add() fails with 0x8002009. As a test, I implemented a separate command that adds the same field to any selected message, and it works fine on messages in the 'Work In Progress' folder. I've attached some code below which hopefully explains what I'm trying to do.

BTW, I'm using GW Client 6.5.0. Perhaps there's a bug which is addressed in a patch?

Has anyone else tried to implement a similar command? Is there an easier way?

Thanks,
Andrew

---------------------------------------

STDMETHODIMP ObjSendAndStoreCmd::Execute()
{
//
// Ensure the Account FieldDefinitions includes our
// user defined field.
//
this->CreateUserDefinedField();

//
// Get the message subject so we can match it in
// the work in progress drafts folder.
// todo: needs to be more accurate than subject!
//
BSTR bstrResult;
this->ExecuteTokenCommand("ItemGetText(\"X00\";9)", &bstrResult);
char *subjectStr = FROM_OLE_STRING(bstrResult);
SysFreeString(bstrResult);

//
// get the work in progress folder
//
DIGWFolder *pDIGWFolder;
IGWFolder *pIGWFolderWIP=NULL;

if ( SUCCEEDED(this->get_CurrentAccount()->get_WorkFolder(&pDIGWFolder)) )
{
pDIGWFolder->QueryInterface(IID_IGWFolder, (void**)&pIGWFolderWIP);
pDIGWFolder->Release();
}
if (!pIGWFolderWIP)
return E_FAIL;

//
// form the fully qualified name for the folder
//
IGWFolder *pIGWFolder=pIGWFolderWIP;
pIGWFolder->AddRef();

BSTR folderName;
pIGWFolder->get_Name(&folderName);
_bstr_t x(folderName, true);
SysFreeString(folderName);


while ( SUCCEEDED(pIGWFolder->get_ParentFolder(&pDIGWFolder)) )
{
pIGWFolder->Release();
pDIGWFolder->QueryInterface(IID_IGWFolder, (void**)&pIGWFolder);
pIGWFolder->get_Name(&folderName);
_bstr_t y(folderName, true);
x = y + "\\" + x;
SysFreeString(folderName);
pDIGWFolder->Release();
}

//
// Save the message into the folder via a token
//
_bstr_t command = L"ItemSaveMessageDraft(\"" + x + L"\")";
this->ExecuteTokenCommand(command.copy(), &gdti);


//
// ItemMessageIDFromView() still returns X00 at this stage
// (even though we've saved the message) so we have to go into the
// folder and look for it.
//
pIGWFolderWIP->Refresh();

DIGWMessages *pDIGWMessages;
IGWMessages *pIGWMessages=NULL;

if ( SUCCEEDED(pIGWFolderWIP->get_Messages(&pDIGWMessages)) )
{
pDIGWMessages->QueryInterface(IID_IGWMessages, (void**)&pIGWMessages);
pDIGWMessages->Release();
}
if (!pIGWMessages)
return E_FAIL;

IGWMessage2 *pIGWMessage=NULL;
long numMessages;
pIGWMessages->get_Count(&numMessages);
for (long msgi=1; msgi<=numMessages; msgi++)
{
VARIANT vItem;
VariantInit(&vItem);
V_VT(&vItem) = VT_I4;
V_I4(&vItem) = msgi;

DIGWMessage *pDIGWMessage;
if ( SUCCEEDED(pIGWMessages->Item(vItem, &pDIGWMessage)) )
{
pDIGWMessage->QueryInterface(IID_IGWMessage2, (void **)&pIGWMessage);
if (pIGWMessage)
{
//
// Compare the subjects. If they match, we've found the
// IGWMessage we want.
//
char *wipSubject = getIGWSubject(pIGWMessage);
if ( strcmp(subjectStr, wipSubject) == 0 )
break;
pIGWMessage->Release();
pIGWMessage=NULL;
free(wipSubject);
}
pDIGWMessage->Release();
}
}

pIGWMessages->Release();

if (!pIGWMessage)
{
DebugStr("Could not find message in Work In Progress folder!");
return E_FAIL;
}

BSTR fieldName = SysAllocString(L"ObjGWField");
VARIANT vFieldValue;
VariantInit(&vFieldValue);
V_VT(&vFieldValue) = VT_I4;
V_I4(&vFieldValue) = 1;

//
// Set the user defined field value on the message.
// THIS IS WHERE IGWFields::Add() FAILS WITH 0x80020009. I KNOW THIS FUNCTION
// WORKS OK BECAUSE I HAVE USED IT TO SET FIELD VALUES ON OTHER MESSAGES.
//
SetMessageFieldValue(pIGWMessage, fieldName, egwNumeric, vFieldValue);

SysFreeString(fieldName);

return S_OK;
}