// Die Komponente "TTextGrid" ist so etwas wie ein abgespecktes // StringGrid mit zusätzlichen Möglichkeiten. Klingt komisch, // ist aber so. Sie besitzt beispielsweise keine Bildlaufleisten. // Wenn Zeilen oder Spalten nicht angezeigt werden sollen, dann // müssen diese ausgeblendet werden (oder man setzt die Komponente // in eine Scrollbox). Es werden auch nicht alle Tastenkombinationen // unterstützt, und die Komponente verfügt über keinen Inplace-Editor, // sondern benutzt ein angeheftetes Memo zur Texteingabe. Das ist aber // auch der Tatsache geschuldet, dass in den Zellen (außer in Fixed-Zellen) // der Text mehrzeilig angezeigt werden kann. Dafür besitzt aber die // Komponente die Möglichkeit rechteckige Zellbereiche (welche sich // normalerweise nicht überlappen dürfen) zu verbinden. Außerdem kann alles // transparent (außer in einer Scrollbox) oder mit einem Hintergrundbild // dargestellt werden. Zusätzlich können Fixed-Zellen als Buttons benutzt // werden.
// Getestet mit D4 unter XP // Überarbeitet
30.9.2011 unit TextGrid;
interface
uses
Windows, SysUtils, Classes, Graphics, Menus,
Controls, StdCtrls, Messages, ExtCtrls, ClipBrd;
type
TTextGrid = class;
TTGSelS = (tgFull, tgPart);
TTGEd = (tgSelf, tgNo, tgStrange);
TTGCDraw = procedure(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
Selected: boolean; var DefaultDraw: boolean) of object;
TTGDirection = (tgUpWards, tgDownWards, tgLeftWards, tgRightWards);
TTGWheel = procedure(Sender: TObject; Direction: TTGDirection;
ACol, ARow: Integer; var Handled: Boolean) of object;
TTGEDiting = procedure(Sender: TObject; ACol, ARow: Integer;
var EditType: TTGEd; var Edit: TCustomEdit) of object;
TTGEDited = procedure(Sender: TObject; ACol, ARow: Integer;
var S: string) of object;
TTGBack = (tgOpaque, tgPicture, tgTransparent,
tgPicTransparent, tgPicFixTransparent, tgTooFixTransparent);
TTGProc = procedure(Sender: TObject; ACol, ARow: Integer; Different: Boolean)
of object;
TTGEPos = (tgEditBottomLeft, tgEditBottomRight, tgEditLeftBottom,
tgEditLeftTop, tgEditRightTop, tgEditRightBottom,
tgEditTopLeft, tgEditTopRight);
TTGMul = (tgMultiLine, tgSingleLine, tgSingleVCenter, tgDefault);
TTGAlig = (tgLeft, tgCenter, tgRight, tgOuter);
TTGMM = array[0..1, 0..1] of integer;
TTGBorder = (tgNone, tgSingle);
TTGArr = record
width, height, Teilew, Teileh: word;
select, different: boolean;
FColor: integer;
FTextLine: TTGMul;
Text: string;
end;
TFHlpCtrl = class(TWinControl)
private
FGrphCtrl: TTextGrid;
protected
FEdit: TMemo;
FL: TLabel;
function KeyDataToShiftState(KeyData: Longint): TShiftState;
procedure Mousewheel(var M: TMessage); message WM_MOUSEWHEEL;
procedure CMDIALOGKEY(var Alt: TWMKey); message CM_DIALOGKEY;
procedure WMKeyDown(var M: TWMKeyDown); message WM_KEYDOWN;
procedure CMEnter(var M: TWMNoParams); message CM_ENTER;
procedure CMExit(var M: TWMNoParams); message CM_EXIT;
procedure WMKeyUp(var M: TWMKeyUp); message WM_KEYUP;
procedure WndProc(var M: TMessage); override;
public
procedure zuClick(Sender: TObject);
constructor Create(AOwner: TComponent;
GrphCtrl: TTextGrid); reintroduce;
destructor Destroy; override;
property TabStop;
property TabOrder;
end;
TTextGrid = class(TGraphicControl)
private
FSD2, FSPS, FCol, FRow, Fi, FMs, FMz, Fu, FSelx, FSely, FZahl: integer;
FFlat, FFoc, FMsg, Fedg, Fda, FDown, FFixBttn, FDD, FDDP,
FEdge, FCt, FTip, FAuto, FPermit, FMatic, FRast: boolean;
FFixC, FPC, FSelC, FNofo, FDisC, FFDisC, FFocusC: TColor;
FLW, FZ, FD2, FFC, FFR, FNW, FNH, FMedg: byte;
FOnEnter, FOnExit: TNotifyEvent;
FOnKeyDown, FOnKeyUp: TKeyEvent;
FArr: array of array of TTGArr;
Fmi: array[0..9] of TMenuItem;
FProcDwn, FProcUp: TTGProc;
FS1, FS2, FVersion: string;
FAlig: array of integer;
FWheel, FDrct: TTGWheel;
FCurM, FCurC: TCursor;
FEditing: TTGEditing;
FFStyle: TFontstyles;
FHlpCtrl: TFHlpCtrl;
FEdited: TTGEDited;
FPop: TPopupMenu;
FRand: TTGBorder;
FCDraw: TTGCDraw;
FStelle: TPoint;
FTimer: TTimer;
FBack: TTGBack;
FPic: TPicture;
FEPos: TTGEPos;
FCC, FRC: word;
FSelS: TTGSelS;
FMulti: TTGMul;
FBmp: TBitmap;
protected
procedure weg;
procedure danach;
procedure setNoFo(c: TColor);
procedure setEFont(f: TFont);
procedure setEdge(b: boolean);
procedure setFCt(b: boolean);
procedure meldung(s: string);
procedure setEPos(p: TTGEPos);
procedure setFixstyle(f: TFontstyles);
procedure SetParent(AParent: TWinControl); override;
procedure SetTabOrder(const Value: Integer);
procedure SetTabStop(const Value: Boolean);
procedure DestroyHlpControl;
procedure DoKeyDown(var Key: Word; Shift: TShiftState);
procedure DoKeyUp(var Key: Word; Shift: TShiftState);
procedure CreateHlpControl(AOwner: TComponent; AParent: TWinControl);
procedure setFocusC(c: TColor);
procedure SetPen(Clr: TColor; Width: Integer; Style: TPenStyle);
procedure paint; override;
procedure Resize; override;
procedure setFEC(c: TColor);
procedure setDisC(c: TColor);
procedure setFDisC(c: TColor);
procedure setRand(r: TTGBorder);
procedure setColv(i: integer);
procedure setFoc(c: boolean);
procedure setRowv(i: integer);
procedure setMulti(b: TTGMul);
procedure setFlat(b: boolean);
procedure setSelC(c: TColor);
procedure setCol(i: integer);
procedure setRow(i: integer);
procedure setCC(w: word);
procedure setRC(w: word);
procedure setFLW(b: byte);
procedure setFFC(b: byte);
procedure setFFR(b: byte);
procedure setPC(c: TColor);
procedure setFNH(b: byte);
procedure setFNW(b: byte);
procedure setFix(c: TColor);
procedure setBack(b: TTGBack);
procedure setPic(p: TPicture);
procedure setCll(x, y: Word; s: string);
procedure setFCl(x, y: word; t: integer);
procedure setCLine(x, y: word; t: TTGMul);
procedure setrh(y, i: word);
procedure setcw(x, i: word);
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X: integer; Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X: integer; Y: Integer); override;
procedure MouseMove(Shift: TShiftState;
X: integer; Y: Integer); override;
procedure EditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure prfLine(x, y: integer; s: string);
procedure setAl(x: word; u: TTGAlig);
procedure OnTimer(Sender: TObject);
procedure click0(sender: TObject);
procedure click1(sender: TObject);
procedure click2(sender: TObject);
procedure click3(sender: TObject);
procedure click4(sender: TObject);
procedure click6(sender: TObject);
procedure click8(sender: TObject);
procedure EditTipFontC(c: Tcolor);
procedure nachrechts(b: boolean);
procedure nachunten(b: boolean);
procedure nachlinks(b: boolean);
procedure nachoben(b: boolean);
procedure setSelS(s: TTGSelS);
procedure setFtip(b: boolean);
procedure EditTipC(c: Tcolor);
procedure home(b: boolean);
procedure ende(b: boolean);
procedure selectieren;
procedure einrichten;
procedure buildRow;
procedure makeback;
procedure buildCol;
procedure DoEnter;
procedure DoExit;
procedure MWeis;
procedure loose;
procedure neu;
procedure ok;
function cw(w: word): word;
function GetFocused: Boolean;
function GetTabStop: Boolean;
function GetCanFocus: Boolean;
function ueberschreiben: boolean;
function multpw(x, y: word): word;
function multph(x, y: word): word;
function waag(x, y: integer): integer;
function senk(x, y: integer): integer;
function zelle(x, y: integer): TPoint;
function l0test(x1, y1, x2, y2: word; out p: TPoint): byte;
function LoadGrid(st: TStream; q: integer): boolean;
function SaveGrid(st: TStream; q: integer): boolean;
function istext(b, immer: boolean): boolean;
function innercol(x1, x2: word): boolean;
function innerrow(y1, y2: word): boolean;
function cline(x, y: word): TTGMul;
function fcl(x, y: word): integer;
function cll(x, y: Word): string;
function Al(x: word): TTGAlig;
function GetTabOrder: Integer;
function rh(w: word): word;
function getETFC: TColor;
function getEfont: TFont;
function getETC: TColor;
function minmax: TTGMM;
function FEC: TColor;
public
constructor Create(Owner: TComponent); override;
destructor Destroy; override;
function SelCount: Cardinal;
function DifferentCount: Cardinal;
function SeparateCells(x, y: word): boolean;
function SaveToStream(st: TStream): boolean;
function Inside(x, y: integer): boolean;
function LoadFromStream(st: TStream): boolean;
function AlignmentToStr(alg: TTGAlig): string;
function SaveBasicsToStream(st: TStream): boolean;
function LoadBasicsFromStream(st: TStream): boolean;
procedure MouseToCell(x, y: integer; Rahmen: boolean;
out ACol, ARow: integer);
procedure Reset;
procedure SetFocus;
procedure ClearText;
procedure SeparateAll;
procedure DeleteCols(x1, x2: word);
procedure DeleteRows(y1, y2: word);
procedure ColWidthsX(x1, x2, degree: word);
procedure MergeCells(x1, y1, x2, y2: word);
procedure RowHeightsX(y1, y2, degree: word);
property CellLine[x, y: word]: TTGMul read cline write setcline;
property FontColor[x, y: Word]: integer read fcl write setfcl;
property Alignments[x: word]: TTGAlig read Al write setAl;
property Cells[x, y: Word]: string read cll write setCll;
property RowHeights[y: word]: word read rh write setrh;
property ColWidths[x: word]: word read cw write setcw;
property CanFocus: Boolean read GetCanFocus;
property Focused: Boolean read GetFocused;
property Canvas;
published
property Font;
property Color;
property Visible;
property Enabled;
property ShowHint;
property ParentFont;
property ParentColor;
property ParentShowHint;
property MoveCopy: boolean read FDDP write FDDP;
property CursorIfMove: TCursor read FCurM write FCurM;
property CursorIfCopy: TCursor read FCurC write FCurC;
property FixFontStyle: TFontstyles read FFStyle write setFixStyle;
property EditTipFontColor: TColor read getETFC write EditTipFontC;
property TabOrder: Integer read GetTabOrder write SetTabOrder;
property FixDisabledColor: TColor read FFDisc write setFDisC;
property LineFocusColor: TColor read FFocusC write setFocusc;
property TabStop: Boolean read GetTabStop write SetTabStop;
property FixButtons: boolean read FFixBttn write FFixBttn;
property NoFocusSelColor: TColor read FNofo write setNofo;
property BorderStyle: TTGBorder read Frand write setRand;
property WheelPermit: boolean read FPermit write FPermit;
property EditTipColor: TColor read getETC write EditTipC;
property DisabledColor: TColor read FDisc write setDisC;
property EditPosition: TTGEPos read FEPos write setEPos;
property SelectStyle: TTGSelS read FSelS write setSels;
property DefaultRowHeight: byte read FNH write setFNH;
property EditFont: TFont read getEFont write SetEFont;
property EditBackGround: TColor read FEC write setFEC;
property SelectColor: TColor read FSelc write setSelC;
property BackGround: TTGBack read FBack write setBack;
property EditShowTip: boolean read FTip write setFTip;
property TextLine: TTGMul read FMulti write setMulti;
property DefaultColWidth: byte read FNW write setFNW;
property AutoSpread: boolean read FAuto write FAuto;
property FixFlat: boolean read FFlat write setFlat;
property FocusRect: boolean read FFoc write setFoc;
property Picture: TPicture read FPic write setPic;
property FixCenter: boolean read FCt write setFCt;
property FixColor: TColor read FFixC write setFix;
property Messages: boolean read FMsg write FMsg;
property LineColor: TColor read FPC write setPC;
property Edge: boolean read FEdge write setEdge;
property Editing: boolean read Fedg write Fedg;
property LineWidth: byte read FLW write setFLW;
property FixedCols: byte read FFC write setFFC;
property FixedRows: byte read FFR write setFFR;
property ColCount: Word read FCC write setCC;
property RowCount: Word read FRC write setRC;
property Col: integer read FCol write setCol;
property Row: integer read FRow write setRow;
property OnFixButtonDown: TTGProc read FProcDwn write FProcDwn;
property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
property OnEditing: TTGEDiting read FEditing write FEditing;
property OnEnter: TNotifyEvent read FOnEnter write FOnEnter;
property OnFixButtonUp: TTGProc read FProcUp write FProcUp;
property OnExit: TNotifyEvent read FOnExit write FOnExit;
property OnKeyUp: TKeyEvent read FOnKeyUp write FOnKeyUp;
property OnChgDirection: TTGWheel read FDrct write FDrct;
property OnEdited: TTGEdited read FEdited write FEdited;
property OnDrawCell: TTGCDraw read FCDraw write FCDraw;
property OnWheel: TTGWheel read FWheel write FWheel;
property OnMouseDown;
property OnMouseMove;
property OnDblClick;
property OnMouseUp;
property OnClick;
end;
procedure Register;
implementation
constructor TTextGrid.Create(Owner: TComponent);
var
x, y: integer;
begin
inherited Create(Owner);
ParentFont := false;
FHlpCtrl := nil;
CreateHlpControl(nil, TWinControl(Owner));
FPop := TPopupMenu.create(Self);
for x := 0 to high(Fmi) do begin
Fmi[x] := TMenuItem.Create(FPop);
FPop.items.add(Fmi[x]);
end;
FTimer := TTimer.create(self);
FTimer.interval := 0;
FTimer.OnTimer := OnTimer;
Fmi[0].caption := 'Zellen verbinden';
Fmi[1].caption := 'Zellen separieren';
Fmi[2].caption := 'Zell-Text editieren';
Fmi[3].caption := 'Zell-Text löschen';
Fmi[4].caption := 'Alle Texte löschen';
Fmi[5].caption := 'Alle Zellverbände separieren';
Fmi[6].caption := 'Ausschneiden';
Fmi[7].caption := 'Kopieren';
Fmi[8].caption := 'Einfügen';
Fmi[9].caption := 'Abbrechen';
Fmi[0].onclick := click0;
Fmi[1].onclick := click1;
Fmi[2].onclick := click2;
Fmi[3].onclick := click3;
Fmi[4].onclick := click4;
Fmi[5].onclick := click4;
Fmi[6].onclick := click6;
Fmi[7].onclick := click6;
Fmi[8].onclick := click8;
FS1 := 'HINWEIS';
FS2 := ' nicht bearbeitet werden, ' +
'da sonst Zellverbände zerstört würden. ';
FVersion := 'DBRTG1.6';
Fedg := true;
FEPos := tgEditBottomLeft;
FSPS := PS_GEOMETRIC or PS_ENDCAP_SQUARE or PS_JOIN_BEVEL;
FDD := false;
FDDP := true;
FMsg := true;
color := clWhite;
FNofo := $DFD4D2;
FFixC := clBtnFace;
FPic := TPicture.create;
FBmp := TBitmap.create;
FEdge := true;
FMedg := 0;
FTip := true;
FRast := false;
FAuto := false;
FMulti := tgSingleVCenter;
FMatic := false;
FFixBttn := true;
Fu := DT_SINGLELINE;
FFDisC := clBtnShadow;
FFocusC := clblack;
FDisC := clBtnFace;
FSelC := $BFB4B2;
FPC := $999999;
FNW := 64;
FNH := 24;
FCC := 5;
FRC := 5;
FLW := 1;
FFC := 1;
FFR := 1;
FZ := 0;
FZahl := 0;
FSelx := -1;
FSely := FSelx;
FFoc := false;
FPermit := true;
setlength(FArr, FCC + 1, FRC + 1);
setlength(FAlig, FCC + 1);
for x := 0 to FCC do begin
FAlig[x] := DT_LEFT;
for y := 0 to FRC do begin
FArr[x, y].width := FNW;
FArr[x, y].height := FNH;
FArr[x, y].select := false;
FArr[x, y].different := false;
FArr[x, y].text := '';
FArr[x, y].FColor := maxint;
FArr[x, y].FTextLine := tgDefault;
FArr[x, y].Teilew := 1;
FArr[x, y].Teileh := 1;
end;
end;
FCol := 1;
FRow := 1;
FArr[FCOL, FROW].select := true;
FCurM := crDrag;
FCurC := crMultiDrag;
end;
procedure TTextGrid.SetPen(Clr: TColor;
Width: Integer; Style: TPenStyle);
var
LogBrush: TLogBrush;
begin
ZeroMemory(@LogBrush, SizeOf(LogBrush));
LogBrush.lbColor := Clr;
Canvas.Pen.Handle := ExtCreatePen(FSPS or Ord(Style),
Width, LogBrush, 0, nil);
end;
destructor TTextGrid.Destroy;
var
x: integer;
begin
DestroyHlpControl;
for x := 0 to high(Fmi) do Fmi[x].free;
FPop.free;
FBmp.free;
FPic.free;
FTimer.free;
inherited Destroy;
end;
destructor TFHlpCtrl.Destroy;
begin
FEdit.free;
FL.free;
inherited Destroy;
end;
procedure TFHlpCtrl.zuClick(Sender: TObject);
begin
FGrphCtrl.ok;
end;
function TFHlpCtrl.KeyDataToShiftState(KeyData: Longint): TShiftState;
begin
Result := [];
if GetKeyState(VK_SHIFT) < 0 then Include(Result, ssShift);
if GetKeyState(VK_CONTROL) < 0 then Include(Result, ssCtrl);
if KeyData and $20000000 <> 0 then Include(Result, ssAlt);
end;
procedure TTextGrid.paint;
var
x, y, z, x1, y1, x2, y2, i, j, tp, bt, m, fd, u, th: integer;
rct, irct: TRect;
f, fsd, dd, d3: Boolean;
ftc: TColor;
fs: TFontStyles;
s: string;
function ohne(const ss: string): string;
var
a: integer;
begin
result := '';
for a := 1 to length(ss) do
if ss[a] = #13 then result := result + #32
else if ss[a] <> #10 then result := result + ss[a];
end;
function tst: boolean;
begin
result := not FFlat or (FDown and (x = FCol) and (Y = FRow));
end;
begin
fd := 0;
Canvas.Font := Font;
ftc := Font.color;
fs := Font.style;
fsd := GetFocused;
with Canvas do begin
th := textheight('Äy');
if (FBack = tgPicture) or (FBack = tgPicTransparent)
or (FBack = tgPicFixTransparent)
then begin
makeback;
draw(0, 0, FBmp);
end;
if (FBack = tgOpaque)
then begin
if enabled then brush.color := color
else brush.color := FDisC;
fillrect(cliprect);
end;
y1 := fz + FD2 - FMedg;
for y := 0 to FRC - 1 do begin
y2 := y1 + Farr[FCC, y].height + FLW;
m := y2;
x1 := fz + FD2 - FMedg;
x2 := x1 + FArr[0, y].width + FLW;
for x := 0 to FCC - 1 do begin
d3 := (FArr[x, y].height > 2) and (FArr[x, y].width > 2);
f := (x < FFC) or (y < FFR);
if FLW = 0 then pen.style := psclear else begin
if fsd then SetPen(FFocusC, FLW, psSolid)
else SetPen(FPC, FLW, psSolid);
end;
if (FArr[x, y].FTextline = tgDefault)
and (FMulti <> tgMultiLine)
or (FArr[x, y].FTextline <> tgDefault)
and (FArr[x, y].FTextline <> tgMultiLine)
then
s := ohne(FArr[x, y].text)
else s := FArr[x, y].text;
if f then
u := DT_VCENTER or DT_SINGLELINE or FAlig[x] * ord(not FCT)
or ord(FCT) * DT_CENTER
else begin
if FARR[x, y].FTextline <> tgDefault then begin
case FARR[x, y].FTextline of
tgMultiline:
u := DT_WORD_ELLIPSIS or DT_WORDBREAK;
tgSingleVCenter: u := DT_SINGLELINE or DT_VCENTER
or FAlig[x];
else u := DT_SINGLELINE or FAlig[x];
end;
u := u or DT_END_ELLIPSIS * ord(FAlig[x] = DT_LEFT);
end else begin
u := Fu or ord(FMulti = tgSingleVCenter) * DT_VCENTER;
u := u or DT_END_ELLIPSIS * ord(FAlig[x] = DT_LEFT)
or FAlig[x] * ord(FMulti <> tgMultiLine);
end;
end;
i := 0;
j := 0;
if FArr[x, y].width > 0 then begin
j := -FLW * ord(FArr[x, FRC].width = 0);
z := succ(x);
while (FArr[z, y].width = 0) do
begin
if (FArr[z, FRC].width > 0) then
inc(j, FLW);
inc(z);
end;
end;
if not f or (FBack = tgTooFixTransparent)
or (FBack = tgPicFixTransparent)
then brush.style := bsclear;
if FArr[x, y].height > 0 then begin
y2 := y1 + FArr[x, y].height + FLW;
i := -FLW * ord(FArr[FCC, y].height = 0);
z := succ(y);
while (FArr[x, z].height = 0) do begin
if (FArr[FCC, z].height > 0) then
inc(i, FLW);
inc(z);
end;
end else y2 := y1;
irct := rect(x1, y1, x2 + j, y2 + i);
dd := true;
if assigned(FCDraw) then
FCDraw(self, x, y, irct, FArr[x, y].select, dd);
if dd then begin
Farr[x, y].different := false;
if Farr[x, y].select or f then begin
if f then begin
if (FBack <> tgTooFixTransparent)
and (FBack <> tgPicFixTransparent)
then begin
if enabled then
brush.color := FFixC
else brush.color := FFDisC;
end;
end else begin
if fsd then
brush.color := FSelC else
brush.color := FNofo;
if (FSelS = tgPart) then begin
inc(irct.left, FsD2 + 3);
inc(irct.top, FsD2 + 3);
dec(irct.right, FD2 + 2);
dec(irct.bottom, FD2 + 2);
end;
end;
fillrect(irct);
end;
end else
FArr[x, y].different := true;
moveto(x1, y1);
if FArr[x, y].height > 0 then
lineto(x2 + j, y1)
else moveto(x2 + j, y1);
if FArr[x, y].width > 0
then lineto(x2 + j, y2 + i)
else moveto(x2 + j, y2 + i);
if ((FArr[x, y].height > 0)
or (y = FRC)) and (FMedg = 0) then
lineto(x1, y2 + i)
else moveto(x1, y2 + i);
if FArr[x, y].width > 0
then lineto(x1, y1);
if FFoc and (x = FCol) and (y = FRow) and not f and dd
and (fsd or (csDesigning in ComponentState))
then drawfocusrect(rect(x1 + 2 + FsD2, y1 + 2 + FsD2,
x2 - 1 - FD2 + j, y2 - 1 - FD2 + i));
if f and dd then begin
Font.Style := FFStyle;
if d3 then begin
pen.width := 1;
pen.style := pssolid;
if not FDown or (x <> FCol) or (Y <> FRow)
then begin
pen.color := clWhite;
fd := 0;
end
else pen.color := clblack;
if tst then begin
moveto(x1 + FsD2 + 1, y2 - 1 - FD2);
lineto(x1 + FsD2 + 1, y1 + FsD2 + 1);
lineto(x2 - FD2, y1 + FsD2 + 1);
end;
if not FDown or (x <> FCol) or (Y <> FRow)
then pen.color := clblack
else begin
pen.color := clWhite;
fd := 1;
end;
if tst then begin
moveto(x2 - 1 - FD2, y1 + 2 + FsD2);
lineto(x2 - 1 - FD2, y2 - FD2 - 1);
lineto(x1 + FsD2 + 1, y2 - FD2 - 1);
end;
end;
end else begin
fd := 0;
Font.Style := fs;
end;
if y2 > y1 then begin
if FArr[x, y].FColor <> maxint then
Font.Color := FArr[x, y].FColor
else Font.color := ftc;
if dd and d3 then begin
tp := y1 + 4 + FsD2 + fd;
if (FMulti = tgMultiline) and (FArr[x, y].FTextline = tgDefault)
or (FArr[x, y].FTextline = tgMultiline) then
bt := tp + ((y2 - FD2 + i - 3 - tp) div th) * th else
bt := y2 - FD2 + i - 3;
rct := rect(x1 + FsD2 + 4 + fd, tp, x2 - 3 - FD2 + j, bt);
drawtext(handle, pchar(s), -1, rct, u);
end;
end;
x1 := x2;
if FArr[x + 1, FRC].width > 0 then
x2 := x1 + FArr[x + 1, y].width + FLW;
end;
y1 := m - ord(FArr[FCC, y].height = 0) * FLW;
end;
if Frand = tgSingle
then begin
pen.style := pssolid;
pen.width := 1;
pen.color := $A0A0A0;
moveto(0, height - 1);
lineto(0, 0);
lineto(width, 0);
pen.color := clBlack;
moveto(1, height - 2);
lineto(1, 1);
lineto(width - 1, 1);
pen.color := $EEEEEE;
moveto(2, height - 2);
lineto(width - 2, height - 2);
lineto(width - 2, 1);
pen.color := clwhite;
moveto(1, height - 1);
lineto(width - 1, height - 1);
lineto(width - 1, 0);
end;
end;
end;
procedure TTextGrid.resize;
var
x, g, w2, h2, a, th: integer;
begin
FMedg := ord(not FEdge) * FLW;
a := (Fz - FMedg) * 2;
th := Fi * ord(FTip);
g := 0;
for x := 0 to FCC - 1 do
inc(g, multpw(x, FRC) + FLW * ord(Farr[x, FRC].width > 0));
width := (g + FLW) * ord(FNW > 0) + a;
g := 0;
for x := 0 to FRC - 1 do
inc(g, multph(FCC, x) + FLW * ord(Farr[FCC, x].height > 0));
height := (g + FLW) * ord(FNH > 0) + a;
if Fda then begin
Fda := false;
if FTip then
FHlpCtrl.brush.color := FHlpCtrl.FL.color;
h2 := 89 + th;
w2 := 185;
case FEPos of
tgEditBottomLeft: begin
FHlpCtrl.FEdit.height := 85;
FHlpCtrl.SetBounds(left, top + height,
w2, FHlpCtrl.FEdit.height + th);
end;
tgEditBottomRight: begin
FHlpCtrl.FEdit.height := 85;
FHlpCtrl.SetBounds(boundsrect.right - w2, top + height,
w2, FHlpCtrl.FEdit.height + th);
end;
tgEditTopLeft: begin
FHlpCtrl.FEdit.height := 85;
FHlpCtrl.SetBounds(left, top - FHlpCtrl.FEdit.height - th,
w2, FHlpCtrl.FEdit.height + th);
end;
tgEditTopRight: begin
FHlpCtrl.FEdit.height := 85;
FHlpCtrl.SetBounds(boundsrect.right - w2,
top - FHlpCtrl.FEdit.height - th,
w2, FHlpCtrl.FEdit.height + th);
end;
tgEditRightTop: begin
FHlpCtrl.FEdit.height := h2 - th;
FHlpCtrl.SetBounds(boundsrect.right, top,
w2, h2);
end;
tgEditRightBottom: begin
FHlpCtrl.FEdit.height := h2 - th;
FHlpCtrl.SetBounds(boundsrect.right, boundsrect.bottom - h2,
w2, h2);
end;
tgEditLeftTop: begin
FHlpCtrl.FEdit.height := h2 - th;
FHlpCtrl.SetBounds(left - w2, top,
w2, FHlpCtrl.FEdit.height + th);
end;
else begin
FHlpCtrl.FEdit.height := h2 - th;
FHlpCtrl.SetBounds(left - w2, boundsrect.bottom - h2,
w2, FHlpCtrl.FEdit.height + th);
end;
end;
FHlpCtrl.FEdit.width := FHlpCtrl.width;
FHlpCtrl.FL.left := (w2 - FHlpCtrl.FL.width) div 2;
FHlpCtrl.FL.top := FHlpCtrl.height - FHlpCtrl.FL.height - 2;
end else weg;
invalidate;
end;
procedure TTextGrid.setBack(b: TTGBack);
begin
if b = FBack then exit;
FBack := b;
invalidate;
end;
procedure TTextGrid.setRC(w: word);
var
x, m, y, b, i: integer;
begin
if w < 1 then w := 1;
if w = FRC then exit;
if (w < FRC) and not (csDesigning in ComponentState) then begin
if not Fedg then begin
meldung('Das Verringern der Zeilenzahl');
exit;
end;
if innerrow(w, FRC - 1) then exit;
end;
m := FRC;
i := m;
FRC := w;
if w > m then
setlength(FArr, FCC + 1, FRC + 1);
for x := 0 to FCC do begin
b := FArr[x, i].width;
for y := m to w do begin
FArr[x, y].Teileh := 1;
FArr[x, y].height := FNH;
FArr[x, y].width := b;
FArr[x, y].Teilew := 1;
FArr[x, y].select := false;
FArr[x, y].different := false;
FArr[x, y].text := '';
FArr[x, y].FColor := Font.color;
end;
end;
if m > w then
setlength(FArr, FCC + 1, FRC + 1);
neu;
end;
procedure TTextGrid.setCC(w: word);
var
x, m, y, h, i: integer;
begin
if w < 1 then w := 1;
if w = FCC then exit;
if (w < FCC) and not (csDesigning in ComponentState) then begin
if not Fedg then begin
meldung('Das Verringern der Spaltenzahl');
exit;
end;
if innercol(w, FCC - 1) then exit;
end;
m := FCC;
i := m;
FCC := w;
setlength(FAlig, FCC + 1);
if w > m then
setlength(FArr, FCC + 1, FRC + 1);
for y := 0 to FRC do begin
h := FArr[i, y].height;
for x := m to w do begin
FArr[x, y].Teilew := 1;
FArr[x, y].width := FNW;
FArr[x, y].height := h;
FArr[x, y].Teileh := 1;
FArr[x, y].select := false;
FArr[x, y].different := false;
FArr[x, y].text := '';
FArr[x, y].FColor := Font.color;
FAlig[x] := DT_LEFT;
end;
end;
if m > w then
setlength(FArr, FCC + 1, FRC + 1);
neu;
end;
procedure TTextGrid.neu;
begin
resize;
invalidate;
end;
procedure TTextGrid.einrichten;
var
x, y, i: integer;
begin
for x := 0 to FCC - 1 do begin
i := 0;
for y := 0 to FRC - 1 do begin
if FArr[x, y].height > 0 then begin
i := y;
FArr[x, y].height := FArr[FCC, y].height;
end
else if FArr[FCC, y].height > 0 then
FArr[x, i].height := FArr[x, i].height + FArr[FCC, y].height;
end;
end;
for y := 0 to FRC - 1 do begin
i := 0;
for x := 0 to FCC - 1 do begin
if FArr[x, y].width > 0 then begin
i := x;
FArr[x, y].width := FArr[x, FRC].width;
end
else if FArr[x, FRC].width > 0 then
FArr[i, y].width := FArr[i, y].width + FArr[x, FRC].width;
end;
end;
end;
procedure TTextGrid.setFLW(b: byte);
begin
if b = FLW then exit;
FLW := b;
FD2 := FLW div 2;
FSD2 := pred(FLW) div 2;
if FD2 + FsD2 = 0 then FsD2 := -1;
einrichten;
neu;
end;
procedure TTextGrid.setFFC(b: byte);
var
x, i, y: integer;
begin
if b > FCC then b := FCC;
if b = FFC then exit;
i := FFC;
FFC := b;
if b > FCOl then
begin
FCol := -1;
FRow := -1;
end;
if FFC > i then
for x := i to FFC do
for y := FFR to FRC - 1 do
FArr[x, y].text := '';
invalidate;
end;
procedure TTextGrid.setFFR(b: byte);
var
x, i, y: integer;
begin
if b > FRC then b := FRC;
if b = FFR then exit;
i := FFR;
FFR := b;
if b > FROW then
begin
FCol := -1;
FRow := -1;
end;
if FFR > i then
for x := FFC to FRC - 1 do
for y := i to FFR do
FArr[x, y].text := '';
invalidate;
end;
procedure TTextGrid.setFlat(b: boolean);
begin
if b = FFlat then exit;
FFlat := b;
invalidate;
end;
procedure TTextGrid.setPC(c: TColor);
begin
if c = FPC then exit;
FPC := c;
invalidate;
end;
procedure TTextGrid.setFNH(b: byte);
var
x, y: integer;
begin
FNH := b;
loose;
for y := 0 to FRC do
for x := 0 to FCC do begin
FARR[x, y].height := b;
FARR[x, y].Teileh := 1;
end;
selectieren;
neu;
end;
procedure TTextGrid.setFNW(b: byte);
var
x, y: integer;
begin
FNW := b;
loose;
for y := 0 to FRC do
for x := 0 to FCC do begin
FARR[x, y].width := b;
FARR[x, y].Teilew := 1;
end;
selectieren;
neu;
end;
procedure TTextGrid.setRand(r: TTGBorder);
begin
if r = FRand then exit;
FRand := r;
Fz := ord(r = tgSingle) * 2;
neu;
end;
procedure TTextGrid.setFix(c: TColor);
begin
if c = FFixC then exit;
FFixC := c;
invalidate;
end;
procedure TTextGrid.setDisC(c: TColor);
begin
if c = FDisC then exit;
FDisC := c;
if not enabled then invalidate;
end;
procedure TTextGrid.setFDisC(c: TColor);
begin
if c = FFDisC then exit;
FFDisC := c;
if not enabled then invalidate;
end;
procedure TTextGrid.setpic(p: TPicture);
begin
FPic.assign(p);
makeback;
invalidate;
end;
procedure TTextGrid.makeback;
var
x, y, z: integer;
begin
if Fpic = nil then exit;
if (FPic.Height > 0) and (FPic.height > 0) then begin
FBmp.width := width;
FBmp.height := height;
with FBmp.canvas do begin
brush.color := color;
fillrect(cliprect);
end;
if (FBack <> tgPicTransparent) and (FBack <> tgPicFixTransparent)
then FBack := tgPicture;
z := height div FPic.height;
for x := 0 to width div FPic.width do
for y := 0 to z do
FBmp.canvas.draw(x * FPic.width, y * FPic.height, FPic.Graphic);
if (FBack = tgPicTransparent) or (FBack = tgPicFixTransparent)
then begin
FBmp.Transparentcolor := color;
FBmp.Transparent := true;
end else FBmp.Transparent := false;
end else begin
FBmp.width := 0;
FBmp.height := 0;
end;
end;
procedure TTextGrid.setMulti(b: TTGMul);
var
x, y: integer;
begin
FMulti := b;
if b = tgMultiline then
Fu := DT_Word_ELLIPSIS or DT_WORDBREAK
else Fu := DT_SINGLELINE;
for x := 0 to FCC - 1 do
for y := 0 to FRC - 1 do
FArr[x, y].FTextline := tgDefault;
invalidate;
end;
function TTextGrid.cll(x, y: Word): string;
begin
if (x < FCC) and (y < FRC) then
result := FArr[x, y].text
else result := '';
end;
procedure TTextGrid.prfLine(x, y: integer; s: string);
begin
if (FArr[x, y].text = '') and (s <> '') and Parent.visible
and (x >= FFC) and (y >= FFR) and (FAlig[x] <> DT_LEFT)
and ((FMulti = tgMultiline) and (FArr[x, y].FTextline = tgDefault)
or (FArr[x, y].FTextline = tgMultiline))
then MWeis;
end;
procedure TTextGrid.setCll(x, y: word; s: string);
begin
if (x < FCC) and (y < FRC)
then begin
if not Fedg and Parent.visible then begin
meldung('Das Verändern von Zell-Inhalten');
exit;
end;
prfLine(x, y, s);
FArr[x, y].text := s;
invalidate;
end;
end;
function TTextGrid.fcl(x, y: word): integer;
var
i: integer;
begin
if (x < FCC) and (y < FRC) then begin
i := FArr[x, y].FColor;
if i = maxint then
result := Font.color
else result := i;
end else result := 0;
end;
function TTextGrid.cline(x, y: word): TTGMul;
begin
if (x < FCC) and (y < FRC) then
result := FArr[x, y].FTextline
else result := tgDefault;
end;
procedure TTextGrid.setCLine(x, y: word; t: TTGMul);
begin
if FArr[x, y].FTextline = t then exit;
if (x < FCC) and (y < FRC) then
FArr[x, y].FTextline := t;
if (x >= FFC) and (y >= FFR) and (FArr[x, y].text <> '')
and (t = tgMultiline) and (FAlig[x] <> DT_LEFT) then MWeis;
invalidate;
end;
procedure TTextGrid.setFCl(x, y: word; t: integer);
begin
if (x < FCC) and (y < FRC) then
FArr[x, y].FColor := t;
invalidate;
end;
procedure TTExtGrid.selectieren;
begin
if (FRow >= FFR) and (FCol >= FFC)
and (FRow < FRC) and (FCol < FCC)
then FArr[FCol, FRow].select := true;
end;
procedure TTextGrid.setrh(y, i: word);
var
x: integer;
begin
if (y < FRC) then begin
for x := 0 to FCC - 1 do
if (FArr[x, y].Teileh > 1)
or (FArr[x, y].height = 0) and (FArr[FCC, y].height > 0)
then begin
if FMsg then
messagebox(0, Pchar('Zeile ' + inttostr(y) + ' kann' +
FS2), PChar(FS1), mb_IconWarning);
exit;
end;
for x := 0 to FCC do
FArr[x, y].height := i;
loose;
if (FRow = y) and (i = 0) then
begin
FCol := -1;
FRow := -1;
end;
einrichten;
selectieren;
neu;
end;
end;
procedure TTextGrid.RowHeightsX(y1, y2, degree: word);
var
x, k: integer;
begin
if y2 < y1 then begin
x := y1;
y1 := y2;
y2 := x;
end;
if y2 >= FRC then y2 := FRC - 1;
if innerrow(y1, y2) then exit;
for k := y1 to y2 do
for x := 0 to FCC do begin
FArr[x, k].height := degree;
if (FRow = k) and (degree = 0) then begin
FRow := -1;
FCol := -1;
end;
end;
loose;
einrichten;
selectieren;
neu;
end;
function TTextGrid.rh(w: word): word;
begin
if (w < FRC) then
result := FArr[FCC, w].height
else result := 0;
end;
procedure TTextGrid.setcw(x, i: word);
var
z: integer;
begin
if (x < FCC) then begin
for z := 0 to FRC - 1 do
if (FArr[x, z].Teilew > 1)
or (FArr[x, z].Width = 0) and (FArr[x, FRC].Width > 0)
then begin
if FMsg then
messagebox(0, Pchar('Spalte ' + inttostr(x) + ' kann' +
FS2), PChar(FS1), mb_IconWarning);
exit;
end;
for z := 0 to FRC do
FArr[x, z].width := i;
loose;
if (FCol = x) and (i = 0) then
begin
FCol := -1;
FRow := -1;
end;
einrichten;
selectieren;
neu;
end;
end;
procedure TTextGrid.ColWidthsX(x1, x2, degree: word);
var
z, k: integer;
begin
if x1 > x2 then begin
z := x1;
x1 := x2;
x2 := z;
end;
if x2 >= FCC then x2 := FCC - 1;
if innercol(x1, x2) then exit;
for k := x1 to x2 do
for z := 0 to FRC do begin
FArr[k, z].width := degree;
if (FCol = k) and (degree = 0) then begin
FCol := -1;
FRow := -1;
end;
end;
loose;
einrichten;
selectieren;
neu;
end;
procedure TTextGrid.DeleteCols(x1, x2: word);
var
z, k, i, xx: integer;
begin
if not Fedg then begin
meldung('Das Löschen von Spalten');
exit;
end;
if x1 > x2 then begin
z := x1;
x1 := x2;
x2 := z;
end;
if x2 >= FCC then x2 := FCC - 1;
xx := X2 - x1;
if innercol(x1, x2) then exit;
if succ(xx) >= FCC then begin
if FMsg then
messagebox(0, Pchar('Das Löschen der Spalten ist nicht möglich.'#13#10 +
'Es muss mindestens eine Spalte übrig bleiben. '),
PChar(FS1), mb_IconWarning);
exit;
end;
for k := 0 to xx do begin
for i := x1 to FCC - 1 do begin
FAlig[i] := FAlig[i + 1];
for z := 0 to FRC do begin
FArr[i, z].Teileh := FArr[i + 1, z].Teileh;
FArr[i, z].Teilew := FArr[i + 1, z].Teilew;
FArr[i, z].width := FArr[i + 1, z].width;
FArr[i, z].height := FArr[i + 1, z].height;
FArr[i, z].FColor := FArr[i + 1, z].FColor;
FArr[i, z].Text := FArr[i + 1, z].Text;
end;
end;
end;
dec(FCC, xx + 1);
setlength(FAlig, FCC + 1);
danach;
end;
procedure TTextGrid.danach;
begin
setlength(FArr, FCC + 1, FRC + 1);
loose;
einrichten;
selectieren;
neu;
end;
procedure TTextGrid.DeleteRows(y1, y2: word);
var
z, k, i, xx: integer;
begin
if not Fedg then begin
meldung('Das Löschen von Zeilen');
exit;
end;
if y1 > y2 then begin
z := y1;
y1 := y2;
y2 := z;
end;
if y2 >= FCC then y2 := FCC - 1;
xx := y2 - y1;
if innerrow(y1, y2) then exit;
if succ(xx) >= FRC then begin
if FMsg then
messagebox(0, Pchar('Das Löschen der Zeilen ist nicht möglich.'#13#10 +
'Es muss mindestens eine Zeile übrig bleiben. '),
PChar(FS1), mb_IconWarning);
exit;
end;
for k := 0 to xx do begin
for i := y1 to FRC - 1 do begin
for z := 0 to FCC do begin
FArr[z, i].Teileh := FArr[z, i + 1].Teileh;
FArr[z, i].Teilew := FArr[z, i + 1].Teilew;
FArr[z, i].width := FArr[z, i + 1].width;
FArr[z, i].height := FArr[z, i + 1].height;
FArr[z, i].FColor := FArr[z, i + 1].FColor;
FArr[z, i].Text := FArr[z, i + 1].Text;
end;
end;
end;
dec(FRC, xx + 1);
danach;
end;
function TTextGrid.cw(w: word): word;
begin
if (w < FCC) then
result := FArr[w, FRC].width
else result := 0;
end;
function TTextGrid.Al(x: word): TTGAlig;
begin
if (x < FCC) and (x >= FFC) then begin
case FAlig[x] of
DT_CENTER: result := tgCenter;
DT_RIGHT: result := tgRight;
else result := tgLeft;
end;
end else result := tgOuter;
end;
procedure TTextGrid.MWeis;
begin
if FMsg then
messagebox(0,
'Zur Info:'#13#10'Mehrzeiliger Text wird nicht ausgerichtet. ',
'Hinweis', mb_IconInformation);
end;
procedure TTextGrid.setAl(x: word; u: TTGAlig);
var
y: integer;
begin
if x >= FCC then exit;
if x >= FFC then
for y := FFR to FRC do begin
if ((FMulti = tgMultiline) and (FArr[x, y].FTextline = tgDefault)
or (FArr[x, y].FTextline = tgMultiline))
and (FArr[x, y].Text <> '') and (u in [tgCenter, tgRight])
then begin
MWeis;
break;
end;
end;
case u of
tgCenter: FAlig[x] := DT_CENTER;
tgRight: FAlig[x] := DT_RIGHT;
else FAlig[x] := DT_LEFT;
end;
invalidate;
end;
procedure TTextGrid.setFoc(c: boolean);
begin
if c = FFoc then exit;
FFoc := c;
invalidate;
end;
procedure TTextGrid.setColv(i: integer);
begin
if (i < -1) or (i >= FCC) or (i < FFC)
then i := -1;
loose;
FCol := i;
if (FRow >= FFR) and (FCol >= FFC) then begin
while (FCol >= 0) and (FArr[FCol, FRow].width = 0) do dec(FCol);
if (FCol >= 0) and (FRow >= 0) then
FArr[FCol, FRow].select := true;
end;
end;
procedure TTextGrid.setCol(i: integer);
begin
setColv(i);
invalidate;
end;
procedure TTextGrid.setRowv(i: integer);
begin
if (i < -1) or (i >= FRC) or (i < FFR)
then i := -1;
loose;
FRow := i;
if (FRow >= FFR) and (FCol >= FFC) then
while (FRow >= 0) and (FArr[FCol, FRow].width = 0) do dec(FCol);
if (FCol >= 0) and (FRow >= 0) then
FArr[FCol, FRow].select := true;
end;
procedure TTextGrid.setRow(i: integer);
begin
setrowv(i);
invalidate;
end;
procedure TTextGrid.setSelC(c: TColor);
begin
if c = FSelC then exit;
FSelC := c;
invalidate;
end;
procedure TTextGrid.setNofo(c: TColor);
begin
if c = FNofo then exit;
FNofo := c;
invalidate;
end;
procedure TTextGrid.loose;
var
x, y: integer;
begin
for x := 0 to FCC - 1 do
for y := 0 to FRC - 1 do
FArr[x, y].select := false;
end;
function TTextGrid.waag(x, y: integer): integer;
var
v, h, i, z: integer;
begin
result := -1;
i := 0;
h := fz;
while i < FCC do begin
v := h + FLW;
h := FArr[i, FRC].width + v;
if FArr[i, FRC].width = 0 then dec(h, FLW);
if (y > -1) and
((FArr[i + 1, y].width = 0) or (FArr[i + 1, y].height = 0))
then z := FLW else z := 0;
if (x >= v) and (x < h + z) then begin
result := i;
break;
end;
inc(i);
end;
end;
function TTextGrid.senk(x, y: integer): integer;
var
o, u, i, z: integer;
begin
result := -1;
u := fz;
for i := 0 to FRC - 1 do begin
o := u + FLW;
u := FArr[FCC, i].height + o;
if FArr[FCC, i].height = 0 then dec(u, FLW);
if (x > -1) and (FArr[x, i + 1].height = 0)
then z := FLW else z := 0;
if (y >= o) and (y < u + z) then begin
result := i;
break;
end;
end;
end;
procedure TTextGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
X: integer; Y: Integer);
var
z, i, s: integer;
p: TPoint;
b, sc: boolean;
function ja: boolean;
var
k, j: integer;
begin
for k := FFC to FCC - 1 do
for j := FFR to FRC - 1 do
if (Farr[k, j].Teilew > 1) or (Farr[k, j].Teileh > 1)
then begin
result := true;
exit;
end;
result := false;
end;
begin
if button = mbMiddle then begin
FRast := not FRast;
exit;
end;
if Button = mbLeft then
loose;
sc := (selcount > 1) or (Button = mbright);
z := senk(-1, y);
if sc and (z = -1) then z := senk(-1, y + FLW);
i := waag(x, z);
if sc and (i = -1) then i := waag(x + FLW, z);
FStelle.x := i;
z := senk(i, y);
if sc and (z = -1) then z := senk(i, y - FLW);
FStelle.y := z;
b := (FStelle.y >= FFR) and (FStelle.x >= FFC);
s := FStelle.x;
z := FStelle.y;
if b then begin
while FArr[s, z].height = 0 do dec(z);
while FArr[s, z].width = 0 do dec(s);
end;
if Button = mbLeft then begin
if (s <> FCol) or (z <> FRow) then FZahl := 0
else if FHlpCtrl.height > 0 then FZahl := -1;
if (FHlpCtrl.height > 0) and (FMz = z) and (FMs = s)
then begin
ok;
exit;
end;
DoEnter;
FROW := z;
FCOL := s;
if b then begin
FArr[s, z].select := true;
invalidate;
FDD := (ssAlt in Shift) and (FArr[s, z].text <> '')
and (FHlpCtrl.height = 0);
if FDD and FDDP then begin
FMs := s;
FMZ := z;
FArr[s, z].select := true;
releasecapture;
if ssCtrl in Shift then Cursor := FCurC
else cursor := FCurM;
invalidate;
end;
end else if FFixBttn and ((z < FFR) or (s < FFC))
and (z > -1) and (s > -1) then begin
FDown := true;
repaint;
if assigned(FProcDwn) then FProcDwn(self, s, z, FArr[s, z].different);
end;
end else if Button = mbRight then begin
DoEnter;
if Fedg then begin
if not FArr[s, z].select or (selcount < 2)
then begin
loose;
FROW := z;
FCOL := s;
Farr[s, z].select := true;
invalidate;
end;
Fmi[0].enabled := b and FArr[s, z].select and (selcount > 1);
Fmi[1].enabled := Inside(s, z);
Fmi[2].enabled := (selcount = 1) and (s = FCol) and (Z = FRow);
Fmi[3].enabled := istext(true, false);
Fmi[4].enabled := istext(true, true);
Fmi[5].enabled := ja;
Fmi[6].enabled := (selcount = 1) and (FArr[FCol, FRow].text <> '');
Fmi[7].enabled := Fmi[6].enabled;
Fmi[8].enabled := (selcount = 1) and clipboard.hasformat(CF_TEXT);
p := clienttoscreen(point(x, y));
Fpop.popup(p.x, p.y);
end;
end;
inherited;
end;
procedure TTextGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
X: integer; Y: Integer);
var
p: TPoint;
begin
if button = mbleft then begin
releasecapture;
cursor := crdefault;
getcursorpos(p);
setcursorpos(p.x + 1, p.y);
p := zelle(x, y);
if FDD and ((FMs <> p.x) or (FMz <> p.y)) and FDDP
and (FMs >= FFC) and (FMz >= FFR)
and (p.x >= FFC) and (p.y >= FFR)
then begin
FCol := p.x;
FRow := p.y;
if ueberschreiben then begin
FArr[p.x, p.y].text := FArr[FMs, FMz].text;
if not (ssCtrl in Shift) then
FArr[FMs, FMz].text := '';
end;
loose;
selectieren;
FDD := false;
invalidate;
FMs := -1;
FMz := -1;
end else begin
inc(Fzahl);
FTimer.interval := 450;
if selcount = 1 then begin
if FZahl > 1 then begin
FZahl := 0;
if not FDD then
click2(self);
end;
end else FZahl := 0;
end;
end;
if FDown then begin
FDown := false;
repaint;
if (FCol > -1) and (FRow > -1) then
if assigned(FProcUp) then
FProcUp(self, FCol, FRow, FArr[FCol, FRow].different);
end;
inherited;
end;
function TTextGrid.Inside(x, y: integer): boolean;
begin
result := (x >= FFC) and (y >= FFR) and
((FArr[x, y].width = 0) and (FArr[x, FRC].width > 0)
or (FArr[x, y].height = 0) and (FArr[FCC, y].height > 0) or
(FArr[x, y].Teileh > 1) or (FArr[x, y].Teilew > 1));
end;
function TTextGrid.zelle(x, y: integer): TPoint;
var
w, s: integer;
begin
s := senk(-1, y);
w := waag(x, s);
s := senk(w, y);
if (s >= FFR) and (w >= FFC) then begin
while FArr[w, s].height = 0 do dec(s);
while FArr[w, s].width = 0 do dec(w);
end;
result.x := w;
result.y := s;
end;
procedure TTextGrid.MouseMove(Shift: TShiftState;
X: integer; Y: Integer);
var
i, k, xw, xs, a, b: integer;
p: TPoint;
begin
cursor := crdefault;
if (ssLeft in Shift) and not FDown then begin
p := zelle(x, y);
if not FDD and (ssAlt in Shift) and FDDP
and (FHlpCtrl.height = 0) and (p.x >= FFC) and (p.y >= FFR)
and (FArr[p.x, p.y].text <> '')
then begin
FDD := true;
FMs := p.x;
FMz := p.y;
releasecapture;
if ssCtrl in Shift then Cursor := FCurC
else cursor := FCurM;
end;
if FDD and FDDP then begin
if (p.x >= FFC) and (p.y >= FFR) then begin
if ssCtrl in Shift then Cursor := FCurC
else cursor := FCurM;
loose;
FArr[p.x, p.y].select := true;
end else cursor := crNoDrop;
end else begin
if (p.y >= FFR) and (p.x >= FFC)
then begin
loose;
if (FRow >= FFC) and (FCol >= FFR) then
FArr[FCol, FRow].select := true;
if (FStelle.x = -1) then FStelle.x := waag(x - FLW, p.y);
if (FStelle.x = -1) then FStelle.x := waag(x + FLW, p.y);
if p.x < FStelle.x then begin
xw := p.x;
p.x := FStelle.x;
end else xw := FStelle.x;
if (FStelle.y = -1) then FStelle.y := senk(p.y, y - FLW);
if (FStelle.y = -1) then FStelle.y := senk(p.y, y + FLW);
if p.y < FStelle.y then begin
xs := p.y;
p.y := FStelle.y;
end else xs := FStelle.y;
if xw < FFC then xw := FFC;
if xs < FFR then xs := FFR;
for k := xs to p.y do
for i := xw to p.x do begin
b := k;
while FArr[i, b].height = 0 do dec(b);
a := i;
while FArr[a, k].width = 0 do dec(a);
FArr[a, b].select := true;
end;
end;
end;
invalidate;
end;
inherited;
end;
function TTextGrid.multpw(x, y: word): word;
begin
result := FArr[x, y].width * FArr[x, y].Teilew;
if FArr[x, y].width > 0 then
inc(result, pred(FArr[x, y].Teilew) * FLW);
end;
function TTextGrid.multph(x, y: word): word;
begin
result := FArr[x, y].height * FArr[x, y].Teileh;
if FArr[x, y].height > 0 then
inc(result, pred(FArr[x, y].Teileh) * FLW);
end;
procedure TTextGrid.MergeCells(x1, y1, x2, y2: word);
var
x, y, w, v, i: integer;
b: byte;
s: string;
procedure fehler;
begin
if FAuto then s := ''
else s := 'überlappende, ';
if FMsg then
messagebox(0, Pchar('Verborgene, ' + s + 'fremdgezeichnete oder' +
' fixierte Zellbereiche können nicht verbunden werden. '),
PChar(FS1), mb_IconWarning);
end;
function testen: byte;
var
bt: byte;
p: TPoint;
begin
result := 0;
bt := l0test(x1, y1, x2, y2, p);
if bt > 0 then begin
if (bt > 1) or not FAuto then begin
fehler;
result := 2;
exit;
end else begin
FMatic := true;
if not
separatecells(p.x, p.y) then begin
if FMsg then
messagebox(0, 'Fehler beim Verbinden aufgetreten. ',
'FEHLER', mb_IconError);
result := 2
end else result := 1;
FMatic := false;
end;
end;
end;
begin
if not Fedg then begin
meldung('Das Verbinden von Zellen');
exit;
end;
if x1 > x2 then begin
w := x1;
x1 := x2;
x2 := w;
end;
if y1 > y2 then begin
w := y1;
y1 := y2;
y2 := w;
end;
if x1 < FFC then x1 := FFC;
if x2 >= FCC then x2 := FCC - 1;
if y1 < FFR then y1 := FFR;
if y2 >= FRC then y2 := FRC - 1;
repeat
b := testen;
if b = 2 then exit;
until b = 0;
v := succ(y2 - y1);
w := succ(x2 - x1);
if (v < 2) and (w < 2) then begin
if FMsg then
messagebox(0, 'Verbinden ist nicht möglich. ',
PChar(FS1), mb_IconWarning);
exit;
end;
loose;
for y := 0 to v - 1 do begin
FArr[x1, y1 + y].teilew := w;
i := 0;
for x := 0 to w - 1 do
i := i + FArr[x1 + x, FRC].width;
FArr[x1, y1 + y].width := i;
for x := 1 to w - 1 do begin
FArr[x1 + x, y1 + y].width := 0;
FArr[x1 + x, y1 + y].Teilew := 1;
if (x1 + x = FCol) and (y1 + y = FRow) then
begin
FCol := -1;
FRow := -1;
end;
end;
end;
for x := 0 to w - 1 do begin
FArr[x1 + x, y1].teileh := v;
i := 0;
for y := 0 to v - 1 do
i := i + FArr[FCC, y1 + y].height;
FArr[x1 + x, y1].height := i;
for y := 1 to v - 1 do begin
FArr[x1 + x, y1 + y].height := 0;
FArr[x1 + x, y1 + y].Teileh := 1;
if (x1 + x = FCol) and (y1 + y = FRow) then
begin
FCol := -1;
FRow := -1;
end;
end;
end;
selectieren;
invalidate;
end;
function TTextGrid.l0test(x1, y1, x2, y2: word; out p: TPoint): byte;
var
x, y: integer;
begin
result := 0;
for x := x1 to x2 do
for y := y1 to y2 do begin
if (FArr[x, y].different) then begin
result := 2;
exit;
end;
if (FArr[x, y].Teileh > 1)
or (FArr[x, y].Teilew > 1) then begin
result := 1;
p := point(x, y);
end;
if (FArr[x, y].width = 0) then begin
if FArr[x, FRC].width > 0 then begin
result := 1;
p := point(x, y);
end else begin
result := 2;
exit;
end;
end;
if (FArr[x, y].height = 0) then begin
if FArr[FCC, y].height > 0 then begin
result := 1;
p := point(x, y);
end else begin
result := 2;
exit;
end;
end;
end;
end;
function TTextGrid.SeparateCells(x, y: word): boolean;
var
i, j, m, n: integer;
b: boolean;
procedure doit(a, b: integer);
begin
FArr[a, b].Teileh := 1;
FArr[a, b].Teilew := 1;
FArr[a, b].width := FArr[a, FRC].width;
FArr[a, b].height := FArr[FCC, b].height;
end;
begin
result := false;
if not Fedg then begin
meldung('Das Separieren von Zellen');
exit;
end;
if x >= FCC then x := FCC - 1;
if y >= FRC then y := FRC - 1;
if Inside(x, y) then begin
loose;
while (FArr[x, y].width = 0) do dec(x);
while (FArr[x, y].height = 0) do dec(y);
doit(x, y);
i := x + 1;
while ((FArr[i, y].Teileh > 1) and (FArr[i, y].Teilew = 1)
or (FArr[i, y].width = 0)) and (i < FCC)
do inc(i);
dec(i, ord(i > x));
b := i = x;
j := y + 1;
while (((FArr[x, j].Teilew = 1) and (FArr[x, j].Teileh = 1)
or (FArr[x, j].height = 0)) and b
or (FArr[x, j].Teilew > 1) and (FArr[x, j].Teileh = 1) and not b)
and (j < FRC)
do inc(j);
dec(j, ord(j > y));
i := x + 1;
while ((FArr[i, y].Teilew > 1) and (FArr[i, y].Teileh = 1) and not b
or (FArr[i, y].width = 0)) and (i < FCC)
do inc(i);
dec(i, ord(i > x));
for m := x to i do
for n := y to j do
doit(m, n);
result := true;
if FMatic then exit;
selectieren;
neu;
end else
if FMsg and not FMatic then
messagebox(0, 'Sie befinden sich nicht in einem Zellverbund. ',
PChar(Fmi[1].caption), mb_IconWarning);
end;
procedure TTextGrid.click1(sender: TObject);
begin
separateCells(FStelle.x, FStelle.y);
end;
function TTextGrid.minmax: TTGMM;
var
x, y: integer;
begin
result[0, 0] := maxint;
result[0, 1] := maxint;
result[1, 0] := -1;
result[1, 1] := -1;
for y := FFR to FRC - 1 do begin
for x := FFC to FCC - 1 do begin
if (y < result[0, 1]) and Farr[x, y].select
then result[0, 1] := y;
if (x < result[0, 0]) and Farr[x, y].select
then result[0, 0] := x;
end;
end;
for x := FCC - 1 downto FFC do begin
for y := FRC - 1 downto FFR do begin
if (y > result[1, 1]) and Farr[x, y].select
then result[1, 1] := y;
if (x > result[1, 0]) and Farr[x, y].select
then result[1, 0] := x;
end;
end;
end;
procedure TTextGrid.click0(sender: TObject);
var
a: TTGMM;
x, y, i, j: integer;
begin
for x := FFC to FCC - 1 do
for y := FFR to FRC - 1 do
if ((FArr[x, y].Teilew > 1) or (FArr[x, y].Teileh > 1))
and (FArr[x, y].select) then begin
i := x + 1;
while (i <= FCC - 1) and ((FArr[i, y].Teilew > 1)
or (FArr[i, y].width = 0) and (FArr[i, FRC].width > 0))
do begin
FArr[i, y].select := true;
inc(i);
end;
dec(i);
j := y + 1;
while (j <= FRC - 1) and (FArr[i, j].height = 0)
and (FArr[FCC, j].height > 0)
do begin
FArr[i, j].select := true;
inc(j);
end;
end;
a := minmax;
mergecells(a[0, 0], a[0, 1], a[1, 0], a[1, 1]);
end;
procedure TTextGrid.click3(sender: TObject);
var
s, w: string;
b: boolean;
begin
b := not (sender = Fmi[3]);
if selcount <> 1 then s := 'n' else s := '';
if istext(true, b) then begin
if not Fedg then begin
meldung('Das Löschen von Texten');
exit;
end;
if not b then w := 'Text der markierten Zelle' + s
else w := 'gesamten Text';
if FMsg then begin
if messagebox(0,
PChar('Wollen Sie wirklich den ' + w
+ ' löschen? '), 'FRAGE', MB_YESNO or MB_ICONQUESTION) <> mryes
then exit;
end;
end;
istext(false, b);
invalidate;
end;
function TTextGrid.SelCount: cardinal;
var
x, y: integer;
begin
result := 0;
for x := FFC to FCC - 1 do
for y := FFR to FRC - 1 do
if FArr[x, y].select then inc(result);
end;
procedure TTextGrid.click2(sender: TObject);
var
b: TTGEd;
ed: TCustomEdit;
begin
if (FRow >= FFR) and (FCol >= FFC) then begin
ed := nil;
b := tgSelf;
FMz := FRow;
FMs := FCol;
if Fedg then
if assigned(FEditing) then FEditing(self, FCol, Frow, b, ed);
if (b = tgNo) or not Fedg then begin
if FMsg then
messagebox(0, 'Diese Zelle darf zur Zeit nicht editiert werden. ',
PChar(FS1), mb_IconWarning);
exit;
end;
if (ed = nil) and (b = tgStrange) then begin
if FMsg then
messagebox(0, 'Es wurde kein Eingabe-Feld zugeordnet. ',
PChar(FS1), mb_IconWarning);
exit;
end;
if b = tgSelf then begin
FDa := true;
FHlpCtrl.Fedit.text := FArr[FCol, FRow].text;
neu;
FHlpCtrl.Fedit.setfocus;
end else begin
FDa := false;
cells[FCol, FRow] := ed.text;
setfocus;
end;
end;
end;
procedure TTextGrid.CreateHlpControl(AOwner: TComponent;
AParent: TWinControl);
begin
if not Assigned(FHlpCtrl) then
begin
FHlpCtrl := TFHlpCtrl.Create(AOwner, Self);
try
FHlpCtrl.TabStop := True;
weg;
except
raise;
end;
end;
end;
procedure TTextGrid.DestroyHlpControl;
begin
if Assigned(FHlpCtrl) then
begin
if Assigned(FHlpCtrl.Parent) then begin
FHlpCtrl.free;
FHlpCtrl := nil;
end;
end;
end;
constructor TFHlpCtrl.Create(AOwner: TComponent;
GrphCtrl: TTextGrid);
begin
inherited Create(AOwner);
FGrphCtrl := GrphCtrl;
FEdit := TMemo.create(self);
GrphCtrl.Fda := false;
FEdit.parent := self;
FEdit.scrollbars := ssVertical;
FEdit.OnkeyDown := GrphCtrl.EditKeyDown;
FEdit.color := clwhite;
FEdit.Font.color := clblack;
FL := TLabel.create(self);
FL.caption := ' Bestätigen mit Strg+Enter ';
FL.Font.color := clmaroon;
FL.Color := clYellow;
FL.Font.Style := [fsBold];
FL.parent := self;
FL.OnClick := zuClick;
FGrphCtrl.Fi := FL.height + 2;
end;
procedure TFHlpCtrl.CMDIALOGKEY(var Alt: TWMKey);
var
Shift: TShiftState;
begin
if Assigned(FGrphCtrl) then
if Alt.CharCode = VK_Menu then begin
Shift := KeyDataToShiftState(Alt.KeyData);
FGrphCtrl.DoKeyDown(Alt.CharCode, Shift);
end;
inherited;
end;
procedure TFHlpCtrl.WMKeyDown(var M: TWMKeyDown);
var
Shift: TShiftState;
begin
if Assigned(FGrphCtrl) then
begin
Shift := KeyDataToShiftState(M.KeyData);
FGrphCtrl.DoKeyDown(M.CharCode, Shift);
if ssCtrl in Shift then
end;
inherited;
end;
procedure TFHlpCtrl.WMKeyUp(var M: TWMKeyUp);
var
Shift: TShiftState;
begin
if Assigned(FGrphCtrl) then
begin
Shift := KeyDataToShiftState(M.KeyData);
FGrphCtrl.DoKeyUp(M.CharCode, Shift);
end;
inherited;
end;
procedure TFHlpCtrl.CMEnter(var M: TWMNoParams);
begin
if Assigned(FGrphCtrl) then
FGrphCtrl.DoEnter;
inherited;
end;
procedure TFHlpCtrl.CMExit(var M: TWMNoParams);
begin
if Assigned(FGrphCtrl) then
FGrphCtrl.DoExit;
inherited;
end;
function TTextGrid.GetCanFocus: Boolean;
begin
if Assigned(FHlpCtrl) then
result := FHlpCtrl.CanFocus
else
result := False;
end;
function TTextGrid.GetFocused: Boolean;
begin
if Assigned(FHlpCtrl) then
result := FHlpCtrl.Focused
else
result := False;
end;
function TTextGrid.GetTabOrder: Integer;
begin
if Assigned(FHlpCtrl) then
result := FHlpCtrl.TabOrder
else
result := -1;
end;
function TTextGrid.GetTabStop: Boolean;
begin
if Assigned(FHlpCtrl) then
result := FHlpCtrl.TabStop
else
result := False;
end;
procedure TTextGrid.SetFocus;
begin
if Assigned(FHlpCtrl) then
if FHlpCtrl.CanFocus then
FHlpCtrl.SetFocus;
end;
procedure TTextGrid.SetTabOrder(const Value: Integer);
begin
if Assigned(FHlpCtrl) then
FHlpCtrl.TabOrder := Value;
end;
procedure TTextGrid.SetTabStop(const Value: Boolean);
begin
if Assigned(FHlpCtrl) then
FHlpCtrl.TabStop := Value;
end;
procedure TTextGrid.SetParent(AParent: TWinControl);
begin
inherited;
if Assigned(Self.Parent) then
begin
FHlpCtrl.Parent := Self.Parent;
FHlpCtrl.Show;
end;
end;
procedure TTextGrid.DoKeyDown(var Key: Word; Shift: TShiftState);
begin
if Assigned(FOnKeyDown) then FOnKeyDown(Self, Key, Shift);
end;
procedure TTextGrid.DoKeyUp(var Key: Word; Shift: TShiftState);
begin
if Assigned(FOnKeyUp) then FOnKeyUp(Self, Key, Shift);
end;
procedure TTextGrid.setfocusC(c: TColor);
begin
if c = FFocusC then exit;
FFocusC := c;
invalidate;
end;
procedure TTextGrid.DoEnter;
begin
weg;
setfocus;
if Assigned(FOnEnter) then FOnEnter(Self);
end;
procedure TTextGrid.DoExit;
begin
weg;
if Assigned(FOnExit) then FOnExit(Self);
end;
procedure TFHlpCtrl.WndProc(var M: TMessage);
var
Shift: TShiftState;
begin
case M.Msg of
WM_SETFOCUS, WM_KILLFOCUS: begin
if Assigned(FGrphCtrl) then
FGrphCtrl.invalidate;
end;
CN_KEYDOWN: begin
Shift := KeyDataToShiftState(M.LParam);
case M.wParam of
VK_Home: FGrphCtrl.home(ssCtrl in shift);
VK_End: FGrphCtrl.Ende(ssCtrl in shift);
13: if (FGrphCtrl.selcount = 1) and (height = 0)
and FGrphCtrl.Fedg then begin
FGrphCtrl.click2(self);
M.Result := 1;
exit;
end;
27: begin
FGrphCtrl.reset;
M.Result := 1;
exit;
end;
VK_DELETE: if height = 0
then begin
FGrphCtrl.click3(self);
M.Result := 1;
exit;
end;
VK_RIGHT: begin
M.Result := 1;
FGrphCtrl.nachrechts(true);
exit;
end;
VK_Left: begin
M.Result := 1;
FGrphCtrl.nachlinks(true);
exit;
end;
VK_up: begin
M.Result := 1;
FGrphCtrl.nachoben(true);
exit;
end;
VK_Down: begin
M.Result := 1;
FGrphCtrl.nachunten(true);
exit;
end;
end;
end;
end;
inherited;
end;
procedure TTextgrid.setFCt(b: boolean);
begin
if b = FCt then exit;
Fct := b;
invalidate;
end;
procedure TTextgrid.buildCol;
begin
if FCol < FFC then begin
FCol := FFC;
while FArr[FCol, FRC].width = 0 do inc(FCol);
end else
while FArr[FCol, FRC].width = 0 do dec(FCol);
end;
procedure TTextgrid.buildRow;
begin
if FRow < FFR then begin
FRow := FFR;
while FArr[FCC, FRow].height = 0 do inc(FRow);
end else
while FArr[FCC, FRow].height = 0 do dec(FRow);
end;
procedure TTextgrid.nachrechts(b: boolean);
var
o: integer;
h: boolean;
begin
h := false;
if b then
if assigned(FDrct) then FDrct(self, tgRightWards, FCol, FRow, h);
if h then exit;
buildRow;
o := FRow;
if (FCol < FFC) then begin
FCol := FFC;
while (FCol < FCC - 1) and (FArr[FCol, FRow].width = 0) do inc(FCol);
end else begin
loose;
if FCol < FCC - 1 then begin
inc(FCol);
while (FCol < FCC - 1) and (FArr[FCol, o].width = 0) do inc(FCol);
while (o > FFR) and (FArr[FCol, o].height = 0) do dec(o);
end;
end;
while (FCol > FFC) and (FArr[FCol, o].width = 0) do dec(FCol);
while (o > FFR) and (FArr[FCol, o].height = 0) do dec(o);
FArr[FCol, o].select := true;
FRow := o;
invalidate;
end;
procedure TTextgrid.nachlinks(b: boolean);
var
o: integer;
h: boolean;
begin
h := false;
if b then
if assigned(FDrct) then FDrct(self, tgLeftWards, FCol, FRow, h);
if h then exit;
buildRow;
o := FRow;
if (FCol < FFC) then begin
FCol := FCC - 1;
while (FCol > FFC) and (FArr[FCol, FRow].width = 0) do dec(FCol);
end else begin
loose;
if FCol > FFC then begin
dec(FCol);
while (FCol > FFC) and (FArr[FCol, o].width = 0) do dec(FCol);
while (o > FFR) and (FArr[FCol, o].height = 0) do dec(o);
end;
end;
while (FCol < FCC - 1) and (FArr[FCol, o].width = 0) do inc(FCol);
while (o > FFR) and (FArr[FCol, o].height = 0) do dec(o);
FArr[FCol, o].select := true;
FRow := o;
invalidate;
end;
procedure TTextgrid.nachoben(b: boolean);
var
l: integer;
h: boolean;
begin
h := false;
if b then
if assigned(FDrct) then FDrct(self, tgUpWards, FCol, FRow, h);
if h then exit;
buildCol;
l := FCol;
if (FRow < FFR) then begin
FRow := FRC - 1;
while (FRow > FFR) and (FArr[FCol, FRow].height = 0) do dec(FRow);
end else begin
while (FRow > FFR) and (FArr[FCol, FRow].height = 0) do dec(FRow);
loose;
if FRow > FFR then begin
dec(FRow);
while (FRow > FFR) and (FArr[l, FRow].height = 0) do dec(FRow);
while (l > FFC) and (FArr[l, FRow].width = 0) do dec(l);
end;
end;
while (FRow < FRC - 1) and (FArr[l, FRow].height = 0) do inc(FRow);
while (l > FFC) and (FArr[l, FRow].width = 0) do dec(l);
FArr[l, FRow].select := true;
FCol := l;
invalidate;
end;
procedure TTextgrid.nachunten(b: boolean);
var
l: integer;
h: boolean;
begin
h := false;
if b then
if assigned(FDrct) then FDrct(self, tgDownWards, FCol, FRow, h);
if h then exit;
buildCol;
l := FCol;
if (FRow < FFR) then begin
FRow := FFR;
while (FRow < FRC - 1) and (FArr[FCol, FRow].height = 0) do inc(FRow);
end else begin
loose;
if FRow < FRC - 1 then begin
inc(FRow);
while (FRow < FRC - 1) and (FArr[l, FRow].height = 0)
do inc(FRow);
while (l > FFC) and (FArr[l, FRow].width = 0) do dec(l);
end;
end;
while (FRow > FFR) and (FArr[l, FRow].height = 0) do dec(FRow);
while (l > FFC) and (FArr[l, FRow].width = 0) do dec(l);
FArr[l, FRow].select := true;
FCol := l;
invalidate;
end;
procedure TTextGrid.setEdge(b: boolean);
begin
if b = FEdge then exit;
FEdge := b;
neu;
end;
procedure TTextGrid.ok;
var
s: string;
begin
s := FHlpCtrl.Fedit.text;
if assigned(FEdited) then FEdited(self, FCol, FRow, s);
cells[FCol, FRow] := s;
weg;
repaint;
setfocus;
end;
procedure TTextGrid.EditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case key of
27: begin
weg;
setfocus;
end;
13: if (ssCtrl in Shift) then begin
key := 0;
ok;
setfocus;
end;
end;
end;
procedure TTextGrid.setEPos(p: TTGEPos);
begin
if p = FEPos then exit;
FEPos := p;
if FHlpCtrl.height > 0 then begin
FDa := true;
resize;
end;
end;
procedure TTextGrid.meldung(s: string);
begin
if FMsg then
messagebox(0, PChar(s + ' ist zur Zeit nicht erlaubt. '),
PChar(FS1), mb_IconWarning);
end;
procedure TTextGrid.weg;
begin
FHlpCtrl.SetBounds(0, 0, 0, 0);
FHlpCtrl.FEdit.text := '';
end;
function TTextGrid.innercol(x1, x2: word): boolean;
var
s, z: integer;
begin
for s := x1 to x2 do
for z := 0 to FRC - 1 do
if (FArr[s, z].Teilew > 1) or (FArr[s, z].Teileh > 1)
or (FArr[s, z].width = 0) and (FArr[s, FRC].width > 0)
or (FArr[s, z].height = 0) and (FArr[FCC, z].height > 0)
then begin
result := true;
if FMsg then
messagebox(0, Pchar('Die Spalten können' +
FS2), PChar(FS1), mb_IconWarning);
exit;
end;
result := false;
end;
procedure TTextGrid.setFixstyle(f: TFontstyles);
begin
if f = FFstyle then exit;
FFStyle := f;
invalidate;
end;
procedure TTextGrid.setSelS(s: TTGSelS);
begin
if s = FSelS then exit;
FSelS := s;
invalidate;
end;
function TTextGrid.innerrow(y1, y2: word): boolean;
var
z, s: integer;
begin
for s := 0 to FCC - 1 do
for z := y1 to y2 do
if (FArr[s, z].Teilew > 1) or (FArr[s, z].Teileh > 1)
or (FArr[s, z].width = 0) and (FArr[s, FRC].width > 0)
or (FArr[s, z].height = 0) and (FArr[FCC, z].height > 0)
then begin
result := true;
if FMsg then
messagebox(0, Pchar('Die Zeilen können' +
FS2), PChar(FS1), mb_IconWarning);
exit;
end;
result := false;
end;
function TTextGrid.DifferentCount: cardinal;
var
x, y: integer;
begin
result := 0;
for x := 0 to FCC - 1 do
for y := 0 to FRC - 1 do
if FArr[x, y].different then inc(result);
end;
function TTextGrid.AlignmentToStr(alg: TTGAlig): string;
begin
case alg of
tgCenter: result := 'zentriert';
tgRight: result := 'rechtsbündig';
tgLeft: result := 'linksbündig';
else result := 'nicht zu ermitteln';
end;
end;
function TTextGrid.SaveBasicsToStream(st: TStream): boolean;
begin
result := SaveGrid(st, 12345678);
end;
function TTextGrid.LoadBasicsFromStream(st: TStream): boolean;
begin
result := LoadGrid(st, 12345678);
end;
function TTextGrid.SaveToStream(st: TStream): boolean;
begin
result := SaveGrid(st, 87654321);
end;
function TTextGrid.LoadFromStream(st: TStream): boolean;
begin
result := LoadGrid(st, 87654321);
end;
function TTextGrid.SaveGrid(st: TStream; q: integer): boolean;
var
x, y, i, w, lg, c: integer;
Logfont: TLogFont;
b: boolean;
begin
w := sizeof(word);
i := sizeof(Integer);
x := length(FVersion);
c := sizeof(TColor);
try
st.size := 0;
st.writebuffer(x, i);
st.writebuffer(FVersion[1], x);
st.writebuffer(q, i);
st.writebuffer(FCC, w);
st.writebuffer(FRC, w);
st.writebuffer(FMulti, sizeof(TTGmul));
for x := 0 to FCC do
for y := 0 to FRC do begin
st.writebuffer(FArr[x, y].width, w);
st.writebuffer(FArr[x, y].height, w);
st.writebuffer(FArr[x, y].Teilew, w);
st.writebuffer(FArr[x, y].Teileh, w);
st.writebuffer(FArr[x, y].FColor, i);
st.writebuffer(FArr[x, y].select, 1);
lg := length(FArr[x, y].Text);
st.writebuffer(lg, i);
st.writebuffer(FArr[x, y].Text[1], lg);
st.writebuffer(FArr[x, y].FTextLine, sizeof(TTGMul));
end;
st.writebuffer(Font.color, c);
if q = 87654321 then begin
st.writebuffer(FFStyle, sizeof(TFontStyles));
st.writebuffer(FFDisc, c);
st.writebuffer(FFocusC, c);
st.writebuffer(FFixBttn, 1);
st.writebuffer(FFoc, 1);
st.writebuffer(Frand, sizeof(TTGBorder));
st.writebuffer(FEPos, sizeof(TTGEPos));
st.writebuffer(FNH, 1);
st.writebuffer(FSelc, c);
st.writebuffer(FNofo, c);
st.writebuffer(FBack, sizeof(TTGBack));
st.writebuffer(FNW, 1);
st.writebuffer(FFixC, c);
st.writebuffer(FFlat, 1);
st.writebuffer(color, c);
st.writebuffer(FMsg, 1);
st.writebuffer(FPC, c);
st.writebuffer(Fedg, 1);
st.writebuffer(FLW, 1);
st.writebuffer(FFC, 1);
st.writebuffer(FFR, 1);
st.writebuffer(FCol, i);
st.writebuffer(FRow, i);
st.writebuffer(FDisc, c);
st.writebuffer(FSels, sizeof(TTGSelS));
st.writebuffer(Fedge, 1);
st.writebuffer(FCt, 1);
for x := 0 to FCC - 1 do
st.writebuffer(FAlig[x], i);
b := FBmp.empty;
st.writebuffer(b, 1);
if not b then
FBmp.savetostream(st);
GetObject(Font.Handle, sizeof(Logfont), @Logfont);
st.writebuffer(LogFont, sizeof(TLogFont));
x := length(Hint);
st.writebuffer(x, i);
st.writebuffer(Hint[1], x);
GetObject(FHlpCtrl.FEdit.Font.Handle, sizeof(Logfont), @Logfont);
st.writebuffer(LogFont, sizeof(TLogFont));
st.writebuffer(FHlpCtrl.FEdit.Font.color, c);
st.writebuffer(FHlpCtrl.FEdit.color, c);
st.writebuffer(FHlpCtrl.FL.color, c);
st.writebuffer(FHlpCtrl.FL.Font.color, c);
st.writebuffer(Fu, i);
end;
result := true;
except
result := false;
if FMsg then
messagebox(0, 'Fehler beim Schreiben in den Stream. ',
'FEHLER', mb_IconError);
end;
end;
function TTextGrid.LoadGrid(st: TStream; q: integer): boolean;
var
x, y, i, w, lg, c: integer;
s: string;
mu: TTGMul;
m: boolean;
lb: byte;
LogFont: TLogfont;
cl: TColor;
begin
result := false;
w := sizeof(word);
i := sizeof(Integer);
c := sizeof(TColor);
try
st.readbuffer(x, i);
setlength(s, x);
st.readbuffer(s[1], x);
st.readbuffer(x, i);
if (s <> FVersion) or (x <> q) then begin
if FMsg then
messagebox(0, 'Ungültige Version oder ungültige Daten. ',
'LOAD TEXTGRID', mb_IconError);
exit;
end;
st.readbuffer(FCC, w);
setlength(FAlig, FCC + 1);
st.readbuffer(FRC, w);
setlength(FArr, FCC + 1, FRC + 1);
st.readbuffer(mu, sizeof(TTGmul));
setMulti(mu);
for x := 0 to FCC do
for y := 0 to FRC do begin
st.readbuffer(FArr[x, y].width, w);
st.readbuffer(FArr[x, y].height, w);
st.readbuffer(FArr[x, y].Teilew, w);
st.readbuffer(FArr[x, y].Teileh, w);
st.readbuffer(FArr[x, y].FColor, i);
st.readbuffer(FArr[x, y].select, 1);
st.readbuffer(lg, i);
setlength(FArr[x, y].Text, lg);
st.readbuffer(FArr[x, y].Text[1], lg);
st.readbuffer(FArr[x, y].FTextLine, sizeof(TTGMul));
end;
st.readbuffer(cl, c);
Font.color := cl;
if q = 87654321 then begin
st.readbuffer(FFStyle, sizeof(TFontStyles));
st.readbuffer(FFDisc, c);
st.readbuffer(FFocusC, c);
st.readbuffer(FFixBttn, 1);
st.readbuffer(FFoc, 1);
st.readbuffer(Frand, sizeof(TTGBorder));
st.readbuffer(FEPos, sizeof(TTGEPos));
st.readbuffer(FNH, 1);
st.readbuffer(FSelc, c);
st.readbuffer(FNofo, c);
st.readbuffer(FBack, sizeof(TTGBack));
st.readbuffer(FNW, 1);
st.readbuffer(FFixC, c);
st.readbuffer(FFlat, 1);
st.readbuffer(cl, c);
color := cl;
st.readbuffer(FMsg, 1);
st.readbuffer(FPC, c);
st.readbuffer(Fedg, 1);
st.readbuffer(lb, 1);
setFLW(lb);
st.readbuffer(FFC, 1);
st.readbuffer(FFR, 1);
st.readbuffer(FCol, i);
st.readbuffer(FRow, i);
st.readbuffer(FDisc, c);
st.readbuffer(FSels, sizeof(TTGSelS));
st.readbuffer(Fedge, 1);
st.readbuffer(FCt, 1);
for x := 0 to FCC - 1 do
st.readbuffer(FAlig[x], i);
st.readbuffer(m, 1);
if m then begin
FPic := nil;
FBmp.width := 0;
FBmp.height := 0;
end else begin
FBmp.loadfromstream(st);
FPic.assign(FBmp);
end;
st.readbuffer(LogFont, sizeof(TLogFont));
Font.Handle := CreateFontIndirect(LogFont);
st.readbuffer(x, i);
setlength(s, x);
st.readbuffer(s[1], x);
Hint := s;
st.readbuffer(LogFont, sizeof(TLogFont));
FHlpCtrl.FEdit.Font.Handle := CreateFontIndirect(LogFont);
st.readbuffer(cl, c);
FHlpCtrl.FEdit.Font.color := cl;
st.readbuffer(cl, c);
FHlpCtrl.FEdit.color := cl;
st.readbuffer(cl, c);
FHlpCtrl.FL.color := cl;
st.readbuffer(cl, c);
FHlpCtrl.FL.Font.color := cl;
st.readbuffer(Fu, i);
end;
neu;
result := true;
except
if FMsg then
messagebox(0, 'Fehler beim Lesen aus dem Stream. ',
'FEHLER', mb_IconError);
end;
end;
procedure TTextGrid.Reset;
begin
loose;
FCol := -1;
FRow := -1;
invalidate;
end;
procedure TTextGrid.setEFont(f: TFont);
begin
FHlpCtrl.Font.assign(f);
end;
function TTextGrid.getEFont: TFont;
begin
result := FHlpCtrl.Font;
end;
procedure TTextGrid.setFEC(c: TColor);
begin
FHlpCtrl.FEdit.Color := c;
end;
function TTextGrid.FEC: TColor;
begin
result := FHlpCtrl.FEdit.Color;
end;
procedure TTextGrid.EditTipC(c: TColor);
begin
FHlpCtrl.FL.Color := c;
end;
procedure TTextGrid.EditTipFontC(c: TColor);
begin
FHlpCtrl.FL.Font.Color := c;
end;
function TTExtGrid.getETC: TColor;
begin
result := FHlpCtrl.FL.Color;
end;
function TTExtGrid.getETFC: TColor;
begin
result := FHlpCtrl.FL.Font.Color;
end;
procedure TTextGrid.setFtip(b: boolean);
begin
if b <> FTip then begin
FTip := b;
resize;
end;
end;
procedure TTextGrid.home(b: boolean);
begin
FCol := FFC;
if b or (FRow < FFR) or (FRow >= FRC) then FRow := FFR;
while (FRow < FRC - 1) and (FArr[FCol, FRow].height = 0) do inc(FRow);
while (Farr[FCol, FRow].width = 0) and (FCol < FCC - 1) do inc(FCol);
loose;
if (FArr[FCol, FRow].height > 0) and (FArr[FCol, FRow].width > 0)
then Farr[FCol, FRow].select := true;
invalidate;
end;
procedure TTextGrid.ende(b: boolean);
begin
FCol := FCC - 1;
if b or (FRow < FFR) or (FRow >= FRC) then FRow := FRC - 1;
while (FRow > FFR) and (FArr[FCol, FRow].height = 0) do dec(FRow);
while (Farr[FCol, FRow].width = 0) and (FCol > FFC) do dec(FCol);
loose;
if (FArr[FCol, FRow].height > 0) and (FArr[FCol, FRow].width > 0)
then Farr[FCol, FRow].select := true;
invalidate;
end;
function TTextGrid.istext(b, immer: boolean): boolean;
var
x, y: integer;
begin
result := false;
for x := FFC to FCC - 1 do
for y := FFR to FRC - 1 do
if ((FArr[x, y].select) or immer)
and (FArr[x, y].text <> '') then begin
if b then begin
result := true;
exit;
end;
FArr[x, y].text := '';
end;
end;
procedure TTextGrid.OnTimer(sender: TObject);
begin
FTimer.interval := 0;
FZahl := 0;
end;
procedure TFHlpCtrl.Mousewheel(var M: TMessage);
var
zDelta: shortint;
fwKeys: word;
b, r: boolean;
begin
with FGrphCtrl do begin
if not FPermit then exit;
fwKeys := LOWORD(M.wParam);
zDelta := HIWORD(M.wParam);
b := false;
r := (fwKeys = MK_CONTROL) xor Frast;
if zDelta < 0 then begin
if r then begin
if assigned(FWheel) then FWheel(self, tgLeftWards, FCol, FRow, b);
if not b
then nachlinks(false);
end else begin
if assigned(FWheel) then FWheel(self, tgDownWards, FCol, FRow, b);
if not b
then nachunten(false);
end;
end else begin
if r then begin
if assigned(FWheel) then FWheel(self, tgRightWards, FCol, FRow, b);
if not b
then nachrechts(false);
end else begin
if assigned(FWheel) then FWheel(self, tgUpWards, FCol, FRow, b);
if not b
then nachoben(false);
end;
end;
end;
end;
procedure TTextGrid.SeparateAll;
var
x, y: integer;
begin
if not Fedg then begin
meldung('Das Separieren von Zellen');
exit;
end;
loose;
FMatic := true;
for x := FFC to FCC - 1 do
for y := FFR to FRC - 1 do
separatecells(x, y);
FMatic := false;
selectieren;
neu;
end;
procedure TTextGrid.click4(Sender: TObject);
begin
if sender = Fmi[5] then
SeparateAll else
click3(self);
end;
procedure TTextGrid.click6(Sender: TObject);
begin
clipboard.asText := FArr[FCol, FRow].text;
if sender = Fmi[6] then begin
FArr[FCol, FRow].text := '';
invalidate;
end;
end;
function TTextGrid.ueberschreiben: boolean;
begin
result := true;
if FMsg and (FArr[FCol, FRow].text <> '') then begin
if messagebox(0,
PChar('Wollen Sie die Zelle wirklich überschreiben? '),
'FRAGE', MB_YESNO or MB_ICONQUESTION) <> mryes
then result := false;
end;
end;
procedure TTextGrid.click8(Sender: TObject);
begin
if ueberschreiben then begin
cells[FCol, FRow] := clipboard.astext;
invalidate;
end;
end;
procedure TTextGrid.ClearText;
begin
click3(self);
end;
procedure TTextGrid.MouseToCell
(x, y: integer; Rahmen: boolean; out ACol, ARow: integer);
var
p: TPoint;
begin
p := zelle(x, y);
if Rahmen then begin
if p.x < 0 then begin
dec(x, succ(FLW));
p := zelle(x, y);
end;
if p.x < 0 then begin
inc(x, succ(FLW * 2));
p := zelle(x, y);
end;
if p.y < 0 then begin
dec(y, succ(FLW));
p := zelle(x, y);
end;
if p.y < 0 then begin
inc(y, succ(FLW * 2));
p := zelle(x, y);
end;
end;
ACol := p.x;
ARow := p.y;
end;
procedure Register;
begin
RegisterComponents('DBR', [TTextGrid]);
end;
end.
|
Zugriffe seit 6.9.2001 auf Delphi-Ecke





