Not found error getting Exception.AppointmentItem

  • Thread starter Thread starter Eric
  • Start date Start date
E

Eric

Can anyone think of any reason I would be getting a "block not found"
(9) error when trying to get the AppointmentItem property from an
Exception object?

I'm able to check the "Exception.Deleted" value, and it is "FALSE". I
know it isn't deleted anyway. I'm also able to get any of the other
"Excpetion." properties, like OriginalDate, Session, Application,
Class (=30).

I'm making this calls from a seperate thread, from a COM add-in DLL,
but all of my other OLE code works fine, and like I say, I can check
all the other properties of the Excpetion object, so why can't I get
the "AppointmentItem" property. Is there something special about it?

I'm able to use Outlook Spy, or VBScript, and I can get the property
just fine. It is just my C++ code which isn't working.

Here is some of my source code. As you can see I'm using the same
"GetOleProp" call several times in a row, and it works fine, until I
get the the AppointmentItem property, where it fails with the "block
not found" type of error (0x????0009).

---------
HRESULT hr;
VARIANT v,p1;

hr = DoOleMethod(item,L"GetRecurrencePattern",&v,0);
assert(!(FAILED(hr) || v.vt != VT_DISPATCH || !v.pdispVal));
IDispatch *rp = v.pdispVal;

hr = GetOleProp(rp,L"Exceptions",&v);
assert(!(FAILED(hr) || v.vt != VT_DISPATCH || !v.pdispVal));
IDispatch *exps = v.pdispVal;

p1.vt = VT_I4;
p1.lVal = 1;
hr = DoOleMethod(exps,L"Item",&v,1,&p1);
assert(!(FAILED(hr) || v.vt != VT_DISPATCH || !v.pdispVal));
IDispatch *exp = v.pdispVal;

hr = GetOleProp(exp,L"AppointmentItem",&v);
if(!FAILED(hr) && v.vt == VT_DISPATCH && v.pdispVal)
{
v.pdispVal->Release();
Prompt("Wow, it worked!");
}
 
I think this other issue is related to this one. If I try and invoke
the "Save" method for a recurring TaskItem sometimes I'll get an
access violation before the call returns. I know Outlook is probably
trying to auto-generate the next recurring TaskItem when the access
violation occurs.

I think it has something to do with me making the Save call from a
thread running under the Outlook process, which is not the main
thread. I know my Save call is routed, by COM, back to Outlook's main
thread. I thought it was safe to work with the Outlook OOM
Application object on multiple threads?

If I make my 2nd thread post a message to a window on the main thread,
then wait for the main thread to process the message, I can
sucessfully make the "Save" call on the main thread (using the same
pointer I was going to use from the 2nd thread). I guess I could just
leave this type of trick in there, whenever I call "Save", and
probably for getting the "Exception.AppointmentItem" object, but what
else is going to break next?

I've gone down this multithread road pretty far already, so I'd hate
to stop using a seperate thread all together for OOM calls. What can
I do to make my design more robust, but keep this other thread? Would
it help to get a new Outlook.Application object at the start of my
thread?
 
For what it is worth, using GetActiveObject() to get my own
Outlook.Application object for my 2nd thread did make both of these
problems go away (the one below, and the other one I posted in this
same thread).

I don't see any harm in the extra code, so I'll probably just go this
route unless anyone has a better idea:

// Error checking removed
CLSID clsid;
CLSIDFromProgID(L"Outlook.Application",&clsid);
IUnknown *punk;
GetActiveObject(clsid,NULL,(IUnknown**)&punk);
IDispatch *pa;
punk->QueryInterface(IID_IDispatch,(void**)&pa);

Then I just us "pa" instead of the application object which Outlook
passed to my COM add-in. I don't think this will end up being a
resource hog or anything, and I Release "pa" when my process is done.
Which I already have code to make sure Outlook doesn't shutdown before
this process is done, so "pa" should always be free before Outlook
ever closes.
 
Back
Top