Witam.
Czy da się zrobić coś takiego.
Chodzi i o coś takiego, jedne popMenu1 działa tylko i wyłącznie dla Cells[0,0] a drugie popMenu2 dla reszty całego komponentu położonego na formie.
Pozdrawiam
Janusz
Witam.
Czy da się zrobić coś takiego.
Chodzi i o coś takiego, jedne popMenu1 działa tylko i wyłącznie dla Cells[0,0] a drugie popMenu2 dla reszty całego komponentu położonego na formie.
Pozdrawiam
Janusz
Ogólnie chodzi o to, aby:
TPopupMenu
i nigdzie ich nie podłączać,Grid.OnMouseDown
należy:
X
i Y
,0
:
Grid.PopupMenu
pierwsze menu,Grid.PopupMenu
drugie menu.W Lazarusie wygląda to tak:
procedure TForm1.StringGrid1MouseDown(ASender: TObject; AButton: TMouseButton; AShift: TShiftState; AX, AY: Integer);
var
Grid: TStringGrid absolute ASender;
Cell: TPoint;
begin
if AButton = mbRight then
begin
Cell := Grid.MouseToCell(Point(AX, AY));
if Cell = Point(0, 0) then
Grid.PopupMenu := PopupMenu1
else
Grid.PopupMenu := PopupMenu2;
end;
end;
Spróbuj czegoś podobnego.
Pod Delphi trochę inaczej:
procedure TForm2.StringGrid1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var
CX, CY: Integer;
begin
TStringGrid(Sender).MouseToCell(MousePos.X, MousePos.Y, CX, CY);
if (CX = 0) and (CY = 0) then
TStringGrid(Sender).PopupMenu:= PopupMenu1
else
TStringGrid(Sender).PopupMenu:= PopupMenu2
end;
W ogóle to zdarzenie OnContextPopup
jest lepsze do tego celu, niż OnMouseDown
. Można też zamiast przypisywać menu do właściwości kontrolki, wywołać je samemu za pomocą metody TPopupMenu.Popup
oraz ustawić Handled
na True
.
No i pod Lazarusem, metoda MouseToCell
nie odróżnia kliknięcia w komórkę od kliknięcia w puste miejsce komponentu. W Delphi też tak jest, czy po kliknięciu w wolną przestrzeń zwraca -1
dla współrzędnych?
Działa tylko musiałem ją trochę zmodyfikować. Mam inne parametry wejściowe.
procedure TForm22.gGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var Grid: TgGrid absolute Sender;
ACol, ARow : integer;
begin
if Button = mbRight then
begin
Grid.MouseToCell(X, Y, ACol, ARow);
if (ACol=0) and (ARow=0) then Grid.PopupMenu := popC00
else Grid.PopupMenu := popCxx;
end;
end;
procedure TForm22.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
// oryginalna siatka ma te same parametry
end;
Dziękuje.
Pozdrawiam
Janusz
Menu kontekstowe komponentu TStringGrid
można wywołać dwojako:
Obie te akcje spowodują wywołanie zdarzenia OnContextPopup
, więc to @kAzek podał poprawne i bezpieczne rozwiązanie. Moje również działa, ale nie obsługuje sposobu z klawiaturą.
Może i metoda @kAzek jest i bardziej prawidłowa. Tylko jak tą metodą z klawiatury
obsłuży Cells[0,0] przy FixedCols=1 , FixedRows=1.
Wniosek jest prosty ten myk jest tylko i wyłącznie dla "myszy".
Ale Obaj macie rację. Jeszcze raz dziękuje za pomoc.
Pozdrawiam
Janusz.
Skrótem klawiatury zawsze wyświetla się nad komórką 0,0 ale można to zmienić aby wyświetlało się tam gdzie rzeczywiście jest kursor o ile ten znajduje się nad kontrolką a jeżeli nie to nie wyświetlać popup wcale.
procedure TForm2.StringGrid1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var
CX, CY: Integer;
begin
Handled:= True; //sami w koncu wywolujemy popup
if (MousePos.X = -1) and (MousePos.Y = -1) then //wywolane z klawiatury
begin
GetCursorPos(MousePos);
MousePos:= TStringGrid(Sender).ScreenToClient(MousePos); //pozycja kursora
end;
TStringGrid(Sender).MouseToCell(MousePos.X, MousePos.Y, CX, CY);
if (CX = 0) and (CY = 0) then
TStringGrid(Sender).PopupMenu:= PopupMenu1
else if (CX = -1) or (CY = -1) then exit //na pustym obsarze
else
TStringGrid(Sender).PopupMenu:= PopupMenu2;
MousePos:= TStringGrid(Sender).ClientToScreen(MousePos);
TStringGrid(Sender).PopupMenu.Popup(MousePos.X, MousePos.Y);
end;