Outlook and CommandBarButton and Instpector

  • Thread starter Thread starter Mita Garg
  • Start date Start date
M

Mita Garg

Hi All,

I am writting a COM Add-in. All i want to do is create a button on the
standard Toolbar of the "New Mail Message" (i.e. when you click on the
"New" button to write emails).
I have managed to create the button on the toolbar, but then this
button appears when you click on the Contacts, Calendar e.t.cs "New"
button. Also it appears when you read each mail from the Inbox.

I WANT TO APPEAR IT OLNY ON THE MAIL "NEW" BUTTON (AND NOT ANYWHERE).
Another problem is it stays in memory when i close Outlook.

My code looks something like this.

Connect.dsr.........
'---------------------------------
Private Sub AddinInstance_OnConnection(ByVal Application As Object, _
ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, _
ByVal AddInInst As Object, custom() As Variant)
On Error Resume Next
If Application.Explorers.Count = 0 And
Application.Inspectors.Count = 0
Then
Exit Sub
End If
'AddInInst represents COMAddIn object
'Create and Initialize a base class
gBaseClass.InitHandler Application, AddInInst.ProgId
'DebugWrite "IDT2 OnConnection"
End Sub

Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode _
As AddInDesignerObjects.ext_DisconnectMode, custom() As Variant)
gBaseClass.UnInitHandler
If RemoveMode = ext_dm_UserClosed Then
Else
End If
Set gBaseClass = Nothing
'DebugWrite "AddinInstance_OnDisconnection"
End Sub

'-----------------------------------

class.....
Friend Sub InitHandler(olApp As Outlook.Application, strProgID As
String)

'Declared WithEvents
Set objOutlook = olApp 'Application Object
'Instantiate a public module-level Outlook application variable
Set golApp = olApp
'CDO Session if required
Set gobjCDO = CreateObject("MAPI.Session")
gobjCDO.Logon "", "", False, False
If Err <> 0 Then
MsgBox "Bad Logon: " & Err.Description
End If
'ProgID string required for CommandBarControls
gstrProgID = strProgID
Set colInsp = objOutlook.Inspectors 'Inspectors Object
End Sub

Friend Sub UnInitHandler()
On Error Resume Next
Set frmTLX = Nothing
objCBButton.Delete
Set objCBButton = Nothing
Set objCB = Nothing
Set objInsp = Nothing
Set objExpl = Nothing
Set colInsp = Nothing
Set objNS = Nothing
Set golNs = Nothing
Set golApp = Nothing
Set gobjCDO = Nothing 'Uncomment for CDO
Set objOutlook = Nothing
End Sub

'Add Set statements as required
'Also remove unnecessary object declarations
Private Sub colInsp_NewInspector(ByVal Inspector As Inspector)
Dim objItem As Object
On Error Resume Next
Dim str As String
Set objInsp = Inspector
Set objItem = objInsp.CurrentItem
Select Case objItem.Class
Case olMail
Set objCB = objInsp.CommandBars("Standard")
'Set objItem = objInsp.CurrentItem
Set objCBButton = CreateAddInCommandBarButton(gstrProgID,
objCB, "TestSMS", "TestSMS", "Send Test SMS", 0, True,
msoButtonIconAndCaption)
End Select
End Sub

Private Sub objCBButton_Click(ByVal Ctrl As Office.CommandBarButton,
CancelDefault As Boolean)
frmTLX.Show
End Sub

'Due to MAPI issues, On_Disconnection might not fire during Outlook
shutdown
'Call UnInitHandler in objExpl_Close event
Private Sub objExpl_Close()
On Error Resume Next
If golApp.Explorers.Count <= 1 And golApp.Inspectors.Count = 0
Then
UnInitHandler
End If
End Sub

'Call UnInitHandler in objInsp_Close event
Private Sub objInsp_Close()
On Error Resume Next
If golApp.Explorers.Count <= 1 And golApp.Inspectors.Count = 0
Then
UnInitHandler
End If
End Sub



