jvcllaz: Add TJvSpellChecker incl demo and sample dictionaries

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6237 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-03-12 08:51:28 +00:00
parent 7df733f676
commit 6eb42439cf
16 changed files with 211307 additions and 5 deletions

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<UseDefaultCompilerOptions Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="JvSpellCheckerDemo"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
<Modes Count="0"/>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="JvCmpR"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="3">
<Unit0>
<Filename Value="JvSpellCheckerDemo.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="JvSpellCheckerForm.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
</Unit1>
<Unit2>
<Filename Value="MainFrm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="frmMain"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit2>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="..\..\bin\JvSpellCheckerDemo"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,16 @@
program JvSpellCheckerDemo;
uses
Forms, Interfaces,
MainFrm in 'MainFrm.pas' {frmMain},
JvSpellCheckerForm in 'JvSpellCheckerForm.pas' {frmSpellChecker};
{$R *.res}
begin
Application.Scaled := True;
Application.Initialize;
Application.CreateForm(TfrmMain, frmMain);
Application.CreateForm(TfrmSpellChecker, frmSpellChecker);
Application.Run;
end.

View File

@@ -0,0 +1,193 @@
object frmSpellChecker: TfrmSpellChecker
Left = 338
Top = 177
BorderStyle = bsDialog
Caption = 'Spell check document'
ClientHeight = 334
ClientWidth = 384
Color = clBtnFace
DefaultMonitor = dmDesktop
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Shell Dlg 2'
Font.Style = []
FormStyle = fsStayOnTop
OldCreateOrder = False
Position = poMainFormCenter
Scaled = False
OnCreate = FormCreate
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 16
Top = 16
Width = 72
Height = 13
Caption = 'Not in wordlist:'
end
object Label2: TLabel
Left = 16
Top = 102
Width = 62
Height = 13
Caption = 'Suggestions:'
end
object lblNoSuggestions: TLabel
Left = 179
Top = 101
Width = 93
Height = 13
Caption = '(nothing to display)'
Visible = False
end
object Label3: TLabel
Left = 16
Top = 56
Width = 65
Height = 13
Caption = 'Replace with:'
end
object edNewWord: TEdit
Left = 16
Top = 72
Width = 254
Height = 21
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
end
object lbSuggestions: TListBox
Left = 16
Top = 120
Width = 254
Height = 82
Anchors = [akLeft, akTop, akRight, akBottom]
ItemHeight = 13
TabOrder = 2
OnClick = lbSuggestionsClick
end
object btnIgnore: TButton
Left = 294
Top = 32
Width = 75
Height = 25
Action = acIgnore
Anchors = [akTop, akRight]
TabOrder = 3
end
object btnIgnoreAll: TButton
Left = 294
Top = 61
Width = 75
Height = 25
Action = acIgnoreAll
Anchors = [akTop, akRight]
TabOrder = 4
end
object btnChange: TButton
Left = 294
Top = 120
Width = 75
Height = 25
Action = acChange
Anchors = [akTop, akRight]
TabOrder = 5
end
object btnClose: TButton
Left = 294
Top = 286
Width = 75
Height = 25
Action = acClose
Anchors = [akRight, akBottom]
Cancel = True
TabOrder = 8
end
object btnAdd: TButton
Left = 294
Top = 149
Width = 75
Height = 25
Action = acAdd
Anchors = [akTop, akRight]
TabOrder = 6
end
object GroupBox1: TGroupBox
Left = 16
Top = 209
Width = 257
Height = 105
Anchors = [akLeft, akRight, akBottom]
Caption = ' Ignore: '
TabOrder = 7
object chkUpperCase: TCheckBox
Left = 24
Top = 23
Width = 207
Height = 17
Caption = '&UPPERCASE words'
TabOrder = 0
end
object chkNumber: TCheckBox
Left = 24
Top = 39
Width = 207
Height = 17
Caption = 'Words with &numbers'
TabOrder = 1
end
object chkURL: TCheckBox
Left = 24
Top = 55
Width = 207
Height = 17
Caption = 'Internet and file &paths'
TabOrder = 2
end
object chkHTML: TCheckBox
Left = 24
Top = 71
Width = 207
Height = 17
Caption = 'HT&ML code'
TabOrder = 3
end
end
object edBadWord: TEdit
Left = 16
Top = 32
Width = 254
Height = 21
Anchors = [akLeft, akTop, akRight]
Color = clBtnFace
ReadOnly = True
TabOrder = 0
end
object alSpell: TActionList
OnUpdate = alSpellUpdate
Left = 296
Top = 224
object acIgnore: TAction
Caption = '&Ignore'
OnExecute = acIgnoreExecute
end
object acIgnoreAll: TAction
Caption = 'Ignore &All'
OnExecute = acIgnoreAllExecute
end
object acChange: TAction
Caption = 'C&hange'
OnExecute = acChangeExecute
end
object acAdd: TAction
Caption = 'A&dd'
OnExecute = acAddExecute
end
object acClose: TAction
Caption = '&Close'
ShortCut = 27
OnExecute = acCloseExecute
end
end
end

