Board index » delphi » advanced OLE Automation problem: have OLE function wait for user login

advanced OLE Automation problem: have OLE function wait for user login

I'm having difficulty with an advanced problem involving
OLE Automation.  I've read several hundread pages on COM
in several Delphi books and many USENET posts, and still
haven't found anything that solves my problem.

I'm working on a "report browser" program -- it displays
various pre-generated reports.  The project specifications
require that the report browser prompt for a username and
login when it is started.  The program has a custom form that
prompts the user for login credentials.

In addition to being used as a stand-alone program, the report
browser is also an OLE Automation server with a single method.
The method will take the user to the requested area within the
the report browser.

Here's the problem:

What happens now is that the code in the .DPR file calls a
procedure "Authenticate_User", the procedure shows the login
screen, and then the OLE Automation function proceeds to execute.  
This is not desired.  I would like the OLE Automation function
to wait for the login process to complete before continuing.

I've considered various ways of achieving this.  A couple of
ideas:

  #1  Create a loop in the OLE Automation function that checks
      whether or not the login process is complete every 250ms.
      Something like this:

          while (not (LoginComplete)) do
              Sleep (250);

      The problem with this is that my program is single-threaded.
      The Sleep 250 stops the current thread.  I'd have to kick
      off another thread to execute this code, or else my program
      will lock up in an infinite loop.

  #2  Similar to #1, only use a timer that keeps resetting itself
      until LoginComplete is true.  I think that would work fine
      for a single-threaded application.

  #3  I could modify the "Authenticate_User" function so that
      it is a critical section.  I could then have both the .DPR
      file and the OLE Automation function call the
      "Authenticate_User" function.  The first call would get
      through and display the login screen.  The second call
      would halt at the critical section until the first call
      was complete, and then it would see that LoginComplete
      is set to true, and would just exit the procedure.  
      Something like this:

              EnterCriticalSection (login);
              try
                if (not (LoginComplete) then
                begin
                  frmLogin.ShowModal ();
                  LoginComplete := true;
                end;
              finally
                LeaveCriticalSection (login);
              end;

      However, I think that in order for this to work, I'd have to
      make the program multithreaded.

Does anyone have any suggestions?  Sample code showing how to do
this would be exteremely appreciated.

Thanks in advance,

Scott A. Miller

 

Re:advanced OLE Automation problem: have OLE function wait for user login


This could be a super easy solution to an easy problem. The following code
should work...
Handy note: avoid using timers... 99% of the times (like here) they are just
redundant and there's a better implementation.

I used Mutexes in an other app that had the same problems yours had...
Basically I had mutexes created/released to do the same thing the Logged var
does here...
You can try this or read more about mutexes and use them instead...

------------------dpr file...

program XYZ; // I assume you created an EXE

uses LoginLib;

begin
  ValidateUser;
  [.. stuff put by Delphi]
end;

------------------implementation unit of your COM object...

[..]
uses LoginLib;

procedure MyFunction;
begin
   while not Logged do Application.ProcessMessages;
   [other stuff]...
end;

------------------And LoginLib
var Logged : boolean;

implemenatation

procedure ValidateUser;
begin
  Logge := FALSE;
  Display form and wait for use input...
  Set Logged to TRUE if succesful...
end;

initialization
  Logged := FALSE:
end;

"Scott A. Miller" <smil...@legis.state.ia.us> wrote in message
news:38F7474E.C36F41F3@legis.state.ia.us...

Quote

> I'm having difficulty with an advanced problem involving
> OLE Automation.  I've read several hundread pages on COM
> in several Delphi books and many USENET posts, and still
> haven't found anything that solves my problem.

> I'm working on a "report browser" program -- it displays
> various pre-generated reports.  The project specifications
> require that the report browser prompt for a username and
> login when it is started.  The program has a custom form that
> prompts the user for login credentials.

> In addition to being used as a stand-alone program, the report
> browser is also an OLE Automation server with a single method.
> The method will take the user to the requested area within the
> the report browser.

> Here's the problem:

> What happens now is that the code in the .DPR file calls a
> procedure "Authenticate_User", the procedure shows the login
> screen, and then the OLE Automation function proceeds to execute.
> This is not desired.  I would like the OLE Automation function
> to wait for the login process to complete before continuing.

> I've considered various ways of achieving this.  A couple of
> ideas:

>   #1  Create a loop in the OLE Automation function that checks
>       whether or not the login process is complete every 250ms.
>       Something like this:

>           while (not (LoginComplete)) do
>               Sleep (250);

>       The problem with this is that my program is single-threaded.
>       The Sleep 250 stops the current thread.  I'd have to kick
>       off another thread to execute this code, or else my program
>       will lock up in an infinite loop.

>   #2  Similar to #1, only use a timer that keeps resetting itself
>       until LoginComplete is true.  I think that would work fine
>       for a single-threaded application.

>   #3  I could modify the "Authenticate_User" function so that
>       it is a critical section.  I could then have both the .DPR
>       file and the OLE Automation function call the
>       "Authenticate_User" function.  The first call would get
>       through and display the login screen.  The second call
>       would halt at the critical section until the first call
>       was complete, and then it would see that LoginComplete
>       is set to true, and would just exit the procedure.
>       Something like this:

>               EnterCriticalSection (login);
>               try
>                 if (not (LoginComplete) then
>                 begin
>                   frmLogin.ShowModal ();
>                   LoginComplete := true;
>                 end;
>               finally
>                 LeaveCriticalSection (login);
>               end;

>       However, I think that in order for this to work, I'd have to
>       make the program multithreaded.

> Does anyone have any suggestions?  Sample code showing how to do
> this would be exteremely appreciated.

> Thanks in advance,

> Scott A. Miller

Re:advanced OLE Automation problem: have OLE function wait for user login


Quote
Alessandro Federici wrote:

> This could be a super easy solution to an easy problem. The following code
> should work...
[...]
> procedure MyFunction;
> begin
>    while not Logged do Application.ProcessMessages;
>    [other stuff]...
> end;

Thanks for the suggestion, Alessandro!  It's very simple and works
great.  I'll confess that I'd never heard of Application.ProcessMessages
before.  The one downside is that the application is busy waiting for
the
user to type in a user name/password.  (I quickly verified that with
System
Monitor -- CPU usage is at 100% until the password is verified.)

After trying your suggestion and having success, I decided also to
implement my idea of using a timer.  The code I wrote for using a
timer was quite a bit more complicated.  Also, I realized that the
code I wrote would work fine for my "serial" COM server, but would
not work for a parallel COM server.  The advantage of using a Timer
is that the the CPU usage is almost 0 while waiting for the user
to login.

In the end, I think I'll use your suggestion as reliability and
maintainability are a higher priority for my application than raw
performance.

Scott A. Miller

Other Threads