Jump to content
Ian Branch

Office Assistant component..

Recommended Posts

image.png.d4afdc792955297bfd6188f2a195fc9f.png

 

The Microsoft Agent is a COM server so you don't need a component for that. Just import the type library, create an instance of the TAgent object in code and then manipulate it through the interfaces.

I used DWScript to drive the agent actions and interaction (hence I made a DWScript wrapper library), but here's some code fractions of the host application:

uses
  AgentObjects_TLB,
  DoubleAgentSvr_TLB,
  ...

type
  TFormMain = class(TForm)
  private
    FAgent: TAgent;
    FAgentCharacter: IAgentCtlCharacter;
    FAgentRequestStart: IAgentCtlRequest;
    FAgentRequestComplete: IAgentCtlRequest;

    procedure LoadAgent;

    procedure AgentOnRequestStart(Sender: TObject; const Request: IDispatch);
    procedure AgentOnRequestComplete(Sender: TObject; const Request: IDispatch);
    procedure AgentOnClick(Sender: TObject; const CharacterID: WideString; Button: Smallint; Shift: Smallint; x: Smallint; y: Smallint);
    procedure AgentWaitForRequest(Request: IAgentCtlRequest; WaitForStart: boolean);
    procedure AgentWaitForIdle;
{$endif AGENT}
    procedure AssistantMessage(const Msg: string);
    procedure AssistantDirectedMessage(FocusArea: TRect; const Msg: string);
    procedure AssistantAction(Action: TAssistantAction);
    procedure AssistantPlay(const Action: string);
    procedure AssistantHide;
  end;
  
...

procedure TFormMain.LoadAgent;
var
  s: string;
begin
  if (FAgent <> nil) then
    exit;

  FAgent := TAgent.Create(Self);
  try
    FAgent.Parent := Self;
    FAgent.Connected := True;
    FAgent.OnRequestStart := AgentOnRequestStart;
    FAgent.OnRequestComplete := AgentOnRequestComplete;
    FAgent.OnClick := AgentOnClick;
    s := 'james.acs';
    if (FileExists(ExtractFilePath(Forms.Application.ExeName)+s)) then
      s := ExtractFilePath(Forms.Application.ExeName)+s;
    FAgent.Characters.Load('James', s);
    FAgentCharacter := FAgent.Characters['James'];
  except
    FAgentCharacter := nil;
    FreeAndNil(FAgent);
  end;
end;

procedure TFormMain.OnShowAgentClick(Sender: TObject);
begin
  LoadAgent;

  if (FAgentCharacter <> nil) and (FAgentCharacter.Visible) then
    FAgentCharacter.Hide(True);
end;

procedure TFormMain.AssistantAction(Action: TAssistantAction);
const
  Actions: array[TAssistantAction] of string = ('Acknowledge', 'Congratulate', 'Confused', 'Decline', 'Pleased');
begin
  if (FAgentCharacter = nil) then
    exit;

  if (not FAgentCharacter.Visible) then
    FAgentCharacter.Show(False);

  FAgentCharacter.Play(Actions[Action]);
end;

procedure TFormMain.AssistantMessage(const Msg: string);
begin
  if (FAgentCharacter = nil) then
    exit;

  if (not FAgentCharacter.Visible) then
    FAgentCharacter.Show(False);
  FAgentCharacter.Speak(Msg, Unassigned);
end;

procedure TFormMain.AssistantPlay(const Action: string);
begin
  if (FAgentCharacter = nil) then
    exit;

  if (not FAgentCharacter.Visible) then
    FAgentCharacter.Show(False);
    
  FAgentCharacter.Play(Action);
end;

procedure TFormMain.AssistantDirectedMessage(FocusArea: TRect; const Msg: string);
begin
  if (FAgentCharacter = nil) then
    exit;

  AgentWaitForRequest(FAgentCharacter.MoveTo(FocusArea.Right, FocusArea.Top - (FAgentCharacter.Height div 2), 1000), False);
  if (not FAgentCharacter.Visible) then
    FAgentCharacter.Show(False);
  AgentWaitForRequest(FAgentCharacter.GestureAt((FocusArea.Left + FocusArea.Right) div 2, (FocusArea.Top + FocusArea.Bottom) div 2), False);
  AssistantMessage(Msg);
end;

procedure TFormMain.AssistantHide;
begin
  if (FAgentCharacter = nil) then
    exit;

  if (FAgentCharacter.Visible) then
    FAgentCharacter.Hide(True);
end;

procedure TFormMain.AgentOnRequestComplete(Sender: TObject; const Request: IDispatch);
begin
  FAgentRequestComplete := Request as IAgentCtlRequest;
  FAgentRequestStart := nil;
