DBGrid mit rechter Maustaste selektieren (Zeos)

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von Aliobaba »

Hallo,

Es ist für den Anwender recht fehleranfällig, wenn er in einer Liste mit der rechten Maustaste auf einen Eintrag klickt (TDB.Grid) und dann aber immer das Mausereignis bezogen auf den ersten Eintrag der Liste als Ergebnis bekommt. Der Anwender muss immer zuerst mit der linken Maustaste die Zeile anwählen, dann erst kann er mit dem Klick auf die rechte Maus das Ergebnis für diese zuerst selektierte Tabellenzeile erhalten.

Mit diesem Problem kämpfen offenbar öfter mal Programmieranfänger. Jedenfalls findet man im Internet schon so einiges. Aber ich komme mit diesen Hilfen nicht zurecht, denn sie beziehen sich auf ein dann aufklappbares Popup-Menü (auch interessant, brauch ich aber vielleicht erst später) oder auf andere Listenobjekte im Formularfenster.

Kann jemand helfen? Ich würde gerne in einem TDBGrid-Objekt (Zeos) mit der linken Maustaste auf eine Zeile klicken, diese Zeile sollte dann den Focus erhalten und zur Verifizierung könnte dann ja eine kurze Message-Box erscheinen, z.B.:

Code: Alles auswählen

ShowMessage('Super, endlich geschafft!');
Danke!
Alibaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von MmVisual »

Das geht im OnClick Event
EleLa - Elektronik Lagerverwaltung - www.elela.de

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von Aliobaba »

Hmm: Ich hab das schon versucht, krieg das aber mit diesem onClick Event nicht hin.

Man braucht dazu das MouseUp- oder MouseDown- Event; der OnClick Event kennt die Variable "Button" und auch "mbRight" nicht. Ich brauche die rechte(!) Maustaste!!
Und das MouseUp- oder MouseDown- Event bezieht sich - egal wohin man den Cursor innerhalb der Liste setzt, zunächst immer auf den ersten Eintrag dieser Liste und erst NACH einem Linkskklick auf den damit angewählten Eintrag.

Code: Alles auswählen

  if Button=mbRight  then Form1.mach_irgendwas;
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von Aliobaba »

Schade, dass niemand Rat weiß; irgendwie muss es aber gehen(!) - und zwar mit Auswertung der X- und Y-Koordinaten, denn damit kann man auch zusätzliche Klappmenüs in Anhängigkeit der Position des aktivierten DBGrid-Feldes öffnen. Einige Dinge habe ich dazu im Internet gefunden, hab's aber nicht verstanden.

Also musste ich mir selber helfen. Vielleicht ineressiert es jemanden, wie:

