Почему я не могу обработать повторный вход цикла сообщений? - PullRequest
0 голосов
/ 28 ноября 2018

Я экспериментирую с повторным входом в цикл сообщений.Обратите внимание, что я не обязательно выберу написать приложение таким образом, я просто хочу уточнить мое понимание циклов сообщений.

Допустим, я запускаю открытие модального диалога с помощью ShowDialog.Насколько я понимаю, вызов, кажется, блокируется, но на самом деле цикл сообщений был повторно введен где-то в стек вызовов, чтобы диалог оставался отзывчивым.Если бы мы не повторно входили в цикл сообщений, диалоговое окно не отображалось бы и т. Д. Таким образом, я понимаю, что ShowDialog работает аналогично Application.DoEvents.

.для рисования сообщений цикл сообщений также может обрабатывать другие сообщения, некоторые из которых могут выполнять обработчики событий.Эти события выполняются во время звонка на ShowDialog.Это может сбивать с толку, потому что кажется, что случайный код выполняется во время вызова ShowDialog, даже если код выполняется в том же потоке, что и ShowDialog.

Допустим, я показываю диалоги ожидание ввода пользователя.В то время как я показываю это диалоговое окно, я получаю еще один звонок с просьбой о том же вводе пользователя.Я не хочу показывать другой диалог.

Если я использую переменную для записи того, запрашиваю ли я в данный момент ввод, я могу сказать, отображается ли уже мой диалог.Если это так, тогда не нужно показывать другое диалоговое окно - оно уже отображается.Я хотел бы дождаться результата первого вызова.

Ниже приведена моя попытка дождаться результата, написанного на F #.Мое ожидание реализуется путем вызова Application.DoEvents, пока не закроется исходное диалоговое окно.Идея состоит в том, что нам нужно вызвать DoEvents, чтобы можно было обработать щелчок ОК из формы, чтобы закрыть его.

open System
open System.Windows.Forms

let showingDialog = ref false
let lastResult = ref DialogResult.None

/// Waits for the original dialog to close.
let waitForOriginalDialogResult () =
    printfn "Doing events while dialog is showing"    
    while !showingDialog do Application.DoEvents()
    !lastResult

/// Actually shows the dialog.
let showDialog () =
    printfn "Showing dialog"
    use dialog = new Form()
    dialog.Controls.Add(new Button(Text = "OK", DialogResult = DialogResult.OK))
    lastResult := dialog.ShowDialog()

/// Either gets user input direct from a dialog, or waits for an existing dialog.
let getUserInput () =
    if !showingDialog then
        waitForOriginalDialogResult()
    else
        showingDialog := true
        try showDialog() finally showingDialog := false
        !lastResult

let timer = new Timer(Interval = 9999)
timer.Tick.Add(fun e -> getUserInput() |> printfn "Sub-show: %A")
timer.Start()
getUserInput() |> printfn "Main show: %A"
timer.Stop()

Если я нажму кнопку ОК до запуска таймера, диалоговое окнозакрывается нормально и все работает.На консоль выводится следующее:

Showing dialog
Main show: OK

Однако после срабатывания таймера нажатие кнопки OK больше не закрывает форму.Диалог кажется совершенно отзывчивым, но я не могу его закрыть.Alt + F4, кнопка X и кнопка OK не работают.Кнопки анимируются так, как будто они нажаты, но диалог не закрывается.Однако я могу использовать кнопки «Развернуть» и «Свернуть», а также изменить размер формы.

Я бы подумал, что вызов DoEvents поднимет сообщение о щелчке ОК или закрытии и закроет форму.Почему не работают кнопки закрытия?

Во-вторых, есть ли способ выполнить такое ожидание, которое работает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...