Want to add a new window (.NET Form) to MissionPlanner GUI

Hello all, this is my first post!

I work as a programmer for a company that is actively using Mission Planner. They have asked me to make some changes to the Mission Planner GUI and one of these changes is to add a new window (.NET Form) to Mission Planner.

Basically, they want some of the functionality of the existing buttons, e.g., Flight Data, to be on that new window.

I downloaded the code based on the excellent Mission Planner article ( Building Mission Planner with Visual Studio — Dev documentation ) and build the solution without any errors in debug and release.

I have identified, more or less, the code that deals with the GUI:

  • MainV2.cs (source file of the main window or .NET Form)
  • GCSViews/ (folder that contains the source code for the screens that appear if any of the top row buttons is pressed)
  • Controls/ (folder that contains the source code for all the controls including those that appear on the screens, e.g. FlightData)

I was thinking of three possible ways to approach this:

  1. Create new source files at the top level, like MainV2.cs, to implement the new window
  2. Implement the changes by creating a new plugin under the Plugins/ folder
  3. Implement the changes as a Python script

To be honest, I don’t know if options 2 & 3 are even feasible programmatically. I am not that familiar with the code yet.

I would appreciate your feedback on any of the options above. Ideally, I am looking for a modular, extensible and maintainable design so options 2 & 3 are preferred.

Thank you in advance!

I’m beginner also and I don’t know much,

but I could add additional GUI with plugins. you don’t even need IDE(you can put .cs file on plugins folder)

and I failed many times with building mission planner. How could you do that?

Just follow the instructions at:

I followed them to the letter and was able to build no problem. The only caveat is you have to use Visual Studio 17.8.x. Any version after this one will build but the Forms designer will not work.

For me, there is many error message such as “:No net_4_x.csproj”

I already tried visual studio installer, but there was error message “No MonoDebugger, Merq, Remoted Simulator”

Excepts this, I imported configuration and installed all.

I’m trying to get support from microsoft.

This is the example custom message box class can be used inside plugin I’m using. :

public class PrettyMessageBox : Form
{
    int TEXT_BOX_WIDTH = 280;
    int TEXT_BOX_HEIGHT = 30;

    private string message_contents;
    private string title_string;

    private Panel titleBar;
    private Button closeButtonOnTitle;
    private Point mouseOffsetOnTitle;
    private bool isMouseDownOnTitle = false;
    private Label titleLabel;

    RichTextBox MessageTextBox;
    private string language = "kr";

    private Button confirmationButtonOnBottom;

    private const string RegistryPath = @"Software\XXXX\XXXX\Settings";

    public PrettyMessageBox(string _message_contents)
    {
        message_contents = _message_contents;
        title_string = "XXXXX";
        PopUpMessageBox();
    }

    public PrettyMessageBox(string _message_contents, string _title_string)
    {
        message_contents = _message_contents;
        title_string = _title_string;
        PopUpMessageBox();
    }

    public PrettyMessageBox(string _message_contents, string _title_string, int _width, int _height)
    {
        message_contents = _message_contents;
        title_string = _title_string;
        TEXT_BOX_WIDTH = _width;
        TEXT_BOX_HEIGHT = _height;
        PopUpMessageBox();
    }

