Stringgrid i przewijanie Scrolla zamiast focusa

Stringgrid i przewijanie Scrolla zamiast focusa
maxiu1989
  • Rejestracja:około 13 lat
  • Ostatnio:ponad rok
  • Postów:84
0

Witam

Tym razem chciałbym zrobić tak żeby scroll w myszce przesuwał pozycje scrollbara a nie focusa na stringgridzie.
Jest to bardzo nie naturalne.

Czy to bedzie trzeba robić "StringGrid1MouseWheelDown" i "toprow" ? Czy odblokuje to jakos inaczej?


MaX (PC) DamaGe
edytowany 2x, ostatnio: olesio
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
2

Raczej tego nie odblokujesz, choć nie wiem jakie właściwości i metody są w klasie TStringGrid w nowszych środowiskach, niż Delphi7; Google też wiele nie wyjaśnia w tej sprawie - najprawdopodobniej nie można tego włączyć/wyłączyć za pomocą jakiejś właściwości, jednak można obsłużyć odpowiednie zdarzenia;

EDIT: Udało się napisać algorytm, który bez względu na wysokość poszczególnych wierszy będzie działał poprawnie (a przynajmniej tak wynika z testów); Stary usunąłem z posta;

Działające rozwiązanie:

Kopiuj
procedure TForm1.StringGrid1MouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  intRowsHeightSum, I: Integer;
begin
  Handled := True;

  with (Sender as TStringGrid) do
  begin
    intRowsHeightSum := 0;
    I := TopRow;

    while (I <= RowCount) and (intRowsHeightSum < Height) do
    begin
      Inc(intRowsHeightSum, RowHeights[I]);
      Inc(I);
    end;

    if intRowsHeightSum > Height then
      TopRow := TopRow + 1;
  end;
end;

procedure TForm1.StringGrid1MouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := True;

  with (Sender as TStringGrid) do
    if TopRow > FixedRows then
      TopRow := TopRow - 1;
end;

Mam nadzieję, że nie tylko u mnie działa bez zarzutu.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 4x, ostatnio: flowCRANE
maxiu1989
Twój dużo lepszy, czasami przycina lekko ostatni wiersz, ale to nic takiego :)
maxiu1989
  • Rejestracja:około 13 lat
  • Ostatnio:ponad rok
  • Postów:84
0

Także zrobiłem podobnie.
Źródło : http://www.delphipages.com/forum/showthread.php?t=175685

Zrobiłem coś takiego, załozyłem że 5 wierszy będzie zawsze widoczne.
Wsume wystarczające, ale jeszcze Twój przetestuje :P

Kopiuj
procedure TForm1.StringGrid1MouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
  var
  toprow : integer;
begin
 
if (Shift = [ssShift])  then
Handled := false else //StringGrid1.LeftCol := StringGrid1.LeftCol -1;
begin
Handled := true; //scrolls the grid, not the selection
toprow :=  StringGrid1.topRow;
if StringGrid1.topRow < StringGrid1.RowCount -5 then StringGrid1.topRow := toprow + 1;
end;
end;
 
procedure TForm1.StringGrid1MouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
  var
  toprow : integer;
begin
 
if (Shift = [ssShift]) then
Handled := false else 
begin
Handled := true;
toprow :=  StringGrid1.topRow;
if toprow > 1 then StringGrid1.topRow := toprow - 1;
 
 
end;
end;

MaX (PC) DamaGe
flowCRANE
Przy pisaniu swojej wersji algorytmu posłużyłem się m.in. tym samym artykułem, co podałeś w linku ;)
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
1

Twój dużo lepszy, czasami przycina lekko ostatni wiersz, ale to nic takiego :)

Napisz w jakim przypadku się przycina to postaram się poprawić;


Edit: Do powyższego algorytmu należy dodać także sumowanie wysokości wszystkich FixedRows oraz za każdym razem GridLineWidth żeby obliczenia były dokładniejsze; Żeby nie było żadnych pikselowych wątpliwości i niedociągnięć trzeba znać grubość obwódki kontrolki, którą niestety narzuca system; Poprawiona wersja algorytmu poniżej:

Kopiuj
procedure TForm1.StringGrid1MouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  intRowsHeightSum, I: Integer;
begin
  Handled := True;

  with (Sender as TStringGrid) do
  begin
    intRowsHeightSum := 0;

    for I := 0 to FixedRows - 1 do
      Inc(intRowsHeightSum, RowHeights[I] + GridLineWidth);

    I := TopRow;

    while (I < RowCount) and (intRowsHeightSum <= ClientHeight) do
    begin
      Inc(intRowsHeightSum, RowHeights[I] + GridLineWidth);
      Inc(I);
    end;
 
    if intRowsHeightSum >= ClientHeight then
      TopRow := TopRow + 1;
  end;
end;

Algorytm działa niemalże bezbłędnie ale tylko wtedy, gdy BorderStyle ustawiony jest na bsNone; Jeśli kontrolka będzie miała jakąś obwódkę, to trzeba jej podwójną wartość (jako ramka górna i dolna) wpisać do zmiennej intRowsHeightSum przed pętlą sumującą - wtedy nie będzie pomyłek.

EDIT2: @maxiu1989 - algorytm poprawiłem jeszcze raz - nie trzeba znać grubości obwódki kontrolki, bo jest do dyspozycji właściwość ClientHeight, dzięki której dokładnie wiadomo jaka jest powierzchnia robocza kontrolki; Nie tylko pomijamy grubość ramki kontrolki, ale także grubość poziomego paska przesuwu (Horizontal Scrollbar), który także mieszałby w obliczeniach; Tak więc po raz ostatni modyfikuję algorytm; No chyba, że trzeba go będzie wyposażyć w obsługę jeszcze innych "przeszkadzających" elementów.


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 8x, ostatnio: flowCRANE
maxiu1989
Tak, teraz działa w każdych warunkach. Kawał dobrego gotowca :) Serdeczne dziękuję.
flowCRANE
W każdych będzie działał, jeśli mając BorderStyle na bsSingle znasz szerokość linii obwódki kontrolki - wtedy powinien działać bezbłędnie; Jeśli zaś BorderStyle jest na bsNone - powyższy będzie działał bezbłędnie (a przynajmniej tak wynika z testów); Nie ma sprawy :>
maxiu1989
Wow :D to dogłębnie zbadałeś sprawę, nawet bym o wielu rzeczach nie pomyślał... Hmm

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.