我正在使用从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的内容,但我不知道如何使用它......(如果可以的话)...
感谢您的帮助。
答案 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线程的人。