home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1999 March
/
Chip_1999-03_cd.bin
/
zkuste
/
delphi
/
INFO
/
DI9805RS.ZIP
/
Llist.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-12-31
|
6KB
|
226 lines
unit LList;
interface
uses
Windows, Messages, SysUtils, Graphics, Controls,
Forms, Dialogs, Menus, StdCtrls, Classes;
type
// The linked list cells.
PCell = ^TCell;
TCell = record
Value : String[20]; // The data.
NextCell : PCell; // The next cell in the list.
end;
TLinkedListForm = class(TForm)
ValueText: TEdit;
CmdInsertAfter: TButton;
CmdRemoveAfter: TButton;
procedure FormCreate(Sender: TObject);
procedure CmdInsertAfterClick(Sender: TObject);
procedure CmdRemoveAfterClick(Sender: TObject);
procedure ValueTextChange(Sender: TObject);
procedure DrawList;
procedure FormPaint(Sender: TObject);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure EnableButtons;
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
sentinel : TCell;
num_items : Integer; // For convenience.
selected : Integer; // Selected cell index. 0 = sentinel.
public
{ Public declarations }
end;
var
LinkedListForm: TLinkedListForm;
implementation
{$R *.DFM}
const
HGT = 14;
GAP = 3;
// Initialize the empty linked list.
procedure TLinkedListForm.FormCreate(Sender: TObject);
begin
sentinel.NextCell := nil;
sentinel.Value := '<sentinel>';
num_items := 0;
// Start with no item selected.
selected := -1;
end;
// Add a new cell after the selected cell.
procedure TLinkedListForm.CmdInsertAfterClick(Sender: TObject);
var
after_me, new_cell : PCell;
i : Integer;
begin
// Find the insertion position.
after_me := @sentinel;
for i := 1 to selected do
after_me := after_me^.NextCell;
// Create the new cell.
New(new_cell);
new_cell^.Value := ValueText.Text;
// Insert the cell in the list.
new_cell^.NextCell := after_me^.NextCell;
after_me^.NextCell := new_cell;
num_items := num_items + 1;
// Select the new cell and redisplay the list.
selected := selected + 1;
DrawList;
EnableButtons;
ValueText.Text := '';
ValueText.SetFocus;
end;
// Remove the cell after the selected cell.
procedure TLinkedListForm.CmdRemoveAfterClick(Sender: TObject);
var
after_me, target : PCell;
i : Integer;
begin
// Find the cell before the target cell.
after_me := @sentinel;
for i := 1 to selected do
after_me := after_me^.NextCell;
// Remove the next cell from the list.
target := after_me^.NextCell;
after_me^.NextCell := target^.NextCell;
// Free the target cell's memory.
Dispose(target);
num_items := num_items - 1;
// Redisplay the list.
DrawList;
EnableButtons;
ValueText.SetFocus;
end;
// Enable the appropriate buttons.
procedure TLinkedListForm.ValueTextChange(Sender: TObject);
begin
CmdInsertAfter.Enabled := ((selected >= 0) and
(ValueText.Text <> ''));
end;
// Display the list, highlighting the selected item.
procedure TLinkedListForm.DrawList;
var
cell_ptr : PCell;
i, x, y : Integer;
rect : TRect;
begin
// Clear the form.
rect.Left := 0;
rect.Top := 0;
rect.Right := ClientWidth;
rect.Bottom := ClientHeight;
Canvas.Brush.Color := clLtGray;
Canvas.FillRect(rect);
// Display the list items.
x := ValueText.Left + ValueText.Width + 5;
y := ValueText.Top;
rect.Left := x;
rect.Right := ClientWidth;
cell_ptr := @sentinel;
for i := 0 to num_items do
begin
if (i = selected) then
begin
Canvas.Brush.Color := clBlack;
Canvas.Font.Color := clLtGray;
end else begin
Canvas.Brush.Color := clLtGray;
Canvas.Font.Color := clBlack;
end;
// Fill in the item's background.
rect.Top := y;
rect.Bottom := y + HGT;
Canvas.FillRect(rect);
// Display the text.
Canvas.TextOut(x, y, cell_ptr^.Value);
y := y + HGT + GAP;
// Move to the next cell.
cell_ptr := cell_ptr^.NextCell;
end;
end;
// Redraw the list.
procedure TLinkedListForm.FormPaint(Sender: TObject);
begin
DrawList;
end;
// Select the item clicked.
procedure TLinkedListForm.FormMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i : Longint;
begin
// Do nothing if the mouse is too far left.
if ((X < ValueText.Left + ValueText.Width + 5) or
(Y < ValueText.Top))
then
selected := -1
else begin
// See which item number it is.
i := (y - ValueText.Top) div (HGT + GAP);
if ((i >= 0) and (i <= num_items)) then
selected := i
else
selected := -1;
end;
// Redraw the list.
DrawList;
// Enable the appropriate buttons.
EnableButtons;
end;
procedure TLinkedListForm.EnableButtons;
begin
CmdInsertAfter.Enabled := ((selected >= 0) and
(ValueText.Text <> ''));
CmdRemoveAfter.Enabled := ((selected >= 0) and
(selected < num_items));
end;
// Free all the linked list memory.
// This doesn't matter for this example program. It would
// be important if the program created and destroyed
// many forms.
procedure TLinkedListForm.FormDestroy(Sender: TObject);
var
target : PCell;
begin
while (sentinel.NextCell <> nil) do
begin
target := sentinel.NextCell;
sentinel.NextCell := target^.NextCell;
Dispose(target);
end;
end;
end.