Outlook commandbars once more

M

Marcin Junger

Hello everyone,
I'm writing an Outlook plugin for Outlook 2003 in Delphi 5. One of its
functions is to display a command bar in new mail inspector. I have read
a lot articles and messages on that topic but I still have sum problems.
Everything works fine when I do not use Word as editor. Problems begin
when I do.
The 1st problem: I cannot set my command bar visible. Command
cbCRM.Set_Visible(true) raises an exception.
The 2nd problem: When I open new mail inspector I have my commandbar. I
can press a button on it and hooked procedure executes. But when I open
the second new mail inspector without closing the 1st one, my command
bar is not docked and buttons are not connected. I have debugged the
code and the behaviour is the same in both OnNewInspector events...
The 3rd problem: When I have MS Word editor open and then start the new
mail inspector, the behaviour is exactly the same as if I had one new
mail inspector already opened (the 2nd problem).
I also had a problem that my bar was available in Word editor, but after
setting idWordEditor.Application.CustomizationContext := idWordEditor
the problem appears to be solved.

The code I wrote to create toolbar, button and hook up events:

procedure OnNewInspector(const Inspector : _Inspector);
var
cbCRM : CommandBar;
btnFile :CommandBarButton;
olMailItem :_MailItem;
idWordEditor : Word97._Document;
begin
(...)
//create command bar
if Inspector.CurrentItem.QueryInterface(IID__MailItem,olMailItem) =
S_Ok then
begin
if not(olMailItem.Sent) then begin
if Inspector.IsWordMail then begin
idWordEditor := IDispatch(Inspector.WordEditor) as _Document;
try
idWordEditor.Application.CustomizationContext := idWordEditor;
finally
pointer(idWordEditor) := nil;
end;
end;

cbCRM :=
Inspector.CommandBars.Add('CRM',EmptyParam,EmptyParam,EmptyParam) as
CommandBar;
cbCRM.Set_Position(msoBarTop);
//cbCRM.Set_Visible(true); <-exception when word
end;
if assigned(cbCRM) then begin
btnFile :=
FindOrAddButton(cbCRM.Controls,Trans('sendandfile'),'sendandfile',Trans('sendandfile'));
if assigned(btnFile) then begin
btnFile.Set_Style(msoButtonIconAndCaption);
MakeConnection(btnFile, DIID__CommandBarButtonEvents, 1,
oEmbeddedCRM.SendAndFile);
end;
end;
end;


function
TOutlookAddin.FindOrAddButton(Controls:CommandBarControls;vButtonName,vResourceName,vToolTip:string):CommandBarButton;
var
x : integer;
begin
result:=nil;
for x:=1 to Controls.Count do
begin
if (Controls.Item[x].Caption=vButtonName) then
begin
result := Controls.Item[x] as CommandBarButton;
break;
end;
end;
if result=nil then
begin
result := Controls.Add(msoControlButton, EmptyParam, EmptyParam,
EmptyParam, EmptyParam) as CommandBarButton;
result.Set_Caption(vButtonName);
if vResourceName<>'' then
BmpToBtn(vResourceName,result);
if vToolTip<>'' then
result.Set_TooltipText(Trans(vToolTip));
end;
end;

procedure TOutlookAddin.MakeConnection(
Unk : IUnknown;
EventIID : TGUID;
EventDispID : integer;
EventProc : TOutlookEventProc;
EventDispID1 : integer=0;
EventProc1 : TOutlookEventProc=nil;
EventDispID2 : integer=0;
EventProc2 : TNewExplorerEvent=nil;
//BJR .60 - need lots more types of events for the OnNewInspector and
//ItemAdd event......
EventDispID3 : integer=0;
EventProc3 : TItemsEvents=nil;
EventDispID4 : integer=0;
EventProc4 : TInspectorsEvents=nil
);
var
CPC: IConnectionPointContainer;
EventClass : TOutlookEventClass;
begin

EventClass := TOutlookEventClass.Create;

EventClass.EventIID:=EventIID;
EventClass.EventProc:=EventProc;
EventClass.EventDispID:=EventDispID;
EventClass.EventProc1:=EventProc1;
EventClass.EventDispID1:=EventDispID1;
EventClass.EventProc2:=EventProc2;
EventClass.EventDispID2:=EventDispID2;
EventClass.EventProc3:=EventProc3;
EventClass.EventDispID3 := EventDispID3;
EventClass.EventProc4:=EventProc4;
EventClass.EventDispID4 := EventDispID4;

if Succeeded(Unk.QueryInterface(IConnectionPointContainer, CPC)) then
if Succeeded(CPC.FindConnectionPoint(EventIID, EventClass.CP)) then
begin
//EventClass.CP._AddRef;
EventClass.CP.Advise(EventClass, EventClass.Cookie);
end;
EventList.AddObject('',EventClass);
end;

Do you have any ideas, comments or suggestions?
Marcin Junger
Sage Ireland
 
D

Dmitry Streblechenko

