App stays on top after opening Outlook

I just recently added a TAdvDocPanel, TAdvToolBar and TAdvGlowButton to my application's main window.  Now when using the Jedi compenent's JvMail.SendMail with an Outlook client, the email composition window of Outlook shows up behind my application and you cannot bring it forward... my app remains on top.


Prior to adding these components, it worked fine.  Am I missing a setting?

Eric

I checked the AdvToolBar/AdvDockPanel code but could not see a reason for this. This doesn't affect how the form becomes active or the z-index of the form.

Do you trigger the sendmail() from a toolbar control? Do you descend your form from TAdvToolBarForm? Does this happen also when you show another form from the same place where you call sendmail()?

Our main form which descends from TForm and contains your toolbar in a panel, opens a modal print dialog, which in turn opens a modal PDF save dialog if the user chose to print to a PDF.  Once the PDF is created, another modal dialog opens up to view or email the document.  If the user chooses to view it, it opens the associated PDF reader which is usually Acrobat Reader.  This comes forward fine.  If the user choose to email, it opens the default email client via JvMail.Send.  If it is Outlook, the main window of our app suddenly comes to the foreground (even above our PDF completed dialog and our Print Report dialog, all modal) and the Outlook composition dialog stays in the background.  This is also true for Windows Live Mail, so it is not specific to Outlook.  This occurs on Win7 and Win 8.1.  The app is compiled with Delphi 2007.  If our app is full screen, the user is screwed since they are locked out until the composition window is closed since it is opened modal.  When you close the composition window, the next modal windows then comes to the foreground... close that and the next once comes into view until we are back at the main window.

We do not have a component JvMail here.
Can this be reproduced in another way?

JvMail is part of the Jedi Code Library (JCL/JVCL).  I also just tried it with MAPIMail from the free SMComponents from scalabium.com with the same results.  I'll keep playing with it to see if I can duplicate it without using third party components.

FYI, if I use ShellExecute to launch the default email client it works fine, but I believe I can't include an attachment. Note:  I got the following example off of a Google search and didn't change it much:

        mm := 'mailto:someone@somewhere.com'
          + '?subject=This is the subject'
          + '&body=This is line 1' + '%0D%0A'
          + 'This is line 2' + '%0D%0A'
          + 'This is line 3';
        retVal := ShellExecute(vForm.handle, 'open', PChar(mm), nil, nil, SW_SHOWNORMAL);
        if retVal <= 32 then
          MessageDlg('Cannot find program to send e-mail.', mtWarning, [mbOK], 0);

I'll also try to write my own using Delphi's own Mapi unit.  Those other components were free and easy to use, so I went with them years ago.  I see several examples on using the Mapi unit, so I'll give that a try and get back with you on my results.

Here is a function that uses the Mapi unit without a 3rd party component. If you cannot duplicate, I will put a sample program together.


Add the following function to your test program and call it using something like this:
SendMailMAPI('test subject', 'test body', '', '', '', 'Mr Recipient', 'recipient@email.com');


// The following based on an example provided at:
// http://www.delphifaq.com/faq/delphi/network/f236.shtml
function SendMailMAPI(
  const pSubject, pBody, pFileName, pSenderName, pSenderEMail,
  pRecepientName, pRecipientEmail: String) : Integer;
var
  vMapiMessage: TMapiMessage;
  vSenderDesc, vRecipientDesc: TMapiRecipDesc;
  vFileAttach: TMapiFileDesc;
  vMapiSendMail: TFNMapiSendMail;
  vMAPIModule: HModule;
begin
  FillChar(vMapiMessage, SizeOf(vMapiMessage), 0);
  with vMapiMessage do
  begin
    if (pSubject<>'') then
    begin
      lpszSubject := PChar(pSubject)
    end;
    if (pBody<>'') then
    begin
      lpszNoteText := PChar(pBody)
    end;
    if (pSenderEMail<>'') then
    begin
      vSenderDesc.ulRecipClass := MAPI_ORIG;
      if (pSenderName='') then
      begin
        vSenderDesc.lpszName := PChar(pSenderEMail)
      end else
      begin
        vSenderDesc.lpszName := PChar(pSenderName)
      end;
      vSenderDesc.lpszAddress := PChar('SMTP:'+pSenderEMail);
      vSenderDesc.ulReserved := 0;
      vSenderDesc.ulEIDSize := 0;
      vSenderDesc.lpEntryID := nil;
      lpOriginator := @vSenderDesc;
    end;
    if (pRecipientEmail<>'') then
    begin
      vRecipientDesc.ulRecipClass := MAPI_TO;
      if (pRecepientName='') then
      begin
        vRecipientDesc.lpszName := PChar(pRecipientEmail)
      end else
      begin
        vRecipientDesc.lpszName := PChar(pRecepientName)
      end;
      vRecipientDesc.lpszAddress := PChar('SMTP:'+pRecipientEmail);
      vRecipientDesc.ulReserved := 0;
      vRecipientDesc.ulEIDSize := 0;
      vRecipientDesc.lpEntryID := nil;
      nRecipCount := 1;
      lpRecips := @vRecipientDesc;
    end else
    begin
      lpRecips := nil
    end;
    if (pFileName='') then
    begin
      nFileCount := 0;
      lpFiles := nil;
    end else
    begin
      FillChar(vFileAttach, SizeOf(vFileAttach), 0);
      vFileAttach.nPosition := Cardinal($FFFFFFFF);
      vFileAttach.lpszPathName := PChar(pFileName);
      nFileCount := 1;
      lpFiles := @vFileAttach;
    end;
  end;
  vMAPIModule := LoadLibrary(PChar(MAPIDLL));
  if vMAPIModule=0 then
  begin
    Result := -1
  end else
  begin
    try
      @vMapiSendMail := GetProcAddress(vMAPIModule, 'MAPISendMail');
      if @vMapiSendMail<>nil then
      begin
        Result := vMapiSendMail(
          0, Application.Handle, vMapiMessage, MAPI_DIALOG or MAPI_LOGON_UI, 0
        );
      end else
      begin
        Result := 1
      end;
    finally
      FreeLibrary(vMAPIModule);
    end;
  end;
end;

In trying to put together a test program for you, I am not able to duplicate the issue in a test program readily.  Hold off doing anything on this until you hear back from me.

OK Guys.. found the problem.  It falls back on my Splash screen which is brought forward using BringToFront.  Only the splash screen is brought to the front and closes and frees itself once the main form has finished loading.  However, when using your toolbar stuff, it seems that the main program has now taken on that setting somehow.  This was not occurring prior to using your toolbar stuff.


To fix the problem, all I had to do was add a SendToBack on the splash screen's Close event to send itself (the spash screen) to the back prior to being destroyed.

Might be something you want to look into. :)

Is this our TAdvSmoothSplashScreen?

No, home grown from about 8 years ago.  I wouldn't spend too much time on it.  After talking with my support guy about what I found, he says we've had a few customer issues where other dialogs of our own have shown up behind our main app (rare, but does occur, and is recoverable by switching tasks and back again).  Not exactly the same thing but I'm wondering if D2007's handling of BringToFront is flawed in some regards or I have a misunderstanding of its usage, and that your toolbar components simply exposed it in a reproducible way.  We used to use StayOnTop for our splash screen, however if our main app had an error during load, the error msg would show up behind the splash screen, so we moved to BringToFront.  Now that we have your tools, I might look at your TAdvSmoothSplashScreen.

Sigh... I'm getting reports from customers that my "fix" has not completely eliminated the issue.  I'll try to create a reproducible example and get it to you.