Действительно ли возможно использовать ShowDialog, не блокируя все формы?

Я думаю, что если кто-то захочет использовать PHP и MySQL или какой-нибудь другой сервер базы данных:

  1. Подумайте об обучении PDO (объекты данных PHP) - это база данных уровень доступа, обеспечивающий единый метод доступа к нескольким базам данных.
  2. Подумайте об обучении MySQLi
  3. Используйте собственные функции PHP, такие как: strip_tags , mysql_real_escape_string или если переменная числовая, просто (int)$foo. Подробнее о типах переменных в PHP читайте здесь . Если вы используете библиотеки, такие как PDO или MySQLi, всегда используйте PDO :: quote () и mysqli_real_escape_string () .

Примеры библиотек:

---- PDO

----- Никакие заполнители - не спешили для SQL-инъекций! Это плохо

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) values ($name, $addr, $city)");

----- Без имени заполнители

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) values (?, ?, ?);

----- Именованные заполнители

$request = $pdoConnection->("INSERT INTO parents (name, addr, city) value (:name, :addr, :city)");

--- MySQLi

$request = $mysqliConnection->prepare('
       SELECT * FROM trainers
       WHERE name = ?
       AND email = ?
       AND last_login > ?');

    $query->bind_param('first_param', 'second_param', $mail, time() - 3600);
    $query->execute();

PS:

PDO побеждает в этом сражении с легкостью. Благодаря поддержке двенадцати различных драйверов баз данных и именованных параметров мы можем игнорировать небольшую потерю производительности и привыкнуть к ее API. С точки зрения безопасности, оба они являются безопасными, пока разработчик использует их так, как они должны использоваться

. Но хотя PDO и MySQLi довольно быстры, MySQLi выполняет незначительную скорость в тестах - ~ 2,5% для незаготовленных отчетов и ~ 6,5% для подготовленных.

И, пожалуйста, проверьте каждый запрос в своей базе данных - это лучший способ предотвратить инъекцию.

48
задан Grant - REINSTATE MONICA 16 April 2015 в 04:23
поделиться

4 ответа

При выполнении Формы B на отдельном потоке от A и C вызов ShowDialog только заблокирует тот поток. Очевидно, это не тривиальные инвестиции работы, конечно.

у Вас может быть диалоговое окно не блок любые потоки вообще путем простого выполнения D Формы, ShowDialog обращаются к отдельному потоку. Это требует того же вида работы, но намного меньше из него, как у Вас только будет одна форма убегающей из основного потока Вашего приложения.

9
ответ дан TheSmurf 7 November 2019 в 12:14
поделиться

Используя несколько GUI потоки являются хитрым бизнесом, и я отговорил бы от него, если это - Ваша единственная мотивация для того, чтобы сделать так.

А намного более подходящий подход должен использовать Show() вместо ShowDialog() и отключить форму владельца до раскрывающихся возвратов формы. Существует всего четыре соображения:

  1. , Когда ShowDialog(owner) используется, раскрывающаяся форма остается сверху своего владельца. То же верно, когда Вы используете Show(owner). С другой стороны, можно установить Owner свойство явно с тем же эффектом.

  2. при установке формы владельца Enabled свойство к false форма показывает нерабочее состояние (дочерние элементы управления "grayed"), тогда как, когда ShowDialog используется, форма владельца все еще отключена, но не показывает нерабочее состояние.

    , Когда Вы звоните ShowDialog, форма владельца отключена в Win32 code— WS_DISABLED, бит стиля установлен. Это заставляет его терять способность получить фокус и "звенеть", когда нажато, но не заставляет его потянуть себя серый.

    при установке формы Enabled свойство к [1 113] дополнительный флаг установлен (в платформе, не базовой подсистеме Win32), который проверяют определенные средства управления, когда они привлекают себя. Этот флаг - то, что говорит средствам управления привлекать себя в нерабочем состоянии.

    Так для эмуляции, что произошло бы с [1 114] мы должны установить собственный компонент WS_DISABLED бит стиля непосредственно, вместо того, чтобы установить форму Enabled свойство к [1 117]. Это выполняется с крошечным битом interop:

    const int GWL_STYLE   = -16;
    const int WS_DISABLED = 0x08000000;
    
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
    void SetNativeEnabled(bool enabled){
        SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) &
            ~WS_DISABLED | (enabled ? 0 : WS_DISABLED));
    }
    
  3. Эти ShowDialog() вызов не возвращается, пока диалоговое окно не отклонено. Это удобно, потому что можно приостановить логику в форме владельца, пока диалоговое окно не вело свой бизнес. Эти Show() вызов, обязательно, не ведет себя этот путь. Поэтому, если Вы соберетесь использовать Show() вместо [1 121], необходимо будет повредить логику в две части. Код, который должен бежать за диалоговым окном, отклонен (который включал бы перевключение формы владельца), должен быть выполнен Closed обработчик событий.

  4. , Когда форма показывается диалоговым окном, установив DialogResult, свойство автоматически закрывает ее. Это свойство установлено каждый раз, когда кнопка с DialogResult свойство кроме [1 125] нажата. Форма, показанная с [1 126], автоматически не закроется как это, таким образом, мы должны будем явно закрыть ее, когда одна из его кнопок увольнения нажата. Обратите внимание, однако, что DialogResult свойство все еще установлено соответственно кнопкой.

