在处理事件时忽略所有新传入的鼠标滚轮消息

Ignore all new incoming mousewheel messages while event is being handled

我正在使用一些从 TCustomControl 派生的自定义组合框控件,并且我正在处理鼠标事件。我们称它为 TMyComboBox。

我正在处理 TMyComboBox.OnChange 并执行一些需要一些时间才能完成的操作(大约 200 毫秒)(进行一些外部硬件更改)。

因为我还实现了鼠标滚轮,所以我可以使用鼠标滚轮更改自定义组合框中的项目。

问题来了。鼠标滚轮事件发生得非常快(滚动时),这引发了我的 TMyComboBox 的 OnChange 事件。

因为 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 的内容,但我不确定如何使用它...(如果可以的话)

感谢您的帮助。

我认为您无法阻止将邮件添加到队列中。但是您可以吞下任何已经在队列中的消息:

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 处理程序的末尾调用该函数。

我不确定我是否会赞扬您提出的建议是个好主意。我想我可能正在寻找解决问题的替代方法。可能是为了避免阻塞 UI 线程而使用线程。