View File

@@ -0,0 +1,329 @@
{******************************************************************
JEDI-VCL Demo
Copyright (C) 2002 Project JEDI
Original author:
Contributor(s):
You may retrieve the latest version of this file at the JEDI-JVCL
home page, located at http://jvcl.delphi-jedi.org
The contents of this file are used with permission, subject to
the Mozilla Public License Version 1.1 (the "License"); you may
not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1_1Final.html
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
******************************************************************}
unit JvSpellCheckerForm;
interface
{$mode objfpc}{$H+}
//{$I jvcl.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, JvSpellChecker, ActnList;
type
{ This is an example form with code that shows how to implement a spell check form
that can be displayed to the end user. The TJvSpellChecker is created dynamically
so you don't need to install it to run the demo: just make sure the JvSpellChecker and
JvSpellIntf units are somewhere in your path.
The main tasks of this form is to:
* Scan for the next misspelled word (GetNextWord)
* Display the misspelled word along with suggested replacements
* Call an event handler to highlight the text in the original control
* Call an event handler when the user wants to replace the word
* Add a word to the user dictionary (btnAdd)
* Add a word to the ignore list (btnIgnoreAll)
This form doesn't implement everything needed for a professional looking form (i.e only
enable buttons as needed) but it can serve as a base for a more complete implementation.
}
TJvReplaceTextEvent = procedure(Sender: TObject; StartIndex, ALength: integer; const NewText: string) of object;
TJvSelectTextEvent = procedure(Sender: TObject; StartIndex, ALength: integer) of object;
TfrmSpellChecker = class(TForm)
Label1: TLabel;
edNewWord: TEdit;
Label2: TLabel;
lbSuggestions: TListBox;
btnIgnore: TButton;
btnIgnoreAll: TButton;
btnChange: TButton;
btnClose: TButton;
btnAdd: TButton;
GroupBox1: TGroupBox;
chkUpperCase: TCheckBox;
chkNumber: TCheckBox;
chkURL: TCheckBox;
chkHTML: TCheckBox;
lblNoSuggestions: TLabel;
Label3: TLabel;
edBadWord: TEdit;
alSpell: TActionList;
acIgnore: TAction;
acIgnoreAll: TAction;
acChange: TAction;
acAdd: TAction;
acClose: TAction;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure acIgnoreExecute(Sender: TObject);
procedure acIgnoreAllExecute(Sender: TObject);
procedure acChangeExecute(Sender: TObject);
procedure acAddExecute(Sender: TObject);
procedure acCloseExecute(Sender: TObject);
procedure alSpellUpdate(AAction: TBasicAction; var Handled: Boolean);
procedure lbSuggestionsClick(Sender: TObject);
private
{ Private declarations }
FStartIndex, FLength: integer;
ASpellChecker: TJvSpellChecker;
FOnReplaceText: TJvReplaceTextEvent;
FOnSelectText: TJvSelectTextEvent;
procedure CloseAndReport(ReportSuccess: boolean);
function GetNextWord: boolean;
procedure DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
procedure DoSelectText(Sender: TObject; StartIndex, ALength: integer);
function GetSpellText: string;
procedure SetSpellText(const Value: string);
procedure DoCanIgnore(Sender: TObject; const Value: string; var CanIgnore: boolean);
procedure CheckSuggestions;
public
{ Public declarations }
property SpellText: string read GetSpellText write SetSpellText;
property OnReplaceText: TJvReplaceTextEvent read FOnReplaceText write FOnReplaceText;
property OnSelectText: TJvSelectTextEvent read FOnSelectText write FOnSelectText;
end;
var
frmSpellChecker: TfrmSpellChecker;
implementation
{$R *.lfm}
procedure TfrmSpellChecker.FormCreate(Sender: TObject);
var S:string;
begin
ASpellChecker := TJvSpellChecker.Create(self);
// Dictionaries are plain text files, one word per row, preferably sorted.
// If you don't load a dictionary, all words are misspelled and you won't get any suggestions
S := ExtractFilePath(Application.ExeName) + 'english.dic';
if not FileExists(S) then
S := '..\Dict\english.dic';
if FileExists(S) then
ASpellChecker.Dictionary := S
else
ShowMessage('Dictionary file not found: make sure you have an english.dic file in the exe folder!');
// ASpellChecker.UserDictionary.LoadFromFile(Application.ExeName + 'custom.dic'); // you need to create this
// set up a custom ignore filter:
ASpellChecker.OnCanIgnore := @DoCanIgnore;
end;
procedure TfrmSpellChecker.DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
begin
// this events calls back to the main form where the content of the rich edit is updated
if Assigned(FOnReplaceText) then
FOnReplaceText(self, StartIndex, ALength, NewText);
end;
function TfrmSpellChecker.GetSpellText: string;
begin
Result := ASpellChecker.Text;
end;
procedure TfrmSpellChecker.SetSpellText(const Value: string);
begin
ASpellChecker.Text := Value;
end;
procedure TfrmSpellChecker.CheckSuggestions;
begin
if lbSuggestions.Items.Count = 0 then
begin
lblNoSuggestions.Parent := lbSuggestions;
lblNoSuggestions.Top := 4;
lblNoSuggestions.Left := (lbSuggestions.ClientWidth - lblNoSuggestions.Width) div 2;
lblNoSuggestions.Visible := true;
end
else
lblNoSuggestions.Visible := false;
end;
function TfrmSpellChecker.GetNextWord: boolean;
begin
// scan for the next misspelled word. Returns false if no more misspelled words are found
Result := false;
while ASpellChecker.SpellChecker.Next(FStartIndex, FLength) do
begin
edBadWord.Text := '';
edNewWord.Text := '';
Result := FLength > 0;
if Result then
begin
edBadWord.Text := Copy(ASpellChecker.Text, FStartIndex, FLength);
lbSuggestions.Items := ASpellChecker.SpellChecker.Suggestions;
if lbSuggestions.Items.Count > 0 then
begin
edNewWord.Text := lbSuggestions.Items[0];
lbSuggestions.ItemIndex := 0;
end
else
edNewWord.Text := edBadWord.Text;
edNewWord.SetFocus;
end;
CheckSuggestions;
Exit;
end;
end;
procedure TfrmSpellChecker.FormShow(Sender: TObject);
begin
if GetNextWord then
DoSelectText(self, FStartIndex, FLength)
else
CloseAndReport(false);
end;
procedure TfrmSpellChecker.DoSelectText(Sender: TObject; StartIndex,
ALength: integer);
begin
// this events calls back to the main form where the selection in the rich edit is updated
if Assigned(FOnSelectText) then FOnSelectText(self, StartIndex, ALength);
end;
procedure TfrmSpellChecker.DoCanIgnore(Sender: TObject; const Value: string;
var CanIgnore: boolean);
var
i: integer;
begin
// custom event to manage some of the options in the dialog
// always ignore words shorter than four letter
if Length(Value) < 4 then
begin
CanIgnore := true;
Exit;
end;
// make some additional checks on the current word to determine if we need to spellcheck it
if chkUpperCase.Checked and (AnsiUpperCase(Value) = Value) then // ignore all UPPERCASE words
begin
CanIgnore := true;
Exit;
end;
if chkNumber.Checked then // ignore words that contains numbers
for i := 1 to Length(Value) do
if {$IFDEF RTL200_UP}CharInSet(Value[i], ['0'..'9', '#', '%']){$ELSE}(Value[i] in ['0'..'9', '#', '%']){$ENDIF RTL200_UP} then
begin
CanIgnore := true;
Exit;
end;
if chkURL.Checked then // ignore URL's and file paths (this code is in no way 100% effective...)
for i := 1 to Length(Value) do
if {$IFDEF RTL200_UP}CharInSet(Value[i], [':', '/', '\']){$ELSE}(Value[i] in [':', '/', '\']){$ENDIF RTL200_UP} then
begin
CanIgnore := true;
Exit;
end;
if chkHTML.Checked then // ignore HTML tags (this code is in no way 100% effective...)
CanIgnore := (Length(Value) < 2) or ((Value[1] = '<') or (Value[Length(Value)] = '>')) or
((Value[1] = '&') and (Value[Length(Value)] = ';'));
end;
procedure TfrmSpellChecker.CloseAndReport(ReportSuccess: boolean);
var
S: string;
begin
if ReportSuccess then
S := 'Spell check completed!'
else
S := 'There is nothing to spell check';
ShowMessage(S);
// delay since we might have been called from the OnShow event (can't close in OnShow)
PostMessage(Handle, WM_CLOSE, 0, 0);
end;
procedure TfrmSpellChecker.acIgnoreExecute(Sender: TObject);
begin
// ignore = skip to next word but don't remember the word we just saw
if GetNextWord then
DoSelectText(self, FStartIndex, FLength)
else
CloseAndReport(true)
end;
procedure TfrmSpellChecker.acIgnoreAllExecute(Sender: TObject);
begin
// ignore all = add to ignore list so it will be skipped in the future as well
ASpellChecker.SpellChecker.Ignores.Add(AnsiLowerCase(edBadWord.Text));
if GetNextWord then
DoSelectText(self, FStartIndex, FLength)
else
CloseAndReport(true);
end;
procedure TfrmSpellChecker.acChangeExecute(Sender: TObject);
begin
// replace the current selection with the word in the edit
DoReplaceText(self, FStartIndex, FLength, edNewWord.Text);
if GetNextWord then
DoSelectText(self, FStartIndex, FLength)
else
CloseAndReport(true)
end;
procedure TfrmSpellChecker.acAddExecute(Sender: TObject);
begin
// Add the misspelled word to the user dictionary. To persist, you must add code to call
// UserDictionary.SaveToFile() at close down as well as UserDictionary.LoadFromFile() at start up.
ASpellChecker.SpellChecker.UserDictionary.Add(edBadWord.Text);
edNewWord.Text := edBadWord.Text;
// change the word as well
if not acChange.Execute then
begin
// move on
if GetNextWord then
DoSelectText(self, FStartIndex, FLength)
else
CloseAndReport(true);
end;
end;
procedure TfrmSpellChecker.acCloseExecute(Sender: TObject);
begin
Close;
end;
procedure TfrmSpellChecker.alSpellUpdate(AAction: TBasicAction;
var Handled: Boolean);
begin
acIgnore.Enabled := edBadWord.Text <> '';
acIgnoreAll.Enabled := acIgnore.Enabled;
acChange.Enabled := not AnsiSameText(edBadWord.Text, edNewWord.Text);
acAdd.Enabled := (edBadWord.Text <> '') and (ASpellChecker.UserDictionary.IndexOf(edBadWord.Text) < 0);
end;
procedure TfrmSpellChecker.lbSuggestionsClick(Sender: TObject);
begin
with lbSuggestions do
if ItemIndex > -1 then
edNewWord.Text := Items[ItemIndex];
end;
end.

View File

@@ -0,0 +1,93 @@
object frmMain: TfrmMain
Left = 353
Height = 398
Top = 156
Width = 535
Caption = 'JvSpellChecker Demo'
ClientHeight = 378
ClientWidth = 535
Color = clBtnFace
Constraints.MinHeight = 200
Constraints.MinWidth = 320
DefaultMonitor = dmDesktop
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Shell Dlg 2'
Menu = mmMain
Position = poScreenCenter
LCLVersion = '1.9.0.0'
Scaled = False
object reText: TMemo
Left = 0
Height = 355
Top = 0
Width = 535
Align = alClient
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'MS Shell Dlg 2'
HideSelection = False
ParentFont = False
ScrollBars = ssBoth
TabOrder = 0
WantTabs = True
WordWrap = False
end
object StatusBar1: TStatusBar
Left = 0
Height = 23
Top = 355
Width = 535
Panels = <
item
Width = 50
end>
SimplePanel = False
end
object mmMain: TMainMenu
left = 120
top = 64
object File1: TMenuItem
Caption = 'File'
object Open1: TMenuItem
Caption = 'Open...'
ShortCut = 16463
OnClick = Open1Click
end
object N1: TMenuItem
Caption = '-'
end
object Close1: TMenuItem
Caption = 'Close'
ShortCut = 32883
OnClick = Close1Click
end
end
object Edit1: TMenuItem
Caption = 'Edit'
object SpellCheck1: TMenuItem
Caption = 'Spell Check...'
ShortCut = 118
OnClick = SpellCheck1Click
end
object N2: TMenuItem
Caption = '-'
end
object Saveasimage1: TMenuItem
Caption = 'Save as image...'
OnClick = Saveasimage1Click
end
end
end
object OpenDialog1: TOpenDialog
Filter = 'Text files|*.txt|RTF files|*.rtf|All files|*.*'
left = 168
top = 160
end
object SaveDialog1: TSaveDialog
FileName = 'new.bmp'
Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]
left = 272
top = 192
end
end

View File

@@ -0,0 +1,142 @@
{******************************************************************
JEDI-VCL Demo
Copyright (C) 2002 Project JEDI
Original author:
Contributor(s):
You may retrieve the latest version of this file at the JEDI-JVCL
home page, located at http://jvcl.delphi-jedi.org
The contents of this file are used with permission, subject to
the Mozilla Public License Version 1.1 (the "License"); you may
not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1_1Final.html
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
******************************************************************}
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus, ComCtrls, JvComponent;
type
TfrmMain = class(TForm)
reText: TMemo;
mmMain: TMainMenu;
File1: TMenuItem;
Edit1: TMenuItem;
SpellCheck1: TMenuItem;
Open1: TMenuItem;
N1: TMenuItem;
Close1: TMenuItem;
StatusBar1: TStatusBar;
OpenDialog1: TOpenDialog;
N2: TMenuItem;
Saveasimage1: TMenuItem;
SaveDialog1: TSaveDialog;
procedure Open1Click(Sender: TObject);
procedure Close1Click(Sender: TObject);
procedure SpellCheck1Click(Sender: TObject);
procedure Saveasimage1Click(Sender: TObject);
private
{ Private declarations }
// FOffset is used to adjust the insert point in the rich edit when the replaced word
// has a different length than the original word
FOffset: integer;
// called when a word should be replaced
procedure DoReplaceText(Sender: TObject; StartIndex, ALength: integer; const NewText: string);
// called when a word needs to be highlighted. NB: set HideSelection := false or you
// won't see the selection in the edit!
procedure DoSelectText(Sender: TObject; StartIndex, ALength: integer);
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
uses
JvSpellCheckerForm;
{$R *.lfm}
procedure TfrmMain.Open1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
reText.Lines.LoadFromFile(OpenDialog1.Filename);
StatusBar1.Panels[0].Text := ' ' + OpenDialog1.Filename;
end;
end;
procedure TfrmMain.Close1Click(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.SpellCheck1Click(Sender: TObject);
begin
// set up the spell-checker form
if not frmSpellChecker.Visible then
begin
// StartIndex is 1-based, SelStart is 0-based, so we set intial FOffset to 1
FOffset := 1;
// the original text to spell check
frmSpellChecker.SpellText := reText.Lines.Text;
// event handler for when a word is to be replaced
frmSpellChecker.OnReplaceText := @DoReplaceText;
// event handler for when a word needs to be selected
frmSpellChecker.OnSelectText := @DoSelectText;
frmSpellChecker.Show; // ShowModal also works
end;
end;
procedure TfrmMain.DoSelectText(Sender: TObject; StartIndex, ALength: integer);
begin
// just select the text in the rich edit so the user can see were he is
reText.SelStart := StartIndex - FOffset;
reText.SelLength := ALength;
end;
procedure TfrmMain.DoReplaceText(Sender: TObject; StartIndex,
ALength: integer; const NewText: string);
begin
reText.SelStart := StartIndex - FOffset;
reText.SelLength := ALength;
// replace the selected text
reText.SelText := NewText;
// adjust offset for next round
Inc(FOffset, ALength - Length(NewText));
end;
procedure TfrmMain.Saveasimage1Click(Sender: TObject);
var Picture:TPicture;
begin
if SaveDialog1.Execute then
begin
Picture := TPicture.Create;
try
// reText.SaveToImage(Picture);
// Picture.SaveToFile(SaveDialog1.Filename);
finally
Picture.Free;
end;
end;
end;
end.

View File

@@ -4,9 +4,6 @@
<Version Value="11"/>
<PathDelim Value="\"/>
<General>
<Flags>
<UseDefaultCompilerOptions Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="SimpleTLTest1"/>
@@ -64,7 +61,7 @@
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SimpleTLTest1"/>
<Filename Value="..\..\bin\SimpleTLTest1"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>