"〈" durch das Zeichen "kleiner als" und
"〉" durch das Zeichen "größer als".
procedure tausche(a,b: string); var x: string; begin x := a; a := b; b := x; end;Niemals! Wie leicht man doch etwas vergisst, sieht man hier.
procedure TForm1.Button1Click(Sender: TObject);
var u, v: string;
begin
u := 'A';
v := 'B';
showmessage('1.' + u + ' 2.' + v);
tausche(u,v);
showmessage('1.' + u + ' 2.' + v + ' Nun vertauscht?');
end;
Die Prozedur tut nicht, was Du erwartet hast. procedure tausche(var a,b: string); (a, und b sind Variablenparameter!).Außerdem hast Du folgende Regel nicht beachtet:
procedure kup(var s: string); overload; begin s := copy(s, 1, length(s) - 1) end; procedure kup(var s: string; Anzahl: integer); overload; begin kup(s); if Anzahl 〉 1 then kup(s, Anzahl - 1); //rekursiv end;Oft will man Zahlen oder Strings tauschen. Durch folgende Prozeduren wird das Programmieren vereinfacht:
procedure tausche(var a, b: string); overload; var c: string; begin c := a; a := b; b := c; end; procedure tausche(var a, b: integer); overload; var c: integer; begin c := a; a := b; b := c; end; procedure tausche(var a, b: Extended); overload; var c: extended; begin c := a; a := b; b := c; end;
function char_(const s: string; const k: integer): char;
begin
if (k 〈= 0) or (k〉length(s)) then result := #0 //oder ' '
else result := s[k]
end;
Das letzte Zeichen eines Strings ermittelt folgende Funktion:
(s='' erlaubt)
function char_last(const s: string): char; begin result := char_(s, length(s)) end;Mit folgender toleranten Funktion kannst du das k-te Zeichen eines Strings überschreiben.1
procedure char_in(var s: string; k: integer; c: char); //s[k]:=c begin while length(s) 〈k do s := s + ' '; s[k] := c end;
function OnlySpaces(s: string): boolean;
begin
result := (s = StringOfChar(' ',length(s)));
end;
k := length(pfad); //z.B. pfad='c:\Programme\Borland\Delphi' while (k>0) and (pfad[k]〈〉'\') do dec(k); pfad := copy(pfad,1,k-1) //Jetzt pfad='c:\Programme\Borland';
function pos_n(const a: string; b: string; n: integer): integer;
var k: integer;
begin
if n 〈1 then Begin result := 0; exit End;
//Sollte nicht vorkommen
if n = 1 then result := pos(a, b) else Begin
k := pos(a, b);
if k = 0 then result := 0 else BEgin
b := copyab(b, k + 1);
result := pos_n(a, b, n - 1); //rekursiv
if result > 0 then result := k + result;
ENd;
End;
end;
function copyab(const s:string; const i:integer):string;
//Rest von s ab i-tem Zeichen
begin result:=copy(s,i,length(s)-i+1) end;
function lastpos(const klein, gross: string): integer;
//die letzte Position von a in b wird gesuch
var k: integer;
begin
for k := length(gross) - length(klein) + 1 downto 1 do
if pos(klein,copyab(gross,k)) = 1 then Begin
result := k;
exit;
End;
result := 0; //nicht vorhanden
end;
function wort_(s: string; k: integer): string;
var n: integer;
begin
s := trim(s);
//entfernt Leerzeichen, #13 oder andere Steuerzeichen
n := pos(' ', s);
if n = 0 then n := pos(#13,s); //Zeilenumbruch
if n = 0 then Begin
if k 〉 1 then result := '' else result := s
End else Begin //z.B. s='abc def;
if k 〉 1 then
result := wort_(copyab(s, n + 1), k - 1)
//rekursiv
else result := copy(s, 1, n - 1);
End;
end;
procedure DruckeRoh_String(DiesenText:string); //uses WinSpool;
var Printer : array [0..255] of char;
p : Integer;
function RawDataToPrinter(const szPrinterName : string;
const data:string;
dwCount : DWORD) : boolean;
var
hPrinter : THandle;
DocInfo : TDocInfo1;
dwJOB : DWORD;
dwBytesWritten : DWORD;
begin
Result := False;
if OpenPrinter (pchar (szPrinterName), hPrinter, Nil) then
try
// Fill in the structure with info about this "document"
DocInfo.pDocName := 'My Document';
DocInfo.pOutputFile := Nil;
DocInfo.pDatatype := 'RAW';
// Inform the spooler the document is beginning
dwJob := StartDocPrinter (hPrinter, 1, @docInfo);
if dwJob 〈〉 0 then
try
if StartPagePrinter (hPrinter) then
try
if WritePrinter (hPrinter, Pchar(data),
dwCount, dwBytesWritten) then
Result := dwBytesWritten = dwCount;
finally
EndPagePrinter (hPrinter)
end
finally
EndDocPrinter (hPrinter);
end
finally
ClosePrinter (hPrinter)
end
end; {RawDataToPrinter}
begin
GetProfileString ('windows',
'device',
',,,',
Printer,
sizeof(Printer));
p := Pos (',', Printer);
if p > 0 then
Printer [p - 1] := #0;
RawDataToPrinter (Printer, DiesenText, length(DiesenText));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DruckeRoh_String(memo1.text+#12);
end;
Neue Seite: #12 Zeilenwechsel: #13#10 Schnellschrift: #27#73#0 Schönschrift: #27#73#2 Unterstreichen Anfang: #27#45#1 Unterstreichen Ende: #27#45#0
procedure AsciiZuAnsi(var s: string); begin if s 〉 '' then OemToChar(Pchar(s), PChar(s)); end; procedure AnsiZuAscii(var s: string); begin if s 〉 '' then CharToOem(Pchar(s), Pchar(s)); end;Wandle also jeden String entsprechend um, bevor Du ihn zum Drucker schickst!
procedure TForm1.Button1Click(Sender: TObject); //Speichern
begin
memo1.Lines.SaveToFile('c:\test.txt');
end;
procedure TForm1.Button2Click(Sender: TObject); //Einlesen
begin
memo1.Lines.LoadFromFile('c:\test.txt');
end;
Damit hast Du eine weitere überflüssige Datei auf dem Wurzelverzeichnis erzeugt.
(Machen übrigens viele Programme ... getarnt als LOG-Datei.). Du solltest die
Datei in einem Ordner ablegen, für den Du Dir noch einen passenden Namen
ausdenken solltest.
uses FileCtrl;
procedure TForm1.Button1Click(Sender: TObject); //Speichern
begin
ForceDirectories('C:\programme\versteckterOrdner');
//Benötigt " uses FileCtrl"
memo1.Lines.SaveToFile('C:\programme\versteckterOrdner\test.txt');
end;
procedure TForm1.Button2Click(Sender: TObject); //Einlesen
begin
memo1.Lines.LoadFromFile('C:\programme\versteckterOrdner\test.txt');
end;
{Benötigt werden neben den beiden Buttons
und dem Memo noch
vom Komponentenreiter "Dialoge" ein
Opendialog und ein Savedialog}
procedure TForm1.Button1Click(Sender: TObject); //Speichern
var pfad: string;
begin
with savedialog1 do if execute then
pfad := filename else exit;
memo1.Lines.SaveToFile(pfad);
end;
procedure TForm1.Button2Click(Sender: TObject); //Einlesen
var pfad: string;
begin
with opendialog1 do if execute then
pfad := filename else exit;
memo1.Lines.LoadFromFile(pfad);
end;
(* Ein einfacher Editor mit Öffnen und Speichern von Dateien.
Dabei soll demonstriert werden, wie benutzerspezifische Angaben
in einer Ini-Datei gespeichert werden.
——————————————————————————————————————————————————————————————
Stichworte: OpenDialog
ClosDialog
IniFiles
*)
unit Unieditor; // DFM-Datei binär gespeichert.
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, IniFiles;
type
TFEditor1 = class(TForm)
Panel1: TPanel;
BOeffnen: TButton;
BSichern: TButton;
BLoeschen: TButton;
BClose: TButton;
StatusBar1: TStatusBar;
Memo1: TMemo;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure BOeffnenClick(Sender: TObject);
procedure BSichernClick(Sender: TObject);
procedure BLoeschenClick(Sender: TObject);
procedure BCloseClick(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
FEditor1: TFEditor1;
implementation
{$R *.DFM}
function IniPfad:string;
begin
result:=extractFilepath(paramstr(0))//der exe-pfad des Programms
+'MyIni.ini';
end;
function HoleDateiPfad:string;
//Dass man noch weiss, wo Datei gespeichert wurde.
var MyIniFile:TIniFile;
//benötigt uses IniFiles.
//Ini-Dateien sind besser als in Registry schreiben!
begin
MyIniFile:=Tinifile.create(Inipfad);
try
result:=MyIniFile.ReadString('Section1','Schluessel1', 'File1');
finally MyIniFile.Free End;
end;
procedure SchreibeDateiPfad(pfad:string); /
/Dass man noch weiss, wo Datei gespeichert wurde
var MyIniFile:TIniFile;
//benötigt uses IniFiles. So besser als in der Registry
begin
MyIniFile:=Tinifile.create(Inipfad);
try
MyIniFile.WriteString('Section1','Schluessel1', pfad);
finally MyIniFile.Free End;
end;
procedure TFEditor1.BOeffnenClick(Sender: TObject);
begin
{Es funktioniert bereits mit den folgenden zwei Zeilen
if OpenDialog1.Execute then
memo1.Lines.LoadFromFile(Opendialog1.Filename);
komfortabler ist:}
with opendialog1 do Begin
//bewirkt, dass nicht stets "Opendialog1." geschriebeb werden muss
title:='Hallo Festplatte! Jetzt bleibt mir nichts verborgen!';
Initialdir:=extractFilepath(holedateipfad);
filename:=extractFilename(holedateipfad);
options:=[ofFileMustExist,ofAllowMultiselect,ofHideReadOnly,
ofShareAware,
ofEnableSizing,{ofShowHelp,}
{ofOldStyleDialog,}ofNoTestFileCreate,ofNoValidate];
Filter :='Pascal-Dateien (*.PAS)|*.PAS|Textdateien (*.txt)|*.TXT|'
+'Alle Dateien (*.*)|*.*';
DefaultExt:='';
if Execute then Begin
memo1.Lines.LoadFromFile(Opendialog1.Filename);
SchreibeDateiPfad(Opendialog1.Filename);
End else showmessage('Abbruch!');
End;
end;
procedure TFEditor1.BSichernClick(Sender: TObject);
begin
{Es funktioniert bereits mit den folgenden zwei Zeilen
if SaveDialog1.Execute then
memo1.Lines.SaveToFile(Savedialog1.Filename);
komfortabler ist:}
with SaveDialog1 do Begin /
/bewirkt, dass nicht stets "Savedialog1." geschriebeb werden muss
Options:=[ofCreatePrompt,ofEnableSizing,ofHideReadOnly,
ofShareAware,ofEnableSizing]; //Ohne Kästchen
//Options:=[ofHideReadOnly,ofOverwritePrompt];
//Rückfrage entfällt
Initialdir:=extractFilepath(HoleDateipfad);
filename:=extractFilename(holedateipfad);
Filter :='Pascal-Dateien (*.PAS)|*.PAS|Textdateien (*.txt)|*.TXT|'
+'Alle Dateien (*.*)|*.*';
DefaultExt:='';
if execute then Begin
memo1.Lines.SaveToFile(Savedialog1.Filename);
schreibeDateiPfad(Savedialog1.Filename);
End else showmessage('Nicht gespeichert');
End;
end;
procedure TFEditor1.BLoeschenClick(Sender: TObject);
begin
Memo1.lines.clear;
end;
procedure TFEditor1.BCloseClick(Sender: TObject);
begin
close
end;
end.
procedure SpeichereString(const s, pfad:string);
var sl: Tstringlist;
begin
sl := Tstringlist.create;
try
sl.text := adjustlinebreaks(s);
sl.SaveToFile(pfad);
finally sl.free end;
end;
Ein TStringlist hat die Methode SaveToFile und damit kannst
Du den String s abspeichern.
s := 'erste Zeile'#13+
'zweite Zeile'#13+
'dritte Zeile'
den folgenden String mit für Windows richtigen Zeilenumbrüchen.
s := 'erste Zeile'#13#10+
'zweite Zeile'#13#10+
'dritte Zeile'
Wie Du den Pfad bestimmen kannst, siehst Du
hier in verschiedenen
Versionen.
{Benötigt werden neben den beiden Buttons
und den drei Bditfeldern wird noch
vom Komponentenreiter "Dialoge" ein
Opendialog und ein Savedialog}
procedure TForm1.Button1Click(Sender: TObject); //Speichern
var zeile1, zeile2, zeile3: string;
pu: Tstringlist;
begin
zeile1 := edit1.text;
zeile2 := edit2.text;
zeile3 := edit3.text;
pu := Tstringlist.Create; //Jedes "Create" benötigt ein "free"
try
pu.Add(Zeile1);
pu.Add(Zeile2);
pu.Add(Zeile3);
// statt pu.savetofile('c:\test.txt');
with savedialog1 do if execute then
pu.SaveToFile(filename);
finally pu.free End;
end;
procedure TForm1.Button2Click(Sender: TObject);
//Am nächsten Tag wieder einlesen
procedure TForm1.FormCreate(Sender: TObject);
var zeile1, zeile2, zeile3: string;
pu: Tstringlist;
begin
pu := Tstringlist.Create; //Jedes "Create" benötigt ein "free"
// statt pu.LoadFromFile('c:\test.txt');
with opendialog1 do if execute then
pu.LoadfromFile(filename);
try
if pu.count 〉 0 then Zeile1 := pu[0] else zeile1 := 'Fehlanzeige';
if pu.count 〉 1 then Zeile2 := pu[1] else zeile2 := 'Fehlanzeige';
if pu.count 〉 2 then zeile3 := pu[2] else zeile3 := 'Fehlanzeige';
//Beachte!
edit1.text := zeile1;
edit2.text := zeile2;
edit3.text := zeile3;
finally pu.free End;
end;
Bemerkung: Das einlesen könnte auch in
"procedure TForm1.FormCreate(Sender: TObject)" erfolgen. Dann mit festem
Speicherpfad, also etwa "pu.LoadFromFile('c:\test.txt')"
spieleSinus(440,100,8); //uses unit wavton——— Beginn der unit ———
unit wavton;
{Ausgerichtete Recordfelder aus!!!}
{$A-}
interface
uses forms, //für application
Classes, // für TMemoryStream
mmsystem; // für sndPlaySound
const sampl441 = 441; //für eine 1/100-Sekunde
Anzahl_stereokanaele = 8;
sampl22050 = 50*sampl441; //22050
type
Tlautstaerke = 0..8;
TRiffHeader = record
riff: Array[0..3] OF Char;
filesize: LongInt;
typeStr: Array[0..3] OF Char;
end;
TChunkRec = record
id: Array[0..3] OF Char;
size: LongInt;
end;
TWaveFormatRec = record
tag: Word;
channels: Word;
samplesPerSec: LongInt;
bytesPerSec: LongInt;
blockAlign: Word;
end;
TPCMWaveFormatRec = record
wf: TWaveFormatRec;
bitsPerSample: Word;
end;
TWAVHeader = record { WAV Format }
riffHdr: TRiffHeader;
fmtChunk: TChunkRec;
fmt: TPCMWaveFormatRec;
dataChunk: TChunkRec;
{ data follows here }
end;
procedure spieleSinus(frequenz: double;
cs: Cardinal; lautstaerke: Tlautstaerke);
//cs=CentiSekuns
implementation
procedure HeadInit(var Header: TWAVHeader);
begin
with Header do
begin
with riffHdr do
begin
//Schreibe 'RIFF' in die ersten 4 bytes
riff[0] := char($52); riff[1] := char($49);
riff[2] := char($46); riff[3] := char($46);
// wird spaeter gesetzt;
filesize := 0;
//Schreibe 'WAVE' in die naechsten 4 bytes
typeStr[0] := char($57); typeStr[1] := char($41);
typeStr[2] := char($56); typeStr[3] := char($45);
end;
with fmtChunk do
begin
//Schreibe 'fmt' + char($20) in die naechsten 4 bytes
id[0] := char($66);
id[1] := char($6D);
id[2] := char($74);
id[3] := char($20);
size := $10;
end;
with fmt.wf do
begin
//its 16 bit, 44kHz Stereo
tag := 1; channels := 2;
samplesPerSec := $AC44;
bytesPerSec := 176400;
blockAlign := 4;
fmt.bitsPerSample := $10;
end;
with dataChunk do
begin
//Schreibe 'data' in die naechsten 4 bytes
id[0] := char($64);
id[1] := char($61);
id[2] := char($74);
id[3] := char($61);
size := 0;
end;
end;
end;
function f0(const k: double): SmallInt; //k=i*Frequ i:=0 to ...
begin
result := Round(sin(k*Pi/sampl22050)*32000/Anzahl_stereokanaele)
// Frequenz Amplitude
{Üblicherweise werden hier für den Sinus Tafeln verwendet und
Schleifen durchlaufen. Das spart Rechenzeit.
Die Werte müssen allerdings dann
gerundet werden, um den Schleifenübergang zu glätten.
Bei gleichstufiger Stimmung ist das in Ordnung.
Hier soll die Frequenz aber exakt ausgegeben werden.
Weitere Frequenzen und Obertöne könner hier aufaddiert werden.}
end;
function AbtastwertSinus(const k:double): SmallInt;
begin
//z.B. k=i*frw1 (für i=441*500(5Sek) frw1=100)=max=sampl220500000
//Longword=0..4294967295
result := f0(k);
end;
procedure spieleSinus(frequenz: double; cs: Cardinal;
lautstaerke: Tlautstaerke);
//cs=CentiSekunde
const Ausgabekanal_wird_bereits_verwendet =
'Ausgabekanal wird bereits verwendet!';
var ms: TMemoryStream;
Header: TWavHeader;
i: integer; //z.B. i=0 to 441*500=441500 (5 Sekunden)
s: SmallInt;
begin
HeadInit(Header);
Header.Datachunk.size := sampl441 * cs * 2 * 2;
//441*cs Samples pro sekunde,
//2 Channels, 2Bytes (16bit)
//FileSize = DataSize + HeaderSize
Header.riffHdr.FileSize := Header.Datachunk.size + 24;
ms := TMemoryStream.Create;
try
ms.Seek(0, 0);
//Write Header to Stream
ms.Write(Header, sizeof(header));
//form here: just data chunks. in this case (16bit stereo):
// 16bit LeftValue, 16bit Right Value,
//16bit LeftValue, 16bit Right Value ...
// in the range of a SmallInt
if cs 〈= 0 then exit; //1
for i := 0 to sampl441 * cs - 2 do BEgin
//Writing left channel
s := AbtastwertSinus(i * frequenz)*Lautstaerke;
ms.Write(s, 2);
//Writing to right channel
ms.Write(s, 2);
ENd;
Finally
sndPlaySound(ms.Memory, SND_MEMORY or SND_SYNC);
//Speichern? Bitte schön: ms.SaveToFile('c:\windows\meinton.wav');
application.ProcessMessages;
ms.Free;
End;
end;
end.
- - - - /Ende der Unit - - - -
unit Unit2;
{Ausgerichtete Recordfelder aus!}
{$A-}
interface
uses forms, //für application
sysutils, //fileexists
Classes, mmsystem, WinProcs;
const sampl441 = 441; //für eine 1/100-Sekunde
sampl22050 = 50*sampl441; //22050
type
TRiffHeader = record
riff: Array[0..3] OF Char;
filesize: LongInt;
typeStr: Array[0..3] OF Char;
end;
TChunkRec = record
id: Array[0..3] OF Char;
size: LongInt;
end;
TWaveFormatRec = record
tag: Word;
channels: Word;
samplesPerSec: LongInt;
bytesPerSec: LongInt;
blockAlign: Word;
end;
TPCMWaveFormatRec = record
wf: TWaveFormatRec;
bitsPerSample: Word;
end;
TWAVHeader = record { WAV Format }
riffHdr: TRiffHeader;
fmtChunk: TChunkRec;
fmt: TPCMWaveFormatRec;
dataChunk: TChunkRec;
{ data follows here }
end;
var lautstaerke: integer = 3200;
procedure spiele(fr1, fr2, fr3, fr4, fr5, fr6, fr7,
fr8: double; tondauer: integer);
procedure spieleton(fr: double; tondauer: integer);
implementation
uses FileCtrl;
procedure HeadInit(var Header: TWAVHeader);
begin
with Header do
begin
with riffHdr do
begin
//Schreibe 'RIFF' in die ersten 4 bytes
riff[0] := char($52);
riff[1] := char($49);
riff[2] := char($46);
riff[3] := char($46);
// wird spaeter gesetzt;
filesize := 0;
//Schreibe 'WAVE' in die naechsten 4 bytes
typeStr[0] := char($57);
typeStr[1] := char($41);
typeStr[2] := char($56);
typeStr[3] := char($45);
end;
with fmtChunk do
begin
//Schreibe 'fmt' + char($20) in die naechsten 4 bytes
id[0] := char($66);
id[1] := char($6D);
id[2] := char($74);
id[3] := char($20);
size := $10;
end;
with fmt.wf do
begin
//its 16 bit, 44kHz Stereo
tag := 1; channels := 2;
samplesPerSec := $AC44;
bytesPerSec := MakeLong($B110, $2);
blockAlign := 4;
fmt.bitsPerSample := $10;
end;
with dataChunk do
begin
//Schreibe 'data' in die naechsten 4 bytes
id[0] := char($64);
id[1] := char($61);
id[2] := char($74);
id[3] := char($61);
size := 0;
end;
end;
end;
function f0(const k: double): SmallInt;
begin
//result := Round(sin(k*Pi/sampl22050)*lautstaerke);
//reiner sinus
result := Round(sin((k * Pi) / sampl22050) * lautstaerke) div 2 +
Round(sin((2 * k * Pi) / sampl22050) * lautstaerke) div 4 +
//1.Oberton
Round(sin((3 * k * Pi) / sampl22050) * lautstaerke) div 6;
//2.Oberton}
end;
function Abtastwert(const k1,k2,k3,k4,k5,k6,k7,k8: double): SmallInt;
var f:Smallint;
begin //z.B. k=i*frw1 (für i=441*500(5Sek)
//frw1=100)=max=sampl220500000
//Longword=0..4294967295
if k1=0 then Begin result:=0; exit End else f:=f0(k1);
result:=f;
if k2=0 then exit;
if k2 〈〉k1 then f:=f0(k2); //else f=f0(k1)
result:=result+f;
if k3=0 then exit;
if k3 〈〉k2 then f:=f0(k3); //else f=f0(k2)
result:=result+f;
if k4=0 then exit;
if k4 〈〉k3 then f:=f0(k4); //else f=f0(k3)
result:=result+f;
if k5=0 then exit;
if k5 〈〉k4 then f:=f0(k5); //else f=f0(k4)
result:=result+f;
if k6=0 then exit;
if k6 〈〉k5 then f:=f0(k6); //else f=f0(k5)
result:=result+f;
if k7=0 then exit;
if k7 〈〉k6 then f:=f0(k7); //else f=f0(k6)
result:=result+f;
if k8=0 then exit;
if k8 〈〉k7 then result:=result+f0(k8) else result:=result+f;
end;
procedure spiele(fr1, fr2, fr3, fr4, fr5, fr6, fr7,
fr8: double; tondauer: integer);
var ms: TMemoryStream;
Header: TWavHeader;
i: integer; //z.B. i=0 to 441*500=441500 (5 Sekunden)
s: SmallInt;
begin
HeadInit(Header);
Header.Datachunk.size := sampl441 * tondauer * 2 * 2;
//441*cs Samples pro sekunde,
//2 Channels, 2Bytes (16bit)
//FileSize = DataSize + HeaderSize
Header.riffHdr.FileSize := Header.Datachunk.size + 24;
ms := TMemoryStream.Create;
try
ms.Seek(0, 0);
//Write Header to Stream
ms.Write(Header, sizeof(header));
//form here: just data chunks. in this case (16bit stereo):
// 16bit LeftValue, 16bit Right Value,
//16bit LeftValue, 16bit Right Value ...
// in the range of a SmallInt
if tondauer 〈= 0 then exit; //kein Ton. Sollte nicht vorkommen
for i := 0 to sampl441 * tondauer - 2 do BEgin
//Writing left channel
s := Abtastwert(i * fr1, i * fr2, i * fr3, i * fr4,
i * fr5, i * fr6, i * fr7, i * fr8);
ms.Write(s, 2);
//Writing to right channel
ms.Write(s, 2);
ENd;
Finally
if not sndPlaySound(ms.Memory, SND_MEMORY or SND_SYNC) then;
ms.Free;
End;
{ sndPlaySound(ms.Memory, SND_MEMORY or SND_ASYNC or SND_LOOP)
führt bei WinNT zu Fehler. Deshalb dort nur snd_sync
sndPlaySound(ms.Memory, SND_MEMORY or SND_SYNC or SND_LOOP) }
end;
procedure spieleton(fr: double; tondauer: integer);
begin
spiele(fr, fr, fr, fr, fr, fr, fr, fr, tondauer);
end;
end.
- - - - - Im Hauptprogramm könnte dann folgendes stehen ————
procedure TForm1.Button1Click(Sender: TObject);
begin
spiele(440, 550, 660, 880, 440, 550, 660, 880,100);
spieleton(440,100);
//Dauer 100 Centisek. = 1 Sek.
end;
jpg.LoadFromFile(opendialog1.filename); image1.picture.bitmap.Assign(jpg);Das ist alles! (Siehe unten "procedure TForm1.Button1_LadenClick(..."
type TRGBValue = packed record
Blue: Byte;
Green: Byte;
Red: Byte;
End;
var
Form1: TForm1;
implementation
uses jpeg;
{$R *.DFM}
procedure TForm1.Button1_LadenClick(Sender: TObject);
var jpg :TJPEGImage; //uses jpeg;
begin
jpg:=TJPEGImage.Create;
try
jpg.Performance :=jpBestQuality;
jpg.ProgressiveDisplay := false;
jpg.Performance := jpBestQuality;
try
with OpenDialog1 do Begin
if not execute then exit;
jpg.LoadFromFile(opendialog1.filename);
image1.picture.bitmap.PixelFormat := pf24bit;
image1.picture.bitmap.Assign(jpg);
image1.width := image1.picture.bitmap.width;
image1.height := image1.picture.bitmap.height;
End;
except Showmessage('Datei existiert nicht') End;
finally jpg.Free; end;
end;
procedure TForm1.Button_HellerClick(Sender: TObject);
const h = 255;
hh = 9*h div 10; //229
var x,y: integer;
pixel: ^TRGBValue;
function groesser(x: word): word; //Faktor: 110 %
begin
{proportional} if x >= hh then result := h
else result := 10*x div 9;
//{additiv} if x > 250 then
//result := 255 else result := x + 5;
end;
begin
if image1.picture.Bitmap.PixelFormat 〈〉 pf24bit then Begin
showmessage('Nicht möglich');
exit;
End;
for y := 0 to image1.Picture.Bitmap.Height - 1 do Begin
Pixel := image1.Picture.Bitmap.ScanLine[y];
for x := 0 to image1.Picture.Bitmap.Width -1 do BEgin
pixel.red := groesser(pixel.Red);
pixel.green := groesser(pixel.green);
pixel.blue := groesser(Pixel.Blue);
inc(Pixel);
ENd;
End;
image1.refresh;
end;
Ein Programm zur Ausgabe der Wertetafel von
1
y = ———————————
(x+2)·(x-2)
procedure TForm1.Button1Click(Sender: TObject);
var x: integer;
y: real;
begin
for x := -4 to 4 do Begin
y := 1/((x+2)*(x-2)); //Doppelte Klammer nicht vergessen!
memo1.lines.add(IntToStr(x)+' '+FloatToStr(y));
End;
end;
Das Programm endet mit einem Laufzeitfehler bei x =- 2
("Division durch Null").
Die Prozedur kann nicht weiter aufgeführt.
Im Memo steht gerade:
-4 0,0833333333333333 -3 0,2Ein Pascal-Programmierer würde nun die Nullstellen des Nenners berechnen (hier natürlich einfach, im Allgemeinen jedoch nicht) und formulieren:
if (x 〈〉 -2) and (x 〈〉 2) then.... In Delphi geht es eleganter: Man kann die Fehlermeldung, die "Exception", folgendermaßen "umleiten":
procedure TForm1.Button1Click(Sender: TObject);
var x: integer;
y: real;
begin
for x := -4 to 4 do Begin
try
y := 1/((x+2)*(x-2));
memo1.lines.add(IntToStr(x)+ ' ' + FloatToStr(y));
EXcept
memo1.lines.add(IntToStr(x)+ ' ' + 'nicht definiert');
ENd;
End;
end;
Im Memo steht dann wie gewünscht:
-4 0,0833333333333333 -3 0,2 -2 nicht definiert -1 -0,333333333333333 0 -0,25 1 -0,333333333333333 2 nicht definiert 3 0,2 4 0,0833333333333333Wenn du jetzt deine Funktion änderst (oder ein Programm hast, bei dem der Benutzer die Funktion eingibt
procedure TForm1.Button1Click(Sender: TObject);
var a: integer;
begin
try
a := StrToInt(edit1.text);
Except showmessage('Sie müssen eine ganze Zahl eingeben') End;
end;
Für Fortgeschrittene (Näheres dazu in der Onlinehilfe):
function f(x: real): real;
begin
result := sqrt(x+3) + sqrt(3 - x) + 1/x;
// Nur definiert für -3 〈= x 〈= 3 und x 〈〉 0
end;
procedure TForm1.Button1Click(Sender: TObject);
var x, y: real;
xs,ys : string;
begin
x := - 4;
while x〈5 do Begin
xs := floatToStr(x);
try
y := f(x);
ys := floatToStr(y);
EXcept on e:Exception do ys := e.Message ENd;
memo1.Lines.Add(xs + ' ' + ys);
x := x + 1;
End;
end;
var irgendetwas :Tirgendetwas;//global oder lokal
//...
irgendetwas := Tirgendetwas.create;
//Für die Instanz wird Speicherplatz reserviert
//manchmal auch: if irgendetwas = nil then
//irgendetwas := Tirgendetwas.create;
//Alles mögliche wird gemacht. Zum Beispiel: Lies eine Datei.
//Bei Abbruch (beispielsweise falls Diskette nicht eingelgt),
//wird Prozedur verlassen.
//Aber folgendes wird auf jeden Fall noch erledigt:
Finally
irgendetwas.free;
irgendetwas := nil; //zu empfehlen!
End; //Speicherplatz wird wieder freigegeben.
Hier ein Beispiel ohne den Aspekt der objektorientierter Programmierung:
Der Teiler einer Zahl wird gesucht. Sobald der Teiler gefunden wurde, wird
die (zeitaufwendige) Schleife verlassen:
procedure TForm1.Button1Click(Sender: TObject);
var a, x, t: integer;
begin
a := 1430503603; //Primzahl?
t := 1;
try
for x := 2 to to round(sqrt(a))
if a mod x = 0 {"x ist Teiler von a"} then Begin
t := x;
exit; //Zeit sparen!
End;
Finally
if t = 1 then showmessage('Primzahl') else
showmessage('Der Teiler ' + inttostr(t) + ' wurde gefunden.');
End;
end;
Bemerkung: Besser wäre hier natürlich die Konstruktion ohne
try ... finally mit break statt exit.
Wenn es aber mehrere Schleifen sind, ist try ... finally
eleganter als das verpönte goto.
Fachleute überlassen es Dir, ob Du das Array oder der Array sagst.
Antwort: Der Rückgabewert der Funktion muss als Typ deklarierte sein:type Tmyarray= array of TImage; //dynamisches Array: Erster Index 0Hier die Funktion mit einem Array als Rückgabewert:
function gibmirarray: Tmyarray;
var i:integer;
begin
setlength(result,Anzahl);
for i:= 0 to Anzahl-1 do Begin
result[i]:= Timage.create(Form1);
//Damit Freigabe bei Form1.destroy
result[i].parent := form1;
result[i].picture.loadfromfile(...);
End;
End;
Das ganze ist in Wettrennen ausgeführt.
for i:=1 to 9 do begin
beep;
end;
Diese Procedure rufe ich durch ein Buttonklick auf und setze einen
Haltepunkt auf das Beep, um den Wert von i abzufangen.
Wenn ich mir das dann anschaue dann zählt die Schleife
komischerweise von 9 nach 1 runter.
i:=1;
label:
if i〈=9 then
begin
Call beep;
inc(i);
goto label;
end;
Den Vergleich mit der Konstanten 9 wiederum kann eine Intel-CPU
nicht direkt ausführen, sondern sie macht etwas wie
tmp:=i-9; if tmp〈0 then... (Das "tmp〈0" ist ein Test auf ein CPU-Flag, ist also elektronenschnell.)Es liegt daher auf der Hand, daß es effizienter ist, wenn die Schleife so formuliert wird, daß sie bei 0 endet, denn dann entfällt die Subtraktion.
function formatiere(name:string; size:integer; time:TDateTime):string;
var s:string; // Untereinander Name Größe Datum
begin
result := name;
while length(result)〈20 do result :=result + ' ';
if size〉0 then s := s + formatFloat('# # # # # # # # #',size) else s :='';
//entferne die Lehrstellenin # # #!
while length(s)〈12 do s :=' ' + s; //rechtsbündig
result := result + s + ' ' + DateToStr(time);
end;
procedure VerzeichnisEinlesen(dir:string);
var SR: TSearchRec;
begin
if dir[length(dir)] 〈〉'\' then
dir:=dir+'\';
with Form1 do begin
memo1.lines.Clear;
memo1.WordWrap := false;
memo1.Font.name := 'Courier New';
if FindFirst(dir+'*.*',faAnyFile,SR)=0 then Begin
repeat
if SR.Name[1] 〈〉'.' then begin
memo1.lines.add(formatiere(sr.name,sr.size,sr.Time));
end;
until FindNext(SR) 〈〉0;
FindClose(SR); //Nach jedem findfirst nötig,
//um sr freizugeben!
End;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
//benötigt uses FileCtrl
var dir: string;
begin //mit uses FileCtrl;
if SelectDirectory('Ordner wählen, dann OK klicken','',dir) then
VerzeichnisEinlesen(dir);
end;
Ein Beispiel mit allen Finessen findest du in
Simon FAQ unter Dateien, Ordner, Laufwerke:
"Wie kann man alle Dateien eines Ordners mitsamt der
Unterverzeichnisse ermitteln?"
procedure Verzeichnisstruktur_Einlesen(Tree : TTreeView;
Verzeichnis : String;
Eintrag : TTreeNode);
Var SR : TSearchRec;
EintragTemp : TTreeNode;
pu : Tstringlist;
k : integer;
begin
if Verzeichnis[length(Verzeichnis)] 〈〉'\' then
Verzeichnis:=Verzeichnis+'\';
//Zuerst kommmen die Einträge _sortiert_ in den Pu_ffer
pu := Tstringlist.Create;
pu.Sorted := true;
try
if FindFirst(Verzeichnis+ '*.*', faDirectory, SR)=0 then begin
repeat
if (SR.Attr and faDirectory = faDirectory)
and (SR.Name[1] 〈〉 '.') then Begin
//Eintrag ist ein Verzeichnis
if (SR.Attr and faDirectory > 0) then pu.Add(sr.name);
End;
until FindNext(SR) 〈〉0;
FindClose(SR); //Nach jedem findfirst
end;
//Jetzt werden die Einträge vom Pu_ffer in treeview1 geschaufelt.
Tree.Items.BeginUpdate;
for k := 0 to pu.Count -1 do Begin
EintragTemp := Tree.Items.AddChild(Eintrag, pu[k]);
Verzeichnisse_Einlesen(Tree,Verzeichnis + pu[k], EintragTemp);
//rekursiv}
End;
Tree.Items.EndUpdate;
Finally pu.Free End;
end; //{Nach Michael Geisler in
//Simon Reinhards FAQ}
procedure TForm1.Button1Click(Sender: TObject);
var Eintrag : TTreeNode;
verz : String;
begin
verz := 'c:';
TreeView1.Items.Clear;
Eintrag := TreeView1.Items.Add(nil,verz);
Verzeichnisse_Einlesen(TreeView1,verz,eintrag);
Eintrag.Expand(false); //verz. wird geöffnet
end;
function SelectedPath(tr: TTreeNode):string;
begin
result := tr.text;
if tr.Parent 〈〉 nil then
result := SelectedPath(tr.parent)+'\'+result;
end;
procedure TForm1.TreeView1Click(Sender: TObject);
begin
showmessage(SelectedPath(treeview1.selected));
end;
function SelectedPath(tr: TTreeNode):string;
begin
result := tr.text;
if tr.Parent 〈〉 nil then
result := SelectedPath(tr.parent)+'\'+result;
//Rekursiv
end;
function attr_(at: integer): string;
begin if at 〈0 then exit;
result := '';
if at and 1 = 1 then result := result + 'R';
if at and 2 = 2 then result := result + 'H';
if at and 4 = 4 then result := result + 'S';
if at and 8 = 8 then result := result + '(LW)';
if at and 64 = 64 then result := result + '(64)';
if at and 128 = 128 then result := result + '(128)';
end;
procedure Listview1itemsadd(const name, groesse, alt, attr: string);
var Newitem: TListItem;
Info: TSHFileInfo; //uses shellapi;
Begin
NewItem := Form1.ListView1.Items.Add;
NewItem.Caption := name;
newItem.subitems.add(groesse);
newItem.subitems.add(alt);
Newitem.subitems.Add(attr);
//if pos('\', name) = 0 then NewItem.ImageIndex := -1 else
Begin
SHGetFileInfo(PChar(name), 0, Info, SizeOf(TSHFileInfo),
SHGFI_SYSIconIndex or SHGFI_TYPENAME);
NewItem.ImageIndex := Info.IIcon;
End;
end;
procedure VerzeichnisEinlesen(dir:string);
var SR : TSearchRec;
pfad : String;
begin
if dir[length(dir)] 〈〉'\' then
dir:=dir+'\';
with Form1 do begin
if FindFirst(dir+'*.*',faAnyFile,SR)=0 then Begin
repeat
if SR.Name[1] 〈〉'.' then Begin
pfad := LowerCase(dir + sr.Name);
Listview1itemsadd(pfad,formatFloat('# # # # # # # # #',sr.size),
//entferne die Lehrstellenin # # #!
DateToStr(sr.time),attr_(sr.attr));
End;
until FindNext(SR) 〈〉0;
FindClose(SR); //Nach jedem findfirst nötig, um sr freizugeben!
End;
end;
end;
procedure Verzeichnisstruktur_Einlesen(Tree : TTreeView;
Verzeichnis : String;
Eintrag : TTreeNode);
Var SR : TSearchRec;
EintragTemp : TTreeNode;
begin
if Verzeichnis[length(Verzeichnis)] 〈〉= '\' then
Verzeichnis:=Verzeichnis+'\';
Tree.Items.BeginUpdate;
if FindFirst(Verzeichnis+ '*.*', faDirectory, SR)=0 then begin
repeat
if (SR.Attr and faDirectory = faDirectory)
and (SR.Name[1] 〈〉 '.') then Begin
//Eintrag ist ein Verzeichnis
if (SR.Attr and faDirectory > 0) then BEgin
EintragTemp := Tree.Items.AddChild(Eintrag, sr.name);
Verzeichnisstruktur_Einlesen(Tree,Verzeichnis
+ sr.name, EintragTemp);
//rekursiv}
ENd;
End;
until FindNext(SR) 〈〉 0;
sysutils.findclose(SR); //Nach jedem findfirst
end;
Tree.Items.EndUpdate;
end; {Nach Michael Geisler in Simon Reinhards FAQ}
procedure InitialisiereIcons;
var SysIL : uint;
SFI : TSHFileInfo;
SmallImages : TImageList;
begin
SmallImages := TImageList.Create(Form1);
SysIL := SHGetFileInfo('', 0, SFI, SizeOf(SFI),
SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
if SysIL 〈〉 0 then Begin
SmallImages.Handle := SysIL;
SmallImages.ShareImages := TRUE;
End;
Form1.ListView1.SmallImages := SmallImages;
end;
procedure TForm1.FormCreate(Sender: TObject);
var NewColumn: TListColumn;
begin
button1.Top := 0;
form1.setbounds(0,0,screen.Width,screen.height);
treeview1.setbounds(0,button1.height,screen.width div 5 - 15,
screen.height - button1.height - 30);
listview1.setbounds(treeview1.width,button1.height,
4*screen.Width div 5 - 15,
treeview1.height);
listview1.ViewStyle := vsReport;
listview1.GridLines := true;
with listview1 do Begin
NewColumn := Columns.Add;
NewColumn.Caption := 'Pfad';
newColumn.Width := listview1.Width div 3;
NewColumn := Columns.Add;
NewColumn.Caption := 'Größe';
newColumn.Width := listview1.Width div 6;
NewColumn := Columns.Add;
NewColumn.Caption := 'Datum';
newColumn.Width := listview1.Width div 6;
NewColumn := Columns.Add;
NewColumn.Caption := 'Attr';
newColumn.Width := listview1.Width div 12;
End;
InitialisiereIcons;
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
listview1.Items.Clear;
VerzeichnisEinlesen(SelectedPath(treeview1.selected));
end;
procedure TForm1.Button1Click(Sender: TObject);
var Eintrag : TTreeNode;
verz : String;
begin
verz := 'c:';
TreeView1.Items.Clear;
Eintrag := TreeView1.Items.Add(nil,verz);
Verzeichnisstruktur_Einlesen(TreeView1,verz,eintrag);
treeview1.alphasort;
Eintrag.Expand(false); //verz. wird geöffnet
end;
Der gesamte Quellcode zum Download:
Ein Dateineexplorer.
//Hilfsfunktionen:
function Str1IstInStr2(const a,b: string): boolean;
begin
result := pos(AnsiLowercase(a),AnsiLowercase(b)) > 0;
end;
function istInderDatei(const s: string; const pfad: string): boolean;
var pu: Tstringlist;
begin
result := false;
try
pu := Tstringlist.Create;
try
pu.LoadFromFile(pfad);
if Str1IstInStr2(s,pu.text) then result := true;
finally pu.free End;
except showmessage(pfad + ' | konnte nicht durchsucht werden') End;
end;
procedure ZuMemoFallsKiterienerfuellt(const pfad, BestimmteDatei,
SuchTextInDerDatei: string);
begin
if Str1IstInStr2(BestimmteDatei,pfad)
and istInderDatei(SuchTextInDerDatei,pfad) then
form1.memo1.lines.add('"'+pfad + '" enthält den Text "' +
SuchTextInDerDatei);
end;
// - - - - - - - - - - - Die Hauptprozedur1
//- - - - - - - - - - - - - -
procedure VerzeichnisDurchsuchen(dir: string; const BestimmteDatei,
SuchTextInDerDatei: string);
//zum Beispiel: Ist dir 'c:\' bestimmte Datei = 'html' und
// SuchTextInDerDatei = 'Hallo Welt'
//werden auf der C-Platte alle html-Dateien durchsucht,
//ob "Hallo Welt" vorkommt
//Die Namen der Dateien werden in memo1 geschrieben
var SR: TSearchRec;
dirtemp : string;
Begin
//application.ProcessMessages;
//form1.label1.caption := dir; //Zeigt, wo gesucht wird
// if Stop then exit;
//falls bei Klick auf Button2 die globale Variable
//Stop := true gesetzt wird
dir := IncludeTrailingBackslash(dir);
if FindFirst(dir+'*.*',faAnyFile,SR)=0 then Begin
repeat
//Eintrag ist eine Datei
If ((sr.attr And faDirectory) = 0) and (SR.Name[1] 〈〉'.') then
ZuMemoFallsKiterienerfuellt(dir + sr.name, BestimmteDatei,
SuchTextInDerDatei);
//Eintrag ist ein Verzeichnis
if (SR.Attr and faDirectory = faDirectory)
and (SR.Name[1] 〈〉 '.') then Begin
dirTemp := dir + sr.name;
VerzeichnisDurchsuchen(dirtemp,BestimmteDatei,
SuchTextInDerDatei);
//Rekursiv
End;
until FindNext(SR) 〈〉0;
FindClose(SR);
End;
End;
procedure TForm1.Button1Click(Sender: TObject);
var dir, datei, suchtext: string;
begin
dir := 'c:\'; //oder dir := edit1.text
datei := '.php'; //oder datei := edit2.text
suchtext := 'Hallo Welt'; // oder suchtext := edit3.text
//Stop := false; //falls Stop (globale Variable) bei Klick
//auf button2 auf true gesetzt werden kann
VerzeichnisDurchsuchen(dir, datei, suchtext);
end;
uses Shellapi;
...
if ShellExecute(application.handle,
Pchar('open'),
Pchar('notepad'),
Pchar('c:\MeiOrdner\Meintext.txt'),
Pchar(''),
sw_ShowNormal) >= 32
then showmessage('Datei ist geöffnet') else
showmessage('Notepad konnte nicht geöffnet werden.');
uses Shellapi; //für Shellexecute
// d.h. Füge deinen uses-Anweisungen noch uses Shellapi hinzu:
function waehleDatei(alterpfad:string):string; //zum Testen
begin
with form1.OpenDialog1 do Begin //Komponente von "Dialoge"
title := 'Wähle deinen Song aus';
filename := extractFilename(alterpfad);
initialdir := extractFilepath(alterpfad);
options := [ofFileMustExist, ofAllowMultiselect,
ofHideReadOnly, ofShareAware,
{ofOldStyleDialog,} ofNoTestFileCreate, ofNoValidate];
if Execute then result := filename
else Begin result :=''; showmessage('Abbruch') End;
End;
end;
procedure Anwendung(pfad:string);
begin
//uses Shellapi wird für ShellExecute benötigt
if ShellExecute(application.handle,
Pchar('open'), //vorgang
Pchar(extractfilename(pfad)),
Pchar(''), //Parameter),
Pchar( extractFilepath(pfad)),
sw_ShowNormal) 〈= 32
then showmessage('Fehlgeschlagen');
end;
procedure TForm1.Button1Click(Sender: TObject);
var pfad:string;
begin
pfad := ExtractFilePath(ParamStr(0));
//paramstr(0) = Pfad der application.
//falls dort der Song oder ähnliches abgelegt wurde
repeat
pfad := waehleDatei(pfad);
//oder pfad := filelistbox1.FileName;
if pfad 〈〉 '' then Begin
showmessage('"' + pfad + '"' +'wird geöffnet.');
Anwendung(pfad);
End;
until pfad = '';
end;
procedure TForm1.Button1Click(Sender: TObject);
var k: integer;
begin
showmessage(paramstr(0));
//liefert den Programmpfad z.B. "c:\programme\meinprogramm.exe"
for k := 1 to paramcount do
showmessage(paramstr(k)); //liefert parameter1 parameter2 ...
end;
procedure TForm1.MeinMenupunkabct1Click(Sender: TObject); begin (sender as Tmenuitem).checked := not (sender as Tmenuitem).checked; menuabc := (sender as Tmenuitem).checked; end;Dann kanst Du einen Programmpunkt folgendermaßen in Abhängigkeit des aktivierten oder deaktivierten Menüpunktes ausführen lassen:
if menuabc then {mach was} else {mach was anderes};
//edit1.text := ''; //Das soll nicht gelöscht werden! edit2.text := ''; ... edit20.text := '';Wie kann ich das eleganter machen?
procedure TForm1.Button1Click(Sender: TObject); //Editfelder löschen
var k: integer;
a: Tcomponent;
begin
for k := 0 to ComponentCount - 1 do Begin
a := components[k];
showmessage(a.name); //Zum Testen
if a.ClassType = TEdit then if a 〈〉 edit1 then
(a as Tedit).text := '';
End;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.Align := alclient;
statusbar1.Panels.Add;
statusbar1.Panels.Add;
statusbar1.Panels[0].Width := 100;
//Rest statusbar1.Panels[1].Width
showmessage('Panel hat nun '
+ IntToStr(statusbar1.Panels.Count)
+ ' Felder'); //Panel hat 2 Felder
end;
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
Zeile: longint;
Spalte: longint;
begin
Zeile := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, Memo1.SelStart,0);
Spalte := SendMessage(Memo1.Handle, EM_LINEINDEX, Zeile, 0);
statusbar1.panels[0].text := 'Zeile ' + IntToStr(Zeile +1);
statusbar1.panels[1].text := 'Spalte '
+ IntToStr((Memo1.SelStart - Spalte) + 1);
end;
procedure TForm1.Button1Click(Sender: TObject);
var i,j: integer;
begin
for i := 0 to stringgrid1.ColCount - 1 do
for j := 0 to stringgrid1.RowCount - 1 do
stringgrid1.cells[i,j] := IntTostr(i) + ' ' + inttostr(j);
application.ProcessMessages;
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject;
ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
begin
with sender as Tstringgrid do
if (Acol=2) or (pos('0',cells[Acol,ARow]) > 0) then Begin
Canvas.brush.Color := clred;
Canvas.Font.Color := clwhite;
canvas.Font.Name := 'Arial';
canvas.Font.Size := 18;
canvas.fillRect(Rect);
canvas.TextOut(Rect.Left,Rect.Top,Cells[ACol,ARow]);
End;
end; //Nach: FAQ von Simon Reinhard
Wichtig: Klicke auf Dein Stringgrid, dann im Objektinspector auf Ereignisse und
ordne "DrawCell" Deine eingefügte Procedur zu (Delphi findes sie sofort)!.
// OldProcfuerOpendialog1: Dword globale Variable
//Idee von Pascal Enz
function DialogProc(Handle: HWND; Msg: DWORD; wParam,
lParam: Integer):Integer; stdcall;
var breite, hoehe: integer;
begin
if MSG = WM_SHOWWINDOW then Begin
//Fenstergröße ändern und zentrieren
breite := 500;
hoehe := screen.height -150;
SetWindowPos(Handle, 0,
(screen.Width - breite) div 2,
(screen.height - hoehe) div 2,
breite,hoehe,0);
//Gleich Befehl ans Fenster senden: Menü "Ansicht|Detail"
SendMessage(Handle, WM_COMMAND, $A004, 0); //
End;
Result := CallWindowProc(Pointer(OldProcfuerOpendialog1),
Handle, Msg, wParam, lParam);
end;
procedure TForm1.OpenDialogShow(Sender: TObject);
//Prozedurkopf von Delphi schreiben lassen
//(im Formular "opendialog1" anklicken und
//im Objectinspektor beim "Ereignis" "onshow" doppelklicken!
var
Handle: HWND;
begin
Handle := GetParent((Sender as TOpenDialog).Handle);
OldProcfuerOpendialog1 := GetWindowLong(Handle, DWL_DLGPROC);
SetWindowLong(Handle, DWL_DLGPROC, Integer(@DialogProc));
end;
procedure TForm1.OpenDialogClose(Sender: TObject);
//Prozedurkopf von Delphi schreiben lassen
//(im Formular "opendialog1" anklicken und
//im Objectinspektor beim "Ereignis" "onclose" doppelklicken!
var
Handle: HWND;
begin
Handle := GetParent((Sender as TOpenDialog).Handle);
SetWindowLong(Handle, DWL_DLGPROC, Integer(OldProcfuerOpendialog1));
OldProcfuerOpendialog1 := 0;
end;
"Tools|Bildeditor|Neu|Symbol|Datei|32·32"
Bild malen, unter "meinbild.ico" abspeichern und
mit "Projekt|Optionen|Anwendung|Symbol laden" das Icon "meinbild.ico"
in Die Ressourcendatei einbinden.
implementation
uses Unit2;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
form2.Show;
i:= 0;
repeat //wiederhole, bis Klick auf ButtonStop
inc(i);
//tu was vernünftiges !
if i mod 10000 = 0 then Begin
button1.caption := inttoStr(i);
//um zu sehen, dass sich was tut
application.ProcessMessages;
End;
if form2.stop then exit;
//Sobald auf den ButtonStop geklickt wird
until false; //Schleife wird nur durch exit verlassen!
end;
end.
Hier ist die ganze passende unit2 wiedergegeben:
unit Unit2; //Was nicht Delphi schreibt ist mit "//!" markiert.
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Buttonstop: TButton;
procedure FormActivate(Sender: TObject);
//Im Objektinspector Ereignisse doppelklicken!
procedure ButtonstopClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
stop: boolean; //! Das mußt Du einfügen !
end;
var
Form2: TForm2;
implementation
uses unit1; //!um form1.enabled zu ändern
{$R *.DFM}
procedure TForm2.FormActivate(Sender: TObject);
begin
stop := false; //!
form1.Enabled := false; !!!
end;
procedure TForm2.ButtonstopClick(Sender: TObject);
begin
close; //!
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
form1.enabled := true; //!
stop := true; //!
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
FormStyle := fsstayontop; //Im Objektinspektor möglich
Form2.BorderStyle := bsnone; //"
button1.Top := 20; //"
button1.Left := 20; //"
button1.Caption := 'Bitte hier klicken'; //"
width := button1.Width + 40; //"
height := button1.Height + 40; //"
end;
end.
procedure TForm1.FormCreate(Sender: TObject);
var hTaskBar: THandle;
begin
//Taskleiste weg!
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_HIDE);
//Form1-Eigenschaften
Formstyle := fsStayOnTop;
Bordericons := []; // (Alles false)
Borderstyle := bsnone;
WindowState := wsnormal;
//wegen Taskleiste nicht wsmaximized
align := alnone;
form1.Top :=0;
form1.left :=0;
form1.Width := screen.Width;
form1.height:= screen.height + 50; //einschließlich
//Taskleiste
Color := clBlack;
Ctl3D := false; //sonst weißer Streifen
cursor := -1; //Kein Cursor!
KeyPreview := True;
//Damit das Fenster auf Tastendruck schliessen kann
End;
Vergiss nicht, den alten Zustand beim Schliessen wieder herzustellen:
procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
var hTaskBar: THandle; //uses Window;
begin
hTaskbar := FindWindow('Shell_TrayWnd', Nil);
ShowWindow(hTaskBar, SW_SHOWNORMAL);
end;
Bei Tastendruck oder Mausbewegung soll dein Bildschirmschoner verschwinden:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
close;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
inc(zaehl);
(*Zahl mußt du als private-Variable deklarieren:
Ergänze in Deimem Programm, dort wo privat steht:
private
zaehl: integer;
{ Private-Deklarationen } *)
if zaehl > 5 then close;
end;
Wichtig: Der Bildschirmschoner soll nur einmal aufgerufen werden. Deshalb Klicke in
Delohi "Ansicht|Units" an und wähle "Project1". In dieses mußt Du die Prozedur "Zweimalverhindern" (Siehe unten)
einfügen und vor "Application.Initialize" aufrufen. Der Quelltext könnte dann folgendermaßen aussehen:
program Project1;
uses
dialogs,
windows,
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
procedure ZweimalVerhindern;
var h: HWND; //uses windows
begin
h:=FindWindow('TApplication','Bildschirmschoner (c) Joschka F.');
if h 〈〉0 then Begin SetForegroundWindow(h); halt End;
end;
begin
ZweimalVerhindern;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Title := 'Bildschirmschoner (c) Joschka F.';
Application.Run;
end.
Download: bildschirmschonerpas.zip
Das Grundgerüst des Bidschirmschoners. initialization OleInitialize(nil); finalization OleUninitialize; //vor end.Aus der Onlinehilfe:
unit InstanceManager; //nach Evan Simpson
{ Diese unit Einbinden:
in .dpr und unit1.pas als erstes: "uses InstanceManager"
und in Form1 folgendes Einfügen
" private
procedure Nachrichauswerten;
procedure TForm1.Nachrichauswerten;
begin
Application.Restore;
Application.BringToFront;
//edit1.Text := WoherKommtDieNachricht; zum Beispiel
//edit2.text := DieNachrichtselbst;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InstanceManager.triggerProc:=Nachrichauswerten;
end;"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
interface
const MutexIdentifizierung = 'Mein eigenes Programm';
AppNotifyValue: integer = 0;
var WoherKommtDieNachricht,DieNachrichtselbst: string;
rcvValue: integer;
ForbidOtherInstance: boolean = True;
triggerProc: procedure of object;
implementation
uses Windows, SysUtils, Messages, Dialogs, Controls;
var mutex, thisWnd: HWND;
IMWndClass: TWndClassA;
mustHalt: boolean;
copydata: TCOPYDATASTRUCT;
function copyab(const s:string; const i:integer):string;
//Rest von s ab i. em Zeichen
begin result:=copy(s,i,length(s)-i+1) end;
function frage(const s: string): boolean;
begin
result := MessageDlg(s, mtConfirmation, [mbYes, mbNo],0) = mrYes;
end;
procedure teiledenStringInzweiTeile(var a,b: string);
var k: integer;
begin
k := 1;
while (k〈〉length(a)) and (a[k] 〈〉 ' ') do inc(k);
b := copyab(a,k+1);
a := copy(a,1,k-1);
end;
function IMWndProc(HWindow: HWnd; Message,
WParam: Longint; LParam: Longint): Longint; stdcall;
begin
if Message=WM_COPYDATA then
begin
WoherKommtDieNachricht
:= StrPas(PCOPYDATASTRUCT(lParam).lpData);
teiledenStringInzweiTeile(WoherKommtDieNachricht,
DieNachrichtSelbst);
rcvValue := PCOPYDATASTRUCT(lParam).dwData;
if Assigned(triggerProc) then triggerProc;
Result := Ord(ForbidOtherInstance);
end
else
Result := DefWindowProc(hWindow, Message, WParam, LParam);
end;
initialization
FillChar(IMWndClass, SizeOf(IMWndClass), 0);
IMWndClass.lpfnWndProc := @IMWndProc;
IMWndClass.hInstance := HINSTANCE;
IMwndClass.lpszClassName := 'TInstanceManager';
if Windows.RegisterClass(IMWndClass) = 0 then RaiseLastWin32Error;
mutex := CreateMutex(nil, True, MutexIdentifizierung);
if GetLastError = ERROR_ALREADY_EXISTS then
begin
if paramcount = 0 then
if frage('Programm läuft schon. Wiklich eine '
+' zweite Instanz des Programms aufrufen?')
then exit;
mustHalt := True;
if WaitForSingleObject(mutex, 5000)=WAIT_OBJECT_0 then
begin
thisWnd := FindWindow(IMwndClass.lpszClassName,
MutexIdentifizierung);
if thisWnd = 0 then RaiseLastWin32Error;
CopyData.dwData := AppNotifyValue;
CopyData.lpData := CmdLine;
CopyData.cbData := StrLen(CmdLine);
mustHalt := (SendMessage(thisWnd,WM_COPYDATA,0,
Integer(@CopyData))>0);
end;
thisWnd := 0;
ReleaseMutex(mutex);
if mustHalt then Halt;
end
else
begin
thisWnd := CreateWindow(IMwndClass.lpszClassName,
MutexIdentifizierung,0,0,0,0,0,0,0,hInstance, nil);
if thisWnd = 0 then RaiseLastWin32Error;
ReleaseMutex(mutex);
end;
finalization
if thisWnd > 0 then DestroyWindow(thisWnd);
end.
Dein Hauptprgramm könnte dann folgendarmaßen aussehen:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure Nachrichauswerten; //Das schreibst Du!
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
uses InstanceManager;
procedure TForm1.Nachrichauswerten; //Das schreibst Du ebenfalls.
begin
Application.Restore;
Application.BringToFront;
memo1.lines.add('Woher:' + WoherKommtDieNachricht
+ ' | Nachricht = ' + DieNachrichtselbst);
end;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
InstanceManager.triggerProc:=Nachrichauswerten; //Wichtig!
end;
end.
x' = x·cos(phi) - y·sin(phi)
y' = x·sin(phi) + y·cos(phi)
Eine Drehung um das Zentrum Z(a|b) kann man als Hintereinanderausführung
von Verschiebung, Drehung und Verschiebung auffassen.
Die Abbildungsgleichungen sind dann:
x' = (x - a)·cos(phi) - (y - b)·sin(phi) + a
y' = (x - a)·sin(phi) + (y- b)·cos(phi) + b
Mit folgender Prozedur ist dies in Delphi realisiert. procedure DrehungUm(a, b, x, y, phi: real; var xs, ys:real); //Zentrum Z(a|b) Punkt P(x|y) wird gedreht um Winkel phi zu Ps(xs|ys) begin phi := phi/180*Pi; //Gradmass in Bogenmass xs := cos(phi)*(x - a) + sin(phi)*(y - b) + a; ys := -sin(phi)*(x - a) + cos(phi)*(y - b) + b; end;Bei folgendem Programm fungiert das Shape Sz als Zentrum. Um Sz rotiert das Shape Sp als Punkt um Sz. Du brauchst dazu noch einen Timer aus der Komponentenpalette System.
{Nach einer Idee von Timo Holzherr}
var
Form1: TForm1;
d : real;
szposx, szposy, spposx, spposy,
a, b, x0, y0, phi: integer;
spmoving, szmoving: boolean;
implementation
{$R *.DFM}
procedure DrehungUm(a, b, x, y, phi: real; var xs, ys:real);
//Zentrum Z(a|b) Punkt P(x|y) wird gedreht um Winkel phi zu Ps(xs|ys)
begin
phi := phi/180*Pi; //Gradmass in Bogenmass
xs := cos(phi)*(x - a) + sin(phi)*(y - b) + a;
ys := -sin(phi)*(x - a) + cos(phi)*(y - b) + b;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin //Anfangswerte setzten
timer1.Interval := 1;
phi := 0;
a := sz.Left;
b := sz.Top;
x0 := sp.left;
y0 := sp.top;
d := sqrt((sz.left - sp.left)*(sz.left - sp.left)
+(sz.top - sp.top)*(sz.top - sp.top));
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var x,y: real;
begin
inc(phi);
if phi 〉= 360 then phi := phi - 360;
DrehungUm(a, b, x0, y0, phi, x, y);
sp.Left := round(x);
sp.top := round(y);
end;
(*Durch folgende Prozeduren kannst du das Shape Sz ("Shape Zentrum")
ziehen.*)
procedure TForm1.SzMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then Begin
SzMoving := True;
SzPosX := X;
SzPosY := Y;
End;
end;
procedure TForm1.SzMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if SzMoving then
begin
sz.Left := sz.Left + X - szPosX;
sz.Top := sz.Top + Y - szPosY;
end;
end;
procedure TForm1.SzMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then Begin
Szmoving := False;
Button1Click(nil);
End;
end;
|
Das Panel ist das blaue Feld. Mit Klick auf das Blaue Feld soll die Form "gezogen" werden können. |
...
private
{ Private-Deklarationen }
PanelMoving: boolean;
PanelPosX, panelPosY: integer;
public
...
. . . und rufe im Objektinspektor bei panel1 folgende Ereignisse auf ....
procedure TForm1.Panel1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then Begin
PanelMoving := True;
PanelPosX := X;
PanelPosY := Y;
End;
end;
procedure TForm1.Panel1MouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then Begin
Panelmoving := False;
End;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
begin
if PanelMoving then
Begin
Form1.Left := Form1.Left + X - PanelPosX;
Form1.Top := form1.Top + Y - PanelPosY;
End;
end;
Beachte dabei, dass Delphi bei Klick im Objektinspektor auf das Ereignis den Rahmen für die
Prozeduren selbst schreibt.
|x| |y|
Spiegelung an der Winkelhalbierenden: | | -> | |
|y| |x|
Spiegelung an der horizontalen Mittelsenkrechten:
|x| |breite - x|
| | -> | |,
|y| | y |
wobei breite (width) die Breite meines Bildes ist.
|x| | y |
Die Hintereinanderazsführung ist dann also: | | -> | |
|y| |breite - x|
Das Programm ist dann schnell erstellt. Es besticht durch seine Einfachheit.
Dafür dauern die Berechnungen für ein bildschirmfüllendes Bild etwa drei Sekunten.
procedure TForm1.Button1Click(Sender: TObject);
var
a, b : TBitmap;
x,y, breite: integer;
begin
a :=Tbitmap.Create;
b := TBitmap.Create;
try
image1.Picture.Bitmap.LoadFromFile(
'c:\fotos\FranzistkaHochformat.bmp');
//ersetze passend!
application.ProcessMessages;
a.Assign(Image1.Picture.Bitmap);
b.Width := Image1.Picture.height;
b.Height := Image1.Picture.Width;
breite := b.Width - 1;
for x := 0 to b.Width -1 do for y := 0 to b.Height - 1 do
b.Canvas.pixels[x,y] := a.Canvas.Pixels[y,breite - x];
Image1.Picture.Assign(b);
finally a.free; b.Free end;
end;
Global:
var lissj_t, lissj_a, lissj_c: integer;
Anfangswerte setzten:
lissj_a := 3;
//zum Beispiel
//(Werte werden bei jedem neuen Aufruf erhöht)
lissj_c := 2; //zum Beispiel
timer1.Enabled := true;
timer1.Interval := 100;
Im Timeraufruf zeichnen lassen:
procedure zeichneKreisAufPanel(x,y:integer);
begin
with form1.Canvas do Begin
Pen.Color := clyellow;
Pen.Width := 2;
Brush.Style := bssolid;
Brush.Color := clred;
Ellipse(x-4,y-4,x+4,y+4)
End
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var h,b: integer;
begin
inc(lissj_t);
h := form1.height div 4;
b := form1.Width div 4;
zeichneKreisAufPanel(2*b
+ round(b*sin(lissj_a/50*lissj_t + lissj_b)),
2*h + round(h*sin(lissj_c/50*lissj_t + lissj_d)));
end;
Beispiel: Ein Memo abspeichern und einlesen. Download: editor function IniPfad:string; var exepfad, exefile: string; begin exepfad := extractFilepath(paramstr(0)); exefile := extractFilename(paramstr(0)); result:=exepfad //der exe-pfad des Programms + copy(exefile,1,length(exefile) - 3) //der Name ohne "exe" + 'ini'; //die Ini-Datei end; 1. Variante: Unter Verwendung der unit TiniFile function HoleDateiPfad:string; //Dass man noch weiss, wo Datei gespeichert wurde. var MyIniFile:TIniFile; //benötigt uses IniFiles. //Ini-Dateien sind besser als in Registry schreiben! begin MyIniFile:=Tinifile.create(Inipfad); try result:=MyIniFile.ReadString('Section1','Schluessel1', 'File1'); //File1 ist Vorgabe finally MyIniFile.Free End; end; procedure SchreibeDateiPfad(pfad:string); //Dass man noch weiss, wo Datei gespeichert wurde var MyIniFile:TIniFile; //benötigt uses IniFiles. So besser als in der Registry begin MyIniFile:=Tinifile.create(Inipfad); try MyIniFile.WriteString('Section1','Schluessel1', pfad); finally MyIniFile.Free End; end; 2. Variante: Wenn man sonst keine weiteren Ini-Daten hat. function HoleDateiPfad:string; var sl: Tstringlist; begin sl := Tstringlist.Create; try try sl.LoadFromFile(IniPfad); if sl.Count > 0 then result := sl[0]; Except {Das erste Mal gibt es keine Datei} End; finally sl.Free End; end; procedure SchreibeDateiPfad(pfad:string); var sl: Tstringlist; begin sl := Tstringlist.Create; try sl.Text := pfad; try sl.SaveToFile(IniPfad); Except {z.B. keine Schreibrechte} End; finally sl.Free End; end; Weiter Für beide Varianten. procedure TForm1.Button1Click(Sender: TObject); begin with opendialog1 do Begin Initialdir:=extractFilepath(holedateipfad); filename:=extractFilename(holedateipfad); options:=[ofFileMustExist,ofAllowMultiselect, ofHideReadOnly,ofShareAware, ofEnableSizing, ofNoTestFileCreate,ofNoValidate]; Filter :='Pascal-Dateien (*.PAS)|*.PAS|Textdateien (*.txt)|*.TXT|' +'Alle Dateien (*.*)|*.*'; DefaultExt:=''; if Execute then Begin memo1.Lines.LoadFromFile(Opendialog1.Filename); SchreibeDateiPfad(Opendialog1.Filename); End else showmessage('Abbruch!'); End; end; procedure TForm1.Button2Click(Sender: TObject); begin with SaveDialog1 do Begin Options:=[ofCreatePrompt,ofEnableSizing, ofHideReadOnly,ofShareAware,ofEnableSizing]; Initialdir:=extractFilepath(HoleDateipfad); filename:=extractFilename(holedateipfad); Filter :='Pascal-Dateien (*.PAS)|*.PAS|Textdateien (*.txt)|*.TXT|' +'Alle Dateien (*.*)|*.*'; DefaultExt:=''; if execute then Begin memo1.Lines.SaveToFile(Savedialog1.Filename); schreibeDateiPfad(Savedialog1.Filename); End else showmessage('Nicht gespeichert'); End; end;
const schluesselpfad = 'Pfad';
schluesselOben = 'Oben';
schluesselLinks = 'Links';
schluesselUnten = 'Unten';
schluesselRechts = 'Rechts';
- - - - - Beispiel für den Inhalt der Ini-Datei hier - - -
|°Pfad°|
c:\Programme\meinProject\abc12
|°Oben°|
141
|°Links°|
424
|°Unten°|
652
|°Rechts°|
461
- - - - -
Diese Unit_init einfach kopieren und in Dein Programm einbinden!1
- - - - - - -
unit Unit_init;
//möglich wäre auch die Stringlist sl im initialization-Abschnitt
//zu erzeugen und beim Finalization-Abschnitt wieder freizugeben
interface
function LiesIni(const schluessel: string):string;
function LiesIniInteger(const schluessel: string): integer;
procedure SchreibeIni(const schluessel, inhalt:string);
implementation
uses Sysutils, classes;
function IniPfad:string;
var exepfad, exefile: string;
begin exepfad := extractFilepath(paramstr(0));
exefile := extractFilename(paramstr(0));
result:=exepfad //der exe-pfad des Programms
+ copy(exefile,1,length(exefile) - 3)
//der Name ohne "exe"
+ 'ini'; //die Ini-Datei
end;
function SchluesselNummer(const schluessel: string;
sl: Tstringlist): integer;
var k: integer; //Ermittelt Zeilennummer des Schlüssels
begin
for k := 0 to sl.Count - 1 do if '|°' + schluessel + '°|' = sl[k]
then Begin
result := k;
exit;
End;
result := -1; //Nicht gefunden
end;
function LiesIni(const schluessel: string):string;
var sl: Tstringlist;
nr: integer;
begin
result := ''; //falls nicht vorhanden
sl := Tstringlist.Create;
try
try sl.LoadFromFile(IniPfad) Except {Das erste Mal} exit End;
nr := SchluesselNummer(schluessel,sl); //z.B. nr := 3 =>
result := sl[4] (sl.count >=5)
if nr 〈0 then exit;
if sl.Count > nr + 1 then result := sl[nr + 1];
finally sl.Free End;
end;
function LiesIniInteger(const schluessel: string): integer;
begin
try result := strToInt(LiesIni(schluessel));
except result := -1 End;
end;
procedure SchreibeIni(const schluessel, inhalt:string);
var sl: Tstringlist;
nr: integer;
begin
sl := Tstringlist.Create;
try
try sl.LoadFromFile(IniPfad) Except {Das erste Mal} End;
nr := SchluesselNummer(schluessel,sl);
//falls Schlüssel vorhanden, nr >= 0
if nr 〈0 then nr := sl.count; //Schlüssel noch nicht vorhanden
while sl.Count 〈= nr + 1 do sl.Add(''); //=> sl.count > nr + 1
//z.B. nr=4 sl[4] ='|°links°|' sl[5] ='125'; notwendig sl.count > 5
sl[nr] := '|°' + schluessel + '°|';
sl[nr+1] := inhalt;
try sl.SaveToFile(IniPfad) Except {keine Schreibrechte} End;
finally sl.Free End;
end;
end.
- - - - - Ende Unit_init - - - - -
var
Form1: TForm1;
IniInhalt: TStringlist;
implementation
{$R *.DFM}
function IniPfad:string;
var exepfad, exefile: string;
begin
exepfad := extractFilepath(paramstr(0));
exefile := extractFilename(paramstr(0));
result:=exepfad
//der exe-pfad des Programms
+ copy(exefile,1,length(exefile) - 3)
//der Name ohne "exe"
+ 'ini';
//die Ini-Datei
end;
function copyab(const s: string; const i: integer): string;
begin result := copy(s, i, length(s) - i + 1) end;
function AnfangDerZeile(section,schluessel: string) :string;
begin
result := section + '|' + schluessel + ' = ';
end;
procedure schreibeIni(section,schluessel,was:string);
var k:integer;
begin
for k := 0 to IniInhalt.Count - 1 do
if pos(AnfangDerZeile(section,schluessel), IniInhalt[k]) = 1
then Begin //Eintrag löschen bzw. überschreiben
if was = '' then iniInhalt.Delete(k) else
iniInhalt[k] := AnfangDerZeile(section,schluessel) + was;
exit;
End;
//Neueintrag
if was > '' then
iniInhalt.Add(AnfangDerZeile(section,schluessel) + was);
end;
function intToStr4(k:integer): string; //von 0000 bis 9999 alphabetisch
begin
result := inttostr(k);
while length(result)〈4 do result := '0' + result;
end;
procedure loescheStringlistInIni(s:string);
var k:integer;
begin
k := 0;
while〈IniInhalt.Count do Begin
if pos(s,IniInhalt[k]) = 1 then iniInhalt.Delete(k) else inc(k);
End;
end;
procedure schreibeIniStringlist(section,
schluessel,stringlisttext:string);
var sl: Tstringlist;
k: integer;
begin
loescheStringlistInIni(section + '|' + schluessel + '|');
sl := Tstringlist.Create;
sl.Text := stringlisttext;
try
for k := 0 to sl.Count - 1 do
schreibeIni(section,schluessel + '|' + inttostr4(k) + '|', sl[k]);
finally sl.free End;
end;
function LeseIni(section,schluessel: string): string;
var k:integer;
begin
for k := 0 to IniInhalt.Count - 1 do
if pos(AnfangDerZeile(section,schluessel), IniInhalt[k]) = 1
then Begin
result := copyab(IniInhalt[k],
length(AnfangDerZeile(section,schluessel)) + 1);
exit;
End;
result :='';
end;
function LeseINIStringlist(section,schluessel: string): string;
var sl: Tstringlist;
k: integer;
begin
sl := Tstringlist.Create;
try
for k := 0 to IniInhalt.count - 1 do
if pos(section + '|' + schluessel + '|', IniInhalt[k]) = 1
then Begin
sl.add(copyab(IniInhalt[k],length(section
+ '|' + schluessel + '|') + 9));
End;
result := sl.text;
finally sl.free End;
end;
function boolToStr(b: boolean): string; //Boolean -> String
begin
if b then result := 'T' else result := 'F';
end;
procedure SchreibeAlleEditfenster(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.ClassType = TEdit then with a as Tedit do
schreibeIni(wo.name,a.name, text);
End;
end;
procedure SchreibeAllecomboboxfenster(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.classType = Tcheckbox then with a as Tcheckbox do
schreibeIni(wo.name, a.name, boolToStr(checked));
End;
end;
procedure SchreibeAllememofelder(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.ClassType = TMemo then with a as TMemo do
schreibeIniStringlist(wo.name,a.name, text);
End;
end;
procedure LeseAlleEditfenster(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.ClassType = TEdit then with a as Tedit do
text := LeseINI(wo.name,a.name);
End;
end;
procedure LeseAlleComboboxfenster(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.classType = Tcheckbox then with a as Tcheckbox do
checked := LeseINI(wo.name, a.name) = boolToStr(true);
End;
end;
procedure LeseAllememofelder(wo: TComponent);
var k: integer;
a: Tcomponent;
begin
for k := 0 to wo.ComponentCount - 1 do Begin
a := wo.components[k];
if a.ClassType = TMemo then with a as TMemo do
text := LeseINIStringlist(wo.name,a.name);
End;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IniInhalt := Tstringlist.create;
try
iniInhalt.LoadFromFile(IniPfad);
LeseAlleEditfenster(Form1);
LeseAllecomboboxfenster(Form1);
LeseAllememofelder(Form1);
except {Das erste Mal} End;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
SchreibeAlleEditfenster(form1);
SchreibeAllecomboboxfenster(form1);
SchreibeAlleMemofelder(form1);
iniInhalt.SaveToFile(IniPfad);
except {Keine Schreibrechte} End;
IniInhalt.Free;
end;
function ShellexecuteFehler(i: integer): string;
begin
Case i of 0: result :=
'The operating system is out of memory or resources.';
ERROR_FILE_NOT_FOUND: result :=
'The specified file was not found.';
ERROR_PATH_NOT_FOUND: result :=
'The specified path was not found.';
ERROR_BAD_FORMAT: result :=
'The .EXE file is invalid (non-Win32 .EXE
or error in .EXE image).';
SE_ERR_ACCESSDENIED: result :=
'The operating system denied access to the specified file.';
SE_ERR_ASSOCINCOMPLETE: result :=
'The filename association is incomplete or invalid.';
SE_ERR_DDEBUSY: result :=
'The DDE transaction could not be completed because '
+'other DDE transactions were being processed.';
SE_ERR_DDEFAIL: result :=
'The DDE transaction failed.';
SE_ERR_DDETIMEOUT: result :=
'The DDE transaction could not be completed '
+'because the request timed out.';
SE_ERR_DLLNOTFOUND: result :=
'The specified dynamic-link library was not found.';
//SE_ERR_FNF : result:='The specified file was not found.';
SE_ERR_NOASSOC : result:='Unbekannter Extender.';
SE_ERR_OOM: result :=
'There was not enough memory to complete the operation.';
//SE_ERR_PNF : result:='The specified path was not found.';
SE_ERR_SHARE: result := 'A sharing violation occurred.';
End;
end;
procedure programmstarten(pfad, parameter: string);
var name: String;
code: integer;
begin
name := extractFilename(Pfad);
pfad := extractFilepath(pfad); //Jetzt nur Pfad
code := ShellExecute(application.handle,
Pchar('open'),
Pchar(name),
Pchar(Parameter),
Pchar(Pfad),
sw_ShowNormal);
if code〈32 then ShellexecuteFehler(code);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with opendialog1 do Begin
options:=[ofFileMustExist,ofAllowMultiselect,
ofHideReadOnly,ofShareAware,
ofEnableSizing, ofNoTestFileCreate,ofNoValidate];
Filter :='EXE-Dateien (*.exe)|*.exe|Batchdateien (*.bat)|*.bat|'
+'Alle Dateien (*.*)|*.*';
DefaultExt:='exe';
End;
if opendialog1.Execute then Begin
programmstarten(opendialog1.filename,'');
//evtl. Parameter abfragen
End;
end;
procedure schreibeRegistry(a,b:string);
var registrierung:TRegistry; //uses registry nicht vergessen
begin
Registrierung:=Tregistry.Create;
Registrierung.Rootkey:=HKEY_LOCAL_MACHINE;
try
Registrierung.OPENKEY('\SOFTWARE\MyName\MyProgramm\Hallo',true);
except
Registrierung.CreateKey('\SOFTWARE\MyName\MyProgramm\Hallo');
end;
Registrierung.WriteString(a,b);
Registrierung.free;
end;
function leseRegistry(a:string):string;
var registrierung:TRegistry;
begin
Registrierung:=Tregistry.Create;
Registrierung.Rootkey:=HKEY_LOCAL_MACHINE;
try
Registrierung.OPENKEY('\MyName\MyProgramm\Hallo',true);
result:=Registrierung.ReadString(a);
except
result:='';
end;
end;
| Die Anwort gibt folgender Quellcode:
Die Procedur wird zum Beispiel folgendermaßen aufgerufen: ZeichneViolinschluessel(200,100, Form1.Canvas) Benötigst Du Farbe in der Figur? Dann füge für rot 'r' statt '+' ein und "clred" statt "clblack" u.s.w. |
procedure zeichneViolinschluessel(a,b: integer; canv: Tcanvas);
const
schluessel =
//gezeichnet mit Programm
//Bildbearbeitung
' ++'#13#10+
' ++++'#13#10+
' ++++'#13#10+
' +++ +'#13#10+
' ++ +'#13#10+
' ++ +'#13#10+
' ++ +'#13#10+
' ++ +'#13#10+
' + ++'#13#10+
' ++ ++'#13#10+
' ++ +++'#13#10+
' ++ +++'#13#10+
' + +++'#13#10+
' +++++'#13#10+
' ++++'#13#10+
' ++++'#13#10+
' ++++'#13#10+
' +++++'#13#10+
' ++++++'#13#10+
' +++++ +'#13#10+
' +++ +'#13#10+
' ++++ +'#13#10+
' ++ +++'#13#10+
' ++ +++++'#13#10+
'+++ +++++++++'#13#10+
'++ ++++ +++++'#13#10+
'++ +++ + +++'#13#10+
'++ + + ++'#13#10+
'++ + + +'#13#10+
' + + + +'#13#10+
' + + + +'#13#10+
' ++ ++ + +'#13#10+
' ++ + + ++'#13#10+
' ++ + ++'#13#10+
' ++ ++'#13#10+
' +++++'#13#10+
' +'#13#10+
' ++'#13#10+
' +'#13#10+
' + +'#13#10+
' +++++ +'#13#10+
' +++++ +'#13#10+
' +++++ +'#13#10+
' +++++ +'#13#10+
' +++ ++'#13#10+
' +++ +++';
var i,j: integer;
puffer: Tstringlist;
begin
puffer := Tstringlist.Create;
try
puffer.Text := schluessel;
with canv do
for i := 0 to puffer.Count - 1 do
for j := 1 to length(puffer[i]) do
if puffer[i][j] 〈〉 ' ' then Pixels[j+a,i+b] := clblack;
finally puffer.Free End;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
zeichneViolinschluessel(0,0, Canvas);
end;
procedure TForm1.Button1Click(Sender: TObject);
const rtf_ressource =
'{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl'+
'{\f0\fswiss\fprq2\fcharset0 Arial;}'+
'{\f1\froman\fprq2\fcharset0 Times New Roman;}}'#13#10+
'{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;'+
'\red0\green128\blue0;}'#13#10+
'{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}}'#13#10+
'\viewkind4\uc1\pard\qc\cf1\b\f0\fs48 TTTon'#13#10+
'\par \cf2\fs32 Version Januar 2007'#13#10+
'\par \''a9 Joachim Mohr'#13#10+
'\par \b0\fs24'#13#10+
'\par Dieses Programm ist - wie alle meine Programme -'#13#10+
'\par f\''fcr den privaten Gebrauch, '
+'f\''fcr (Hoch-)Schulen und f\''fcr'#13#10+
'\par gemeinn\''fctzige Organisationen frei.'#13#10+
'\par \cf0'#13#10+
'\par \cf3\b\fs20 Wenn Ihnen das Programm '+
'gef\''e4llt, dann schicken Sie eine Email '+
'an\cf0\b0 :'#13#10+
'\par \pard\keepn\s1\qc\cf1\b wegen.spamcrawler.'+
'geaendert@t-online.de'#13#10+
'\par \pard\qc\cf3 Es sollte keine offene '
+'Emailadresse ins Internet '+
'dieselbe Adresse.\cf0\b0'#13#10+
'\par'#13#10+
'\par \cf1\b Viel Spa\''df mit den TT-Programmen'#13#10+
'\par \pard\keepn\s2\qc Joachim Mohr'#13#10+
'\par \pard\qc T\''fcbingen am Neckar'#13#10+
'\par \cf2\f1\fs32 www.joachimmohr.de}';
var ms: TMemoryStream;
sl: Tstringlist;
begin
ms := TMemoryStream.Create;
sl := TStringlist.Create;
try
sl.Text := rtf_ressource;
sl.SaveToStream(ms);
ms.Position := 0;
Richedit1.PlainText := false;
richedit1.Lines.loadfromstream(ms);
finally sl.free; ms.free end;
end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
OleCtrls, SHDocVw, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
WebBrowser1: TWebBrowser;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
const beispiel =
'〈html〉'#13#10+
'〈head〉'#13#10+
' 〈title〉 Die ist die Titelzeile eines Testes 〈/title〉'#13#10+
'〈/head〉'#13#10+
'〈body text="#000000" bgcolor="#FFFFFF"〉'#13#10+
'〈h1〉Die ist ein Test〈/h1〉#13#10+
'〈/body〉'#13#10+
'〈/html〉';
var
Form1: TForm1;
implementation
uses activeX;
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.text := beispiel;
end;
procedure LoadStream(WebBrowser: TWebBrowser; Stream: TStream);
var
PersistStreamInit: IPersistStreamInit; // uses activeX;
StreamAdapter: IStream;
MemoryStream: TMemoryStream;
begin
WebBrowser.Navigate('about:blank');
repeat
Application.ProcessMessages;
Sleep(0);
until WebBrowser.ReadyState = READYSTATE_COMPLETE;
if WebBrowser.Document.QueryInterface(IPersistStreamInit,
PersistStreamInit) = S_OK then
begin
if PersistStreamInit.InitNew = S_OK then
begin
MemoryStream:= TMemoryStream.Create;
try
MemoryStream.CopyFrom(Stream, 0);
MemoryStream.Position:= 0;
except
MemoryStream.Free;
raise;
end;
StreamAdapter:= TStreamAdapter.Create(MemoryStream, soOwned);
PersistStreamInit.Load(StreamAdapter);
end;
end;
end;
procedure UeberStreamzeigen(const s:string);
var Str: TStringStream;
begin
Str:= TStringStream.Create(s);
try
LoadStream(form1.webbrowser1, Str);
finally
Str.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ueberstreamzeigen(memo1.text);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
close
end;
end.
const strtext = 'Binärfile als Textfile gespeichert, '
+ 'alle Bytes > #39 (wegen Hochkomma)'
s01 = 'dieser String merkt sich, bei welchen '
+'Bytes in strtext ein "Hub" notwendig war'
... gespeichert werden können.
{Ein Binärstring wird in zwei Strings übergeführt,
die als Dephistring akzeptabel sind}
Procedure BinaerStrToTextStr(const b:string; var strtext,
str01:string; kurz:boolean);
const Hub = 40; //Oberhalb #39 (Hochkomma)
var k:integer;
function NullEinsStrgZuTextstr(const s01:string): string;
//Jeweils 7 Bytes - zum Beispiel - "0011000" wird
//in ein "lesbares" Byte übergeführt
var k,j: integer;
a: string;
function NullEinsZuChar(const s:string): char;
//zum Beispiel s='0011000';
var j,n: byte;
begin //geht auch kürzer mit "shr" und "and"
//("Maschinennaher Code").
n := 0;
for j := 1 to 7 do
if (j 〈=length(s)) and (s[j] = '1') then
Case j of 7: n := n + 1;
6: n := n + 2;
5: n := n + 4;
4: n := n + 8;
3: n := n + 16;
2: n := n + 32;
1: n := n + 64;
End; //n maximal 127
if n〈Hub then n := n + 128;
//So wird ein "unlesbares" Char "lesbar"
result := char(n)
end;
begin
setlength(a,7);
setlength(result,length(s01) div 7+1);
k := 0;
while k 〈= length(s01) do Begin
for j := 1 to 7 do
if (k + j 〈=length(s01)) and (s01[k+j] = '1')
then a[j] := '1' else a[j] := '0';
inc(k,7);
result[k div 7] := NullEinsZuChar(a);
End;
end;
begin
setlength(strtext,length(b));
// strtext := stringtest + 〈irgend ein Zeichen〉 kostet zu viel Zeit
setlength(str01,length(b));
// Deswegen wird gleich zu Anfang Speicherplatz reserviert
for k := 1 to length(b) do
if ord(b[k]) >= Hub then Begin
strtext[k] := b[k];
str01[k] := '0';
End else Begin
strtext[k] := char(ord(b[k]) + Hub);
//Nicht "lesbares" Char wird "lesbar".
str01[k] := '1';
//Das muss man sich merken "0" oder "1"
End;
if kurz then str01 := NullEinsStrgZuTextstr(str01);
end;
Im Programm könnte man zum Beispiel folgendermaßen eine (natürlich nur kurze) wav-Datei einlesen
und in zwei "lesbare" Strings in eine Datei so schreiben,
dass die Konstanten sofort in die Richedit1-Komponente kopiert werden können.
function pfad: string;
begin
with form1.opendialog1 do
if execute then pfad := filename else pfad := '';
end;
function FileToBinaerStr(const pfad: string): string;
//String als Puffer für die Bytes
var
F: TStream;
begin
F := TFileStream.Create(pfad, fmOpenRead or fmShareDenyWrite);
try
SetLength(result, F.Size);
F.ReadBuffer(PChar(result)^, F.Size);
finally
F.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const HK = ''''; //Hochkomma
var binaerstr,strtext,str01: string;
k: integer;
begin
binaerstr := FileToBinaerStr(pfad);
binaerstrToTextStr(binaerstr,strtext,str01,true);
richedit1.text :='const strtext = ';
k := 1;
while k〈length(strtext) do Begin
richedit1.lines.Add(HK + copy(strtext,k,80) + HK + '+');
k := k +80;
End;
richedit1.Text := copy(richedit1.Text,1,length(richedit1.text) - 1)
+ ';'#13#10+#13#10 + 's01 = ';
k := 1;
while k〈length(str01) do Begin
richedit1.lines.Add(HK + copy(str01,k,80) + HK + '+');
k := k +80;
End;
richedit1.Text := copy(richedit1.Text,1,length(richedit1.text) - 1)
+ ';';
end;
Die Umkehrfunktion wird in das Delphiprogramm, die die Ressource verwenden soll, eingebunden.
function TextStrToBinaerst(const t,s01:string; kurz: boolean): string;
const Hub = 40; //Oberhalb Hochkomma
var k:integer;
s01echtausNullEins: string;
function TextStrZuNullEinsStr(const t:string): string;
var k: integer;
function CharZuNullEins(const c:char): string;
//geht auch "maschinennäher"
var k,n: integer;
begin
setlength(result,7);
n := ord(c);
if n >=128 then n := n - 128;
//Das war ursprünglich ein "unlesbares" Char.
for k := 1 to 7 do
Case k of
7: if n and 1 = 1 then result[k] := '1' else result[k] := '0';
6: if n and 2 = 2 then result[k] := '1' else result[k] := '0';
5: if n and 4 = 4 then result[k] := '1' else result[k] := '0';
4: if n and 8 = 8 then result[k] := '1' else result[k] := '0';
3: if n and 16 = 16 then result[k] := '1' else result[k] := '0';
2: if n and 32 = 32 then result[k] := '1' else result[k] := '0';
1: if n and 64 = 64 then result[k] := '1' else result[k] := '0';
End;
end;
begin
result := '';
for k := 1 to length(t) do result := result + CharZuNullEins(t[k]);
end;
begin
if kurz then s01echtausNullEins := TextStrZuNullEinsstr(s01) else
s01echtausNullEins := s01;
setlength(result,length(t));
for k := 1 to length(t) do
if s01echtausNullEins[k] = '0' then result[k] := t[k] else
result[k] := char(ord(t[k]) - Hub);
end;
Der folgende Sound (hier kürzer)
kann dann folgendermaßen ins Delphiprogramm eingebunden und abgespielt werden.
//Nicht vergessen uses MMSystem
procedure spieleBinaerstring(const b: string);
var ms: TMemoryStream;
begin
ms :=tmemorystream.Create;
try
ms.Seek(0, 0);
ms.Write(Pchar(b)^, length(b));
ms.Seek(0, 0);
sndPlaySound(ms.Memory, SND_MEMORY or SND_SYNC);
//uses MMSystem
Finally ms.Free; End;
end;
procedure TForm1.Button2click(Sender: TObject);
const strtext = //Eine Wav-Datei als "lesbaren" String
//Dazu gehört s01: Zusätzlich pro Byte ein Bit (wegen des "Hubes")
'RIFF ...';
s01 = 'â@?s...';
begin
spieleBinaerstring(TextStrToBinaerst(strtext,s01,true));
end;
procedure TForm1.Button1Click(Sender: TObject);
var ms: TResourceStream;
jpg :TJPEGImage; //benötigt "uses jpeg"
begin
jpg:=TJPEGImage.Create;
ms :=TResourceStream.CreateFromID(Hinstance,105,RT_RCDATA);
try
jpg.LoadFromStream(ms);
image1.Picture.bitmap.Assign(jpg);
form1.Width := image1.picture.Width;
form1.Height := image1.picture.Height+panel1.Height;
//anpassen!
Finally ms.Free; jpg.free End;
end;
procedure TForm1.Button1Click(Sender: TObject);
var ms: TResourceStream;
begin
ms :=TResourceStream.CreateFromID(Hinstance,105,RT_RCDATA);
try
sndPlaySound(ms.Memory, SND_MEMORY or SND_SYNC);//uses MMSystem
Finally ms.Free; End;
end;
105 RCDATA "MYSOUND.WAV" 106 RCDATA "MYNEXTSOUND.WAV"so kannst Du mit
ms :=TResourceStream.CreateFromID(Hinstance,106,RT_RCDATA);über die zweite Datei verfügen.
function FileToString(const FileName: String): String;
var
F: TStream;
k: Integer;
begin
F := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
SetLength(Result, F.Size);
F.ReadBuffer(PChar(Result)^, F.Size);
finally
F.Free;
end;
for k :=1 to length(Result) do if
not (result[k] in [#9, #10, #13, #32..#255]) then result[k] := ' ';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(
'Die Ascii-Zeichen der zu öffnenden Datei werden angezeigt.');
with opendialog1 do Begin
Filter :='Alle Dateien (*.*)|*.*';
DefaultExt:='';
if Execute then Begin
richedit1.text := FileToString(Opendialog1.Filename);
End else showmessage('Abbruch!');
End;
end;
uses
//...
shlobj, //IShellLink
activex, //IPersistFile
Registry, //Registry
comobj; //CreateComObject
procedure AufDesktop(Datei,name:string);
var Shortcut: IUnknown;
SLink: IShellLink;
PFile: IPersistFile;
Wdatei: WideString;
Reg: TRegIniFile;
dir: string;
begin
shortCut := CreateComObject(CLSID_ShellLink);
SLink := ShortCut as IShellLink;
PFile := ShortCut as IPersistFile;
SLink.SetArguments('');
SLink.SetPath(Pchar(Datei));
SLink.SetWorkingDirectory('c:\');
Reg := TReginiFile.Create(
'Software\Microsoft\Windows\CurrentVersion\Explorer');
try
Dir := Reg.ReadString('Shell Folders', 'Desktop', '');
WDatei := Dir + '\'+ name + '.LNK';
PFile.Save(PWChar(Wdatei), False);
finally Reg.free End;
showmessage('Sie sehen nun -wenn alle Fenster minimiert sind- '
+ Datei + ' auf dem Desktop.'#13 +
'Gelöscht wird diese Verknüpfung nach Anklicken '
+'mit der rechten Maustaste.');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
aufdesktop('c:\ttw\ttmathe.exe','ttmathe'); //zum Beispiel
end;