Programowanie w języku Delphi » Gotowce

Numery linii

  • 2015-01-05 01:24
  • 4 komentarze
  • 2563 odsłony
  • Oceń ten tekst jako pierwszy
Zapewne w wielu edytorach widziałeś takie coś: na
dole napisane jest, w której linii znajduje się kursor. My pokażemy
Wam dodatkowo jak przechodzić do dowolnej linii w Memo lub RichEdit i wstawiać tekst właśnie w miejsce ustawionego kursora.

Najpierw funkcja pobierająca numer linii oraz znaku w Memo.

function TMainForm.GetCursor: TPoint;
begin
{
  Jako rezultat Y zostaje przypisana wartość płynąca z komunikatu
  EM_LINEFROMACHER. Komunikat podaje numer linii, w której znajduje
  się kursor. Jeżeli parametr wParam to $FFFF to podaje numer linii, w której
  umieszczony jest kursor.
}
  Result.Y := SendMessage(Memo.Handle, EM_LINEFROMCHAR, -1, 0);
{
  Poniższa wartość niesie ze sobą informacje o numerze znaku w linii.
 
  Komunikat EM_LINEINDEX to informacja o pozycji pierwszego znaku w linii określonej
  poprzez parametr wParam. Jeżeli wParam to $FFFF zwraca numer pierwszego znaku
  w linii, w której znajduje się kursor.
 
  Jeżeli od wartości SelStart komponentu Memo odejmiemy rezultat wykonania
  komunikatu to otrzymamy numer znaku, w którym znajduje się kursor.
}
  Result.X := Memo.SelStart - SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0);
{
  Obie wartości trzeba podnieść o jeden gdyż w Delphi pierwsza linia będzie
  oznaczona jako 0, a my tego nie chcemy :)
}
  Inc(Result.X);
  Inc(Result.Y);
end;


Funkcja ta jako rezultat zwraca zmienną typu TPoint, która przechowuje współrzędne X i Y które oznaczają pozycję w Memo. Właściwie większość ważnych rzeczy została już opisane w komentarzach.

Teraz procedura ustawiająca kursor- trochę prostsza:

procedure TMainForm.SetCursor(Row, Column: Integer);
begin
{
  Pierwsze polecenie ustawia kursor w linii określonej parametrem Row.
  Drugie polecenie dodaje do tego wartość parametru Column, które oznacza
  numer znaku w linii.
}
  Memo.SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0);
  Memo.SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0) + Column;
end;


Dwie główne procedury już mamy - teraz pozostaje je tylko
wykorzystać. Informacje dotyczące pozycji kursora będą wyświetlane
w komponencie typu TPanel:

(****************************************************************)
(*                                                              *)
(*       Copyright (C) 2001 by Service for programmers          *)
(*            Build:  13.04.2001  -  Adam Boduch                *)
(*             HTTP://WWW.PROGRAMOWANIE.OF.PL                   *)
(*      E - mail:  [email protected]                            *)
(*                                                              *)
(****************************************************************)
 
unit MainFrm;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;
 
type
  TMainForm = class(TForm)
    Memo: TMemo;
    Panel: TPanel;
    btnSetCursor: TButton;
    edtLine: TEdit;
    edtChar: TEdit;
    procedure MemoKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure btnSetCursorClick(Sender: TObject);
  private
    procedure SetCursor(Row, Column : LongInt);
    function GetCursor : TPoint;
  end;
 
var
  MainForm: TMainForm;
 
implementation
 
{$R *.DFM}
 
 
function TMainForm.GetCursor: TPoint;
begin
{
  Jako rezultad Y zostaje przypisana wartosc plynaca z komunikatu
  EM_LINEFROMACHER. Komunikat podaje numer linii, w ktorej znajduje
  sie kursor. Jezeli parametr wParam to $FFFF to podaje numer linii, w ktorej
  umieszczony jest kursor.
}
  Result.Y := SendMessage(Memo.Handle, EM_LINEFROMCHAR, -1, 0);
{
  Ponizsza wartosc niesie ze soba informacje o numerze znaku w linii.
 
  Komunikat EM_LINEINDEX to informacja o pozycji pierwszego znaku w linii okreslonej
  poprzez parametr wParam. Jezeli wParam to $FFFF zwraca numer pierwszego znaku
  w linii, w ktorej znajduje sie kursor.
 
  Jezeli od wartosci SelStart komponentu Memo odejmiemy rezultad wykonania
  komunikatu to otrzymamy numer znaku, w ktorym znajduje sie kursor.
}
  Result.X := Memo.SelStart - SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0);
{
  Obie wartosci trzeba podniesc o jeden gdyz w Delphi pierwsza linia bedzie
  oznaczona jako 0, a my tego nie chcemy :)
}
  Inc(Result.X);
  Inc(Result.Y);
end;
 
procedure TMainForm.SetCursor(Row, Column: Integer);
begin
{
  Pierwsze polecenie ustawia kursor w linii okreslonej parametrem Row.
  Drugie polecenie dodaje do tego wartosc parametru Column, ktore oznacza
  numer znaku w linii.
}
  Memo.SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0);
  Memo.SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, -1, 0) + Column;
end;
 
procedure TMainForm.MemoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
{ Jezeli uzytkownik nacisnie klawisz to wywolana zostanie procedura, a
  informacja o numerze linii i znaku pojawi sie na Panelu. }
  Panel.Caption := Format('Linia %d, znak: %d', [GetCursor.Y, GetCursor.X]);
end;
 
procedure TMainForm.btnSetCursorClick(Sender: TObject);
begin
{
  Po nacisnieciu przycisku pobierane zostaja dane z komponentow tekstowych
  i na podst. tych danych w komponencie Memo ustawiany zostaje kursor, a
  w miejsce kursora dodany zostaje tekst.
}
  SetCursor(StrToInt(edtLine.Text), StrToInt(edtChar.Text));
  Memo.SelText := 'www.4programmers.net';
end;
 
end.

4 komentarze

RudyBestyj 2007-03-11 17:48

Do (|) i tyle :P
Zamiast:

Memo.Perform(EM_LINEFROMCHAR, $FFFF, 0)

Powinno być:
SendMessage(Memo.Handle, EM_LINEFROMCHAR, -1, 0)

I wtedy działa OK

uan 2006-08-09 20:09

a dlaczego nie piszesz nic o WordWrap? Gdy WordWrap = True, to zwracany jest numer linii i kolumny z ekranu (zawinięcie wiersza zwiększa ilość linii).
Stawiam browar dla tego kto wie jak wyciągnąć prawdziwy numer linii (w miarę szybko, bez skanowania wszystkich znaków EOL).

migajek 2006-06-25 19:20

"rezultad", "Komunikat podaje numer linii, w ktorej znajduje
  sie kursor. Jezeli parametr wParam to $FFFF to podaje numer linii, w ktorej
  umieszczony jest kursor."
i to Ty Adamie? :P

maciejplonski 2006-04-10 21:54

wstawiłem i mi wyskoczyło duuuuużo błedów