    private void PopUpMessageBox()
    {
        // 001. 
        this.FormBorderStyle = FormBorderStyle.None;
        this.StartPosition = FormStartPosition.CenterScreen;
        this.MaximizeBox = false;
        this.MinimizeBox = false;
        this.Padding = new Padding(1);

        // 002. 
        MessageTextBox = new RichTextBox();
        MessageTextBox.Multiline = true;
        MessageTextBox.ReadOnly = true;
        MessageTextBox.ScrollBars = RichTextBoxScrollBars.None;
        MessageTextBox.TabStop = false;
        MessageTextBox.Enter += (s, e) => this.ActiveControl = null; 
        MessageTextBox.Cursor = Cursors.Arrow; 

        // 003.
        string language = ReadLanguageOption();
        MessageTextBox.Text = message_contents;
        if (language == "kr")
        {
            MessageTextBox.Font = new("맑은 고딕", 10);
        }
        else
        {
            MessageTextBox.Font = new("Calibri", 10);
        }
        MessageTextBox.Size = new Size(TEXT_BOX_WIDTH, TEXT_BOX_HEIGHT);
        this.Size = new Size(TEXT_BOX_WIDTH + 20, TEXT_BOX_HEIGHT + 80);

        MessageTextBox.Location = new Point(
            (this.ClientSize.Width - MessageTextBox.Width) / 2,
            (this.ClientSize.Height - MessageTextBox.Height) / 2
        );
        this.Controls.Add(MessageTextBox);

        // 004.
        titleBar = new Panel();
        titleBar.Dock = DockStyle.Top;
        titleBar.Height = 30;
        titleBar.MouseDown += titleBarMouseDown;
        titleBar.MouseMove += titleBarMouseMove;
        titleBar.MouseUp += titleBarMouseUp;
        this.Controls.Add(titleBar);

        // 005.
        closeButtonOnTitle = new Button();
        closeButtonOnTitle.Text = "r"; // = X in Webdings font
        closeButtonOnTitle.Font = new Font("Webdings", 10, FontStyle.Bold);
        closeButtonOnTitle.FlatStyle = FlatStyle.Flat;
        closeButtonOnTitle.FlatAppearance.BorderSize = 0;
        closeButtonOnTitle.Size = new Size(30, 30);
        closeButtonOnTitle.Location = new Point(titleBar.Width - closeButtonOnTitle.Width, 0);
        closeButtonOnTitle.Anchor = AnchorStyles.Top | AnchorStyles.Right;
        closeButtonOnTitle.Click += (s, e) =>
        {
            this.Close();
        };
        titleBar.Controls.Add(closeButtonOnTitle);

        // 006.
        titleLabel = new Label();
        titleLabel.Text = title_string;
        titleLabel.Font = new Font("맑은 고딕", 10, FontStyle.Regular);
        titleLabel.TextAlign = ContentAlignment.MiddleLeft;
        titleLabel.AutoSize = false;
        titleLabel.Dock = DockStyle.Left;
        titleLabel.Width = titleBar.Width - closeButtonOnTitle.Width;
        titleLabel.MouseDown += titleBarMouseDown;
        titleLabel.MouseUp += titleBarMouseUp;
        titleLabel.MouseMove += titleBarMouseMove;
        titleBar.Controls.Add(titleLabel);
        titleLabel.BringToFront();

        // 007.
        confirmationButtonOnBottom = new Button();
        if (language == "kr")
        {
            confirmationButtonOnBottom.Text = "확인";
            confirmationButtonOnBottom.Font = new Font("맑은 고딕", 10);
        }
        else
        {
            confirmationButtonOnBottom.Text = "OK";
            confirmationButtonOnBottom.Font = new Font("Calibri", 10);
        }
        confirmationButtonOnBottom.FlatStyle = FlatStyle.Flat;
        confirmationButtonOnBottom.FlatAppearance.BorderColor = Color.LightGray;
        confirmationButtonOnBottom.Size = new Size(130, 25);
        int center_x = (this.ClientSize.Width - confirmationButtonOnBottom.Width) / 2;
        int y = MessageTextBox.Bottom + 10;
        confirmationButtonOnBottom.Location = new Point(center_x, y);
        confirmationButtonOnBottom.Click += (s, e) => { this.Close(); }; // sender, event args
        confirmationButtonOnBottom.MouseEnter += (s, e) =>
        {
            confirmationButtonOnBottom.BackColor = Color.FromArgb(211, 240, 224); // Hovered fill color
            confirmationButtonOnBottom.FlatAppearance.BorderColor = Color.FromArgb(134, 191, 160); // Hovered border
        };

        confirmationButtonOnBottom.MouseLeave += (s, e) =>
        {
            confirmationButtonOnBottom.BackColor = Color.White;
            confirmationButtonOnBottom.FlatAppearance.BorderColor = Color.FromArgb(169, 169, 169);
        };
        this.Controls.Add(confirmationButtonOnBottom);
    }
    
