Search code examples
c#winformscompact-framework.net-1.1pocketpc

Start Bar Shows Up Over Maximized Form (Pocket PC 2003)


Environment

  • Windows XP SP3 x32
  • Visual Studio 2005 Standard
  • Windows Mobile/Pocket PC 2003
  • .NET Compact Framework 1.0 SP3 and .NET Framework 1.1
  • Honeywell Dolphin 9500 Handheld Barcode Scanner

Goal

I have a three form application and an external class (Program.cs) that has the application entry point, Main(). The main form loads first and then, from within MainForm_Load(...), instantiates/shows a new form kind of like a splash screen. I want all three forms to be maximized. All three forms have the following properties set:

  • this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
  • this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
  • this.ControlBox = false;

Problem

The "splash screen" form shows up full screen without any issue. I then dispose of it and show the main screen (first to load and the param for Application.Run();. From the main screen, once a list box SelectedIndexChanged event is detected, a third form is shown (leaving the main form behind said third form). That third form shows the task bar over the top portion of my form: image here Upon closing this form, the main form now has the task bar overlayed as well.

Code

Friend paste links. Let me know if I should just post the code here. WorkOrderView is over a thousand lines so I figured this would be easier.

Unrelated Suggestions

I am quite a green programmer and I especially lack experience in this environment. So, if you have any suggestions/criticisms on the way I'm doing some things, don't hesitate to hit me with them. Probably best to just comment on the post instead of posting an answer for those types of replies.

Thanks!


Solution

  • First off, I only run Windows Mobile 5 (WM5) these days. (I got to move up from PocketPC 2003 a couple of years ago. LOL)

    I've found that defining a Form's Window Size does not work well on mobile devices, and that showing/hiding multiple forms is awkward and never behaves the way you want.

    Still, make sure your Main Form has it's WindowState set to Maximized.

    I also set ControlBox and MinimizeBox to False, if that helps.

    Instead of using multiple forms, it will look much nicer if you simply use Panels as your forms with the Main Form as some kind of MDI container (bad choice of words, but that is what I'm doing).

    In my Designer View, each panel is just a small box full of controls.

    • To work with each panel, select it in the Visual Studio designer, and you will see a position box (arrows up & down and left & right).
    • Right-Click the position box and click Bring to Front.
    • Now go over to the panel control's Properties and set Dock to Fill.
    • While this panel is full screen, add all of your buttons, textboxes, etc. with appropriate names. Names like pnl1_button1 and pnl2_button1 are easier to understand in your code than the VS default button1 and button2.
    • When you are through with your design view of this panel, go back to the Dock properties and set it back to None.
    • Go on to the next panel control.

    I have found it also helps to maintain a small sketch of your panels with their names and the names of their controls.

    In the Load event of your main form, set every Panel's Dock property to DockStyle.Fill. Then, as you want to show one form, simply call Panel1.BringToFront() instead of dialog.Show().

    Mobile development isn't hard, but it is different. :)

    EDIT:

    In the project's Program.cs file, I keep the following static tools that I can use to turn ON and OFF the Start Menu (doesn't work so well in WM5, but I've still got it in my code from my PocketPC version).

    I have not had to open this project in a year or so, but it should all be valid. Give them a try. If I've left something out, just let me know.

    Once this is pasted into your project's Program.cs file, just call Program.ShowWindowsMenu(false); when your program starts and Program.ShowWindowsMenu(true); when your program exits.

    static IntPtr _taskBar;
    static IntPtr _sipButton;
    
    public enum Notify_Events {
      NOTIFICATION_EVENT_NONE = 0,
      NOTIFICATION_EVENT_TIME_CHANGE = 1,
      NOTIFICATION_EVENT_SYNC_END = 2,
      NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
      NOTIFICATION_EVENT_RS232_DETECTED = 9,
      NOTIFICATION_EVENT_RESTORE_END = 10,
      NOTIFICATION_EVENT_WAKEUP = 11,
      NOTIFICATION_EVENT_TZ_CHANGE = 12,
      NOTIFICATION_EVENT_OFF_AC_POWER,
      NOTIFICATION_EVENT_ON_AC_POWER
    }
    
    public enum WindowPosition {
      SWP_HIDEWINDOW = 0x0080,
      SWP_SHOWWINDOW = 0x0040
    }
    
    [DllImport("coredll.dll", EntryPoint = "FindWindowW", SetLastError = true)]
    public static extern IntPtr FindWindowCE(string lpClassName, string lpWindowName);
    
    [DllImport("coredll.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
    
    static void ShowWindowsMenu(bool enable) {
      try {
        if (enable) {
          if (_taskBar != IntPtr.Zero) {
            SetWindowPos(_taskBar, IntPtr.Zero, 0, 0, 240, 26, (int)WindowPosition.SWP_SHOWWINDOW); // display the start bar
          }
        } else {
          _taskBar = FindWindowCE("HHTaskBar", null); // Find the handle to the Start Bar
          if (_taskBar != IntPtr.Zero) { // If the handle is found then hide the start bar
            SetWindowPos(_taskBar, IntPtr.Zero, 0, 0, 0, 0, (int)WindowPosition.SWP_HIDEWINDOW); // Hide the start bar
          }
        }
      } catch (Exception err) {
        ErrorWrapper(enable ? "Show Start" : "Hide Start", err);
      }
      try {
        if (enable) {
          if (_sipButton != IntPtr.Zero) { // If the handle is found then hide the start bar
            SetWindowPos(_sipButton, IntPtr.Zero, 0, 0, 240, 26, (int)WindowPosition.SWP_SHOWWINDOW); // display the start bar
          }
        } else {
          _sipButton = FindWindowCE("MS_SIPBUTTON", "MS_SIPBUTTON");
          if (_sipButton != IntPtr.Zero) { // If the handle is found then hide the start bar
            SetWindowPos(_sipButton, IntPtr.Zero, 0, 0, 0, 0, (int)WindowPosition.SWP_HIDEWINDOW); // Hide the start bar
          }
        }
      } catch (Exception err) {
        ErrorWrapper(enable ? "Show SIP" : "Hide SIP", err);
      }
    }
    
    static void ErrorWrapper(string routine, Exception e) {
      if (!String.IsNullOrEmpty(e.Message)) {
        MessageBox.Show(e.Message, routine, MessageBoxButtons.OKCancel, MessageBoxIcon.None, 0);
      }
    }
    

    EDIT2:

    Declare a private static instance of your main form, then wrap that in a try....catch routine inside your project's Program.cs file like so:

    static Form1 ppcForm = null;
    
    static void Main() {
      ShowWindowsMenu(false);
      try {
        ppcForm = new Form1();
        Application.Run(ppcForm );
      } catch (Exception err) {
        if (!String.IsNullOrEmpty(err.Message)) {
          ErrorWrapper("Mobile Form (Program)", err);
        }
      } finally {
        ShowWindowsMenu(true);
      }
    }