Public Function CreateAddInCommandBarButton _
(strProgID As String, objCommandBar As CommandBar, _
strCaption As String, strTag As String, strTip As String, _
intFaceID As Integer, blnBeginGroup As Boolean, intStyle As
Integer) _
As Office.CommandBarButton

Dim ctlBtnAddIn As CommandBarButton
Dim objPicture As stdole.IPictureDisp 'Only for Office XP
Dim objMask As stdole.IPictureDisp 'Only for Office XP

Dim str As String


str = App.Path + "\MESSAGEmanager.bmp"
On Error Resume Next
' Test to determine if button exists on command bar.
Set ctlBtnAddIn = objCommandBar.FindControl(Tag:=strTag)
If ctlBtnAddIn Is Nothing Then
' Add new button.
Set ctlBtnAddIn =
objCommandBar.Controls.Add(Type:=msoControlButton,
Parameter:=strTag)
Set objPicture = LoadPicture(str)
Set objMask = LoadPicture(str)
With ctlBtnAddIn
.Caption = strCaption
.Tag = strTag

'for image comment these three lines
'If intStyle <> msoButtonIconAndCaption Then
' .FaceId = intFaceID
'End If

.Style = intStyle
.Picture = objPicture
.Mask = objMask
.ToolTipText = strTip
.BeginGroup = blnBeginGroup
' Set the OnAction property with ProgID of Add-In
.OnAction = "<!" & strProgID _
& ">"
End With
End If

' Return reference to new commandbar button.
Set CreateAddInCommandBarButton = ctlBtnAddIn

End Function
 
What is the Class property returning when you open a contact item or
other item type?

Always declare any toolbars, menus or buttons you create as temporary.
 
Sorry, I did not understand this question of yours. I have shown my
whole class in there.

Another thing what I want to do is, say I have the Button on the
toolbar, if i click on that button, it should show a from. On that
form I have a button say "AddressBook". When you click on this button,
it displays the Addressbook DialogBox, Then you select one name say
Mita from the book. Now i pull out the name, smpt address of Mita and
populate the List View. Have done till this.

Now what i want is, when the user clicks on the OK button of the from,
it should get the list from the ListView and set it next to the "To"
field, exactly like when you select the name from the addressbook, and
when you hit OK names appear next to the To button.

Some code

' When click on the AddressBook button on the form and poupulate the
ListView
Private Sub AddressBook_Click()
On Error Resume Next
Dim colRecipients As MAPI.Recipients
Dim objRecipient As MAPI.Recipient
Dim objAddressEntry As MAPI.AddressEntry
Dim name As String
Dim address As String
Dim addrType As String
Dim str As String
Dim itmField As MSComctlLib.ListItem
Dim objFields As MAPI.Fields
Dim objField As MAPI.Field
Dim objMailAddresses As MAPI.Field
Dim strAddresses
Dim intCounter As Integer

' open the Address Book
Set colRecipients = gobjCDO.AddressBook(Title:="Select Names",
ParentWindow:=Me.hwnd)
With LstViewAddress.ListItems
.Clear
For Each objRecipient In colRecipients
Set objAddressEntry = objRecipient.AddressEntry
name = objAddressEntry.name
' Get the fields collection of the address entry
Set objFields = objAddressEntry.Fields
' Pull out proxy addresses
Set objMailAddresses =
objFields.Item(PR_EMS_AB_PROXY_ADDRESSES)
If Not objMailAddresses Is Nothing Then
' Add the addresses to an array
strAddresses = objMailAddresses.Value
If (strAddresses <> "") Then
' Loop through the array and display single address
For intCounter = LBound(strAddresses) To
UBound(strAddresses)
'Check if it has the SMTP string
If Mid(strAddresses(intCounter), 1, 4) = "SMTP"
Then
address = Mid(strAddresses(intCounter), 6)
End If
Next
End If
End If
Set itmField = .Add(Text:=name)
itmField.SubItems(1) = address
itmField.SubItems(2) = "FAX"
Next
End With
End Sub