See my reply in the delphi.oleautomation newsgroup.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

Marcin Junger said:
Hello everyone,
I'm writing an Outlook plugin for Outlook 2003 in Delphi 5. One of its
functions is to display a command bar in new mail inspector. I have read a
lot articles and messages on that topic but I still have sum problems.
Everything works fine when I do not use Word as editor. Problems begin
when I do.
The 1st problem: I cannot set my command bar visible. Command
cbCRM.Set_Visible(true) raises an exception.
The 2nd problem: When I open new mail inspector I have my commandbar. I
can press a button on it and hooked procedure executes. But when I open
the second new mail inspector without closing the 1st one, my command bar
is not docked and buttons are not connected. I have debugged the code and
the behaviour is the same in both OnNewInspector events...
The 3rd problem: When I have MS Word editor open and then start the new
mail inspector, the behaviour is exactly the same as if I had one new mail
inspector already opened (the 2nd problem).
I also had a problem that my bar was available in Word editor, but after
setting idWordEditor.Application.CustomizationContext := idWordEditor the
problem appears to be solved.

The code I wrote to create toolbar, button and hook up events:

procedure OnNewInspector(const Inspector : _Inspector);
var
cbCRM : CommandBar;
btnFile :CommandBarButton;
olMailItem :_MailItem;
idWordEditor : Word97._Document;
begin
(...)
//create command bar
if Inspector.CurrentItem.QueryInterface(IID__MailItem,olMailItem) = S_Ok
then
begin
if not(olMailItem.Sent) then begin
if Inspector.IsWordMail then begin
idWordEditor := IDispatch(Inspector.WordEditor) as _Document;
try
idWordEditor.Application.CustomizationContext := idWordEditor;
finally
pointer(idWordEditor) := nil;
end;
end;

cbCRM :=
Inspector.CommandBars.Add('CRM',EmptyParam,EmptyParam,EmptyParam) as
CommandBar;
cbCRM.Set_Position(msoBarTop);
//cbCRM.Set_Visible(true); <-exception when word
end;
if assigned(cbCRM) then begin
btnFile :=
FindOrAddButton(cbCRM.Controls,Trans('sendandfile'),'sendandfile',Trans('sendandfile'));
if assigned(btnFile) then begin
btnFile.Set_Style(msoButtonIconAndCaption);
MakeConnection(btnFile, DIID__CommandBarButtonEvents, 1,
oEmbeddedCRM.SendAndFile);
end;
end;
end;


function
TOutlookAddin.FindOrAddButton(Controls:CommandBarControls;vButtonName,vResourceName,vToolTip:string):CommandBarButton;
var
x : integer;
begin
result:=nil;
for x:=1 to Controls.Count do
begin
if (Controls.Item[x].Caption=vButtonName) then
begin
result := Controls.Item[x] as CommandBarButton;
break;
end;
end;
if result=nil then
begin
result := Controls.Add(msoControlButton, EmptyParam, EmptyParam,
EmptyParam, EmptyParam) as CommandBarButton;
result.Set_Caption(vButtonName);
if vResourceName<>'' then
BmpToBtn(vResourceName,result);
if vToolTip<>'' then
result.Set_TooltipText(Trans(vToolTip));
end;
end;

procedure TOutlookAddin.MakeConnection(
Unk : IUnknown;
EventIID : TGUID;
EventDispID : integer;
EventProc : TOutlookEventProc;
EventDispID1 : integer=0;
EventProc1 : TOutlookEventProc=nil;
EventDispID2 : integer=0;
EventProc2 : TNewExplorerEvent=nil;
//BJR .60 - need lots more types of events for the OnNewInspector and
//ItemAdd event......
EventDispID3 : integer=0;
EventProc3 : TItemsEvents=nil;
EventDispID4 : integer=0;
EventProc4 : TInspectorsEvents=nil
);
var
CPC: IConnectionPointContainer;
EventClass : TOutlookEventClass;
begin

EventClass := TOutlookEventClass.Create;

EventClass.EventIID:=EventIID;
EventClass.EventProc:=EventProc;
EventClass.EventDispID:=EventDispID;
EventClass.EventProc1:=EventProc1;
EventClass.EventDispID1:=EventDispID1;
EventClass.EventProc2:=EventProc2;
EventClass.EventDispID2:=EventDispID2;
EventClass.EventProc3:=EventProc3;
EventClass.EventDispID3 := EventDispID3;
EventClass.EventProc4:=EventProc4;
EventClass.EventDispID4 := EventDispID4;

if Succeeded(Unk.QueryInterface(IConnectionPointContainer, CPC)) then
if Succeeded(CPC.FindConnectionPoint(EventIID, EventClass.CP)) then
begin
//EventClass.CP._AddRef;
EventClass.CP.Advise(EventClass, EventClass.Cookie);
end;
EventList.AddObject('',EventClass);
end;

Do you have any ideas, comments or suggestions?
Marcin Junger
Sage Ireland
 
Top