//---------------------------------------------------------------------------
        bool RegistryRead()
        {
            bool bRet = false;

            using (RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_KEY))
            {
                if (key != null)
                {
                    try
                    {
                        int        min        = RegGetInt(key, "iMin0001", DEF_MINCHAR1);
                        int        max        = RegGetInt(key, "iMax0001", DEF_MAXCHAR1);
                        CheckState checkState = IntToCheckState(RegGetInt(key, "checkState0001", CheckStateToInt(DEF_CHECKSTATE1)));
                        t[0] = new CheckBoxVars(min, max, checkState, DEF_MINCHAR1, DEF_MAXCHAR1, DEF_CHECKSTATE1, checkBox1, labelMin1, labelMax1, textBoxMin1, textBoxMax1);
                        t[0].DisplayVals();

                        min        = RegGetInt(key, "iMin0002", DEF_MINCHAR2);
                        max        = RegGetInt(key, "iMax0002", DEF_MAXCHAR2);
                        checkState = IntToCheckState(RegGetInt(key, "checkState0002", CheckStateToInt(DEF_CHECKSTATE2)));
                        t[1]       = new CheckBoxVars(min, max, checkState, DEF_MINCHAR2, DEF_MAXCHAR2, DEF_CHECKSTATE2, checkBox2, labelMin2, labelMax2, textBoxMin2, textBoxMax2);
                        t[1].DisplayVals();

                        min        = RegGetInt(key, "iMin0003", DEF_MINCHAR3);
                        max        = RegGetInt(key, "iMax0003", DEF_MAXCHAR3);
                        checkState = IntToCheckState(RegGetInt(key, "checkState0003", CheckStateToInt(DEF_CHECKSTATE3)));
                        t[2]       = new CheckBoxVars(min, max, checkState, DEF_MINCHAR3, DEF_MAXCHAR3, DEF_CHECKSTATE3, checkBox3, labelMin3, labelMax3, textBoxMin3, textBoxMax3);
                        t[2].DisplayVals();

                        min        = RegGetInt(key, "iMin0004", DEF_MINCHAR4);
                        max        = RegGetInt(key, "iMax0004", DEF_MAXCHAR4);
                        checkState = IntToCheckState(RegGetInt(key, "checkState0004", CheckStateToInt(DEF_CHECKSTATE4)));
                        t[3]       = new CheckBoxVars(min, max, checkState, DEF_MINCHAR4, DEF_MAXCHAR4, DEF_CHECKSTATE4, checkBox4, labelMin4, labelMax4, textBoxMin4, textBoxMax4);
                        t[3].DisplayVals();

                        min        = RegGetInt(key, "iMin0005", DEF_MINCHAR5);
                        max        = RegGetInt(key, "iMax0005", DEF_MAXCHAR5);
                        checkState = IntToCheckState(RegGetInt(key, "checkState0005", CheckStateToInt(DEF_CHECKSTATE5)));
                        t[4]       = new CheckBoxVars(min, max, checkState, DEF_MINCHAR5, DEF_MAXCHAR5, DEF_CHECKSTATE5, checkBox5, labelMin5, labelMax5, textBoxMin5, textBoxMax5);
                        t[4].DisplayVals();

                        pwLength           = RegGetInt(key, "iLength000", DEF_LENGTH);
                        textBoxLength.Text = pwLength.ToString();

                        bRet = true;
                    }
                    catch { }
                }
            }
            return(bRet);
        }
        //---------------------------------------------------------------------------
        private void buttonGen_Click(object sender, EventArgs e)
        {
            // strategy:
            // 1) get the range from each field if it's "on" and "include"
            //
            // 2) assign each include field a weight based on the % of the overall range of all fields
            //
            // 3) get the # of chars in the total length of the password that should be assigned to each field
            //    based on the % of the total range the particular field represents
            //
            // 4) make a List the length of the password to be generated and select x chars from field 1,
            //    y chars from field 2, Etc. and add the # of chars for that field to the list.
            //
            // 5) now randomly select indices from the list to populate the password box - Voila!

            try { pwLength = Convert.ToInt32(textBoxLength.Text); }
            catch { pwLength = -1; }

            if (pwLength < 1 || pwLength > DEF_MAXLENGTH)
            {
                MessageBox.Show("Length " + pwLength.ToString() + " is not allowed!");
                pwLength           = DEF_LENGTH;
                textBoxLength.Text = pwLength.ToString();
            }

            string       sKey          = "";
            int          iTotalRange   = 0;
            int          iBiggestRange = 0;
            CheckBoxVars cbv           = null;

            // Check limits of enabled fields
            for (int ii = 0; ii < DEF_FIELD_COUNT; ii++)
            {
                string   sCheckBox = "checkBox" + (ii + 1).ToString();
                CheckBox checkBox  = (CheckBox)panel1.Controls.Find(sCheckBox, true)[0];

                if (checkBox.CheckState == CheckState.Unchecked)
                {
                    continue;
                }

                var v = (CheckBoxVars)checkBox.Tag;

                int iMin, iMax;

                try { iMin = Convert.ToInt32(v.minBox.Text); }
                catch { iMin = -1; }

                if (iMin < 1 || iMin > DEF_MAXCHARLENGTH)
                {
                    MessageBox.Show("Min character at (" + iMin.ToString() + ") at " + (ii + 1).ToString() + " is not allowed!");
                    return;
                }

                try { iMax = Convert.ToInt32(v.maxBox.Text); }
                catch { iMax = -1; }

                if (iMax < 1 || iMax > DEF_MAXCHARLENGTH)
                {
                    MessageBox.Show("Max character (" + iMax.ToString() + ") at " + (ii + 1).ToString() + " is not allowed!");
                    return;
                }

                if (iMin > iMax)
                {
                    MessageBox.Show("Min (" + iMin.ToString() + ") is > Max (" + iMax.ToString() + ") at " + (ii + 1).ToString() + "!");
                    return;
                }

                // set and display
                v.Min = iMin;
                v.Max = iMax;

                v.range      = v.Max - v.Min;
                iTotalRange += v.range;

                // save reference to our vars with the most range
                if (v.range > iBiggestRange)
                {
                    iBiggestRange = v.range;
                    cbv           = v; // have our vars handy for use (below)!
                }
            }

            var l        = new List <Char>();
            var r        = new Random();
            int iRetries = 0;

            // get the range deltas for included fields
            for (int ii = 0; ii < DEF_FIELD_COUNT; ii++)
            {
                string   sCheckBox = "checkBox" + (ii + 1).ToString();
                CheckBox checkBox  = (CheckBox)panel1.Controls.Find(sCheckBox, true)[0];

                if (checkBox.CheckState != CheckState.Checked)
                {
                    continue;
                }

                var v = (CheckBoxVars)checkBox.Tag;

                v.fraction = v.range / (double)iTotalRange;
                v.numChars = (int)Math.Round(v.fraction * pwLength);

                for (int jj = 0; jj < v.numChars; jj++)
                {
                    if (l.Count < pwLength)
                    {
                        if (v.Min <= v.Max + 1)
                        {
                            Char c = (Char)r.Next((int)v.Min, (int)(v.Max + 1));
                            if (!IsExcluded(c))
                            {
                                l.Add(c);
                            }
                            else
                            {
                                if (++iRetries > pwLength * DEF_RETRIES)
                                {
                                    MessageBox.Show("Unable to generate key with current settings (1).");
                                    return;
                                }

                                jj--; // continue on and retry for a non-excluded char
                            }
                        }
                        else
                        {
                            MessageBox.Show("Error: Min is < Max at: " + (ii + 1).ToString());
                            break;
                        }
                    }
                }
            }

            iRetries = 0;

            // this is sort of a fudge for padding out the password, if needed.
            // cbv is set above...
            if (cbv != null)
            {
                while (l.Count < pwLength)
                {
                    Char c = (Char)r.Next(cbv.Min, cbv.Max + 1);
                    if (!IsExcluded(c))
                    {
                        l.Add(c);
                    }
                    else
                    {
                        if (++iRetries > pwLength * DEF_RETRIES)
                        {
                            MessageBox.Show("Unable to generate key with current settings (2).");
                            return;
                        }
                    }
                }
            }

            while (l.Count > 0)
            {
                int idx = r.Next(l.Count);
                sKey += l[idx];
                l.RemoveAt(idx);
            }

            textBoxKey.Text = sKey;
        }