'When hit the OK button on the Form
Private Sub AddressBook_Click()
WHAT TO DO HERE
End Sub
 
Your code for NewInspector has the following line:
Select Case objItem.Class
What Class is being returned in the NewInspector event handler?

When you use the Session.AddressBook method you are getting MAPI
Recipients. You can store the EntryID (ID) of those Recipients
somewhere and use that to get the Recipients as Outlook Recipients
using the NameSpace.GetRecipientFromID method. Each of those
Recipients would then be added to the MailItem's Recipients
collection. An alternative would be to work all in CDO and add each
Recipient to the Message object's Recipients collection, then get the
Message as an Outlook MailItem using the NameSpace.GetItemFromID
method, using the ID and StoreID of the new Message you created. The
Message will only have an ID property after it is saved using the
..Update method. You would have to go to an Outlook MialItem at some
point since a CDO Message doesn't know anything about the UI or being
displayed.
 
Hi Ken Thanks for your Reply. I have solved all my problem, except one
small thing.

The second problem which I mentioned have solved it the way you
suggested but there is one little problem in that. I get the display
name too long (say for ex - aaa@comapny@number). How can I just have
the display name as just "aaa".
Instead of sending a normal email message I am trying to send a Fax
message.

This is my code

Dim objItem As Object
Dim colRecipients As MAPI.Recipients
Dim objRecipient As MAPI.Recipient
Dim objAddressEntry As MAPI.AddressEntry
Dim name As String
Dim number As String
Dim company As String
Dim strFormattedString As String

Set objItem = golApp.ActiveInspector.CurrentItem
'.CreateItem(olMailItem)
Set colRecipients = gobjCDO.AddressBook(Title:="Select Names",
ParentWindow:=Me.hwnd)
For Each objRecipient In colRecipients
Set objAddressEntry = objRecipient.AddressEntry
name = ""
name = objAddressEntry.Fields(CdoPR_DISPLAY_NAME).Value
number = ""
company = objAddressEntry.Fields(CdoPR_COMPANY_NAME).Value
number = ""
number = objAddressEntry.Fields(CdoPR_PRIMARY_FAX_NUMBER).Value
If (number = "") Then
number = objAddressEntry.Fields(CdoPR_BUSINESS_FAX_NUMBER).Value
End If
strFormattedString = name + "@" + company + "@" + number
objRecipient.name = "[FAX:" + strFormattedString + "]"
objRecipient.Type = 1
objRecipient.Resolve
objItem.Recipients.Add (objRecipient.name)
Next
objItem.Display
colRecipients.Resolve
End Sub

WHEN I LOOK INTO THE ITEMS RECIPIENT COLLECTION, I GET THE NAME AS
name@compnay@number" and ADDRESSENTRY ALSO AS "name@compnay@number"
and ADDRESSENTRY TYPE AS "fax". HOW DO I GET THE NAME AS JUST "name".
BUT IF I DO
objRecipient.name = name
objRecipient.AddressEntry.Address = "[FAX:" + strFormattedString +
"]"
Then i get the Exchange Address which I don't want.

Regards Mita
 
If I understand what you are asking you want just "aaa" from
CdoPR_DISPLAY_NAME and not the full string following the first "@"?

Just use InStr to get the position of the first "@" and take what's to
the left of it:
n = InStr(1, name, "@")
name = Left(name, n-1)
 
Hi Ken,

I have already tried this. This way i get the Exchange Address and
AddressType as Ex reather than the Fax Address and Address Type as
FAX.

If I do
strFormattedString = name + "@" + company + "@" + number
objRecipient.name = "[FAX:" + strFormattedString + "]"
objRecipient.Type = 1
objRecipient.Resolve
objItem.Recipients.Add (objRecipient.name)

