我有一个表单,同时有一个TImage和一个TButton控件。我注意到TImage(快速点击!)对OnClick事件的响应速度似乎有点慢,所以我测量了一下。对于100多次点击(尽可能快地点击,尽可能保持每个控件的速度一致),我得到了指标:TButton:平均~105- 116 ms TImage:平均~220- 235 ms
我重复了几次类似的结果。为什么TImage处理点击的速度只有TButton的一半?从WM_LBUTTON_DOWN到OnClick事件的Windows消息队列的处理速度会更慢吗?如果点击在前一次点击的N ms内,也许它会吞下点击?
似乎没有什么在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;
字符串
1条答案
按热度按时间xn1cxnb41#
VCL源代码是你的好朋友。正如所指出的,这是由Windows在快速点击时发送的双击消息引起的。
让我们看看当点击足够快以触发双击时会发生什么:
第1步-鼠标左键向下:
字符串
第2步-鼠标左键上升。
型
第3步-再次按下鼠标左键。
这一次,它是一个双击!注意,这是处理一个完全不同的消息-来自操作系统的双击消息,而不是鼠标按下消息。这里的处理程序仍然会触发
MouseDown
事件,但 * 不会在鼠标按钮重新抬起时触发click事件 *。型
由于Button是一个特殊的
TWinControl
,它会接收到特殊的BN_CLICKED
消息,该消息是在按钮被点击时生成的,无论它是否是双击。作为一个简单的控件,它做的工作很简单,因此当快速点击时(比双击速度快),您会看到按钮的点击事件是原来的两倍。型
您还可以注意到,由于
TButton
将接收这些特殊消息,因此它是在其ControlStyle
中没有csClickEvents
选项的情况下创建的,因此尽管它也是一个TControl
,但上述步骤中用于TImage
(和其他)控件的处理并不适用(即:在WMLButtonDown
处理程序中为Click
启动)。正如您所发现的,
OnMouseDown
或OnMouseUp
事件将允许您捕获TImage
控件中的所有此类事件,无论它们应被视为单击还是双击。或者,如果你不关心你的
TImage
处理双击,你可以设置控件样式为:型
在
TControl.WndProc
中:型
您可以看到双击事件被转换为简单的鼠标按下事件。