I'm trying to create a simple component to draw rows/columns of 
buttons. The first thing I'm trying to get done is the mouse event 
handling. I was able to figure out how to catch the windows messages 
and have them trigger published events from some examples I've found, 
but I'm having a problem it. If you click very quickly in rapid 
succession, the control seems to steal the mouse input for the entire 
application. You can't even click on the form's close button as the 
click gets taken.

In a test project, I notice that in a listbox that displays the 
events when they are fired, when it shows a MouseUp event firing 
without a corresponding MouseDown, that's when the control will begin 
to steal all mouse input from that point onward. You have to kill the 
app at that point. I read a post through a Google search about 
problems like this happening with TGraphicControl descendants, so I 
tried changing it to a TCustomPanel, but the problem is still there.

Can anyone tell me what is causing this and how I can fix it?

Here's a stripped down version of the component code with only the 
relevant parts:

unit MyButtonPanel;

interface

uses
  Types, Classes, Messages, Controls, Graphics, ExtCtrls;

type

  TMouseDownEvent = procedure(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer) of object;
  TMouseUpEvent = procedure(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer) of object;
  TMouseClickEvent = procedure(Sender: TObject; Btn: Integer) of 
object;

  TMyButtonPanel = class(TGraphicControl)
  private
    FOnMouseDown: TMouseDownEvent;
    FOnMouseUp: TMouseUpEvent;
    FOnMouseClick: TMouseClickEvent;
  protected
    procedure WM_LBUTTONDOWN(var Msg: TWMLButtonDown); Message 
WM_LBUTTONDOWN;
    procedure WM_LBUTTONUP(var Msg: TWMLButtonUp); message 
WM_LBUTTONUP;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property OnMouseClick: TMouseClickEvent read FOnMouseClick write 
FOnMouseClick;
    property OnMouseDown: TMouseDownEvent read FOnMouseDown write 
FOnMouseDown;
    property OnMouseUp: TMouseUpEvent read FOnMouseUp write 
FOnMouseUp;
  end;

procedure Register;

implementation

uses
  Forms, Consts, SysUtils, CommCtrl, Themes, Dialogs;

Constructor TMyButtonPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

Destructor TMyButtonPanel.Destroy;
begin
  inherited destroy;
end;

procedure TMyButtonPanel.WM_LBUTTONDOWN(Var Msg: TWMLButtonDown);
begin
  if Assigned(FOnMouseDown) then FOnMouseDown(Self, mbLeft, 
KeysToShiftState(Msg.Keys), Msg.XPos, Msg.YPos);
  if Assigned(FOnMouseClick) then FOnMouseClick(Self, 0);
end;

procedure TMyButtonPanel.WM_LBUTTONUP(Var Msg: TWMLButtonDown);
begin
  if Assigned(FOnMouseUp) then FOnMouseUp(Self, mbLeft, 
KeysToShiftState(Msg.Keys), Msg.XPos, Msg.YPos);
end;

procedure Register;
begin
  RegisterComponents('Samples', [TMyButtonPanel]);
end;

end.

--------------------------------------------
Events in Test Project:

procedure TMain.MyButtonPanel1MouseClick(Sender: TObject; Btn: 
Integer);
begin
  ListBox1.Items.Add( IntToStr(Btn) );
end;

procedure TMain.MyButtonPanel1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ListBox1.Items.Add('MouseDown');
end;

procedure TMain.MyButtonPanel1MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ListBox1.Items.Add('MouseUp');
end;
---------------------------------------------
_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to