Wednesday, June 6, 2007

Programmatically Minimize an Application in .NET CF 2.0

I once made a solution that runs on full screen. The solution was written completely in managed code (except for the CE Setup and other small stuff..). Since I took over the screen completely, I don't have access to the (X) button in the upper right corner of the screen. I wanted the application running at all times, but I also wanted the user to be able to get in and out of the application. Since the user won't be able to access the Start button, I added a "Close" button to my application. This "Close" button won't exit the application, instead it will just Minimize the application.

In the .NET Compact Framework 2.0, you can't just set the form's WindowState to WindowState.Minimized since the WindowState enum only contains Normal and Maximized. Currently, the only way you can programmatically minimize an application is by doing a P/Invoke to ShowWindow and passing SW_MINIMIZE to specify how the window will be displayed. It is also required that your Form has the Taskbar visible, this is done by setting the following properties:

  FormBorderStyle = FormBorderStyle.FixedDialog;
  WindowState = FormWindowState.Normal;
  ControlBox = true;
  MinimizeBox = true;
  MaximizeBox = true;

Here's a small code snippet of how to minimize your application

[DllImport("coredll.dll")]
static extern int ShowWindow(IntPtr hWnd, int nCmdShow);

const int SW_MINIMIZED = 6;

void Minimize() {
  // The Taskbar must be enabled to be able to do a Smart Minimize
  this.FormBorderStyle = FormBorderStyle.FixedDialog;
  this.WindowState = FormWindowState.Normal;
  this.ControlBox = true;
  this.MinimizeBox = true;
  this.MaximizeBox = true;

  // Since there is no WindowState.Minimize, we have to P/Invoke ShowWindow
  ShowWindow(this.Handle, SW_MINIMIZED);
}

24 comments:

  1. You can just Form.Hide() instead of P/Invoking ShowWindow.

    --Neil

    Neil Cowburn
    Principal Partner
    OpenNETCF Consulting, LLC

    ReplyDelete
  2. The application won't be visible in the Memory - Running Programs if you call Hide()

    ReplyDelete
  3. Ah, right. You didn't state that in your requirements :)

    Anyways, whether it is listed in Running Programs or not is a moot point. The CF CLR does a mutex check when loading an app. If an instance is already running, the app loader brings the running instance to the foreground.

    ReplyDelete
  4. Yeah, I guess it was my fault that I didn't state the requirements so well. Maybe I should rename the title of this entry to "Programmatically Smart Minimize an Application in .NET CF 2.0".

    Anyway, it's actually quite interesting how the application behaves if Form.Hide() was called on the main form. In my experience, I could never get the application back to the foreground, even when I try to re-launch the application. And I couldn't really find it in 'Memory - Running programs' to terminate it. I was just stuck with a heavy .NETCF application running in the background.

    So what I do instead is to call ShowWindow() to smart minimize my application, and for bring it back up I handle the Activated event where I set the WindowState to Maximized.

    ReplyDelete
  5. I have the same situation... and your solution is working perfect for me :)

    Gerardo

    ReplyDelete
  6. perfect code snippet! Thanx!

    ReplyDelete
  7. Perfect solution, works great!
    I was just fighting with correct behaviour od Running Programs with multiple maximized forms... and that was just what I needed! Thanks a lot!

    ReplyDelete
  8. its working fine... good solution to run application in backgroung .

    ReplyDelete
  9. Thanks, great codesnippet. Now my app "minimizes" automatically on a timer if no user input for 2s. Great for an interactive popup...
    //Gunnar

    ReplyDelete
  10. Anyone know how to start an app. minimised on Windows Mobile?

    ReplyDelete
  11. Use this ShowWindow function with value 6 in InitializeComponent function and the application will start minimized..

    ReplyDelete
  12. Doesn't work in initcomponent.

    ReplyDelete
  13. Hi,

    This code works perfectly. It also works with:

    this.FormBorderStyle = FormBorderStyle.None;

    At least in Windows Mobile 6.1 VGA.

    By the way, though my application appears in the list of minimized application, it has no icon, only its name. Can anyone tell me how to get an icon in there?

    Thanks!

    ReplyDelete
  14. Hi,

    To start minimized app I use a timer and set the tick event to use this Minimize function. Set the timer interval to 1000.
    Enable timer in form_load and disable in tick event after Minimize.

    To minimize to a tray icon use TrayIcon.cs class

    ReplyDelete
  15. Nice code. Till now what i found, there is no other way to programmatically minimize the application. this is the only way i can say.

    I have one question:
    During installation of the application I have registered it to launch at device boot time. My question, is there any way to get any notification that the app is launched by User or it is auto launched (i.e. Device boot time)?

    Thanks
    Sital

    ReplyDelete
  16. Thanks this was very helpfull

    ReplyDelete
  17. Hi all,

    All nice code. I have another challenge:
    I want to use the Form.Hide() method (triggered by an Deactivate event) since it really hides the form so the app can not be closed from the memory or task manager. You probably guessed its behaving like a service :-). I have some code that puts an icon in the task tray and when tapped, it brings back up the form (Form.Show()). This all works fine.

    However, I can't find/think of any code that Show()'s the form after relaunching it from the Start > Programs menu. Does anyone have any idea? Trying mutex detection didn't work, so I think that NetCF already has a mutex check done before I get to it in the Main() method in program.cs.

    Thanks
    Arjen

    ReplyDelete
  18. Hi Arjen,

    I had the same issue as yours and that is why I used P/Invoke ShowWindow() to minimize the form, you can use ShowWindow() with a different parameter to show the form.

    Hide() and Show() sets the visibility of the window, If you Hide() a window then it won't appear in the running tasks

    ReplyDelete
  19. i have similar kind of requirement for windows mobile 6 application. can you help me?

    ReplyDelete
  20. This works perfect.
    I tried to maximize the form using a phisical button like UP.

    Is it possible?

    Thanks.

    ReplyDelete
  21. Great solution, thanks.
    But, would somebody be so kind and tell me how can I get back form minimized by this way?

    Thaks in advance.

    ReplyDelete
  22. Since you can't run multiple instances of the same app in Windows Mobile you can just start the program like you would normally do and it would be restored or you can resume it through the phones task manager (Control Panel - Memory - Running Programs)

    ReplyDelete
  23. Thank you very much!!!

    ReplyDelete
  24. True to a degree, but I think this is a great conversation starter! We use graphics like this and another related to Bloom's and apps in a workshop we lead.Cell Phone Tracking App Reviews

    ReplyDelete