Реализация этих четырех вещей, Ваш код становится чем-то как:

class FormB : Form{
    void Foo(){
        SetNativeEnabled(false); // defined above
        FormD f = new FormD();
        f.Closed += (s, e)=>{
            switch(f.DialogResult){
            case DialogResult.OK:
                // Do OK logic
                break;
            case DialogResult.Cancel:
                // Do Cancel logic
                break;
            }
            SetNativeEnabled(true);
        };
        f.Show(this);
        // function Foo returns now, as soon as FormD is shown
    }
}

class FormD : Form{
    public FormD(){
        Button btnOK       = new Button();
        btnOK.DialogResult = DialogResult.OK;
        btnOK.Text         = "OK";
        btnOK.Click       += (s, e)=>Close();
        btnOK.Parent       = this;

        Button btnCancel       = new Button();
        btnCancel.DialogResult = DialogResult.Cancel;
        btnCancel.Text         = "Cancel";
        btnCancel.Click       += (s, e)=>Close();
        btnCancel.Parent       = this;

        AcceptButton = btnOK;
        CancelButton = btnCancel;
    }
}
86
ответ дан P Daddy 7 November 2019 в 12:14
поделиться

Можно использовать отдельный поток (как ниже), но это входит в опасную территорию - необходимо только пойти около этой опции, если Вы понимаете последствия поточной обработки (синхронизация, перекрестный распараллельте доступ, и т.д.):

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Button loadB, loadC;
    Form formA = new Form {
        Text = "Form A",
        Controls = {
            (loadC = new Button { Text = "Load C", Dock = DockStyle.Top}),
            (loadB = new Button { Text = "Load B", Dock = DockStyle.Top})
        }
    };
    loadC.Click += delegate {
        Form formC = new Form { Text = "Form C" };
        formC.Show(formA);
    };
    loadB.Click += delegate {
        Thread thread = new Thread(() => {
            Button loadD;
            Form formB = new Form {
                Text = "Form B",
                Controls = {
                    (loadD = new Button { Text = "Load D",
                        Dock = DockStyle.Top})
                }
            };
            loadD.Click += delegate {
                Form formD = new Form { Text = "Form D"};
                formD.ShowDialog(formB);
            };
            formB.ShowDialog();  // No owner; ShowDialog to prevent exit
        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    };
    Application.Run(formA);
}

(Очевидно, Вы на самом деле не структурировали бы код как вышеупомянутое - это - просто самый короткий способ показать поведение; в реальном коде у Вас был бы класс на форму, и т.д.)

11
ответ дан Peter Mortensen 7 November 2019 в 12:14
поделиться

Запустите FormB в новом потоке в FormA:

        (new System.Threading.Thread(()=> {
            (new FormB()).Show();
        })).Start();

Теперь, любые формы, открытые в использовании нового потока, ShowDialog () только заблокирует FormB и НЕ FormA или FormC

4
ответ дан Robert Venables 7 November 2019 в 12:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: