Einzelnen Beitrag anzeigen

schöni

Registriert seit: 23. Jan 2005
Ort: Dresden
445 Beiträge
 
Delphi 7 Personal
 
#1

Ereignisse werden nicht korrekt verteilt

  Alt 11. Okt 2014, 15:02
Hallo,

ich beschäftige mich gerade mit der Verteilung von Ereignissen in Objekten. Ich habe dazu eine Unit geschrieben DControl (D)esigned Control(s). Dort gibt es die Klasse TCustomControl, die eine DispatchEvent-Methode enthält, die so aussieht:

Delphi-Quellcode:
procedure TCustomControl.DispatchEvents;
var Event: TMEBEvent; ix: Integer;
begin
  GetMEBEvent(Event);
  case Event.ofKbdEventKind of
   evkKeyDown:
    DoKeyDown(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
   evkKeyUp:
    DoKeyUp(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
   else ;
  end;
  case Event.ofKbdEventKind of
   evkKeyDown:
    DoKeyDown(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
   evkKeyUp:
    DoKeyUp(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
  end;
  case Event.ofMouse.EventKind of
   evmMouseDown:
    DoMouseDown(
       self, Event.ofMouse.MButtns,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
   evmMouseMove:
    DoMouseMove(
       self,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
   evmMouseUp:
    DoMouseUp(
       self, Event.ofMouse.MButtns,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
  end;
  ix := ComponentCount-1;
  while ix>=0 do
  begin
    case Event.ofKbdEventKind of
     evkKeyDown:
      TCustomControl(Components[ix]).DoKeyDown(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
     evkKeyUp:
      TCustomControl(Components[ix]).DoKeyUp(self, Event.ofKeyboard.VirtCode,Event.ofKeyboard.Shift);
    end;
    case Event.ofMouse.EventKind of
     evmMouseDown:
      TCustomControl(Components[ix]).DoMouseDown(
       self, Event.ofMouse.MButtns,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
     evmMouseMove:
      TCustomControl(Components[ix]).DoMouseMove(
       self,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
     evmMouseUp:
      TCustomControl(Components[ix]).DoMouseUp(
       self, Event.ofMouse.MButtns,
       Event.ofKeyboard.Shift,
       Event.ofMouse.x,
       Event.ofMouse.y
     );
   end;
   Dec(ix);
  end;
end;
die DoKey.... Methoden rufen die passenden Key... Methoden auf.
die DoMouse.... Methoden tun das gleiche für die Mouse... Methoden.

die DoRun Methode meiner CustomApplication ist die hier:

Delphi-Quellcode:
procedure TMyCustApp.DoRun;
begin
  ...
  AControl := TTestControl.Create(self);
  repeat
    AControl.DispatchEvents;
  until Terminated;
  ...
end;



//Die GetMEBEVentMethode ---> MEB -> Marke Eigenbau
Delphi-Quellcode:
procedure GetMEBEvent(var Event: TMEBEvent);
begin
  Event.ofKbdEventKind := evkNone;
  Event.ofMouse.EventKind := evmNone;
  if {$ifndef FPC}crt.{$endif}keypressed then
  begin
    {KeyPress(Event.ofKeyboard.VirtCode, Event.ofKeyboard.Shift);}
    Event.ofKeyboard.CharCode := readKey;
    if Event.ofKeyboard.CharCode = #0 then Event.ofKeyboard.Scancode := ord(readKey);
    {$endif}
   Event.ofKeyboard.Left := (ssLeft IN Event.ofKeyboard.Shift);
    Event.ofKbdEventKind := evkKeyDown;
    ___pressed_key___:= true;
  end;
  if (not crt.keypressed) and ___pressed_key___ then
  begin
    Event.ofKbdEventKind := evkKeyUp;
    ___pressed_key___:= false;
  end;
  GetMouseEvent(Event.ofMouse);
end;


//nun die GetEvent Methode für die Musereignisse:
function GetMouseEvent(var Event: TMouseEvStruct): TMouseEventKind;
begin
  GetMouseEvent := evmNone;
  Event.x := AppMouse.GetX;
  Event.y := AppMouse.GetY;
  if AppMouse.Buttons = 1 then begin Event.Buttons := 1; Include(Event.MButtns, mbLeft); end;
  if AppMouse.Buttons = 2 then begin Event.Buttons := 2; Include(Event.MButtns, mbRight); end;
  if Event.Buttons <> 0 then
  begin
    ___pressed_mouse_:= true;
    Event.EventKind := evmMouseDown;
    GetMouseEvent := evmMouseDown;
  end;
  {if (not button(0)) and (not button(1)) then Event.Buttons := 0;}
  if ___pressed_mouse_ and (Event.Buttons = 0) then
  begin
    ___pressed_mouse_:= false;
    Event.EventKind := evmMouseUp;
    GetMouseEvent := evmMouseUp;
  end;
  Event.Moved := AppMouse.moved;
  if Event.Moved then Event.EventKind := evmMouseMove;
  Event.Cursor := 0; { sp„ter anpassen }
end;
Zur Maussteuerung verwende ich die Unit Winmouse aus Freepascal, die jedoch mit dieser Klasse gekapselt wird.

Delphi-Quellcode:
type
  TMouseDriverClass = Class(TObject)
  public
    constructor Init;
    function Buttons: {$ifdef FPC}Longint;{$else}Word;{$endif}
    destructor Done; virtual;
    function Error: Boolean;
    procedure Hide;
    procedure Show;
    procedure SetLimitRange(x1,y1,x2,y2: {$ifdef FPC}Longint{$else}word{$endif});
    procedure SetXY(X,Y: {$ifdef FPC}Longint{$else}word{$endif});
    procedure GetXY(var X, Y: {$ifdef FPC}Longint{$else}word{$endif});
    function GetX: {$ifdef FPC}Longint;{$else}word;{$endif}
    function GetY: {$ifdef FPC}Longint;{$else}word;{$endif}
    function InRect(x1,y1, x2,y2: {$ifdef FPC}Longint{$else}word{$endif}): Boolean;
    procedure LoadCursor(Index: Integer);
    function moved: Boolean;
    function DeltaX: Integer;
    function DeltaY: Integer;
  end;

Auf der Tastatur wird nur das Ereignis KeyUp, nicht aber KeyDown oder Keypress erkannt. Die Mausereignisse werden gar nicht erkannt. Auch die MausButtons werden nicht korrekt erkannt.

Was läuft da in meinem Quellcode falsch?

Gibt es eine besser geeignete Maus Unit.

Ich habe den Quellcode mit Lazarus geschrieben. Datei -> Neu -> Freepascal Konsolenprogramm.
Damit der Topf nicht explodiert, lässt man es ab und zu mal zischen.

Geändert von schöni (11. Okt 2014 um 15:07 Uhr)
  Mit Zitat antworten Zitat