end;

procedure TFormMain.AgentOnRequestStart(Sender: TObject; const Request: IDispatch);
begin
  FAgentRequestComplete := nil;
  FAgentRequestStart := Request as IAgentCtlRequest;
end;

procedure TFormMain.AgentWaitForIdle;
begin
  while (FAgentRequestStart <> nil) and
    ((FAgentRequestComplete = nil) or (FAgentRequestStart.ID <> FAgentRequestComplete.ID)) do
    Forms.Application.ProcessMessages;
end;

procedure TFormMain.AgentWaitForRequest(Request: IAgentCtlRequest; WaitForStart: boolean);
begin
  if (WaitForStart) then
  begin
    while (FAgentRequestStart = nil) or (FAgentRequestStart.ID <> Request.ID) do
      Forms.Application.ProcessMessages;
  end else
  begin
    while (FAgentRequestComplete = nil) or (FAgentRequestComplete.ID <> Request.ID) do
      Forms.Application.ProcessMessages;
  end;
end;


procedure TFormMain.OnClose(Sender: TObject);
begin
  if (FAgentCharacter <> nil) then
  begin
    if (FAgentCharacter.Visible) then
    begin
      FAgentCharacter.Play('Wave');
      FAgentCharacter.Speak('Goodbye', Unassigned);
      AgentWaitForRequest(FAgentCharacter.Hide(False), False);
    end;
    FAgentCharacter := nil;
    FAgent.Connected := False;
  end;
end;

Since Microsoft Agent has been deprecated for ages you should use something like DoubleAgent instead. DoubleAgent is drop-in-compatible (i.e. uses the same interfaces and the same API).

http://doubleagent.sourceforge.net/

 

Share this post


Link to post
47 minutes ago, Anders Melander said:

image.png.d4afdc792955297bfd6188f2a195fc9f.png

LMAO :classic_laugh: :classic_biggrin: 🤣  Never thought I would ever see the topic of MSAgent come up again.  It has been so long since Microsoft killed it off (a decade!).  And my earlier efforts to port MSAgent to other platforms was put on hold years ago (I still want to see Merlin flying around on my Android phone and iPad tablet :classic_biggrin:)

47 minutes ago, Anders Melander said:

The Microsoft Agent is a COM server so you don't need a component for that.

Well, you don't NEED a component, but it can certain make things a little easier to work with.  I wrote a full VCL wrapper for MSAgent: http://msagent.lebeausoftware.org, though it was written for C++Builder only at the time, I never got around to porting it to Delphi (I think I started that a long time ago, but I never finished it).

Quote

Just import the type library, create an instance of the TAgent object in code and then manipulate it through the interfaces.

Documentation for the MSAgent interfaces is on MSDN: https://docs.microsoft.com/en-us/windows/win32/lwef/microsoft-agent

 

Microsoft Agent is actually broken up into two APIs - the MSAgent ActiveX Control, and the MSAgent Server Interface.  The Control is primarily meant for scripting environments, whereas the Server Interface is meant for applications.  So make sure you use the Server Interface for a better experience in Delphi.

Edited by Remy Lebeau

Share this post


Link to post

Hi Anders & Remy,

Thank you both for your responses.  Very informative.

I'm afraid things like TAgent, MSAgent ActiveX & MSAgent Server are not things I have any knowledge of.

This 'Clippy' thing is something I am playing with att and if it is appropriate it will be on Win 7 PCs.  Customer refuses to update.

I see the note/reference about Double Agent.  I will have a look.

Are there any limitations/expectations to its use?  I am hoping it will be OS/App agnostic, aside from being Windows based.

 

Regards & Tks again.

Ian

Share this post


Link to post

BTW, it doesn't have to be this 'Clippy' thing, it is the concept of some sort of animated prompt that interests me.

Share this post


Link to post
42 minutes ago, Ian Branch said:

it is the concept of some sort of animated prompt that interests me.

Yes, well it's one of those things that sounds like a great idea - and it's very easy to sell to management and the customer.

Unfortunately once you start to work with it you quickly realize that it's extremely difficult to integrate with the existing application without getting in the way and that there are better/easier/cheaper ways of doing whatever it's purpose is supposed to be. It's not for nothing that users hated the feature and Microsoft quickly abandoned it.

I've implemented it in at least three different applications and it never saw any use beyond the welcome sequence.

 

Share this post


Link to post

Hi Anders,

Thanks for the feedback.  I can certainly see how it would be useful in some sort of training environment.

ATT as I learn about it I have only implemented in its basic form as a novelty thing when closing the App.

Applicability to other areas is still in question.

IIUC it isn't going to work as is under Win 7 so that will be a road block.

