ОС выводит WM_LBUTTONDBLCLK
на второй нажатие левой кнопки мыши.Когда вы выполняете вызов ShowModal
здесь, приложение не получает возможности обработать, еще не опубликованное, сообщение WM_LBUTTONUP
до тех пор, пока не отобразится ваше диалоговое окно.Так как TDBGrid
запускает событие OnCellClick
, пока элемент управления обрабатывает сообщение WM_LBUTTONUP
, и сообщение оказывается отправленным в сетку, поскольку модальная форма является активным окном, вы столкнулись с проблемой.
Поведение сетки имеет вид задокументировано ;
Происходит, когда пользователь отпускает мышь в одной из ячеек сетки.
хотя можно утверждать, что следовало бы упомянуть, что вам даже не нужно нажимать кнопку мыши ...
Это неудачное дизайнерское решение, это не то, как работает щелчок.Подумайте о том, чтобы нажать кнопку на одной ячейке и отпустить на другой.Нет OnCellClick
должен быть уволен.Текущее поведение довольно запутанно, событие запускается для ячейки, на которой вы нажали кнопку - при условии, что вы отпустите кнопку в действительной ячейке, а не в пустом месте.
Как вы узнали, вы даже можете запустить событие, нажав кнопку в другой форме и отпустив ее в ячейке сетки этой формы.В этом случае событие запускается для выбранной в данный момент ячейки, и положение мыши не играет в этом никакой роли.Мое мнение таково, что OnCellClick
- полный беспорядок.
Вы можете использовать ответ Кобика для решения.Приведенное ниже решение не может быть выполнено, если по какой-то причине кнопка мыши удерживается при втором нажатии в течение какого-либо периода времени.
Публикация сообщения, полученного пользователем, для задержки показа диалогового окна, как предлагается в комментариях к вопросу, не работает, поскольку отправленные сообщения имеют более высокий приоритет, чем входные сообщения.См. документацию для GetMessage
для более подробной информации.
Если вы перейдете по ссылке, вы заметите, что таймерный подход, также предложенный в комментариях к вопросу, будет работать.В отличие от комментария предполагается, что временной интервал не имеет значения, поскольку сообщение WM_TIMER
имеет самый низкий приоритет.И это хорошо, что делает этот подход безопасным.
Я хотел включить таймер в модальное диалоговое окно, так как он владеет контролем проблемы.
procedure TForm2.FormCreate(Sender: TObject);
begin
DBGrid1.Enabled := False;
Timer1.Interval := 1;
Timer1.Enabled := True;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
DBGrid1.Enabled := True;
Timer1.Enabled := False;
end;