views:

201

answers:

1

I have created a custom action for my setup project and have successfully implemented a form that displays a progress bar for a download step in my install (I'm using a WebClient in my custom action code). So I have two questions that relate to each other.

  1. Is there any way to show a download progress bar in the main setup window rather than creating a separate form that I display as I have done? I would prefer this.

  2. If not, then what can I do to cause my form to display in front of the actual setup window when I call form.ShowDialog()? I've also called BringToFront() on it which doesn't work either. It's there, but it's always behind the main setup window. Seems there has to be some way to get the correct z-order.

Thanks for your help.

A: 

So I gave up on the idea of integrating the progress bar into the actual installer screen, but it's just plain ridiculous what it takes to get the Windows Form to display on top. I have to get a handle to the installer Window and send it to the background because bringing the progress bar window forward simply won't work. I've moved to Mac development now so coming back to this is just frustrating. I remember thinking C# .NET was pretty cool. It's got NOTHING on Cocoa/Objective-C.

It's infuriating having a method called BringToFront() that simply ignores you. Why do I have to drop down to Windows API code to do something as fundamental to a GUI as managing the the Z-Order? Z-Order? Seriously?

In case you're wondering, here's what I ended up doing (via google):

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern bool SetWindowPos(
      IntPtr hWnd, // window handle
      IntPtr hWndInsertAfter, // placement-order handle
      int X, // horizontal position
      int Y, // vertical position
      int cx, // width
      int cy, // height
      uint uFlags); // window positioning flags

public const uint SWP_NOSIZE = 0x1;
public const uint SWP_NOMOVE = 0x2;
public const uint SWP_SHOWWINDOW = 0x40;
public const uint SWP_NOACTIVATE = 0x10;

[DllImport("user32.dll", EntryPoint = "GetWindow")]
public static extern IntPtr GetWindow(
      IntPtr hWnd,
      uint wCmd);

public const uint GW_HWNDFIRST = 0;
public const uint GW_HWNDLAST = 1;
public const uint GW_HWNDNEXT = 2;
public const uint GW_HWNDPREV = 3;

public static void ControlSendToBack(IntPtr control)
{
    bool s = SetWindowPos(
          control,
          GetWindow(control, GW_HWNDLAST),
          0, 0, 0, 0,
          SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}

I get a handle to the installer window and then call ControlSendToBack() on it. It works, but it sends it to the very back. I tried another method that would just send it back one position, but this wouldn't work either. Windows programming--as good as it was in 1995. Cool.

Matt Long