Игнорировать все новые входящие сообщения колесика мыши во время обработки события

Я использую некоторый пользовательский элемент управления со списком, полученный из TCustomControl, и я обрабатываю события мыши. Назовем его TMyComboBox.

Я обрабатываю TMyComboBox.OnChange и выполняю некоторые операции, для завершения которых требуется некоторое время (около 200 мс) (выполнение некоторых внешних аппаратных изменений).

Поскольку я также внедрил колесико мыши, я могу изменять элементы в своем пользовательском поле со списком с помощью колесика мыши.

Вот в чем проблема. Событие колеса мыши происходит очень быстро (при прокрутке), и это вызывает событие OnChange моего TMyComboBox.

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

Итак, как я могу предотвратить получение сообщения о колесе мыши в очереди сообщений, если мой OnChange все еще выполняет какую-то работу?

Псевдокод

function TMyComboBox.DoMouseWheelDown(Shift: TShiftState;
  MousePos: TPoint): Boolean;
begin
  Self.Cursor := crHourGlass;
  if (Self.Focused and (Self.IndexSelectData + 1 < FScaleCode.Count ) ) then Self.IndexSelectData := Self.IndexSelectData + 1;
  Self.Cursor := crArrow;
end;

function TMyComboBox.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
begin
  Self.Cursor := crHourGlass;
  if (Self.Focused and (Self.IndexSelectData - 1 > -1 ) ) then Self.IndexSelectData := Self.IndexSelectData - 1;
  Self.Cursor := crArrow;
end;

procedure TMyComboBox.OnChange(Sender: TNotifyEvent);
begin
  -> MessageQueue.Lock; // stop receiving message into queue
  ProcessHardware; // long procedure (approx. 200ms)
  -> MessageQueue.Unlock; // continue recieving message into queue
end;

Примечание. При установке IndexSelectData будет поднят OnChange.

Я кое-что читал о PeekMessages, но не знаю, как его использовать... (если вообще можно использовать)

Спасибо за помощь.


person Nix    schedule 30.01.2015    source источник


Ответы (1)


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

procedure SwallowPendingMessages(hWnd: HWND; MsgFilterMin, MsgFilterMax: UINT);
var
  M: TMsg;
begin
  while PeekMessage(M, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE) do begin
    //gulp
  end;
end;

Вы бы вызвали функцию в конце обработчика OnChange.

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

person David Heffernan    schedule 30.01.2015
comment
Это оно! Пока я не найду лучшее решение, как вы упомянули. Спасибо - person Nix; 30.01.2015
comment
+ голосование, но вы можете просто отключить/включить комбо, чтобы предотвратить получение дальнейших данных, а затем вернуть фокус... (Странное изменение политики комментариев, нельзя писать +1-...) - person Sertac Akyuz; 30.01.2015
comment
@SertacAkyuz Я думаю, что ProcessHardware не прокачивает очередь, что означает, что сообщения будут стоять в очереди. Я думаю, что отключение помогло бы только в том случае, если бы очередь обслуживалась своевременно. - person David Heffernan; 30.01.2015
comment
@David - отключение запрещает системе публиковать ввод в поле. Кажется, работает со сном. - person Sertac Akyuz; 30.01.2015
comment
@SertacAkyuz PostMessage терпит неудачу, если окно отключено? Я не знал этого. - person David Heffernan; 30.01.2015
comment
@ Дэвид - Нет, я не думаю, что это потерпит неудачу. Моя точка зрения заключалась в том, что ОС не будет отправлять входные сообщения в отключенное окно. Но тогда, возможно, он отправляет родителю, который я не тестировал, что может усложнить ситуацию. Проверено сейчас, ваше решение - лучшее, родитель получает сообщение о колесе, пока комбо отключено. - person Sertac Akyuz; 30.01.2015
comment
@SertacAkyuz Как всегда спасибо! - person David Heffernan; 30.01.2015