2013-07-04 2 views
3

В приложении FireMonkey (Delphi XE3) происходит следующее. Посмотрите на следующий коде (это просто фиктивный пример, чтобы проиллюстрировать проблему):Почему TButton.enable не дает ожидаемого результата в этом случае?

procedure TForm1.Button4Click(Sender: TObject); 
var 
    i: Integer; 
begin 
    Button4.Enabled:= false; //This should gray-out the button 

    // get busy for some time 
    for I := 0 to 100000000000 do 
    begin 

    end; 

    Button4.Enabled:= true; 
end; 

я ожидал Button4 получить неактивные перед входом в занятые операции, представленных «для» петли. Тем не менее, это не так.

К концу выполнения обработчика OnClick кнопка не реагирует на кнопку Button4.Enabled: = false. Зачем?

Как это решить?

Это прекрасно работает в VCL.

Спасибо.

+0

MainThread предназначен только для задач пользовательского интерфейса, а не для длительных задач расчета. Это нужно сделать в фоновом задании. Отключите кнопку запуска фоновой задачи и включите ее, когда фоновая задача будет завершена. –

ответ

6

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

Непосредственным решением было бы позвонить Button4.Repaint, что позволит кнопке обновить его внешний вид. Тем не менее, это не обрабатывает все сообщения.

Плохое исправление заключалось бы в том, чтобы иногда вызывать Application.ProcessMessages в вашем цикле, но нужно позвонить, что обычно является признаком того, что вы делаете что-то неправильно.

Наконец, лучшим решением было бы переместить вашу долговременную задачу в другой поток. Отключите кнопку при запуске задачи и включите ее, когда задача завершится.

+0

Роб, нет метода обновления для элементов управления FMX? – Jason

+0

Вы меня спрашиваете или говорите, @ Джейсон? Похоже, такого метода нет в Fire Monkey. Тем не менее, есть переиздание, которое также работает в VCL. Это синоним обновления. –

+0

ну, я не смог найти один - метод обновления - так что просто поместил его там, не сделав заявление на одеяло, если я ошибался. FWIW, я тестировал с помощью перерисовки только сейчас, и это не сработало для меня, тогда как Application.ProcessMessages, так что это может быть немного сложнее для элементов управления, связанных с FMX. – Jason