Create a new message in Outlook and display as a modal
I need to create and send a message with Outlook from an application. The email form should appear modal, mainly because I am creating an attachment, and should be removed when the user sends (or drops) an email.
My problem is that I am making Outlook a modal modal ("MailIt.Display (True)"), the Outlook message box displayed in the background. The "Outlook.ActiveWindow.Activate" command brings it to the front, but it can be called when the windows are already visible, and so I cannot name it if the window is modal. I tried this code:
MailIt.Display(False);
OleVariant(Outlook.ActiveWindow).Activate;
MailIt.Display(True);
But the id doesn't work, if the form already displays it normally, it can't be switched to modal. Any ideas? My environment: Windows 8 (UAC disabled), XE3, Outlook 2010.
Just tried to send my form to the background as suggested by Arioch:
SetWindowPos(AWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
MailIt.Display(AModal);
SetForegroundWindow(AWnd);
In this case Outlook became front-end (as I need it), but mine from may become invisible (if there are other applications running with forms open), so it doesn't solve the problem either. It should be Outlook in modal state on top and my app is next to Outlook.
SetWindowPos(AWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE)
Better then HWND_BOTTOM, but Outlook is not guaranteed to be prioritized.
EDITED2. Final (hopefully) event based solution (suggestion from Kobik):
uses
Vcl.OleServer, Winapi.ActiveX;
Type
TOutlookMsgForm = class
private
protected
FOutlook: OutlookApplication;
FMessageSent: Boolean;
procedure OnOpen(ASender: TObject; var Cancel: WordBool);
procedure OnSend(ASender: TObject; var Cancel: WordBool);
function TryDisplayOutlookMail(const AMailTo, ASubject, ABody: string;
const AAttachmentFileNames: array of string; AWnd: HWND; AModal: Boolean): boolean;
property Outlook: OutlookApplication read FOutlook write FOutlook;
property MessageSent: Boolean read FMessageSent write FMessageSent;
public
class function DisplayOutlookMail(const AMailTo, ASubject, ABody: string;
const AAttachmentFileNames: array of string; AWnd: HWND; AModal: Boolean = True): boolean; static;
end;
{ TOutlookMsgForm }
procedure TOutlookMsgForm.OnOpen(ASender: TObject; var Cancel: WordBool);
begin
if (Outlook<>nil) and (Outlook.ActiveWindow<>nil) then
OleVariant(Outlook.ActiveWindow).Activate;
end;
procedure TOutlookMsgForm.OnSend(ASender: TObject; var Cancel: WordBool);
begin
Cancel := False;
MessageSent := True;
end;
function TOutlookMsgForm.TryDisplayOutlookMail(const AMailTo, ASubject, ABody: string;
const AAttachmentFileNames: array of string; AWnd: HWND; AModal: Boolean): boolean;
var
MailIt: MailItem;
Mail: TMailItem;
i: Integer;
begin
MessageSent := False;
try
OleInitialize(nil);
try
Outlook := CoOutlookApplication.Create;
Mail := nil;
try
MailIt := Outlook.CreateItem(olMailItem) as MailItem;
MailIt.To_ := AMailTo;
MailIt.Subject := ASubject;
MailIt.Body := ABody;
for i := Low(AAttachmentFileNames) to High(AAttachmentFileNames) do
MailIt.Attachments.Add(AAttachmentFileNames[i], EmptyParam, EmptyParam, EmptyParam);
Mail := TMailItem.Create(nil);
Mail.ConnectTo(MailIt);
Mail.OnOpen := OnOpen;
Mail.OnSend := OnSend;
MailIt.Display(AModal);
if AModal and (AWnd<>0) then
SetForegroundWindow(AWnd);
Result := true;
finally
FreeandNil(Mail);
MailIt := nil;
Outlook := nil;
end;
finally
OleUnInitialize;
end;
except
Result := False;
end;
end;
Therefore, it is solved (try # 3). Thank!
source to share