【发布时间】:2015-08-14 20:13:04
【问题描述】:
我有一个包含 TImage 和 TButton 控件的表单。我注意到 TImage 对 OnClick 事件的响应速度似乎有点慢(快速点击!)所以我测量了它。对于 100 多次点击(并尽可能快地点击,使每个控件的点击率尽可能一致),我得到了指标: TButton:平均~105-116ms TImage:平均~220-235ms
我重复了几次,结果相似。为什么 TImage 处理点击率大约是 TButton 的一半?处理从 WM_LBUTTON_DOWN 到 OnClick 事件的 Windows 消息队列会更慢吗?如果它们在上一次点击的 N 毫秒内,它可能正在吞噬点击?
TImage 的属性中似乎没有任何影响这一点的东西。
注意:此处使用 Delphi 7 和标准 VCL 控件(如果相关)。
编辑:这是一些示例代码,演示了我如何计时:
// Define variables (in class definition)
m_dwBtnClicks, m_dwImgClicks: DWORD;
m_dwLastBtnClickTicks, m_dwLastImgClickTicks: DWORD;
m_fTotalBtnClicksTicks, m_fTotalImgClicksTicks: Single;
// Initialise variables (in form's OnCreate event)
m_dwBtnClicks := 0;
m_dwImgClicks := 0;
m_dwLastBtnClickTicks := 0;
m_dwLastImgClickTicks := 0;
m_fTotalImgClicksTicks := 0.0;
m_fTotalImgClicksTicks := 0.0;
// OnClick events
procedure TfrmQwerty.btnClick(Sender: TObject);
var
dwTime: DWORD;
begin
// TButton click!
Inc(m_dwBtnClicks);
dwTime := GetTickCount();
if (m_dwLastBtnClickTicks > 0) then
m_fTotalBtnClicksTicks := (m_fTotalBtnClicksTicks + (dwTime - m_dwLastBtnClickTicks));
m_dwLastBtnClickTicks := dwTime;
end;
procedure TfrmQwerty.imgClick(Sender: TObject);
var
dwTime: DWORD;
begin
// TImage click!
Inc(m_dwImgClicks);
dwTime := GetTickCount();
if (m_dwLastImgClickTicks > 0) then
m_fTotalImgClicksTicks := (m_fTotalImgClicksTicks + (dwTime - m_dwLastImgClickTicks));
m_dwLastImgClickTicks := dwTime;
end;
// Some TTimer::OnTimer event to update the results on-screen
procedure TfrmQwerty.OnTextEntryTimer(Sender: TObject);
var
fTime: Single;
begin
// Stop the timer
TextEntryTimer.Enabled := False;
if (m_dwBtnClicks > 1) then
begin
fTime := m_fTotalBtnClicksTicks / m_dwBtnClicks;
lblButtonClicks.Caption := Format('BtnClicks = %d [Avg = %.3fms]', [
m_dwBtnClicks, fTime]);
end;
if (m_dwImgClicks > 1) then
begin
fTime := m_fTotalImgClicksTicks / m_dwImgClicks;
lblImageClicks.Caption := Format('ImgClicks = %d [Avg = %.3fms]', [
m_dwImgClicks, fTime]);
end;
// Restart the timer
TextEntryTimer.Enabled := True;
end;
【问题讨论】:
-
你在计时什么?请展示一个简短的演示程序,使我们能够执行完全相同的计时。
-
TButton使用BN_CLICKED系统通知来触发OnClick事件,而TImage只跟踪鼠标向下/鼠标向上事件对,所以我不会对存在差异感到惊讶。跨度> -
@DavidHeffernan:好的,添加了一些示例代码来显示事情是如何计时的。没有什么花哨。当我注意到很大的不同时,正在用 QWERTY 风格的屏幕键盘上的 TImage 替换 TButton。
-
@David,可能回答这个话题的问题是,为什么
TButton没有双击事件?我认为它根本不需要等待事件是单击还是双击的决定(由于使用的按钮样式,它不会收到BN_DBLCLK通知)。但这只是一个疯狂的猜测。我现在没有时间进行更深入的调查。 -
@Alain - 不,我说的是控制风格。 Image1.ControlStyle := Image1.ControlStyle - [csDoubleClicks];