Try something along the following lines (not fully tested)
...
I just want to say how very grateful I am to you for your suggestion.
I wrote an Outlook macro which uses a Form but the user needs to browse while the Form is up so it has to be modeless. If the user clicks the bottom right hand corner of the screen to bring up the Desktop window, the Form disappears permanently, which is very frustrating. When you re-activate Outlook it does not display the Form.
I used your solution but had a further difficulty in establishing the handle of the window. Neither FindWindow nor a more complex process using EnumWindow (refer
https://www.everythingaccess.com/tu...external-application-window-to-the-foreground) would return it. I suspect it may be due to the fact that a Form's class is generated (even though I omitted the Class parameter with 0& in the FindWindow call).
In the end I discovered I can just get the active window handle.
As the loss of modeless forms on going to desktop should be a common problem but I struggled to find anything on it, I'm returning the favour by including the summary below of what I learned on my journey. I hope this helps others as you have helped me. (Please forgive any bad code or descriptions, I am a 'noob' in VBA.
)
Option Explicit
' Windows API Constant index to owner of window (incorrectly named as parent)
Private Const GWL_HWNDPARENT = -8
' Windows API Function to retrieve handle of active window.
' (Note using FindWindow or EnumWindows doesn't work -
' perhaps it's because a Form gets a generated class.
' Certainly the title of the window really is "Create Workflow", but it doesn't get found, even if you omit the Class parameter)
Private Declare Function GetActiveWindow Lib "USER32" () As Long
' Windows API Function to modify window attribute using window handle. (Needs to be defined differently for different versions, hence the Win64 compile constant.)
' Here used to change owner of Form to Desktop.
' Without this, when you click in the bottom right hand corner to see the Desktop, it brings the Desktop window to top, and of course Outlook and the Form window disappear.
' But when you re-activate to Outlook, Outlook doesn't know anything about the Form window!! Not does it appear in the Alt-Tab window list because Desktop is not an owner.
' Making Desktop the owner means that the Form appears in the Alt-Tab list.
' Note this is not recommended practice, but I can't find a better way.
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
#Else
Private Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub WorkflowCreate()
'
' eMail bits
Dim olApp As Outlook.Application
Dim CurrItem As Object
Dim Email As MailItem
Dim SubjectEd, Ellipsis As String
Dim EmailSaved As Boolean
Dim hWnd As LongPtr
' Use the current email for information such as workflow title
Set olApp = Outlook.Application ' (Try With instead sometime)
On Error Resume Next
Select Case TypeName(olApp.ActiveWindow)
Case "Explorer" ' we are currently viewing Outlook main window
Set CurrItem = olApp.ActiveExplorer.Selection.Item(1)
Case "Inspector" ' we are currently viewing opened item window
Set CurrItem = olApp.ActiveInspector.CurrentItem
End Select
On Error GoTo 0
' Check if it is an email and save it
If Not CurrItem Is Nothing Then
If TypeOf CurrItem Is MailItem Then
Set Email = CurrItem
On Error GoTo Cont
Email.Subject = Replace(Email.Subject, "[Jira10]", "")
SubjectEd = Left(Email.Subject, 150)
If SubjectEd <> Email.Subject Then
Ellipsis = "..."
End If
SubjectEd = Replace(SubjectEd, ":", "")
SubjectEd = Replace(SubjectEd, "\", "-")
SubjectEd = Replace(SubjectEd, "/", "-")
SubjectEd = Replace(SubjectEd, ">", "-")
SubjectEd = Replace(SubjectEd, "<", "-")
SubjectEd = Replace(SubjectEd, "|", "-")
SubjectEd = Replace(SubjectEd, "?", "")
SubjectEd = Replace(SubjectEd, "*", "-")
SubjectEd = Replace(SubjectEd, """", "'")
SubjectEd = Replace(SubjectEd, "[", "")
SubjectEd = Replace(SubjectEd, "]", "")
SubjectEd = Replace(SubjectEd, "(", "")
SubjectEd = Replace(SubjectEd, ")", "")
SubjectEd = Trim(SubjectEd)
If MsgBox("Save email with subject " & SubjectEd & Ellipsis & "?", vbYesNo, "Create Workflow") = 6 Then
Email.SaveAs "H:\jpmDesk\Desktop\Temp\" & SubjectEd & ".msg", olMSG
EmailSaved = True
End If
Set Email = Nothing
Cont:
End If
End If
' Show the user the form - it will generate the email if they click OK
' Note
' To allow the user to browse Outlook during filling out the Form, it needs to be Modeless which means this sub continues and finishes.
' This means that the simplest approach is the form has to create the email as it knows when OK is clicked
Dim Form As WorkflowForm
Set Form = New WorkflowForm
If SubjectEd <> "" Then
Form.WorkflowTitle = SubjectEd
Else
Form.WorkflowTitle = "enter a title..."
End If
If Not EmailSaved Then
Form.AddlInfo = "None"
End If
Form.Show 'vbModeless commented out as form is now defined as ShowModal=False
' Give the Desktop ownership of the Form so it shows up in Alt-Tab
' (Note Outlook will still manage the life of the Form)
hWnd = GetActiveWindow()
SetWindowLongPtr hWnd, GWL_HWNDPARENT, 0& ' 0& = DesktopWindow
Set Form = Nothing
Set olApp = Nothing
End Sub ' WorkflowCreate