I had a look at DoubleAgent but it appears the animations are no longer available.

Anyway, it is still a learning exercise for me, even if it isn't used in the end.

 

Regards,

Ian

Screenshot_3.jpg

Share this post


Link to post
15 hours ago, Ian Branch said:

Hi Team,

I came across this by accident...

http://www.delphiarea.com/products/delphi-packages/assistant

It hasn't been touched in years.

Does anybody know of something similar and more recently supported?

I am using D10.4 att.

 

Regards & TIA,

Ian

Wow, I didn't know these animations broke out of Microsoft tools into the wild. Pretty bold to implement this into Delphi project. People were complaining when Ribbon started appearing in software, I can't imagine what same people would say when a clip, monkey or a butler shows up on a screen and start 'helping' 🙂

 

1 hour ago, Ian Branch said:

I can certainly see how it would be useful in some sort of training environment.

I do customize my software to some extent to what I like, but this is way out there for me - and that's why it's very interesting 🙂

So, I'm very interested in your feedback how it turned out to be, how your users reacted to it. If you want update this thread in a couple of weeks or months, please do.

Share this post


Link to post
3 hours ago, Ian Branch said:

I'm afraid things like TAgent, MSAgent ActiveX & MSAgent Server are not things I have any knowledge of.

Office Assistant was the predecessor to Microsoft Agent.  Assistant started life in Microsoft Office 97, where 'Clippy' was just one of several animated characters you could choose from.  The technology evolved into a standalone API that any application could utilize.  Eventually the old Assistant tech was replaced with the newer MSAgent tech in Microsoft Office 2000.  Though some features of Assistant didn't make it into MSAgent and remained specific to Office, and Office didn't utilize everything that MSAgent offered.

Quote

This 'Clippy' thing is something I am playing with att and if it is appropriate it will be on Win 7 PCs.  Customer refuses to update.

Microsoft completely removed MSAgent from Windows in Win7.  There is a separate install pack for MSAgent that you can download from Microsoft just for Win7,  But from Win8 onwards, MSAgent is dead tech, you can't install it anymore, so if you want to use MSAgent in Win8 onwards then you have to use Double Agent instead.

Quote

Are there any limitations/expectations to its use?

You mean, other than it relying on outdated technology?  Or that creating custom characters for it is a PITA?  Although, at its peak popularity, there were a lot of 3rd party characters you could download for MSAgent.  I'm sure many of those downloads have dried up over the years, but there are quite a few still floating around.

3 hours ago, Ian Branch said:

BTW, it doesn't have to be this 'Clippy' thing, it is the concept of some sort of animated prompt that interests me.

Back in the day, one of the main competitors to MSAgent was Living Actor.  It had a similar concept as MSAgent, but with better graphics (ie, 3D vectored models instead of 2D bitmaps).  It has continued to evolve over the years into something that is completely different than what it started out as.

 

I'm sure there are plenty of other assistent-like alternatives nowadays, if you search around.

Edited by Remy Lebeau

Share this post


Link to post
2 hours ago, Anders Melander said:

I've implemented it in at least three different applications and it never saw any use beyond the welcome sequence.

Same here.  Even though I was a Microsoft MVP for the MSAgent technology, I never actually used it in any of my production applications, only in things like guided tutorials and trade show presentations.

Share this post


Link to post
2 hours ago, Ian Branch said:

I had a look at DoubleAgent but it appears the animations are no longer available.

DoubleAgent uses the same animations as MS Agent did, so you can just use those.

Share this post


Link to post
9 minutes ago, Remy Lebeau said:

I never actually used it in any of my production applications, only in things like guided tutorials and trade show presentations.

@Remy Lebeau May I ask why did you decide not to use in released software, did you have any user feedback on the feature and you decided not to include it, or the feature was never meant to be for released version?

Share this post


Link to post
1 hour ago, Mike Torrettinni said:

@Remy Lebeau May I ask why did you decide not to use in released software

Simple - I never had a need for it in my production software.  Oh sure, the technology was fun to work with, and all.  I used it on my company's website for awhile to help new users navigate around the site, and in demo softwares to guide new users around screens and features, and in slideshows to explain to viewers what was being shown.  But, in the end, it did not serve much practical use otherwise that couldn't be done in other simpler/more efficient ways.

Quote

did you have any user feedback on the feature and you decided not to include it

No.

Quote

the feature was never meant to be for released version?

Microsoft itself used it in some of their released software.  Look at the (negative) feedback they got from that.  Not many people liked it.  Of course, that was not the fault of the technology itself, but in the annoying ways in which Microsoft decided to use it.

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post

Agreed.  Quite interesting.

The consensus thus far for the 'tool' would seem to be it is more of academic value than production.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×