    private void titleBarMouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            mouseOffsetOnTitle = new Point(-e.X, -e.Y);
            isMouseDownOnTitle = true;
        }
    }

    private void titleBarMouseMove(object sender, MouseEventArgs e)
    {
        if (isMouseDownOnTitle)
        {
            Point mousePos = Control.MousePosition;
            mousePos.Offset(mouseOffsetOnTitle.X, mouseOffsetOnTitle.Y);
            this.Location = mousePos;
        }
    }

    private void titleBarMouseUp(object sender, MouseEventArgs e)
    {
        isMouseDownOnTitle = false;
    }


    private string ReadLanguageOption()
    {
        using (RegistryKey key = Registry.CurrentUser.OpenSubKey(RegistryPath))
        {
            if (key != null)
            {
                string languageOption = key.GetValue("Language") as string;
                return languageOption;
            }
        }
        return "kr";
    }

    protected override void OnActivated(EventArgs e)
    {
        base.OnActivated(e);
        ApplyCustomStyles();
    }

    // borderlines
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        Color borderColor = Color.FromArgb(74, 83, 86);
        ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle,
            borderColor, 2, ButtonBorderStyle.Solid, // Left
            borderColor, 2, ButtonBorderStyle.Solid, // Top
            borderColor, 2, ButtonBorderStyle.Solid, // Right
            borderColor, 2, ButtonBorderStyle.Solid // Bottom
            );
    }

    // shadows on borderlines
    protected override CreateParams CreateParams
    {
        get
        {
            const int CS_DROPSHADOW = 0x00020000;
            CreateParams cp = base.CreateParams;
            cp.ClassStyle |= CS_DROPSHADOW;
            return cp;
        }
    }

    private void ApplyCustomStyles()
    {
        Color darkGray = Color.FromArgb(70, 70, 70);
        this.BackColor = Color.White;
        this.ForeColor = darkGray;

        MessageTextBox.BackColor = Color.White;
        MessageTextBox.ForeColor = Color.DarkGray;
        MessageTextBox.BorderStyle = BorderStyle.None;

        titleBar.BackColor = Color.FromArgb(74, 83, 86);
        titleBar.ForeColor = darkGray;
        closeButtonOnTitle.ForeColor = Color.DarkGray;
        closeButtonOnTitle.BackColor = Color.Transparent;
        titleLabel.ForeColor = Color.DarkGray;
        titleLabel.BackColor = Color.Transparent;

        confirmationButtonOnBottom.BackColor = Color.White;
        confirmationButtonOnBottom.ForeColor = darkGray;

        confirmationButtonOnBottom.BackColor = Color.White;
        confirmationButtonOnBottom.ForeColor = darkGray;
    }
} // end of PrettyMessageBox class

It looks like there is a problem with the Mono framework. I had issues to get Mission Planner to build and the list below are my own notes that I kept for future reference. I hope this helps but other than that there is not much I can do.

Visual Studio design time issue #3306

Mission Planner will only work with VS 2022 17.8.x

even so it may be necessary to fiddle with VS to be able to open GUI CS files (*.cs) with the designer by adjusting scaling to 100% and then adjusting back to automatic

to allow git to integrate with VS

  1. Windows Settings
  2. Privacy & Security
  3. Windows Security
  4. App & browser control
  5. Exploit protection settings
  6. Force randomization for images (Mandatory ALSR)
    switch to “off by default”

The above is very important. If the setting is ON then git will NOT download certain files and the Mission Planner solution won’t build.

to run the build without errors

copy all xml files from

C:\Program Files (x86)\Mission Planner

to

C:\Users\user\source\repos\MissionPlanner\bin\net461

where is the VS build type, i.e. debug or release and the MissionPlanner.exe is created under net461

debug type build more projects than release

to grant access to build executable

  1. Windows Settings
  2. Privacy & Security
  3. Windows Security
  4. Virus & threat protection
  5. Virus & threat protection settings
  6. Controlled folder access
  7. Allow an app through controlled folder access
  8. Add an allowed app
  9. Add pathname to mission planner executable debug & release

I successfully built debug version of mission planner.

At first I downloaded misson planner code(zip) on github, that was the reason it was not compiled.

But, debug version is very slow and impossible to use. Very laggy. Even though my laptop spec is good.