When I look into the objItem -Recipients - Items collection, i get
AddressEntry
as say for examle "Alec (e-mail address removed)@34234". and NAME also as
"Alec (e-mail address removed)@34234" and AddressType as FAX.

But if do

strFormattedString = name + "@" + company + "@" + number
objRecipient.name = name
objRecipient.AddressEntry.Address = strFormattedString
objRecipient.AddressEntry.AddressType = "FAX"
objRecipient.Type = 1
objRecipient.Resolve
objItem.Recipients.Add (objRecipient.name)

When I look into the objItem -Recipients - Items collection, i get
AddressEntry
as "Exchange Address" and name as "Alec Dunn" but THEN AddressType is
EX.

I WANT THE ADDRESSENTRY AS FAX ADDRESS AND ADDRESSTYPE AS "FAX" RATHER
THAN "EX"
WHICH IS THE FIRST CASE BUT THEN I GET MY DISPLAY NAME TOO LONG WHICH
IS "NAME@COMPANY@NUMBER".

Ken Slovak - said:
If I understand what you are asking you want just "aaa" from
CdoPR_DISPLAY_NAME and not the full string following the first "@"?

Just use InStr to get the position of the first "@" and take what's to
the left of it:
n = InStr(1, name, "@")
name = Left(name, n-1)




Mita Garg said:
Hi Ken Thanks for your Reply. I have solved all my problem, except one
small thing.

The second problem which I mentioned have solved it the way you
suggested but there is one little problem in that. I get the display
name too long (say for ex - aaa@comapny@number). How can I just have
the display name as just "aaa".
Instead of sending a normal email message I am trying to send a Fax
message.

This is my code

Dim objItem As Object
Dim colRecipients As MAPI.Recipients
Dim objRecipient As MAPI.Recipient
Dim objAddressEntry As MAPI.AddressEntry
Dim name As String
Dim number As String
Dim company As String
Dim strFormattedString As String

Set objItem = golApp.ActiveInspector.CurrentItem
'.CreateItem(olMailItem)
Set colRecipients = gobjCDO.AddressBook(Title:="Select Names",
ParentWindow:=Me.hwnd)
For Each objRecipient In colRecipients
Set objAddressEntry = objRecipient.AddressEntry
name = ""
name = objAddressEntry.Fields(CdoPR_DISPLAY_NAME).Value
number = ""
company = objAddressEntry.Fields(CdoPR_COMPANY_NAME).Value
number = ""
number = objAddressEntry.Fields(CdoPR_PRIMARY_FAX_NUMBER).Value
If (number = "") Then
number = objAddressEntry.Fields(CdoPR_BUSINESS_FAX_NUMBER).Value
End If
strFormattedString = name + "@" + company + "@" + number
objRecipient.name = "[FAX:" + strFormattedString + "]"
objRecipient.Type = 1
objRecipient.Resolve
objItem.Recipients.Add (objRecipient.name)
Next
objItem.Display
colRecipients.Resolve
End Sub

WHEN I LOOK INTO THE ITEMS RECIPIENT COLLECTION, I GET THE NAME AS
name@compnay@number" and ADDRESSENTRY ALSO AS "name@compnay@number"
and ADDRESSENTRY TYPE AS "fax". HOW DO I GET THE NAME AS JUST "name".
BUT IF I DO
objRecipient.name = name
objRecipient.AddressEntry.Address = "[FAX:" + strFormattedString +
"]"
Then i get the Exchange Address which I don't want.

Regards Mita
 
Now you have me totally confused. If you are trying to send a fax why
are you setting the properties of the AddressEntry that the Recipient
represents? If you want the AddressEntry.Name property to show some
specific format why aren't you setting AddressEntry.Name? In fact, if
the AddressEntries collection is set up the way you want to begin with
you shouldn't need to set anything in the properties of those objects
at all in your code.

Also, posting things in all caps is considered shouting and is
considered as rude.
 
Back
Top