PDA

View Full Version : Bring CA Managed DLL Dialog to Front



destek
11-08-2010, 05:43 PM
I have a dialog I wrote in a managed DLL custom action. Unfortunately it always appears behind any windows that are on the desktop.
Does anyone have any suggestions on how to force the dialog to the front.
I am Using VB.NET in VS2008.
I have tried me.focus and me.topmost=true, but neither appear to do anything.
This is a 64-bit installer (x64:1033) for Windows 7.

Des

destek
11-09-2010, 05:00 PM
well - I've raised an issue with IS support on this. I checked the knowledge base and while I did find lots of questions about this issue - there were no real answers - so it seems to be a vexing problem with Vista and Windows 7.
This issue does NOT appear to affect Windows XP - ONLY Windows 7 at this time.
Indeed almost any dialogs you create in a custom action will pop up behind other windows on the desktop - not just InstallShield wizard windows - but any other windows that were there before you started the installer.
If Flexera support comes back with a workaround or fix I will let this forum know what they said.

Thanks!

destek
12-01-2010, 07:19 AM
OK - it took Flexera 3 weeks to get back to me - said they have had a "high volume of incidents" ...

The support answer was not correct - but got me into the ballpark.

As it turns out it is a problem with .net code. They suggested I look at the getforegroundwindow api, but I did not need to know who the foreground window is (I really don't care) - I just needed to force the window in my managed (vb.net) custom action DLL to the foreground. Remember, I tried using the native .net calls me.setfocus and me.topmost - neither of which worked when run as a custom action from InstallShield. The dialog window would always pop-up behind the InstallShield wizard as well as most any other window that was open on the desktop. This only happens on Windows 7 systems (XP was just fine).

As it turns out the Win32 API SetForegroundWindow is what does work. Using that API to force my dialog window to the foreground did what .setfocus failed to do. In order to use this API you must PInvoke it properly:



<DllImport("user32.dll")> _
Private Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function


Then calling the code is pretty much a snap...




Friend Sub BringMeForward(ByVal hWnd As IntPtr)

Dim bSet As Boolean = SetForegroundWindow(hWnd)

End Sub



I call BringMeForward with the window handle of my dialog form in the form_shown sub



Private Sub MyForm_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
Dim hWnd As IntPtr = Me.Handle
If IsNothing(hWnd) = False Then
BringMeForward(hWnd)
Else
MsgBox("No Window Handle!")
End If

End Sub


This puts the form in the foreground and gives it input focus.