You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/RnQ/SciterLib.pas

2138 lines
68 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit SciterLib;
{$I RnQConfig.inc}
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, System.UITypes, System.StrUtils, System.Variants, System.TypInfo,
Generics.Collections, Vcl.Graphics, Vcl.Forms, Vcl.Imaging.PNGImage, Vcl.Imaging.GIFImg, Vcl.Menus,
Sciter, SciterApi, RDGlobal, ICQCommon, ICQContacts, Nodes, CLBox, ChatBox, RQLog, RnQTips, PrefSheet, UtilLib;
{$I PubRTTI.inc}
type
TSCOptions = set of (sco_multi, sco_groups, sco_predefined);
TSprite = record
name: String;
x, y, width, height: Integer;
end;
TMessageStatus = record
when, msgid: String;
eventimg: Variant;
end;
TMessageHeader = record
when, caption, text, img: String;
end;
TContactStatus = record
code: Byte;
name, desc: String;
official, bot, deleted: Boolean;
statusimg, eventimg: Variant;
end;
TContactXStatus = record
status, text: String;
end;
TCommonSettings = record
supportAvatars, avatarShowInHint, avatarUsePalette, animateWindows, animatedScroll, quitConfirmation, alertTopMost: Boolean;
end;
TNodeData = record
kind, group, divisor, order: Integer;
uid, uid2show: TUID;
hash, displayed, nick, first, last, birth, birthLocal, lastActivity,
clientClosed, clientDesc, onlineSince, lastTimeSeenOnline: String;
status, xstatus, clientimg, bdimg: Variant;
expanded, local, needAuth, hasAvatar, noClient: Boolean;
end;
TNativeProc = procedure(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
PNativeProc = ^TNativeProc;
TNativeData = record
Method: TNativeProc;
UseTag: Boolean
end;
TNativeMethods = class
Box: Pointer;
Methods: TDictionary;
public
constructor Create(Owner: Pointer);
destructor Destroy; override;
procedure AddMethod(Name: String; Proc: TNativeProc; UseTag: Boolean = False);
procedure ClearMethods;
procedure RegisterMethods(NativeMethods: TNativeMethods; var ReturnValue: TSciterValue);
end;
{$I NoRTTI.inc}
TSciterEx = class(TSciter)
private
ContactStatus: TContactStatus;
ContactXStatus: TContactXStatus;
StatusSprite, EventSprite, ClientSprite, BDSprite: TSprite;
public
function GetNodeData(var Node: TNode; Lite: Boolean = False): TNodeData;
function IsVisible(Element: HELEMENT): Boolean;
function GetID(Element: HELEMENT): String;
function GetAttr(Element: HELEMENT; const AttrName: AnsiString): String;
function GetTag(Element: HELEMENT): String;
constructor Create(AOwner: TComponent);
end;
TSciterHelper = class helper for TSciter
function LoadTemplate(const Doc, Filename: String; Debug: Boolean = True): Boolean;
procedure InitRequest(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard: Boolean; out Delay: Boolean; out Myself: Boolean);
end;
TRequestHandler = class
private
FDataStream: TMemoryStream;
protected
procedure ProcessRequest(ASender: TObject; URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard: Boolean; out Delay: Boolean; out Myself: Boolean);
procedure CheckAnimatedGifSize(var ms: TMemoryStream);
public
constructor Create(Sender: TSciter);
destructor Destroy; override;
end;
TUI = class(TSciterEx)
private
CommonMethods, MainMethods, ChatMethods, ViewInfoMethods, PrefsMethods: TNativeMethods;
public
CL: TContactList;
Chat: TChatBox;
Log: TLog;
Tips: TTips;
Prefs: TPrefs;
constructor Create(AOwner: TComponent);
destructor Destroy; override;
procedure AppActivate(Sender: TObject);
procedure AppDeactivate(Sender: TObject);
function CallOnElement(Element: HELEMENT; const FuncName: AnsiString; Params: TArray; IsMethod: Boolean = False): Variant;
procedure FireOnElement(Element: HELEMENT; cmd: UINT; data: Variant; async: Boolean = True);
procedure CreateCL;
procedure CreateChat;
procedure CreateLog;
procedure CreateTips;
procedure ApplySystemColor;
function GetFocused(Window: HWINDOW): HELEMENT;
// function GetCurrentRoot: HELEMENT;
function GetImageColors(var str: TMemoryStream): TParams;
function EnterPassword(Title: String; MaxLength: Integer = 0): String;
procedure EnterLockPassword(Title: String; Hint: String; MaxLength: Integer = 0);
function CreateDialog(const Msg: String; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; Seconds: Integer): Integer;
procedure MessageDialog(Msg: String; Kind: TMsgDlgType; const UID: String = '');
function InputQuery(Caption, Text, Icon: String): String;
function SwitchUser(ShowConflictMsg: Boolean = False): TUID;
function SelectContacts(const Caption, Btn: String; Options: TSCOptions; CheckUID: TUID = ''): TParams;
procedure InitSettings;
procedure ReloadUsers;
procedure ViewInfo(UID: TUID; Caption: String; UpdateOnly: Boolean = False);
procedure OpenPrefs(const Page: String = ''; Full: Boolean = True);
procedure OpenHistorySearch;
procedure OpenUpdater;
function OpenLangs(Langs: Variant): Integer;
procedure UpdateViewInfoAnP(UID: TUID);
procedure UpdateOutbox;
procedure UpdateDB;
procedure UpdateSessions(Current: Boolean = False);
procedure CloseAllChildWindows;
procedure LoadData(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
procedure ScriptingCall(ASender: TObject; const Args: TElementOnScriptingCallArgs);
end;
procedure GetTrans(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetTranslations(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetSpriteData(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetGroups(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure CheckOnline(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure SetLargeWindowIcon(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure CheckUIN(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure CheckAddUIN(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetMaxPasswordLength(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetPwd(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetCurrentUserName(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetCurrentUserAcc(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure GetAccountPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure SaveAccountPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
procedure IsAIM(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
function GetWindowHandle(argc: UINT; argv: PSciterValue; Root: Boolean = True): HWND;
function MakeSprite(const Pic: TPicName): TSprite;
var
UI: TUI;
implementation
uses
GlobalLib, GroupsLib, RoasterLib, IniLib, ThemesLib, RQUtil, RDUtils, Murmur2,
RnQNet, RnQLangs, RnQGlobal, RnQGraphics32, RQThemes, RnQPics, RnQDialogs, RnQ_Avatars, RnQMacros, Stickers,
ICQConsts, Protocol_ICQ, events, hook, mainDlg, usersDlg, viewInfoDlg, aboutDlg, outboxDlg, RnQdbDlg, selectcontactsDlg,
HistAllSearch, HiddenForm, StatusForm;
constructor TNativeMethods.Create(Owner: Pointer);
begin
Box := Owner;
Methods := TDictionary.Create;
end;
destructor TNativeMethods.Destroy;
begin
Methods.Free;
inherited;
end;
procedure TNativeMethods.AddMethod(Name: String; Proc: TNativeProc; UseTag: Boolean = False);
var
MethodData: TNativeData;
begin
MethodData.Method := Proc;
MethodData.UseTag := UseTag;
Methods.Add(Name, MethodData);
end;
procedure TNativeMethods.ClearMethods;
begin
Methods.Clear
end;
procedure TNativeMethods.RegisterMethods(NativeMethods: TNativeMethods; var ReturnValue: TSciterValue);
var
Method: TPair;
begin
for Method in NativeMethods.Methods do
TSciter.RegisterNativeFunctor(ReturnValue, PWideChar(Method.Key), @Method.Value.Method, THelpers.IfThen(Method.Value.UseTag, Box, nil));
end;
function LooksLikeALink(const link: String): Boolean;
begin
Result := StartsText('http://', link) or StartsText('https://', link) or StartsText('www.', link);
end;
{ TRequestHandler }
constructor TRequestHandler.Create(Sender: TSciter);
begin
FDataStream := nil;
end;
destructor TRequestHandler.Destroy;
begin
FreeAndNil(FDataStream);
inherited;
end;
procedure TRequestHandler.CheckAnimatedGifSize(var ms: TMemoryStream);
var
aGif: TGIFImage;
sz: Single;
FStreamFormat: TPAFormat;
PNG: TPNGImage;
begin
FStreamFormat := DetectFileFormatStream(ms);
if (FStreamFormat = PA_FORMAT_GIF) then
begin
ms.Seek(0, soFromBeginning);
aGif := TGIFImage.Create;
try
aGif.LoadFromStream(ms);
with aGif do
if Images.Count > 1 then
begin
sz := 4.85 * Images.Count * Width * Height / 1048576;
if sz > 50 then
try
ms.Clear;
PNG := TPNGImage.Create;
PNG.Assign(aGif.Images[0].Bitmap);
PNG.SaveToStream(ms);
PNG.Free;
ms.Seek(0, soFromBeginning);
except end;
end;
finally
aGif.Free;
end;
end;
end;
procedure TRequestHandler.ProcessRequest(ASender: TObject; URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
var
Hash: LongWord;
Img: TBytes;
PNG: TPNGImage;
Ico: TIcon;
RealURL, FileURL, FileName, MurmurStr: String;
Mini: Boolean;
Pic: TPicName;
ResStream: TResourceStream;
StrStream: TStringStream;
Cached, IsImg, Check, Ignore, Async, HasAoP: Boolean;
FBox: TSciter;
Contact: TICQContact;
FileInfo: TICQFileInfo;
Pos: Integer;
begin
Ignore := False;
Async := False;
Myself := False;
FBox := ASender as TSciter;
if StartsText('file://', url) or StartsText('sciter:', url) then
if ContainsStr(url, 'url(') then // Some weird Sciter bug
begin
Pos := String(url).LastIndexOf('url(');
url := String(url).Substring(Pos + 4, Length(url) - Pos - 5);
end else
Exit;
FDataStream := nil;
if StartsText('template:', url) then
begin
FDataStream := TMemoryStream.Create;
RealURL := Copy(url, 10, Length(url));
FBox.GetPackedItem('template', PWideChar(RealURL), FDataStream);
end else if StartsText('themeicon:', url) then
begin
RealURL := Copy(url, 11, Length(url));
Ico := TIcon.Create;
if theme.pic2ico(RQteDefault, RealURL, Ico) then
begin
FDataStream := TMemoryStream.Create;
Ico.SaveToStream(FDataStream)
end else
Ignore := True;
Ico.Free;
end else if StartsText('themepic:', url) then
begin
Pic := Copy(url, 10, Length(url));
if not theme.GetOrigPic(Pic, FDataStream) then
Ignore := True;
end else if StartsText('themepicsingle:', url) then
begin
RealURL := Copy(url, 16, Length(url));
if theme.Pic2PNG(RealURL, PNG) then
begin
FDataStream := TMemoryStream.Create;
PNG.SaveToStream(FDataStream)
end else
Ignore := True;
FreeAndNil(PNG);
end else if StartsText('pluginpic:', url) then
begin
Pic := Copy(url, 11, Length(url));
if theme.Pic2PNG(Pic, PNG) then
begin
FDataStream := TMemoryStream.Create;
PNG.SaveToStream(FDataStream);
end else
Ignore := True;
FreeAndNil(PNG);
end else if StartsText('contactpic:', url) and UseContactThemes and Assigned(ContactsTheme) then
begin
Pic := Copy(url, 12, Length(url));
if not ContactsTheme.GetOrigPic(Pic, FDataStream) then
Ignore := True;
end else if StartsText('smile:', url) then
begin
Pic := Copy(url, 7 + 1, Length(url));
if not theme.GetOrigSmile(Pic, FDataStream) then
Ignore := True;
end else if StartsText('sticker:', url) then
begin
RealURL := Copy(url, 9 + 1, Length(url));
TThread.CreateAnonymousThread(procedure
var
fs: TMemoryStream;
begin
fs := TMemoryStream.Create;
if String(url).startsWith('sticker:a') then
GetAnimatedSticker(RealURL, fs)
else
GetSticker(RealURL, fs);
if Assigned(FBox) and Running then
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
FreeAndNil(fs);
end).Start;
Delay := True;
Exit;
end else if StartsText('picker:', url) then
begin
RealURL := Copy(url, 8 + 1, Length(url));
TThread.CreateAnonymousThread(procedure
var
fs: TMemoryStream;
begin
fs := TMemoryStream.Create;
if String(url).startsWith('picker:a') then
GetAnimatedSticker(RealURL, fs, True)
else
GetSticker(RealURL, fs, 'stickerpicker_small');
if Assigned(FBox) and Running then
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
FreeAndNil(fs);
end).Start;
Delay := True;
Exit;
end else if StartsText('listicon:', url) then
begin
RealURL := Copy(url, 10 + 1, Length(url));
TThread.CreateAnonymousThread(procedure
var
fs: TMemoryStream;
begin
var
fn: String;
fs := TMemoryStream.Create;
fn := StickerPath + RealURL + '_listicon_small.webp';
if FileExists(fn) then
fs.LoadFromFile(fn);
if Assigned(FBox) and Running then
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
FreeAndNil(fs);
end).Start;
Delay := True;
Exit;
end else if StartsText('avatar:', url) or StartsText('miniavatar:', url) then
begin
Mini := StartsText('miniavatar:', url);
RealURL := Copy(url, IfThen(Mini, 12, 8), Length(url));
Contact := Account.AccProto.GetContact(RealURL);
if Contact.icon.ToShow = IS_AVATAR then
begin
FDataStream := TMemoryStream.Create;
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 0);
if Assigned(FDataStream) and (FDataStream.Size = 0) then
begin
FreeAndNil(FDataStream);
Ignore := True;
end;
if Mini and not Ignore then
ResampleProportional(FDataStream, 32, 32);
end else if Contact.icon.ToShow = IS_PHOTO then
begin
FDataStream := TMemoryStream.Create;
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 1);
if Assigned(FDataStream) and (FDataStream.Size = 0) then
begin
FreeAndNil(FDataStream);
Ignore := True;
end;
end else Ignore := True;
end else if StartsText('justavatar:', url) then
begin
RealURL := Copy(url, 12, Length(url));
Contact := Account.AccProto.GetContact(RealURL);
FDataStream := TMemoryStream.Create;
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 0);
if Assigned(FDataStream) and (FDataStream.Size = 0) then
begin
FreeAndNil(FDataStream);
Ignore := True;
end;
end else if StartsText('justphoto:', url) then
begin
RealURL := Copy(url, 11, Length(url));
Contact := Account.AccProto.GetContact(RealURL);
FDataStream := TMemoryStream.Create;
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 1);
if Assigned(FDataStream) and (FDataStream.Size = 0) then
begin
FreeAndNil(FDataStream);
Ignore := True;
end;
end else if StartsText('resource:', url) then
begin
RealURL := Copy(url, 10, Length(url));
ResStream := TResourceStream.Create(HInstance, UpperCase(RealURL), RT_RCDATA);
try
FDataStream := TMemoryStream.Create;
ResStream.SaveToStream(FDataStream);
finally
ResStream.Free;
end;
end else if StartsText('iconresource:', url) then
begin
RealURL := Copy(url, 14, Length(url));
ResStream := TResourceStream.Create(HInstance, UpperCase(RealURL), RT_ICON);
try
FDataStream := TMemoryStream.Create;
ResStream.SaveToStream(FDataStream);
finally
ResStream.Free;
end;
end else if StartsText('link:', url) then
begin
RealURL := ValidateURL(Copy(url, 6, Length(url)));
if ContainsText(RealURL, 'files.icq.net/') then
if Account.AccProto.AimSid = '' then
begin
RealURL := '';
OnlFeature(Account.AccProto);
end
else
begin
FileInfo := GetICQFileLinkInfoPrivate(RealURL);
if FileInfo.dlink = '' then
FileURL := FileInfo.jsonlink
else
FileURL := FileInfo.dlink;
if not (FileURL = '') then
RealURL := FileURL;
end;
OpenURL(RealURL);
Ignore := True;
end else if StartsText('mailto:', url) then
begin
openURL(url);
Ignore := True;
end else if StartsText('embedded:', url) then
begin
if TryStrToLongWord(Copy(url, 10, Length(url)), Hash) and Assigned(embeddedImgs) and embeddedImgs.TryGetValue(Hash, Img) then
begin
FDataStream := TMemoryStream.Create;
FDataStream.Write(Img, Length(Img));
CheckAnimatedGifSize(FDataStream);
end;
end else if StartsText('tabicon:', url) then
begin
PNG := nil;
if TryStrToLongWord(Copy(url, 9, Length(url)), Hash) and Assigned(TabsIconCache) and TabsIconCache.TryGetValue(Hash, PNG) then
if Assigned(PNG) then
begin
FDataStream := TMemoryStream.Create;
PNG.SaveToStream(FDataStream)
end else
Ignore := True;
end else if StartsText('check:', url) or StartsText('download:', url) then
begin
if StartsText('check:', url) then
begin
Check := True;
RealURL := Copy(url, 7, Length(url));
end
else
begin
Check := False;
RealURL := Copy(url, 10, Length(url));
end;
if LooksLikeALink(RealURL) then
begin
MurmurStr := ImgCacheInfo.ReadString(RealURL, 'hash', '0');
FileName := myPath + 'Cache\Images\' + MurmurStr + '.' + ImgCacheInfo.ReadString(RealURL, 'ext', 'jpg');
if MurmurStr = '0' then
Cached := False
else
Cached := FileExists(FileName);
if not Check then
Async := True
else if Cached then
begin
IsImg := True;
Async := False;
end else if ImgCacheInfo.ValueExists(RealURL, 'mime') and not MatchText(ImgCacheInfo.ReadString(RealURL, 'mime', ''), ImageContentTypes) then
begin
IsImg := False;
Async := False;
end else
Async := True;
if not Async then
begin
StrStream := TStringStream.Create('{ isImg: ' + IfThen(IsImg, '1', '0') + ', isLottie: ' + IfThen(IsLottieMime(RealURL), '1', '0') + ', link: "' + RealURL + '" }', TEncoding.UTF8);
FDataStream := TMemoryStream.Create;
FDataStream.CopyFrom(StrStream, 0);
StrStream.Free;
end;
end else
Ignore := True;
end else
begin
Discard := False;
Delay := False;
Exit;
end;
if not Ignore then
begin
if not Async then
begin
Delay := False;
FDataStream.Seek(0, soFromBeginning);
FBox.DataReady(url, FDataStream.Memory, FDataStream.Size);
end
else
begin
Myself := True;
RAPI.RequestUse(RequestId);
TThread.CreateAnonymousThread(procedure
var
ms: TMemoryStream;
fs: TFileStream;
ss: TStringStream;
begin
if Check then
begin
ss := TStringStream.Create('{ isImg: ' + IfThen(CheckType(RealURL), '1', '0') + ', isLottie: ' + IfThen(IsLottieMime(RealURL), '1', '0') + ', link: "' + RealURL + '" }', TEncoding.UTF8);
TThread.Synchronize(nil, procedure begin
if Running then
begin
RAPI.RequestSetSucceeded(RequestId, 200, ss.Memory, ss.Size);
RAPI.RequestUnUse(RequestId);
end;
end);
FreeAndNil(ss);
Exit;
end;
fs := nil;
ms := nil;
if not Cached then
Cached := DownloadAndCache(RealURL);
if Cached then
try
FileName := myPath + 'Cache\Images\' + ImgCacheInfo.ReadString(RealURL, 'hash', '0') + '.' + ImgCacheInfo.ReadString(RealURL, 'ext', 'jpg');
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
ms := TMemoryStream.Create;
ms.LoadFromStream(fs);
CheckAnimatedGifSize(ms);
TThread.Synchronize(nil, procedure begin
if not Running then
Exit;
RAPI.RequestSetSucceeded(RequestId, 200, ms.Memory, ms.Size);
RAPI.RequestUnUse(RequestId);
if Assigned(UI.Chat) then
UI.Chat.FinishImage(url);
if Assigned(PreviewChat) then
PreviewChat.FinishImage(url);
end);
except end else
TThread.Synchronize(nil, procedure()
begin
if not Running then
Exit;
RAPI.RequestSetFailed(RequestId, 404, nil, 0);
RAPI.RequestUnUse(RequestId);
end);
FreeAndNil(fs);
FreeAndNil(ms);
end).Start;
end;
Discard := False;
end else
Discard := True;
FreeAndNil(FDataStream);
end;
function MakeSprite(const Pic: TPicName): TSprite;
var
Rect: TGPRect;
begin
Rect := theme.GetPicRect(RQteDefault, Pic);
Result.name := theme.GetPicSprite(RQteDefault, Pic);
Result.x := -rect.X;
Result.y := -rect.Y;
Result.width := rect.Width;
Result.height := rect.Height;
end;
{ TSciterEx }
function TSciterEx.GetNodeData(var Node: TNode; Lite: Boolean = False): TNodeData;
var
LastActivity: TDateTime;
Group: TGroup;
Pic: String;
Event: Thevent;
begin
Result := Default(TNodeData);
if not Assigned(Node) then
Exit;
Result.divisor := Integer(Node.divisor);
Result.group := Node.groupId;
Result.kind := Node.kind;
Result.order := Node.order;
if Node.kind = NODE_DIV then
begin
case Node.divisor of
d_online: Result.order := 1;
d_nil: Result.order := 2;
d_recent: Result.order := 3;
d_offline: Result.order := 4;
d_contacts: Result.order := 5;
end;
end else if Node.kind = NODE_GROUP then
begin
Group := groups.Get(Node.groupId);
Result.displayed := Group.Name;
Result.expanded := Group.Expanded[Node.divisor];
Result.local := Group.IsLocal;
end else if Node.kind = NODE_CONTACT then
if Assigned(Node.contact) then
begin
Result.displayed := Node.contact.Displayed;
Result.uid := Node.contact.UID;
Result.uid2show := Node.contact.UIN2Show;
Result.nick := Node.contact.Nick;
Result.first := Node.contact.First;
Result.last := Node.contact.Last;
Result.birth := THelpers.IfThen(Node.contact.Birth = 0, '', DateToStr(Node.contact.Birth));
Result.birthLocal := THelpers.IfThen(Node.contact.BirthL = 0, '', DateToStr(Node.contact.BirthL));
Result.needAuth := not Node.contact.Authorized and not Node.contact.CntIsLocal;
Result.local := Node.contact.CntIsLocal;
Result.noClient := Node.contact.NoClient;
Result.clientClosed := TimeToString(Node.contact.ClientClosed);
Result.clientDesc := Node.contact.ClientDesc;
Result.onlineSince := TimeToString(Node.contact.OnlineSince);
Result.lastTimeSeenOnline := TimeToString(Node.contact.LastTimeSeenOnline);
if Lite then
Exit;
LastActivity := TCE(Node.contact.data^).lastMsgTime;
if LastActivity < StartTime then
// if not Node.contact.IsOnline then
begin
LastActivity := TCE(Node.contact.data^).lastEventTime;
if LastActivity < StartTime then
LastActivity := 0;
end;
Result.lastActivity := FloatToStr(LastActivity);
Result.hasAvatar := CheckAvatar(Node.contact);
// Status
Pic := RosterImgNameFor(Node.contact);
if Pic = '' then
Exit;
ContactStatus.official := Node.contact.Official;
ContactStatus.bot := Node.contact.Bot;
ContactStatus.deleted := Node.contact.Deleted;
ContactStatus.code := Node.contact.GetStatus;
ContactStatus.desc := Node.contact.StatusStr;
ContactStatus.name := Node.contact.GetStatusName;
StatusSprite := MakeSprite(Pic);
ContactStatus.statusimg := RecordToVar(StatusSprite);
Event := eventQ.firstEventFor(Node.contact);
if Assigned(Event) and not (Event.pic = '') then
begin
EventSprite := MakeSprite(Event.pic);
ContactStatus.eventimg := RecordToVar(EventSprite);
end else
ContactStatus.eventimg := False;
Result.status := RecordToVar(ContactStatus);
ContactXStatus.status := Node.contact.XStatus;
ContactXStatus.text := XStatus2Text(ContactXStatus.status);
Result.xstatus := RecordToVar(ContactXStatus);
// Client
if not (Node.contact.ClientPic = '') then
begin
ClientSprite := MakeSprite(Node.contact.ClientPic);
Result.clientimg := RecordToVar(ClientSprite);
end else
Result.clientimg := False;
// Birthday
case Node.contact.Days2Bd of
0: Pic := PIC_BIRTH;
1: Pic := PIC_BIRTH1;
2: Pic := PIC_BIRTH2;
else
Pic := '';
end;
if not (Pic = '') then
begin
BDSprite := MakeSprite(Pic);
Result.bdimg := RecordToVar(BDSprite);
end else
Result.bdimg := False;
end;
Result.hash := IntToStr(CalcMurmur2(TEncoding.UTF8.GetBytes(IntToStr(Result.kind) + '_' + IntToStr(Result.divisor) + '_' + IntToStr(Result.group) + '_' + String(Result.uid))));
end;
function TSciterEx.IsVisible(Element: HELEMENT): Boolean;
var
pResult: LongBool;
begin
API.SciterIsElementVisible(Element, pResult);
Result := pResult;
end;
function TSciterEx.GetID(Element: HELEMENT): String;
begin
Result := GetAttr(Element, 'id');
end;
procedure GetTextCallback(str: PWideChar; str_length: UINT; param: Pointer); stdcall;
begin
if not (str = nil) and not (str_length = 0) then
String(param^) := String(str);
end;
function TSciterEx.GetAttr(Element: HELEMENT; const AttrName: AnsiString): String;
begin
Result := '';
if AttrName = '' then
Exit;
API.SciterGetAttributeByNameCB(Element, PAnsiChar(AttrName), PLPCWSTR_RECEIVER(@GetTextCallback), @Result);
end;
function TSciterEx.GetTag(Element: HELEMENT): String;
begin
API.SciterGetElementTypeCB(Element, PLPCSTR_RECEIVER(@GetTextCallback), @Result);
end;
constructor TSciterEx.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// OnLoadData := InitRequest;
end;
{ TSciterHelper }
function TSciterHelper.LoadTemplate(const Doc, Filename: String; Debug: Boolean = True): Boolean;
begin
SetOption(SCITER_SET_SCRIPT_RUNTIME_FEATURES, UINT_PTR(ALLOW_FILE_IO) or UINT_PTR(ALLOW_SOCKET_IO) or UINT_PTR(ALLOW_EVAL) or UINT_PTR(ALLOW_SYSINFO));
SetOption(SCITER_SET_PX_AS_DIP, UINT_PTR(False));
SetOption(SCITER_SET_DEBUG_MODE, UINT_PTR(DevMode and Debug));
if DevMode then
Result := LoadURL(FilePathToURL(myPath + Doc + '\' + Filename))
else if FileExists(myPath + Doc + '.zip') then
Result := LoadURL(FilePathToURL(myPath + Doc + '.zip#' + Filename))
else
begin
LoadPackedResource(Doc, RT_RCDATA);
Result := LoadURL(Doc + ':' + Filename);
end;
end;
procedure TSciterHelper.InitRequest(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
var
handler: TRequestHandler;
begin
handler := TRequestHandler.Create(Self);
handler.ProcessRequest(ASender, URL, ResType, RequestId, Discard, Delay, Myself);
handler.Free;
end;
// Native methods
procedure GetSpriteData(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
str: String;
Sprite: TSprite;
begin
if argc = 0 then
Exit;
str := SciterVarToString(argv);
if str = '' then
Exit;
with UI do
begin
Sprite := MakeSprite(str);
V2S(RecordToVar(Sprite), retval);
end;
end;
procedure GetTrans(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
strData: String;
begin
if argc = 0 then
Exit;
strData := SciterVarToString(argv);
strData := GetTranslation(strData);
API.ValueStringDataSet(retval, PWideChar(strData), Length(strData), 0);
end;
function EnumParams(param: Pointer; const pkey: PSciterValue; const pval: PSciterValue): BOOL; stdcall;
var
key, val: String;
newval: TSciterValue;
begin
Result := True;
key := SciterVarToString(pval);
if key = '' then
Exit;
val := SciterVarToString(pval);
val := GetTranslation(val);
API.ValueInit(@newval);
API.ValueStringDataSet(@newval, PWideChar(val), Length(val), 0);
API.ValueSetValueToKey(param, pkey, @newval);
API.ValueClear(@newval);
end;
procedure GetTranslations(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
arrSize, i: UINT;
strData: PWideChar;
strLen: UINT;
val: TSciterValue;
begin
if argc = 0 then
Exit;
if argv.t = UINT(T_OBJECT) then
if argv.u = UINT(UT_OBJECT_OBJECT) then
API.ValueEnumElements(argv, @EnumParams, retval)
else if argv.u = UINT(UT_OBJECT_ARRAY) then
begin
arrSize := 0;
API.ValueIsolate(argv);
API.ValueElementsCount(argv, arrSize);
for i := 0 to arrSize - 1 do
begin
API.ValueInit(@val);
if API.ValueNthElementValue(argv, i, val) = HV_OK then
begin
API.ValueStringData(@val, strData, strLen);
strData := PWideChar(GetTranslation(strData));
API.ValueStringDataSet(@val, strData, Length(strData), 0);
API.ValueNthElementValueSet(retval, i, @val)
end;
API.ValueClear(@val);
end;
end;
end;
procedure GetGroups(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
I, Tmp: Integer;
AddOut: Boolean;
GroupItems: TArray;
MenuItems: TParams;
begin
Tmp := 0;
API.ValueIntData(argv, Tmp);
AddOut := Tmp = 1;
GroupItems := groups.GetGroups(AddOut);
SetLength(MenuItems, Length(GroupItems));
for I := 0 to Length(MenuItems) - 1 do
MenuItems[I] := UI.RecordToVar(GroupItems[I]);
V2S(MenuItems, retval);
end;
procedure CheckOnline(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
res: Boolean;
begin
res := OnlFeature(Account.AccProto);
API.ValueIntDataSet(retval, RDUtils.IfThen(res, 1), T_BOOL, 0);
end;
procedure SetLargeWindowIcon(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Hndl: HWND;
HIco: HIcon;
Pic: String;
begin
Hndl := GetWindowHandle(argc, argv);
if Hndl <= 0 then
Exit;
Inc(argv);
Pic := SciterVarToString(argv);
try
if Pic = '' then
HIco := Application.Icon.Handle
else
HIco := LoadIcon(HInstance, PWideChar(Pic));
// SendMessage(Hndl, WM_SETICON, ICON_SMALL, HIco);
SendMessage(Hndl, WM_SETICON, ICON_BIG, HIco);
except end;
end;
procedure CheckUIN(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Res: Boolean;
begin
Res := Account.AccProto.ValidICQ(Trim(SciterVarToString(argv)));
if not Res then
MsgDlg('Invalid UIN', True, mtError);
V2S(Res, retval);
end;
procedure CheckAddUIN(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UID: TUID;
Contact: TICQContact;
Res: Boolean;
begin
Res := False;
if argc < 1 then
Exit;
UID := Trim(SciterVarToString(argv));
if not Account.AccProto.ValidICQ(UID) then
MsgDlg('Invalid UIN', True, mtError)
else
begin
Contact := Account.AccProto.GetContact(UID);
if not Assigned(Contact) then
MsgDlg('Couldn''t create contact!', True, mtError)
else if Contact.IsInRoster then
begin
roasterLib.focus(Contact);
MsgDlg(GetTranslation('%s already exists', [uid]), False, mtWarning)
end else
Res := True;
end;
V2S(Res, retval);
end;
procedure GetSessionsList(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Sessions: TArray;
SessionsVar: TParams;
I: Integer;
begin
I := 0;
Sessions := Account.AccProto.GetSessionsList;
for var Session in Sessions do
begin
SetLength(SessionsVar, I + 1);
SessionsVar[I] := UI.RecordToVar(Sessions[I]);
Inc(I);
end;
V2S(SessionsVar, retval);
end;
procedure CloseSession(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Hash: String;
Current: Integer;
begin
Hash := SciterVarToString(argv);
Inc(argv);
Current := 0;
API.ValueIntData(argv, Current);
if not (Hash = '') then
Account.AccProto.CloseSession(Hash, Current = 1);
end;
procedure CloseAllSessions(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
Account.AccProto.CloseAllSessions;
end;
procedure GetMaxPasswordLength(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(Account.AccProto._MaxPwdLen, retval);
end;
procedure GetPwd(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(Account.AccProto.Pwd, retval);
end;
procedure GetContactIdle(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UIN: TUID;
IdleTime: Integer;
Contact: TICQContact;
begin
Contact := nil;
IdleTime := 0;
UIN := SciterVarToString(argv);
if not (UIN = '') then
Contact := Account.AccProto.GetContact(UIN);
if Assigned(Contact) then
IdleTime := Contact.IdleTime;
V2S(IdleTime, retval);
end;
procedure GetContactImportant(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UIN: TUID;
Important: String;
Tmp: Integer;
GetLocal: Boolean;
Contact: TICQContact;
begin
Contact := nil;
Important := '';
UIN := SciterVarToString(argv);
if not (UIN = '') then
Contact := Account.AccProto.GetContact(UIN);
Inc(argv);
Tmp := 0;
API.ValueIntData(argv, Tmp);
GetLocal := Tmp = 1;
if Assigned(Contact) then
Important := THelpers.IfThen(GetLocal, Contact.lclImportant, Contact.ssImportant);
V2S(Important, retval);
end;
procedure GetContactIgnored(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UIN: TUID;
Contact: TICQContact;
Ignored: Boolean;
begin
Contact := nil;
Ignored := False;
UIN := SciterVarToString(argv);
if not (UIN = '') then
Contact := Account.AccProto.GetContact(UIN);
if Assigned(Contact) then
Ignored := Contact.IsInList(LT_SPAM) or IgnoreList.exists(Contact);
V2S(Ignored, retval);
end;
procedure GetCurrentUserName(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(RnQUser, retval);
end;
procedure GetGroupName(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Group: Integer;
begin
Group := 0;
API.ValueIntData(argv, Group);
if Group = 0 then
V2S('', retval)
else
V2S(groups.ID2Name(Group), retval);
end;
procedure GetContactData(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UIN: TUID;
Contact: TICQContact;
Node: TNode;
NodeData: TNodeData;
begin
Contact := nil;
UIN := SciterVarToString(argv);
if not (UIN = '') then
Contact := Account.AccProto.GetContact(UIN);
if not Assigned(Contact) then
begin
V2S(varNull, retval);
Exit;
end;
with UI do
begin
if TCE(Contact.Data^).Node = nil then
TCE(Contact.Data^).Node := TNode.Create(d_nil, Contact);
NodeData := GetNodeData(TCE(Contact.Data^).Node);
V2S(RecordToVar(NodeData), retval);
end;
end;
procedure GetCurrentUserAcc(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(Account.AccProto.MyAccNum, retval);
end;
procedure GetAccountPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(AccPass, retval);
end;
procedure SaveAccountPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
if argc = 0 then
Exit;
if UpdateAccountEncryption(SciterVarToString(argv)) then
ActionManager.Execute(AK_SAVECONFIG, SaveDelay);
end;
procedure SaveNewAccountPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
if argc > 0 then
NewAccPass := SciterVarToString(argv);
end;
procedure CheckLockPassword(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Pwd: String;
begin
if argc = 0 then
Exit;
Pwd := SciterVarToString(argv);
if not (AccPass = '') then
V2S(CompareText(AccPass, Pwd) = 0, retval)
else
V2S(Account.AccProto.PwdEqual(Pwd), retval);
end;
procedure OpenLink(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
URL: String;
begin
URL := SciterVarToString(argv);
if not (URL = '') then
OpenURL(URL);
end;
procedure OpenPortal(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
OpenURL(rnqSite)
end;
procedure IsOnline(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(Assigned(Account.AccProto) and Account.AccProto.IsOnline, retval)
end;
procedure IsAIM(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
MyInf: TICQContact;
IsAIM: Boolean;
begin
IsAIM := False;
if not Assigned(Account.AccProto) then
Exit;
MyInf := Account.AccProto.GetMyInfo;
if Assigned(MyInf) then
IsAIM := MyInf.isAIM;
V2S(IsAIM, retval);
end;
procedure IsElevated(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(utilLib.IsElevated, retval);
end;
procedure IsWindows10(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(IsTen, retval);
end;
procedure ProcessMacro(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
I, Key: Integer;
Shift: TShiftState;
function Match(Shortcut: TShortcut): Boolean;
var
HK: Word;
State: TShiftState;
begin
ShortCutToKey(Shortcut, HK, State);
if ShortCut and scCommand <> 0 then Include(State, ssCommand); // WIN key
Result := ((HK and not scCommand) = Key) and (State = Shift);
end;
begin
Key := 0;
API.ValueIntData(argv, Key);
Shift := [];
Inc(argv);
I := 0;
API.ValueIntData(argv, I);
if I = 1 then
Shift := Shift + [ssShift];
Inc(argv);
I := 0;
API.ValueIntData(argv, I);
if I = 1 then
Shift := Shift + [ssCtrl];
Inc(argv);
I := 0;
API.ValueIntData(argv, I);
if I = 1 then
Shift := Shift + [ssAlt];
Inc(argv);
I := 0;
API.ValueIntData(argv, I);
if I = 1 then
Shift := Shift + [ssCommand];
if HotkeysEnabled and (Key > 0) then
for I := Low(Macros) to High(Macros) do
if not Macros[I].sw and Match(Macros[i].hk) then
ExecuteMacro(Macros[i].opcode);
end;
procedure GetUploadServerName(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
if ServerToUpload = 0 then
V2S('files.icq.net', retval)
else if ServerToUpload = 1 then
V2S('code.highspec.ru', retval)
else
V2S('rnq.ru', retval);
end;
procedure GetUpdateInfo(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
UpdateInfo: TUpdateInfo;
begin
CheckUpdates(UpdateInfo);
V2S(UI.RecordToVar(UpdateInfo), retval);
end;
procedure GetDoubleClickDelay(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
V2S(GetDoubleClickTime, retval);
end;
function GetWindowHandle(argc: UINT; argv: PSciterValue; Root: Boolean = True): HWND;
var
B: PByte;
Pb: Cardinal;
Hndl: HWND;
begin
B := nil;
Hndl := 0;
if (argc > 0) and ((argv.t = UINT(T_OBJECT)) and (argv.u = UINT(UT_OBJECT_NATIVE))) or (argv.t = UINT(T_RESOURCE)) then
API.ValueBinaryData(argv, B, Pb);
if Assigned(B) then
API.SciterGetElementHwnd(B, Hndl, Root);
Result := Hndl;
end;
//procedure ActivateWindow(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
//var
// Hndl: HWND;
//begin
// Hndl := GetWindowHandle(argc, argv);
// if Hndl > 0 then
// SetForegroundWindow(Hndl);
//end;
procedure IsWindowActive(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
var
Hndl, Forg: HWND;
begin
Hndl := GetWindowHandle(argc, argv);
Forg := GetForegroundWindow;
if Hndl > 0 then
V2S((Forg = Hndl) or (Forg = GetParent(Hndl)), retval)
else
V2S(False, retval)
end;
procedure SetupWindowTask(Window: HWND; ShowButton: Boolean; WindowType: Integer = 0);
var
ExStyle: Integer;
begin
if Window = 0 then
Exit;
ExStyle := GetWindowLongPtr(Window, GWL_EXSTYLE);
if ShowButton then
ExStyle := ExStyle or WS_EX_APPWINDOW
else
ExStyle := ExStyle and not WS_EX_APPWINDOW;
if WindowType > 0 then
ExStyle := ExStyle or WindowType;
SetWindowLongPtr(Window, GWL_EXSTYLE, ExStyle);
end;
procedure ShowTaskbarButton(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
SetupWindowTask(GetWindowHandle(argc, argv), True);
end;
procedure HideTaskbarButton(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
SetupWindowTask(GetWindowHandle(argc, argv), False);
end;
procedure HideTaskbarButton2(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
SetupWindowTask(GetWindowHandle(argc, argv), False, WS_EX_NOACTIVATE);
end;
//procedure SetDesktopAsParent(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
//var
// Window: HWND;
//begin
// Window := GetWindowHandle(argc, argv, False);
// SetParent(Window, 0);
// SetWindowLongPtr(Window, GWLP_HWNDPARENT, 0);
//end;
procedure SavePreviousWindow(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
PrevWnd := GetForegroundWindow;
end;
procedure ClearPreviousWindow(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
PrevWnd := 0;
end;
procedure SwitchToPreviousWindow(tag: Pointer; argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
begin
if PrevWnd > 0 then
begin
SetForegroundWindow(PrevWnd);
PrevWnd := 0;
end;
end;
// TUI
constructor TUI.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
SetParentComponent(AOwner);
CommonMethods := TNativeMethods.Create(Self);
MainMethods := TNativeMethods.Create(Self);
ChatMethods := TNativeMethods.Create(Self);
ViewInfoMethods := TNativeMethods.Create(Self);
PrefsMethods := TNativeMethods.Create(Self);
OnLoadData := LoadData;
OnScriptingCall := ScriptingCall;
end;
destructor TUI.Destroy;
begin
CommonMethods.Free;
MainMethods.Free;
ChatMethods.Free;
ViewInfoMethods.Free;
PrefsMethods.Free;
inherited;
end;
procedure TUI.CreateCL;
begin
CL := TContactList.Create;
CL.Root := Pointer(NativeInt(Call('createContactList', [])));
API.SciterGetElementHwnd(CL.Root, CL.Window, True); // SCDOM_OK
// Hide close button
// SetWindowLongPtr(CL.Window, GWL_STYLE, GetWindowLongPtr(CL.Window, GWL_STYLE) and not WS_SYSMENU);
// Remove icon and hide taskbar button
SetupWindowTask(CL.Window, False, WS_EX_DLGMODALFRAME);
UninstallHook;
InstallHook(CL.Window);
LastMonCnt := GetActiveMonitorCount;
CL.SavePositionForCurrentMonitorCount;
end;
procedure TUI.CreateChat;
begin
Chat := TChatBox.Create;
Chat.Root := Pointer(NativeInt(Call('createChat', [])));
API.SciterGetElementHwnd(Chat.Root, Chat.Window, True); // SCDOM_OK
// Do not repaint under child windows (plugin tabs)
SetWindowLongPtr(Chat.Window, GWL_STYLE, GetWindowLongPtr(Chat.Window, GWL_STYLE) or WS_CLIPCHILDREN);
end;
procedure TUI.CreateLog;
begin
Log := TLog.Create;
Log.Root := Pointer(NativeInt(Call('createLog', [])));
API.SciterGetElementHwnd(Log.Root, Log.Window, True);
end;
procedure TUI.CreateTips;
begin
Tips := TTips.Create;
Tips.Root := Pointer(NativeInt(Call('createTips', [])));
API.SciterGetElementHwnd(Tips.Root, Tips.Window, True);
Tips.InitWndProc;
SetupWindowTask(Tips.Window, False, WS_EX_NOACTIVATE);
end;
function TUI.CallOnElement(Element: HELEMENT; const FuncName: AnsiString; Params: TArray; IsMethod: Boolean = False): Variant;
var
RetVal: TSciterValue;
Handle: HWINDOW;
Res: SCDOM_RESULT;
begin
if Element = nil then Exit;
Res := API.SciterGetElementHwnd(Element, Handle, True);
if Res <> SCDOM_OK then
begin
ODS('CallOnElement failed: res ' + IntToStr(Integer(res)));
Exit;
end;
if Handle = 0 then
begin
ODS('CallOnElement failed: handle is zero');
Exit;
end;
API.ValueInit(@RetVal);
if IsMethod then
begin
if (CallScriptMethod(Element, FuncName, Params, RetVal) = SCDOM_OK) then
S2V(@RetVal, Result)
end else if (CallScriptFunction(Element, FuncName, Params, RetVal) = SCDOM_OK) then
S2V(@RetVal, Result);
API.ValueClear(@RetVal);
end;
procedure TUI.FireOnElement(Element: HELEMENT; cmd: UINT; data: Variant; async: Boolean = True);
begin
Fire(Element, cmd, data, async);
end;
procedure TUI.MessageDialog(Msg: String; Kind: TMsgDlgType; const UID: String = '');
begin
Call('showAlert', [Kind, Msg, False]);
end;
function TUI.InputQuery(Caption, Text, Icon: String): String;
begin
Result := Call('inputQuery', [Caption, Text, Icon]);
end;
function TUI.GetFocused(Window: HWINDOW): HELEMENT;
begin
if not (API.SciterGetFocusElement(Window, Result) = SCDOM_OK) then
Result := nil;
end;
//function TUI.GetCurrentRoot: HELEMENT;
//begin
// if not (API.SciterGetRootElement(GetForegroundWindow, Result) = SCDOM_OK) then
// Result := nil;
//end;
procedure TUI.AppActivate(Sender: TObject);
begin
InactiveTime := 0;
if Assigned(UI) and Assigned(UI.Tips) then
UI.Tips.Reposition;
Account.AccProto.CheckEventSubscribe(6);
end;
procedure TUI.AppDeactivate(Sender: TObject);
begin
InactiveTime := 0;
CheckTopMost;
end;
procedure TUI.ApplySystemColor;
begin
if not (AccentColor = clWhite) then
Call('setSystemColor', [GetRValue(AccentColor), GetGValue(AccentColor), GetBValue(AccentColor)]);
end;
function TUI.GetImageColors(var str: TMemoryStream): TParams;
var
img: Variant;
buf: Pointer;
Freq, StartCount, StopCount: Int64;
TimingSeconds: real;
begin
img := VarArrayCreate([0, str.Size - 1], varByte);
buf := VarArrayLock(img);
str.Seek(0, soFromBeginning);
str.ReadBuffer(buf^, str.Size);
VarArrayUnlock(img);
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(StartCount);
Result := Call('getImageColors', [img]);
QueryPerformanceCounter(StopCount);
TimingSeconds := (StopCount - StartCount) / Freq;
ODS('Vibrant run: ' + floattostr(TimingSeconds));
end;
function TUI.EnterPassword(Title: String; MaxLength: Integer = 0): String;
begin
Result := Call('enterPassword', [Title, Hint, MaxLength]);
end;
procedure TUI.EnterLockPassword(Title: String; Hint: String; MaxLength: Integer = 0);
begin
Call('enterLockPassword', [Title, Hint, MaxLength]);
end;
function TUI.SwitchUser(ShowConflictMsg: Boolean = False): TUID;
begin
Result := Call('switchUser', [ShowConflictMsg]);
end;
function TUI.SelectContacts(const Caption, Btn: String; Options: TSCOptions; CheckUID: TUID = ''): TParams;
begin
Result := Call('openUINList', [Caption, Btn, Byte(Options), CheckUID]);
end;
procedure TUI.ReloadUsers;
begin
Call('reloadUsers', []);
end;
procedure TUI.ViewInfo(UID: TUID; Caption: String; UpdateOnly: Boolean = False);
begin
Call('openViewInfo', [UID, Caption, UpdateOnly]);
end;
procedure TUI.OpenPrefs(const Page: String = ''; Full: Boolean = True);
begin
Call('openPrefs', [Page, Full]);
end;
procedure TUI.OpenHistorySearch;
begin
Call('openHistorySearch', []);
end;
procedure TUI.OpenUpdater;
begin
Call('openUpdater', []);
end;
function TUI.OpenLangs(Langs: Variant): Integer;
begin
Result := Call('openLangs', [Langs]);
end;
procedure TUI.UpdateViewInfoAnP(UID: TUID);
begin
Call('updateViewInfoAnP', [UID]);
end;
procedure TUI.UpdateOutbox;
begin
Call('updateOutbox', []);
end;
procedure TUI.UpdateDB;
begin
Call('updateDB', []);
end;
procedure TUI.UpdateSessions(Current: Boolean = False);
begin
Call('updateSessionsManager', [Current]);
end;
procedure TUI.CloseAllChildWindows;
begin
Call('closeChildWindows', []);
end;
function TUI.CreateDialog(const Msg: String; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; Seconds: Integer): Integer;
var
Button, DefaultButton, CancelButton: TMsgDlgBtn;
DefaultButtonVar, CancelButtonVar: Variant;
ButtonsVar: TParams;
I: Integer;
Title, Icon, ResultBtn: String;
begin
case DlgType of
mtWarning:
Icon := PIC_EXCLAMATION;
mtError:
Icon := PIC_HAND;
mtInformation:
Icon := PIC_ASTERISK;
mtConfirmation:
Icon := PIC_QUEST;
mtBuzz:
Icon := PIC_BUZZ;
mtCustom:
Icon := '';
end;
if DlgType <> mtCustom then
Title := GetTranslation(LoadResString(Captions[DlgType]))
else
Title := Application.Title;
if RnQUser > '' then
Title := Title + ' (' + RnQUser + ')';
I := 0;
for Button in Buttons do
begin
SetLength(ButtonsVar, I + 1);
ButtonsVar[I] := SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(Button)));
Inc(I);
end;
if mbOk in Buttons then
DefaultButton := mbOk
else if mbYes in Buttons then
DefaultButton := mbYes
else
DefaultButton := mbRetry;
if mbCancel in Buttons then
CancelButton := mbCancel
else if mbNo in Buttons then
CancelButton := mbNo
else
CancelButton := mbOk;
DefaultButtonVar := SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(DefaultButton)));
CancelButtonVar := SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(CancelButton)));
ResultBtn := Call('createDialog', [Icon, Title, Msg, False, ButtonsVar, DefaultButtonVar, CancelButtonVar, Seconds]);
if ResultBtn = 'mbYes' then Result := mrYes
else if ResultBtn = 'mbNo' then Result := mrNo
else if ResultBtn = 'mbOK' then Result := mrOK
else if ResultBtn = 'mbCancel' then Result := mrCancel
else if ResultBtn = 'mbAbort' then Result := mrAbort
else if ResultBtn = 'mbRetry' then Result := mrRetry
else if ResultBtn = 'mbIgnore' then Result := mrIgnore
else if ResultBtn = 'mbAll' then Result := mrAll
else if ResultBtn = 'mbNoToAll' then Result := mrNoToAll
else if ResultBtn = 'mbYesToAll' then Result := mrYesToAll
else if ResultBtn = 'mbHelp' then Result := mrHelp
else if ResultBtn = 'mbClose' then Result := mrClose
else Result := mrOK;
end;
procedure TUI.InitSettings;
var
Settings: TCommonSettings;
begin
Settings.supportAvatars := Account.AccProto.AvatarsSupport;
Settings.avatarShowInHint := AvatarShowInHint;
Settings.avatarUsePalette := AvatarUsePalette10;
Settings.animateWindows := AnimateWindows;
Settings.animatedScroll := AnimatedScroll;
Settings.quitConfirmation := QuitConfirmation;
Settings.alertTopMost := AlertTopMost;
Call('initCommonSettings', [RecordToVar(Settings)]);
end;
procedure TUI.LoadData(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
begin
if (theme.token = 101) and (StartsText('themepic', url) or StartsText('pluginpic:', url) or StartsText('smile:', url)) then
Discard := True // Theme is not loaded yet
else
InitRequest(ASender, URL, ResType, RequestId, Discard, Delay, Myself);
end;
procedure TUI.ScriptingCall(ASender: TObject; const Args: TElementOnScriptingCallArgs);
begin
if Args.Method = 'getNativeApi' then
if (Args.ArgumentsCount = 0) or (Args.Argument[0] = '') then
with CommonMethods do
begin
// Common
AddMethod('GetTranslation', GetTrans);
AddMethod('GetTranslations', GetTranslations);
AddMethod('GetSpriteData', GetSpriteData);
//AddMethod('ActivateWindow', ActivateWindow);
AddMethod('IsWindowActive', IsWindowActive);
AddMethod('SetLargeWindowIcon', SetLargeWindowIcon);
AddMethod('ShowTaskbarButton', ShowTaskbarButton);
AddMethod('HideTaskbarButton', HideTaskbarButton);
AddMethod('HideTaskbarButton2', HideTaskbarButton2);
//AddMethod('SetDesktopAsParent', SetDesktopAsParent);
AddMethod('SavePreviousWindow', SavePreviousWindow);
AddMethod('ClearPreviousWindow', ClearPreviousWindow);
AddMethod('SwitchToPreviousWindow', SwitchToPreviousWindow);
AddMethod('GetContactIdle', GetContactIdle);
AddMethod('GetContactImportant', GetContactImportant);
AddMethod('GetContactIgnored', GetContactIgnored);
AddMethod('GetCurrentUserName', GetCurrentUserName);
AddMethod('GetGroupName', GetGroupName);
AddMethod('GetContactData', GetContactData);
AddMethod('GetAccountPassword', GetAccountPassword);
AddMethod('SaveAccountPassword', SaveAccountPassword);
AddMethod('SaveNewAccountPassword', SaveNewAccountPassword);
AddMethod('CheckLockPassword', CheckLockPassword);
AddMethod('OpenLink', OpenLink);
AddMethod('OpenPortal', OpenPortal);
AddMethod('CheckOnline', CheckOnline);
AddMethod('IsOnline', IsOnline);
AddMethod('IsAIM', IsAIM);
AddMethod('IsElevated', IsElevated);
AddMethod('IsWindows10', IsWindows10);
AddMethod('ProcessMacro', ProcessMacro);
AddMethod('GetUploadServerName', GetUploadServerName);
AddMethod('GetDoubleClickDelay', GetDoubleClickDelay);
// Users
AddMethod('GetUsersData', GetUsersData);
AddMethod('OpenICQReg', OpenICQReg);
AddMethod('ChangeOrAddUser', ChangeOrAddUser);
AddMethod('CheckAccountPass', CheckAccountPass);
AddMethod('CreateAccount', CreateAccount);
AddMethod('DeleteAccount', DeleteAccount);
// Search
AddMethod('CreatePreviewChat', CreatePreviewChat);
AddMethod('FreePreviewChat', FreePreviewChat);
AddMethod('OpenPreview', OpenPreview);
AddMethod('SearchHistory', SearchHistory);
AddMethod('GetHistory', GetHistory);
AddMethod('GetHistoryEntry', GetHistoryEntry);
AddMethod('GetHistoryChunk', GetHistoryChunk);
AddMethod('GetHistoryLength', GetHistoryLength);
AddMethod('CopyHistoryText', CopyHistoryText);
AddMethod('MatchHistoryEntry', MatchHistoryEntry);
AddMethod('KeyToIndex', KeyToIndex);
// Outbox
AddMethod('GetOutboxMessages', GetOutboxMessages);
AddMethod('GetOutboxProcess', GetOutboxProcess);
AddMethod('SetOutboxProcess', SetOutboxProcess);
AddMethod('UpdateOutboxText', UpdateOutboxText);
AddMethod('DeleteOutboxEvent', DeleteOutboxEvent);
AddMethod('SendOutboxEvent', SendOutboxEvent);
// Update
AddMethod('GetUpdateInfo', GetUpdateInfo);
// DB
AddMethod('GetContactsDB', GetContactsDB);
AddMethod('CleanContactsDB', CleanContactsDB);
AddMethod('AddAllDB2CL', AddAllDB2CL);
AddMethod('DeleteContactFromDB', DeleteContactFromDB);
// UIN lists
AddMethod('GetContacts', GetContacts);
AddMethod('GetUINLists', GetUINLists);
AddMethod('GetUINList', GetUINList);
AddMethod('SaveUINList', SaveUINList);
AddMethod('DeleteUINList', DeleteUINList);
// Tips
AddMethod('ClearTip', ClearTip);
RegisterMethods(CommonMethods, Args.ReturnSciterValue);
Args.Handled := True;
end else if (Args.Argument[0] = 'main') then
with MainMethods do
begin
// Main
AddMethod('CheckUIN', CheckUIN);
AddMethod('CheckAddUIN', CheckAddUIN);
AddMethod('GetGroups', GetGroups);
AddMethod('GetSessionsList', GetSessionsList);
AddMethod('CloseSession', CloseSession);
AddMethod('CloseAllSessions', CloseAllSessions);
AddMethod('GetMaxPasswordLength', GetMaxPasswordLength);
AddMethod('GetPwd', GetPwd);
AddMethod('GetCurrentUserAcc', GetCurrentUserAcc);
// CL
AddMethod('DivisorToTitle', DivisorToTitle);
AddMethod('ToggleOnlineOnly', ToggleOnlineOnly);
AddMethod('ToggleFilter', ToggleFilter);
AddMethod('GroupStateChanged', GroupStateChanged);
AddMethod('OpenContact', OpenContact);
AddMethod('BarButtonClick', BarButtonClick);
AddMethod('GoOnline', GoOnline);
AddMethod('RenameContact', RenameContact);
AddMethod('RenameGroup', RenameGroup);
AddMethod('RemoveGroup', CLBox.RemoveGroup);
AddMethod('DeleteCurrentGroup', DeleteCurrentGroup);
AddMethod('SetGroupOrder', SetGroupOrder);
AddMethod('SetClicked', SetClicked);
AddMethod('SetStatus', SetStatus);
AddMethod('ToggleVisibility', ToggleVisibility);
AddMethod('Lock', Lock);
AddMethod('Unlock', Unlock);
AddMethod('ViewInfoAbout', ViewInfoAbout);
AddMethod('OpenChatWith', OpenChatWith);
AddMethod('ReloadLang', ReloadLang);
AddMethod('GetCL', GetCL);
AddMethod('ReloadTheme', ReloadTheme);
AddMethod('ReloadThemeList', ReloadThemeList);
AddMethod('OpenContactThemes', OpenContactThemes);
AddMethod('SelectTheme', SelectTheme);
AddMethod('SelectSmiles', SelectSmiles);
AddMethod('SelectSounds', SelectSounds);
AddMethod('OpenMyInfo', OpenMyInfo);
AddMethod('OpenMyWebProfile', OpenMyWebProfile);
AddMethod('OpenHelpSite', OpenHelpSite);
AddMethod('OpenHelpLocal', OpenHelpLocal);
AddMethod('ShowAndActivate', ShowAndActivate);
AddMethod('Toggle', Toggle);
AddMethod('Quit', CLBox.Quit);
AddMethod('AddGroup', CLBox.AddGroup);
AddMethod('DeleteEmptyGroups', DeleteEmptyGroups);
AddMethod('ToggleShowGroups', CLBox.ToggleShowGroups);
AddMethod('ToggleShowEmptyGroups', CLBox.ToggleShowEmptyGroups);
AddMethod('ToggleStatusSeparation', CLBox.ToggleStatusSeparation);
AddMethod('AddGroupToServer', AddGroupToServer);
AddMethod('RemoveCurrentGroupFromServer', RemoveCurrentGroupFromServer);
AddMethod('MoveAllFromCurrentToGroup', MoveAllFromCurrentToGroup);
AddMethod('OpenChatWithCurrent', OpenChatWithCurrent);
AddMethod('SendMailToCurrent', SendMailToCurrent);
AddMethod('HasEmail', HasEmail);
AddMethod('GetSpamContact', GetSpamContact);
AddMethod('AddCurrentContactToServer', AddCurrentContactToServer);
AddMethod('IsCurrentInRoster', IsCurrentInRoster);
AddMethod('CurrentRequestXStatus', CurrentRequestXStatus);
AddMethod('CurrentRequestAuth', CurrentRequestAuth);
AddMethod('CurrentGrantAuth', CurrentGrantAuth);
AddMethod('CurrentRequestAvatar', CurrentRequestAvatar);
AddMethod('CurrentViewInfo', CurrentViewInfo);
AddMethod('AddCurrentToGroup', AddCurrentToGroup);
AddMethod('MoveCurrentToGroup', MoveCurrentToGroup);
AddMethod('RemoveCurrentContactFromServer', RemoveCurrentContactFromServer);
AddMethod('DeleteCurrentContact', DeleteCurrentContact);
AddMethod('DeleteCurrentContactHistory', DeleteCurrentContactHistory);
AddMethod('DeleteCurrentContactAndHistory', DeleteCurrentContactAndHistory);
AddMethod('CurrentIsInQuietList', CurrentIsInQuietList);
AddMethod('AddCurrentToQuietList', AddCurrentToQuietList);
AddMethod('CurrentIsInIgnoreList', CurrentIsInIgnoreList);
AddMethod('AddCurrentToIgnoreList', AddCurrentToIgnoreList);
AddMethod('GetCurrentUIN2Show', GetCurrentUIN2Show);
AddMethod('IsGroupLocal', IsGroupLocal);
AddMethod('GetGroupName', GetGroupName);
AddMethod('GetContactGroup', GetContactGroup);
AddMethod('ContactNeedsAuth', ContactNeedsAuth);
AddMethod('IsContactLocal', IsContactLocal);
AddMethod('AddContact', AddContact);
AddMethod('SearchContact', SearchContact);
AddMethod('SavePassword', SavePassword);
AddMethod('HasBorder', HasBorder);
AddMethod('FlashChatWindow', FlashChatWindow);
AddMethod('OnCLShow', OnCLShow);
AddMethod('OnCLHide', OnCLHide);
AddMethod('OnCLMouseEnter', OnCLMouseEnter);
AddMethod('OnCLMouseLeave', OnCLMouseLeave);
AddMethod('OnCLActivate', OnCLActivate);
// Status Message
AddMethod('SaveXStatusAndMessage', SaveXStatusAndMessage);
AddMethod('SetXStatusAndMessage', SetXStatusAndMessage);
AddMethod('GetStatusMessage', GetStatusMessage);
AddMethod('GetStatusMessages', GetStatusMessages);
// About
AddMethod('GetAboutInfo', GetAboutInfo);
RegisterMethods(MainMethods, Args.ReturnSciterValue);
Args.Handled := True;
end else if (Args.Argument[0] = 'chat') then
with ChatMethods do
begin
AddMethod('OnChatShow', OnChatShow);
AddMethod('OnChatHide', OnChatHide);
AddMethod('OnChatResize', OnChatResize);
AddMethod('OnChatActivate', OnChatActivate);
AddMethod('UpdateChatXY', UpdateChatXY);
AddMethod('SaveEmbeddedFile', SaveEmbeddedFile);
AddMethod('LoadHistory', LoadHistory);
AddMethod('UpdateSelection', UpdateSelection);
AddMethod('GetLinkInfo', GetLinkInfo);
AddMethod('GetYoutubeLinks', GetYoutubeLinks);
AddMethod('GetVimeoLinks', GetVimeoLinks);
AddMethod('GetVolumeLevel', GetVolumeLevel);
AddMethod('SaveVolumeLevel', SaveVolumeLevel);
AddMethod('UploadLastSnapshot', UploadLastSnapshot);
AddMethod('DeleteSnapshot', DeleteSnapshot);
AddMethod('ChatPageSelected', ChatPageSelected);
AddMethod('ChatPageDeselected', ChatPageDeselected);
AddMethod('PluginPageSelected', PluginPageSelected);
AddMethod('PluginPageDeselected', PluginPageDeselected);
AddMethod('SetTabDragging', SetTabDragging);
AddMethod('CloseChatPage', CloseChatPage);
AddMethod('ClosePluginPage', ClosePluginPage);
AddMethod('AddUIN2CL', AddUIN2CL);
AddMethod('GetSpriteData', GetSpriteData);
AddMethod('CopyLink', CopyLink);
AddMethod('SavePicture', SavePicture);
AddMethod('GetEvent', GetEvent);
AddMethod('SaveAs', SaveAs);
AddMethod('AddLinkToFav', AddLinkToFav);
AddMethod('DeleteMessages', DeleteMessages);
AddMethod('AddToAntispam', AddToAntispam);
AddMethod('ToggleSmiles', ToggleSmiles);
AddMethod('ToggleRelTimes', ToggleRelTimes);
AddMethod('RealizeEvents', ChatBox.RealizeEvents);
AddMethod('StoreSplit', StoreSplit);
AddMethod('InputChangedFor', InputChangedFor);
AddMethod('GetMessageByIdx', GetMessageByIdx);
AddMethod('WrapText', WrapText);
AddMethod('SendChatMessage', SendChatMessage);
AddMethod('EditChatMessage', EditChatMessage);
AddMethod('GetChatMessageText', GetChatMessageText);
AddMethod('ClosePages', ClosePages);
AddMethod('UploadFile', UploadFile);
AddMethod('UploadFiles', UploadFiles);
AddMethod('ChatButtonClick', ChatButtonClick);
AddMethod('PluginButtonClick', PluginButtonClick);
AddMethod('ToggleTranslit', ToggleTranslit);
AddMethod('SendStickerToCurrent', SendStickerToCurrent);
AddMethod('GetSpellingSuggestions', GetSpellingSuggestions);
AddMethod('GetStickerPacks', GetStickerPacks);
AddMethod('GetStoreStickerPacks', GetStoreStickerPacks);
AddMethod('SearchStickerPacks', SearchStickerPacks);
AddMethod('BuyStickerPack', BuyStickerPack);
AddMethod('RemoveStickerPack', RemoveStickerPack);
AddMethod('GetStickerPackContent', ChatBox.GetStickerPackContent);
AddMethod('GetEventHeaderTime', GetEventHeaderTime);
AddMethod('OnChatMouseEnter', OnChatMouseEnter);
AddMethod('OnChatMouseLeave', OnChatMouseLeave);
AddMethod('AttachWindow', AttachWindow);
AddMethod('DetachWindow', DetachWindow);
RegisterMethods(ChatMethods, Args.ReturnSciterValue);
Args.Handled := True;
end else if (Args.Argument[0] = 'viewinfo') then
with ViewInfoMethods do
begin
AddMethod('GetContactViewInfo', GetContactViewInfo);
AddMethod('GetContactViewInfoData', GetContactViewInfoData);
AddMethod('GetContactInfo', GetContactInfo);
AddMethod('DeleteContactFromList', DeleteContactFromList);
AddMethod('SaveServerInfo', SaveServerInfo);
AddMethod('SaveLocalInfo', SaveLocalInfo);
AddMethod('IsContactInCL', IsContactInCL);
AddMethod('UpdateBirthAge', UpdateBirthAge);
AddMethod('SetIconShowType', SetIconShowType);
AddMethod('SetNoDBDelete', SetNoDBDelete);
AddMethod('SetTranslit', SetTranslit);
AddMethod('ApplyInfoStatus', ApplyInfoStatus);
AddMethod('ApplyNotes', ApplyNotes);
AddMethod('VerifyPhone', VerifyPhone);
AddMethod('LoadAvatarAsync', LoadAvatarAsync);
AddMethod('LoadThumb', LoadThumb);
AddMethod('LoadPhoto', LoadPhoto);
AddMethod('ClearAvatarOrPhoto', ClearAvatarOrPhoto);
AddMethod('ChangeAvatar', ChangeAvatar);
AddMethod('GetCaptionColors', GetCaptionColors);
RegisterMethods(ViewInfoMethods, Args.ReturnSciterValue);
Args.Handled := True;
end else if (Args.Argument[0] = 'preferences') then
with PrefsMethods do
begin
AddMethod('OnPrefsCreate', OnPrefsCreate);
AddMethod('OnPrefsClose', OnPrefsClose);
AddMethod('UpdatePrefsXY', UpdatePrefsXY);
AddMethod('SetViewMode', SetViewMode);
AddMethod('ResetPlugins', ResetPlugins);
AddMethod('PrefsReset', PrefsReset);
AddMethod('PrefsApply', PrefsApply);
AddMethod('AddProfile', AddProfile);
AddMethod('DeleteProfile', DeleteProfile);
AddMethod('AddBotQuestion', AddBotQuestion);
AddMethod('DelBotQuestion', DelBotQuestion);
AddMethod('AddIgnoredContacts', AddIgnoredContacts);
AddMethod('AddIgnoredContactToSrv', AddIgnoredContactToSrv);
AddMethod('RemoveIgnoredContactFromSrv', RemoveIgnoredContactFromSrv);
AddMethod('DelIgnoredContact', DelIgnoredContact);
AddMethod('AddQuietContacts', AddQuietContacts);
AddMethod('DelQuietContact', DelQuietContact);
AddMethod('StoreProfile', StoreProfile);
AddMethod('StoreQuestion', StoreQuestion);
AddMethod('UpdateMainProfile', UpdateMainProfile);
AddMethod('UpdateQuestions', UpdateQuestions);
AddMethod('ViewContactInfo', ViewContactInfo);
AddMethod('OpenContactChat', OpenContactChat);
AddMethod('IsOnline', IsOnline);
AddMethod('ApplyTransparency', ApplyTransp);
AddMethod('ChooseColor', ChooseColor);
AddMethod('GetFont', GetFont);
AddMethod('SetFontProps', SetFontProps);
AddMethod('RefreshLangs', RefreshLangs);
AddMethod('ManageLangs', ManageLangs);
AddMethod('UserDicts', UserDicts);
AddMethod('SetMainSpellcheckLang', SetMainSpellcheckLang);
AddMethod('TestTips', TestTips);
AddMethod('GetCurrentAccountPath', GetCurrentAccountPath);
AddMethod('GetKeyName', GetKeyName);
AddMethod('HotkeySelect', HotkeySelect);
AddMethod('HotkeyDefault', HotkeyDefault);
AddMethod('HotkeySave', HotkeySave);
AddMethod('HotkeyDelete', HotkeyDelete);
AddMethod('UpdateEventTriggers', UpdateEventTriggers);
AddMethod('StoreEventTrigger', StoreEventTrigger);
AddMethod('UpdateDisabledEvents', UpdateDisabledEvents);
AddMethod('StoreDisabledEvents', StoreDisabledEvents);
AddMethod('SoundTest', SoundTest);
AddMethod('PlaySound', PlaySound);
AddMethod('TimeTest', TimeTest);
AddMethod('IsAudioPresent', IsAudioPresent);
AddMethod('BASSWarning', BASSWarning);
AddMethod('ReloadPlugins', ReloadPlugins);
AddMethod('OpenPluginPrefs', OpenPluginPrefs);
AddMethod('UpdateThemeEditProp', UpdateThemeEditProp);
AddMethod('AddThemeProp', AddThemeProp);
AddMethod('CheckPath', CheckPath);
AddMethod('GetXStatusMsg', GetXStatusMsg);
AddMethod('GetChatStyles', GetChatStyles);
AddMethod('GetMainStyles', GetMainStyles);
RegisterMethods(PrefsMethods, Args.ReturnSciterValue);
Args.Handled := True;
end;
end;
end.