Componentes.Terceros.jvcl/official/3.32/examples/JvRichEdit/MessengerMainFormU.pas

623 lines
16 KiB
ObjectPascal

{******************************************************************
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.sourceforge.net
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 MessengerMainFormU;
{$I jvcl.inc}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ActnList, ImgList, ComCtrls, ToolWin, StdCtrls, JvRichEdit,
ExtCtrls, JvExStdCtrls;
{ Emoticons are copyright Mozilla (www.mozilla.org) }
type
TMessengerMainForm = class(TForm)
Panel1: TPanel;
JvRichEdit1: TJvRichEdit;
Panel2: TPanel;
edtNewText: TEdit;
Button1: TButton;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ImageList1: TImageList;
ActionList1: TActionList;
actCool: TAction;
actCry: TAction;
actEmbarressed: TAction;
actFoot: TAction;
actFrown: TAction;
actInnocent: TAction;
actKiss: TAction;
actLaughing: TAction;
actMoney: TAction;
actSealed: TAction;
actSurprised: TAction;
actTongue: TAction;
actUndecided: TAction;
actWink: TAction;
actYell: TAction;
actSmile: TAction;
ToolButton6: TToolButton;
ToolButton7: TToolButton;
ToolButton8: TToolButton;
ToolButton9: TToolButton;
ToolButton10: TToolButton;
ToolButton11: TToolButton;
ToolButton12: TToolButton;
ToolButton13: TToolButton;
ToolButton14: TToolButton;
ToolButton15: TToolButton;
ToolButton16: TToolButton;
ToolButton17: TToolButton;
ToolButton18: TToolButton;
ToolButton19: TToolButton;
actBold: TAction;
actItalic: TAction;
actUnderline: TAction;
actSend: TAction;
Timer1: TTimer;
procedure actBoldExecute(Sender: TObject);
procedure actItalicExecute(Sender: TObject);
procedure actUnderlineExecute(Sender: TObject);
procedure OnEmoticonClick(Sender: TObject);
procedure actSendExecute(Sender: TObject);
procedure actBoldUpdate(Sender: TObject);
procedure actItalicUpdate(Sender: TObject);
procedure actUnderlineUpdate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
FCurrentFont: TFont;
FHeaderFont: TFont;
FYourLines: Integer;
FReadOnlySend: Boolean;
FReadOnlyHandled: Boolean;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure HandleReadOnly;
procedure HandleReadOnlyOff;
procedure HandleReadOnlyOn;
procedure AddImageToEdit(const AImageIndex: Integer);
procedure AddImageToRichEdit(const AImageIndex: Integer);
procedure AddTextToRichEdit(P: PChar; const ALength: Integer; AFont: TFont);
procedure ParseString(const S: string);
procedure SendString(const S: string; const You: Boolean);
end;
var
MessengerMainForm: TMessengerMainForm;
implementation
uses
RichEdit
{$IFDEF COMPILER6_UP}
, DateUtils
{$ENDIF};
{$R *.dfm}
const
CImageToString: array[0..15] of string = (
{0}':-@', { Yell }
'8-)', { Cool }
':,(', { Cry }
'(blush)', { Embarressed }
':-&', { Foot }
{5}':-(', { Frown }
'O :-)', { Innocent }
':*', { Kiss }
'LOL', { Laughing }
':-$', { Money }
{10}':-x', { Sealed }
':-)', { Smile }
':-o', { Surprised }
':-p', { Tongue }
':-\', { Undecided }
';-)' { Wink }
);
var
ReadOnlyMessages: array[0..2] of string = (
'You can''t resize and/or drag-drop the images because the rich ' +
'edit control is read-only 8-) Type "readonly" to set the ReadOnly property ' +
'of the rich edit to false',
'Try to drag-drop the images, and then to resize the images',
'(blush) I meant "read-only on" or "read-only off"'
);
procedure TMessengerMainForm.actBoldExecute(Sender: TObject);
begin
if fsBold in FCurrentFont.Style then
FCurrentFont.Style := FCurrentFont.Style - [fsBold]
else
FCurrentFont.Style := FCurrentFont.Style + [fsBold];
end;
procedure TMessengerMainForm.actBoldUpdate(Sender: TObject);
begin
if Sender is TAction then
TAction(Sender).Checked := fsBold in FCurrentFont.Style;
end;
procedure TMessengerMainForm.actItalicExecute(Sender: TObject);
begin
if fsItalic in FCurrentFont.Style then
FCurrentFont.Style := FCurrentFont.Style - [fsItalic]
else
FCurrentFont.Style := FCurrentFont.Style + [fsItalic];
end;
procedure TMessengerMainForm.actItalicUpdate(Sender: TObject);
begin
if Sender is TAction then
TAction(Sender).Checked := fsItalic in FCurrentFont.Style;
end;
procedure TMessengerMainForm.actSendExecute(Sender: TObject);
begin
SendString(edtNewText.Text, True);
end;
procedure TMessengerMainForm.actUnderlineExecute(Sender: TObject);
begin
if fsUnderline in FCurrentFont.Style then
FCurrentFont.Style := FCurrentFont.Style - [fsUnderline]
else
FCurrentFont.Style := FCurrentFont.Style + [fsUnderline];
end;
procedure TMessengerMainForm.actUnderlineUpdate(Sender: TObject);
begin
if Sender is TAction then
TAction(Sender).Checked := fsUnderline in FCurrentFont.Style;
end;
procedure TMessengerMainForm.AddImageToEdit(const AImageIndex: Integer);
var
S: string;
LSelLength, LSelStart: Integer;
begin
if (AImageIndex < 0) and (AImageIndex >= 16) then
Exit;
S := edtNewText.Text;
LSelLength := edtNewText.SelLength;
LSelStart := edtNewText.SelStart;
if LSelLength > 0 then
begin
Delete(S, LSelStart + 1, LSelLength);
Insert(CImageToString[AImageIndex], S, LSelStart + 1);
edtNewText.Text := S;
edtNewText.SelStart := LSelStart;
edtNewText.SelLength := Length(CImageToString[AImageIndex]);
end
else
begin
Insert(CImageToString[AImageIndex], S, LSelStart + 1);
edtNewText.Text := S;
edtNewText.SelStart := LSelStart + Length(CImageToString[AImageIndex]);
edtNewText.SelLength := 0;
end;
end;
procedure TMessengerMainForm.AddImageToRichEdit(const AImageIndex: Integer);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
ImageList1.GetBitmap(AImageIndex, Bitmap);
JvRichEdit1.InsertGraphic(Bitmap, False);
{ Move cursor }
with JvRichEdit1.GetSelection do
JvRichEdit1.SetSelection(cpMin + 1, cpMin + 1, False);
finally
Bitmap.Free;
end;
end;
procedure TMessengerMainForm.AddTextToRichEdit(P: PChar; const ALength: Integer; AFont: TFont);
var
S: string;
begin
if ALength < 0 then
Exit;
SetString(S, P, ALength);
JvRichEdit1.InsertFormatText(-1, S, AFont);
{ Move cursor }
with JvRichEdit1.GetSelection do
JvRichEdit1.SetSelection(cpMin + ALength, cpMin + ALength, False);
end;
constructor TMessengerMainForm.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCurrentFont := TFont.Create;
FHeaderFont := TFont.Create;
FHeaderFont.Color := clRed;
FHeaderFont.Style := [fsBold];
FHeaderFont.Name := 'Verdana';
end;
destructor TMessengerMainForm.Destroy;
begin
FCurrentFont.Free;
FHeaderFont.Free;
inherited Destroy;
end;
procedure TMessengerMainForm.FormShow(Sender: TObject);
begin
SendString('Hello, how are you doing :)', False);
FocusControl(edtNewText);
Randomize;
end;
procedure TMessengerMainForm.HandleReadOnly;
begin
FReadOnlySend := True;
ReadOnlyMessages[0] := 'read-only off :-p';
end;
procedure TMessengerMainForm.HandleReadOnlyOff;
begin
FReadOnlyHandled := True;
ReadOnlyMessages[0] := 'read-only off :-p';
if JvRichEdit1.ReadOnly then
begin
{ cheap effect :-p }
JvRichEdit1.Color := clYellow;
Application.ProcessMessages;
Sleep(50);
JvRichEdit1.ReadOnly := False;
JvRichEdit1.Color := clWindow;
end;
end;
procedure TMessengerMainForm.HandleReadOnlyOn;
begin
FReadOnlyHandled := True;
if not JvRichEdit1.ReadOnly then
begin
{ cheap effect :-p }
JvRichEdit1.Color := clRed;
Application.ProcessMessages;
Sleep(50);
JvRichEdit1.ReadOnly := True;
JvRichEdit1.Color := clWindow;
end;
end;
procedure TMessengerMainForm.OnEmoticonClick(Sender: TObject);
begin
if Sender is TAction then
AddImageToEdit(TAction(Sender).ImageIndex);
end;
procedure TMessengerMainForm.ParseString(const S: string);
var
P, Q: PChar;
State: Integer;
procedure AddImage(const SmileIndex, SmileLength: Integer);
begin
AddTextToRichEdit(Q, P - Q - SmileLength + 1, FCurrentFont);
AddImageToRichEdit(SmileIndex);
State := 0;
Q := P + 1;
end;
begin
P := PChar(S);
Q := P;
State := 0;
// State = 1.. then looking at ":-A" with A = @x)( etc.
// 10.. "LOL"
// 20.. "O :-)"
// 30.. "(blush)"
// 40.. ":'-("
// 50.. "8-)"
// 60.. ";-)"
// 70.. "readonly"
// 80.. "read-only on" or "read-only off"
//
// State = 1 -> ":" read
// State = 2 -> ":-" read
// State = 11 -> "LO" read
// State = 22 -> "O :" read
// State = 23 -> "O :-" read
//
// etc.
while P^ <> #0 do
begin
case P^ of
'$':
if State in [2, 23] then
AddImage(9, 3) // :-$
else
State := 0;
'&':
if State in [2, 23] then
AddImage(4, 3) // :-&
else
State := 0;
'(':
case State of
1, 22: AddImage(5, 2); // :(
2, 23: AddImage(5, 3); // :-(
40: AddImage(2, 3); // :,(
41: AddImage(2, 4); // :'-(
else
State := 30;
end;
')':
case State of
1, 22: AddImage(11, 2); // :)
2: AddImage(11, 3); // :-)
23: AddImage(6, 5); // O :-)
35: AddImage(3, 7); // (blush)
51: AddImage(1, 3); // 8-)
61: AddImage(15, 3); // ;-)
else
State := 0;
end;
'*':
if State = 1 then
AddImage(7, 2) // :*
else
State := 0;
',':
if State in [1, 22] then
State := 40
else
State := 0;
'-':
case State of
1, 22, 40, 50, 60: Inc(State);
73: State := 80;
else
State := 0;
end;
'8': State := 50;
'"': State := -1; // to prevent "read.." etc will be triggered by the program
':':
if State = 21 then
State := 22
else
State := 1;
';': State := 60;
'@':
case State of
1, 22: AddImage(0, 2); // :@
2, 23: AddImage(0, 3) // :-@
else
State := 0;
end;
'D':
case State of
1, 22: AddImage(8, 2); // :D = LOL
2, 23: AddImage(8, 3) // :-D = LOL
else
State := 0;
end;
'L':
if State = 11 then
AddImage(8, 3) // LOL
else
State := 10;
'O':
if State = 10 then
State := 11
else
State := 20;
'\', '/':
if State in [2, 23] then
AddImage(14, 3) // :-\
else
State := 0;
'a':
if State = 71 then
State := 72
else
State := 0;
'b':
if State = 30 then
State := 31
else
State := 0;
'd':
if State = 72 then
State := 73
else
State := 0;
'e':
if State = 70 then
State := 71
else
State := 0;
'f':
case State of
86: State := 87;
87: HandleReadOnlyOff;
else
State := 0;
end;
'h':
if State = 34 then
State := 35
else
State := 0;
'l':
if State in [31, 75, 82] then
Inc(State)
else
State := 0;
'n':
case State of
74, 81: Inc(State);
86: HandleReadOnlyOn;
else
State := 0;
end;
'o':
case State of
2, 23: AddImage(12, 3); // :-o
73, 80, 85: Inc(State);
else
State := 0;
end;
'p':
if State in [2, 23] then
AddImage(13, 3) // :-p
else
State := 0;
'r':
if State <> -1 then
State := 70
else
State := 0;
's':
if State = 33 then
State := 34
else
State := 0;
'u':
if State = 32 then
State := 33
else
State := 0;
'x', 'X':
if State in [2, 23] then
AddImage(10, 3) // :-x
else
State := 0;
'y':
case State of
76: HandleReadOnly;
83: State := 84;
else
State := 0;
end;
' ':
case State of
20, 84: Inc(State);
11: State := 21;
else
State := 0;
end;
end;
Inc(P);
end;
if Q < P then
AddTextToRichEdit(Q, P - Q, FCurrentFont);
end;
procedure TMessengerMainForm.SendString(const S: string; const You: Boolean);
var
OldActive: TWinControl;
begin
OldActive := ActiveControl;
try
{ Ensure rich edit control is focused before moving }
FocusControl(JvRichEdit1);
{ Goto end }
JvRichEdit1.SetSelection(MaxInt, MaxInt, False);
if You then
begin
FHeaderFont.Color := clRed;
AddTextToRichEdit('You: ', 5, FHeaderFont);
Inc(FYourLines);
end
else
begin
FHeaderFont.Color := clGreen;
AddTextToRichEdit('JVCL: ', 5, FHeaderFont);
FYourLines := 0;
end;
ParseString(S + #13#10);
{ Goto end & scroll }
JvRichEdit1.SetSelection(MaxInt, MaxInt, True);
finally
FocusControl(OldActive);
end;
end;
procedure TMessengerMainForm.Timer1Timer(Sender: TObject);
const
CLameResponse: array[0..4] of string = (
'What?',
'Huh??',
':)',
'Really :-o',
'Good 8-)');
begin
if Random(10 * (1 + FYourLines)) < 9 then
Exit;
if FReadOnlySend and not FReadOnlyHandled then
begin
SendString(ReadOnlyMessages[2], False);
FReadOnlyHandled := True;
end
else
if FYourLines = 0 then
SendString('Hello :-@', False)
else
if Random(10) < 4 then
begin
if JvRichEdit1.ReadOnly then
SendString(ReadOnlyMessages[0], False)
else
begin
SendString(ReadOnlyMessages[1], False);
ReadOnlyMessages[1] := 'read-only on :-p';
end;
end
else
SendString(CLameResponse[Random(5)], False);
end;
end.