How to detect if outlook is really running

  • Thread starter Thread starter David
  • Start date Start date
D

David

Hello,
I am trying to gracefully manage intercation with outllook2003 via VB6.

I am using this to detect if outlook is loaded:
On Error Resume Next
Set myOlApp = GetObject("", "Outlook.Application")
If Err.Number <> 0 Then
MsgBox "oops, Outlook not running."
...

But outlook might be loaded but not operational for queries I have later.
The reason is that the user needs to complete password selecting connect
mode, offline mode. Only then outlook is ready for further iqueries (I want
to check the appointments).

In case that the user hit cancel or password is incorrect then i get funny
dialog box from the OS to retry, resume that can lead to hang or crush of my
VB app.

How can i make sure that outlook is:
1. loaded
2. ready for further "discussion"
If outlook is not ready (as defined above) i want to provide a message to
user to properly complete launch outlook.

Thanks
David
 
After you get your Outlook object check for any Explorers.

If myOlApp.Explorers.Count >= 1 Then
'Outlook is initialized
 
Thanks but this is not working.
Let me try to explain what do I mean:

I launch outlook and i get a dialogbox: connect work offline cancel.
At this stage outlook is running and probably at least one explorer is there
as well.

so the solution you suggested is not good and i still move forward assumin
outlook is ready and then i get this error message: "Component Request
Pending" "This action cannot be completed because other application is busy.
Choose 'Switch to' to activate the busy application and correct the problem"
switch to, Retry buttons.

So i need a better detection mechanism to know outlook is really running.

thanks
David
 
Thanks.
That wont do it as I know for sure outlook is loaded hence its process will
be there but I need to know that the user passed the dialog boxes like
password or connect/offline.

David
 
Hi David,

with some API you can check if the Dialog is still displaying. In German
the Caption of the Dialog is "Profil auswählen" - please replace the
String for your Environment.

Private Declare Function GetWindow Lib "user32" (ByVal hWnd _
As Long, ByVal wCmd As Long) As Long
Private Declare Function GetDesktopWindowA Lib "user32" Alias
"GetDesktopWindow" () As Long
Private Declare Function GetWindowTextA Lib "user32" (ByVal hWnd As
Long, ByVal lpString As String, ByVal cch As Long) As Long

Public Function UserPassedDialogBox() as Boolean
UserPassedDialogBox= not (FindChildWindowText(GetDesktopWindow,
"Profil auswählen") )
End Sub

Private Function FindChildWindowText(ByVal lHwnd As Long, _
ByRef sFind As String _
) As Long
Dim lRes As Long
Const STR_AST As String = "*"
Dim sFindLC As String

lRes = GetWindow(lHwnd, GW_CHILD)
If lRes Then
sFindLC = LCase$(sFind)
Select Case InStr(sFindLC, STR_AST)
Case Is > 0
Do
If LCase$(GetWindowText(lRes)) Like sFindLC Then
FindChildWindowText = lRes
Exit Function
End If
lRes = GetWindow(lRes, GW_HWNDNEXT)
Loop While lRes <> 0

Case Else
Do
If LCase$(GetWindowText(lRes)) = sFindLC Then
FindChildWindowText = lRes
Exit Function
End If
lRes = GetWindow(lRes, GW_HWNDNEXT)
Loop While lRes <> 0
End Select
End If
End Function

Private Function GetWindowText(ByVal lHwnd As Long) As String
Const CN_SIZE As Long = 256
Dim sBuffer As String * CN_SIZE
Dim lSize As Long

sBuffer = String$(CN_SIZE, vbNullChar)
lSize = GetWindowTextA(lHwnd, sBuffer, CN_SIZE)
If lSize > 0 Then
GetWindowText = Left$(sBuffer, lSize)
End If
End Function
 
At the time you get that login message to work online or whatever there are
no Explorers. They are added after you address that prompt.
 
According to what i observed there is one explorer (you actually see it) and
the code detects it and fails to determine that we did not pass this point.
hence the solution does not work.

Michael's solution should work but is not elegant and wont hold for usage in
another localized os/office.

Your soultion seemed the best way to do it but it does not work. I hope it
is my mistake.


David
 
Hi Ken,

I have tested with OL 2000: if I use GetObject and the Profile Dialog is
showing, then there is an Explorer already.
 
Hi David,
Michael's solution should work but is not elegant and wont hold for usage in
another localized os/office.

In different localization you need to translate - like all your Buttons
and Messages. Where is the problem?

Another, more elegant way: call Application.Session.Logon , , False,
False

If the Profile Dialog is still showing, then the call will throw an
Error immediately.
 
Michael,
thanks a lot for following up on this. You are doing a good service to this
newsgroup.

You say: call Application.Session.Logon , , False, False

Can you explain more?

how do you use this in this sequence?

On Error Resume Next
Set myOlApp = GetObject("", "Outlook.Application")
If Err.Number <> 0 Then
MsgBox "oops, Outlook not running."

David
 
Yes, you're correct, I misspoke. An Explorer is present at that time.

I suppose the best way to handle it would be using the Win32 API's and
looking at which windows are present. If that dialog's window is around then
Outlook is looking for a response. You can use a tool such as Spy++ from
Visual Studio to see which windows are showing under the Outlook application
object.

The Outlook process is named "outlook.exe" and a window that's only present
when an Explorer is present is "tooltips_class32". Using that information
you can use Spy++ to see which window is that connect method dialog. Then in
code you could call EnumProcesses and FindWindow to see what's around. An
alternative would be looking for a top level window with a class of
"mspim_wnd32" and a title of "Microsoft Outlook". That seems to be there
whether Outlook has a UI or not.
 
Hi David,
thanks a lot for following up on this. You are doing a good service to this
newsgroup.

thanks, but I´m very new here and the praise should be for Ken among
others.
how do you use this in this sequence?

On Error Resume Next
Set myOlApp = GetObject("", "Outlook.Application")
If Err.Number <> 0 Then
MsgBox "oops, Outlook not running."
Else
myOlApp.Session.Logon , , False, False
If Err.Number <> 0 Then
MsgBox "oops, Outlook is running but still not ready."
End If

You also will get an Error but don´t have to wait for it :-)

BTW: Generally you should use GetObject without "" for the first
Argument if you like to get a running Instance. In case of Outlook this
doesn´t matter, but in case of Word e.g. this would result in two
running EXEs.
 
Back
Top