Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi StringGrid und Popupmenü (https://www.delphipraxis.net/51211-stringgrid-und-popupmenue.html)

dioony 8. Aug 2005 14:15


StringGrid und Popupmenü
 
Mittag!

Irgendwie hab ich nicht eine richtige Lösung hier gefunden, daher hoffe ich, dass ihr mir weiterhelfen könnt:

Ich habe ein StrinGrid und wenn man auf eine Zelle klickt öffnet sich durch das OnSelectCell- Ereignis ein dynamisches Popupmenü. Das funktioniert auch soweit. Das Problem besteht nun, wenn das Popupmenü länger ist als die Zeilen des StringGrids. Wenn ich dann nämlich nach unten gehen werden alle Zellen von dem angeklickten bis zum unteren Ende markiert.
Kann man das Markieren irgendwie unterdrücken?

So sieht das ganze aus:

Delphi-Quellcode:

procedure TForm5.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
var items : array of TMenuItem;
var i: Integer;
begin


   if ARow>0 then
   begin
     if ARow<> StringGrid1.RowCount-1 then
     begin
        PopupMenu1.Items.Clear;
        SetLength(items,1);
        if ACol = 1 then
        begin
            SetLength(items,12);
            for i:=1 to 10 do
            begin
              items[i]:=TMenuItem.Create(self);
              items[i].Caption:=inttostr(i);
              if i = strtoint(StringGrid1.Cells[ACol,ARow]) then
              begin
                 items[i].Checked:=true;
              end;
              PopupMenu1.Items.Add(items[i]);
            end;
            SetLength(items,(High(items)+1));
            items[high(Items)]:=TMenuItem.Create(self);
            items[high(Items)].Caption:='andere Anzahl';
            PopupMenu1.Items.Add(items[high(Items)]);
        end;

        if ACol = 2 then
        begin

           SetLength(items,Form2.ListBox6.Count);
           for i:=0 to Form2.ListBox6.Count-1 do
           begin
             items[i]:=TMenuItem.Create(self);
             items[i].Caption:=Form2.ListBox6.Items[i];
             if Form2.ListBox6.Items[i] = StringGrid1.Cells[ACol,ARow] then
             begin
               items[i].Checked:=true;
             end;
             PopupMenu1.Items.Add(items[i]);
           end;
        end;
        if ACol = 3 then
        begin
           SetLength(items,Form2.ListBox8.Count);
           for i:=0 to Form2.ListBox8.Count-1 do
           begin
             items[i]:=TMenuItem.Create(self);
             items[i].Caption:=Form2.ListBox8.Items[i];
             if Form2.ListBox8.Items[i] = StringGrid1.Cells[ACol,ARow] then
             begin
               items[i].Checked:=true;
             end;
             PopupMenu1.Items.Add(items[i]);
           end;
        end;

        SetLength(items,(High(items)+1));
        items[high(Items)]:=TMenuItem.Create(self);
        items[high(Items)].Caption:='-';
        PopupMenu1.Items.Add(items[high(Items)]);


        SetLength(items,(High(items)+1));
        items[high(Items)]:=TMenuItem.Create(self);
        items[high(Items)].Caption:='Bild Löschen';
        PopupMenu1.Items.Add(items[high(Items)]);


        PopupMenu1.Popup(Mouse.CursorPos.X,Mouse.CursorPos.Y);
     end;
   end;
end;
gruß
Dioony

omata 9. Aug 2005 17:56

Re: StringGrid und Popupmenü
 
Moin,

ich würde dafür OnMouseDown benutzen...

Delphi-Quellcode:
procedure TForm.StringGridMouseDown(Sender: TObject;
                                    Button: TMouseButton;
                                    Shift: TShiftState;
                                    X, Y: Integer);
var ACol, ARow:integer;
begin
  if Button = mbRight then begin
    with Sender as TStringGrid do
      MouseToCell(X, Y, ACol, ARow);
    if (ACol > 0) and (ARow > 0) then
      PopupMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
  end;
end;
MfG
Thorsten

marabu 9. Aug 2005 18:32

Re: StringGrid und Popupmenü
 
Hallo Dioony,

deine Anwendung spielt Rambo auf dem Desktop, wenn das PopupMenu sich durch bloßes Anwählen einer Grid-Zelle zeigt. Der Vorschlag von Thorsten mit der rechten Maustaste zielt schon eher in eine akzeptable Richtung, aber warum so kompliziert? Das PopupMenu kann sehr gut statisch an das StringGrid gebunden werden. In meinen Programmen wird das Kontextmenü im Ereignis PopupMenu.OnPopup() konfiguriert.

Grüße vom marabu

omata 9. Aug 2005 18:40

Re: StringGrid und Popupmenü
 
Moin,

das war auch erst mein Gedanke, aber wenn man die PopupMenu-Eigenschaft benutzt, wird es auch geöffnet, wenn man mit der Maus über keinem Gridfeld ist (Außenbereiche). Kann man dann auch das komplette Öffnen des Popupmenus im OnPopup verhindern?

Das war mein Problem, sonst hätte ich auch den Weg über die Popup-Eigenschaft vorgeschlagen.

MfG
Thorsten

marabu 9. Aug 2005 18:57

Re: StringGrid und Popupmenü
 
Hallo Thorsten,

so könnte das aussehen:

Delphi-Quellcode:
procedure TDemoForm.PopupMenuPopup(Sender: TObject);
var
  p: TPoint;
  iCol, iRow: integer;
begin
  with StringGrid do begin
    p := ScreenToClient(PopupMenu.PopupPoint);
    MouseToCell(p.X, p.Y, iCol, iRow);
    if (iCol < FixedCols) or (iRow < FixedRows) then begin
      ShowMessage('what the heck you think you are doing here?');
      Abort;
    end;
  end;
end;
marabu

omata 9. Aug 2005 19:03

Re: StringGrid und Popupmenü
 
Oh ja, das ist eine Möglichkeit. Die kannte ich so noch nicht.
Muss allerdings sagen, das Abort mich doch sehr an die Bösen Dinge wie Goto, Halt, Exit oder Break errinert und deshalb soetwas für mich nicht in Frage kommt.
Aber es ist auf jeden Fall eine Möglichkeit.

MfG
Thorsten

marabu 9. Aug 2005 19:12

Re: StringGrid und Popupmenü
 
Es ist genauso wenig Böses an den von dir aufgezählten Befehlen, wie an einem Brotmesser - ein qualifizierter Benutzer wird es benutzen ohne sich selbst zu verletzen. Abort ist die von den Machern der VCL vorgesehene Methode zum Abbrechen eines Events.

Freundliche Grüße vom marabu

omata 9. Aug 2005 19:28

Re: StringGrid und Popupmenü
 
Ja, mit böse meinte ich nur, dass diese Befehle nichts mit strukturierter Programmierung zu tun haben, weil es Sprungbefehle sind. Natürlich, wenn man weiss was man tut ist immer alles ok. Es geht ja auch mehr darum, so zu programmieren, dass andere es auch verstehen. Naja, wie dem auch sei wir werden hier OT und eigentlich haben wir ja schon gute Lösungen für das Problem gegeben.

Und auch wenn Abort von der VCL der vorgeschriebene Weg ist, die VCL hat auch ein paar unschöne Stellen, dass heisst nicht das das der tollste Weg ist...

Also nichts für ungut...
Thorsten


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz