Inspector won't close in outlook 2010 when using external apps to send emails
-
sexta-feira, 13 de agosto de 2010 22:12
I have an Add-In that intercepts the ApplicationEvents_11_ItemSendEventHandler. I want to disregard emails that got initiated from external apps, using the 'send to' feature (i.e. from word, excel, etc.). In outlook 2007 I just return out of the send event handler, the email composition window closes without any problem. In Outlook 2010, the email composition window never closes after I return from the send even handler.
Can someone tell me why that is the case in Outlook 2010. Can I manually close the email composition window? I tried getting the mailitem's inspector and closing that, but that didn't work (it crashed).
Todas as Respostas
-
segunda-feira, 16 de agosto de 2010 13:47I haven't had any problems with Outlook 2010 Inspectors and handling send events compared to Outlook 2007 in any of my addins.How are you detecting that a specific Inspector was created using Simple MAPI (Send To)?Are you releasing all of your object references and making sure they all are released and garbage collected?How did you get the Inspector and cause the crash, did you cast the Item to a MailItem and use GetInspector(), or did you do something else?
--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Professional Programming Outlook 2007.
Reminder Manager, Extended Reminders, Attachment Options.
http://www.slovaktech.com/products.htm"outlookman" <=?utf-8?B?b3V0bG9va21hbg==?=> wrote in message news:243e8465-a638-41b1-ac28-b4f7262457f9...I have an Add-In that intercepts the ApplicationEvents_11_ItemSendEventHandler. I want to disregard emails that got initiated from external apps, using the 'send to' feature (i.e. from word, excel, etc.). In outlook 2007 I just return out of the send event handler, the email composition window closes without any problem. In Outlook 2010, the email composition window never closes after I return from the send even handler.
Can someone tell me why that is the case in Outlook 2010. Can I manually close the email composition window? I tried getting the mailitem's inspector and closing that, but that didn't work (it crashed).
Ken Slovak MVP - Outlook -
segunda-feira, 16 de agosto de 2010 17:47
To detect whether or not the email was created using Simple MAPI, I check whether the email also got started in the InspectorsEvents_NewInspectorEventHandler - I manage a list of mailItem entryIDs that I check for in the send handler. If there is a better way to check for Simple MAPI, I'm open for suggestions.
I think I'm cleaning everything up, using Marshal.ReleaseComObject. I also tried exiting out of the Send Event handler right away, (after having Cancel set to false), but that doesn't close the window.
The crash happened, when I casted the Item to MailItem, then did GetInspector (without brackets), and then called close on the inspector.
-
segunda-feira, 16 de agosto de 2010 18:09
Using EntryID requires that the item was saved first, of course . Unsaved items have a null or blank EntryID.
What I usually do is iterate the Inspectors collection. A Simple MAPI Inspector is actually added to the collection even though the NewInspector() event never fires.
If you have a list of items you've handled then any Inspector in Inspectors that isn't being handled is your mystery Inspector. I use a timer to get that Inspector by checking the Inspectors collection at intervals looking for unhandled Inspectors. If I find one I add it to the Inspectors list I maintain.
Once you have the Inspector you can call Inspector.Close(). You usually do have to set a timer to handle the Close() call, it often fires an exception if you try to close the Inspector() within an event handler for that Inspector.
Ken Slovak MVP - Outlook -
segunda-feira, 16 de agosto de 2010 18:54
yeah, I saved the item first to get the EntryID.
How do you get the Inspectors collection?
-
segunda-feira, 16 de agosto de 2010 19:25Inspectors is a property of the Outlook.Application object. As long as you have that, and you must have it to set up an Application_ItemSend() handler, you can get the Inspectors collection.
Ken Slovak MVP - Outlook -
segunda-feira, 16 de agosto de 2010 22:39
ok, I played around with the inspectors a bit, and noticed that the Application.Inspectors.Count stays 0 in the Outlook 2010 case. In other words, Outlook 2010 doesn't add any inspectors when doing Simple MAPI. Am I missing something? I also tested it in Outlook 2007, and there it behaves like you described.
-
segunda-feira, 16 de agosto de 2010 23:24
I tinkered a little more with it. Now, Inspectors.Count is greater than 0, and I do this to close the window. Again, works in outlook 2007, doesn't do a thing in outlook 2010.
Outlook.Inspectors inspectors = this.Application.Inspectors;
foreach (Outlook.Inspector externalInspector in inspectors)
{
externalInspector.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard);
Marshal.ReleaseComObject(externalInspector);
}
-
terça-feira, 17 de agosto de 2010 14:21
I checked on this in Outlook 2010, and the Simple MAPI Inspector is definitely added to the Inspectors collection and increments the count of Inspectors.
What's different with the Simple MAPI Inspector is that it doesn't seem to want to close in Outlook 2010 when Inspector.Close() is called, as you noted. Possibly that's due to handling of the Inspector as modal. Normal Inspectors still do close properly when Inspector.Close() is called.
In this case the only workaround that I see is to set a flag property on that Simple MAPI Inspector's item or in an Inspector wrapper class indicating that it's a Simple MAPI Inspector. A check for Outlook.Version.StartsWith("14") would detect Outlook 2010, and you can then call the Win32 API function PostMessage() with a message sent to the Inspector window of WM_CLOSE.
You'd need to get the hWnd of the Inspector window, that can be done using the Win32 call FindWindow().
So I'd use declarations and code something like this:
[
DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[
DllImport("user32", SetLastError = true)]
[
return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool PostMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
// pseudo-code, not exact
// "insp" is the Simple MAPI Inspector
// check for Outlook 2010 to see if this is needed
IntPtr _inspHwnd = FindWindow("rctrl_renwnd32", insp.Caption);
const int WM_CLOSE = 0x10;
if (_simpleMAPI)
{
int retVal = PostMessage(_inspHwnd , WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
That would close down that Simple MAPI window for you.
Ken Slovak MVP - Outlook -
terça-feira, 17 de agosto de 2010 22:32
yuk!
I did the PostMessage thing and that did the trick. Not very elegant, but it works now :-)
-
terça-feira, 17 de agosto de 2010 22:47
Simple MAPI Inspector handling isn't supported.
Sometimes there are some ugly hacks involved to get things working. And of course each new SP or version has to be tested to see if the hacks no longer work.
But if that's the only way to get things done, sometimes ugly can be beautiful <g>
Ken Slovak MVP - Outlook- Marcado como Resposta Amy LiModerator quinta-feira, 19 de agosto de 2010 01:31
-
quinta-feira, 9 de maio de 2013 20:27
I found an example at http://blog.webonweboff.com/ and converted it to VB.net but still no joy... could someone please explain to me what I am missing?
Private Const WM_CLOSE = &H10 Private Sub beforeActualSend(ByVal objItem As Object, ByRef Cancel As Boolean) Handles Application.ItemSend Dim oMsg As Outlook.MailItem = Nothing Dim oInspector As Outlook.Inspector = Nothing Dim inspHwnd As System.IntPtr Dim retVal As Boolean If TypeOf (objItem) Is Outlook.MailItem Then oMsg = objItem If Not oMsg Is Nothing Then Try oInspector = oMsg.GetInspector If Not oInspector Is Nothing Then MsgBox("Here we go!!!") End If Finally If Not oInspector Is Nothing Then inspHwnd = FindWindow("rctrl_renwnd32", oInspector.Caption) retVal = PostMessage(inspHwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero) Marshal.ReleaseComObject(oInspector) End If End Try End If End If End Sub <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)> _ Private Shared Function FindWindow( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As IntPtr End Function <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)> _ Private Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Boolean End Function
-
sexta-feira, 10 de maio de 2013 15:13
You can't close the window in Application.ItemSend() and that's pretty late in the process anyway.
Handle the item.Send() event for the item and cancel the event by setting Cancel == true.
Then you'd need to set a timer in the event handler to fire after the event ends. Then when the timer fires you need to synch the thread the timer fired in to the Outlook thread the addin run ins.
Then and only then can you successfully close the window by sending a WM_CLOSE nessage and have it work and not fire various thread exceptions.
Also, please don't hijack closed threads, start one of your own and if necessary reference a link to another thread if it's related to your problem.
Ken Slovak MVP - Outlook
-
sábado, 11 de maio de 2013 20:03
Apologies for replying in this threat but its because it describes my problem and the suggested solution does not seem to work. I will starta new threat

