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

时间:2015-01-30 15:35:42

标签: delphi custom-controls mouse vcl mousewheel

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

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

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

这就是问题所在。鼠标滚轮事件发生得非常快(滚动时),这会引发我的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的内容,但我不知道如何使用它......(如果可以的话)...

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

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

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线程的人。