Leider wertet nur der normale "Linksclick" und "OnCellClick" die Position des aktivierten Feldes in einer DBGrid (Zeos) aus. Mit "OnCellClick" kann man aber (jedenfalls ich nicht) nicht auswerten, ob mit der rechten oder linken Maustaste geklickt wird :(

Zunächst schaute ich, in welcher "Reihenfolge" die Event-Ereignisse auftreten:

beim Linksklick:
Down (Zelle wird noch nicht gewechselt)
Up (neue zelle wird nicht angewählt Aber Da gibt es Shift State!)
Cellclick (neue Reihe ist angewählt NACH dem MouseUp

beim Rechtsklick
Down (Zelle wird noch nicht gewechselt)
Up (Zelle wird gewechselt Da gibt es aber Shift State!)
---- es gibt keinen: Cellclick

Ich wertete also im in OnMouseDown-Ereignis aus, welche Maustaste gedrückt wurde und gab das Ergenis in eine Variable

Code: Alles auswählen

  If (ssCtrl in Shift) then
  begin
    Maus_ssCtrlAlt_erfolgt := 1;
  end;
  If (ssAlt in Shift) then
  begin
    Maus_ssCtrlAlt_erfolgt := 2;
  end;         
Diese Variable kann man dann im Ereignis "OnCellClick" auswerten - der Cursor steht ja jetzt an der richtigen Position

Code: Alles auswählen

 if Maus_ssCtrlAlt_erfolgt = 1 then  // also: Strg-Taste ist gedrückt
 begin
    ////////
 end;
 if Maus_ssCtrlAlt_erfolgt = 2 then  // also: Alt-Taste ist gedrückt
 begin
    ///////
 end;
 Maus_ssCtrlAlt_erfolgt := 0;                            
 
Damit "umgehe" ich das Problem, indem ich statt Rechts- oder LinksKlick die linke Maustaste mit "Strg" oder "Alt" kombiniert drücke.

TROTZDEM!! Ich würde gerne dazulernen:
Kann mir noch jemand Hinweise geben, wie ich die X- und Y-Koordinaten des DBGrid-Feldes auswerten kann?

Nochmal mein eigentliches Problem:
Es ist für den Anwender recht fehleranfällig, wenn er in einer Liste mit der rechten Maustaste auf einen Eintrag klickt (TDB.Grid) und dann aber immer das Mausereignis bezogen auf den ersten Eintrag der Liste als Ergebnis bekommt. Der Anwender muss immer zuerst mit der linken Maustaste die Zeile anwählen, dann erst kann er mit dem Klick auf die rechte Maus das Ergebnis für diese zuerst selektierte Tabellenzeile erhalten.

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von Michl »

Da ich gerade das gleiche Problem hatte, habe ich mir mal den Linksklick der DBGrid angesehen. Es steht doch eigentlich nichts dem im Weg, einen Linksklick zu simulieren und dann das PopUp auszuführen:

Code: Alles auswählen

procedure TForm1.DBGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssRight in Shift then begin                                 //ist rechte Maustaste gedrückt?!
    with DBGrid1 do MouseDown(mbLeft, [ssLeft], X, Y);           //Linksklick Maustaste "vortäuschen" - Eingriff in Protected-Procedure-MouseDown von TCustomDBGrid - einfach fein, dieses Lazarus!
    PopupMenu1.Items[0].Caption:=DBGrid1.SelectedField.AsString; //Mach irgendwas mit den Daten z.B. Popup
    PopupMenu1.PopUp;
  end;
end; 
Habe ich probiert, funktioniert für meine Zwecke perfekt :D.

[EDIT] Für mich gut ist auch:

Code: Alles auswählen

    with DBGrid1 do MouseDown(mbLeft, [ssLeft], 20, Y);
Gebe ich x einen festen Wert, so habe ich auch gleich mein Auswahlfeld (UNIQUE).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: DBGrid mit rechter Maustaste selektieren (Zeos)

Beitrag von Michl »

Ich bemängel mich mal selbst:

Da lt. Bugtracker http://bugs.freepascal.org/view.php?id=14534 und dortige Diskussion dieses Verhalten (with...) wohl irgendwann abgeschafft wird, ist die zuvor genannte Methode zwar super easy, aber nicht zukunftssicher.

Um trotzdem die Position der rechtsgeklickten Zelle zu erhalten und nicht rechnen zu müssen (übernimmt DBGrid), kann man wie folgt den Linksklick ausführen/vortäuschen:
Eine eigene Klasse von DBGrid ableiten und die Procedure "MouseDown" nach public verschieben:

Code: Alles auswählen

type
  TMeinDBGrid = class(TDBGrid)
  private
  public
    procedure MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer); override;
  end; 
 
  TForm1 = class(TForm)
    DBGrid1: TMeinDBGrid;
    ...
 
procedure TMeinDBGrid.MouseDown(Button: TMouseButton; Shift:TShiftState; X,Y:Integer);
begin
  inherited;
end;
 
procedure TForm1.DBGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssRight in Shift then begin                                 //ist rechte Maustaste gedrückt?!
    DBGrid1.MouseDown(mbLeft, [ssLeft], 20, Y);                  //Linksklick Maustaste "vortäuschen"
    PopupMenu1.Items[0].Caption:=DBGrid1.SelectedField.AsString; //Mach irgendwas mit den Daten z.B. Popup
    PopupMenu1.PopUp;
  end;
end;  

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten