I have a form with both a TImage and a TButton control. I noticed the rate of responding to the OnClick event seemed a bit slow for the TImage (rapid clicking!) so I measured it. For 100+ clicks (and clicking as fast as I could, keeping the rate as consistent as I could for each control) I got the metrics: TButton: Average ~105-116ms TImage: Average ~220-235ms
I repeated this a few times with similar results. Why is the TImage processing clicks about half the rate of the TButton? Could it be slower to process the Windows message queue from WM_LBUTTON_DOWN to the OnClick event? Maybe it is swallowing Clicks if they are within N ms of the previous click?
There's doesn't seem to be anything in the properties of the TImage that affects this.
Note: Using Delphi 7 and the standard VCL controls here, if that is relevant.
EDIT: Here is some example code demonstrating how I timed things:
// 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
usesBN_CLICKED
system notification for triggeringOnClick
event whilstTImage
only tracks mouse down/mouse up event pair, so I would not be surprised there can be difference. – TLamaTButton
have a double click event ? I think it simply does not need to wait for a decision if the event is going to be click or double click (due to the used button style it does not receiveBN_DBLCLK
notification). But it's just a wild guess. I've no time for deeper investigation right now. – TLama