From ed94f608dd20f979df505e09069d11979e859e56 Mon Sep 17 00:00:00 2001 From: MrShoor Date: Sat, 18 Jul 2015 12:55:36 -0700 Subject: [PATCH] initial --- .gitignore | 7 + CRules.rc | 6 + CRules.res | Bin 0 -> 2424 bytes Case.txt | 59 ++++ Lang_EnCaps.txt | 74 ++++ Lang_EnNoCaps.txt | 73 ++++ Lang_RuCaps.txt | 74 ++++ Lang_RuNoCaps.txt | 74 ++++ NiceTypes.pas | 10 + TNice.dpr | 20 ++ TNice.dproj | 117 ++++++ TNice.res | Bin 0 -> 68640 bytes Translit.txt | 62 ++++ agt_action_fail.ico | Bin 0 -> 2462 bytes agt_action_success.ico | Bin 0 -> 2462 bytes text_x_chdr.ico | Bin 0 -> 67646 bytes untEditor.dfm | 75 ++++ untEditor.pas | 250 +++++++++++++ untOptions.dfm | 539 ++++++++++++++++++++++++++++ untOptions.pas | 783 +++++++++++++++++++++++++++++++++++++++++ 20 files changed, 2223 insertions(+) create mode 100644 CRules.rc create mode 100644 CRules.res create mode 100644 Case.txt create mode 100644 Lang_EnCaps.txt create mode 100644 Lang_EnNoCaps.txt create mode 100644 Lang_RuCaps.txt create mode 100644 Lang_RuNoCaps.txt create mode 100644 NiceTypes.pas create mode 100644 TNice.dpr create mode 100644 TNice.dproj create mode 100644 TNice.res create mode 100644 Translit.txt create mode 100644 agt_action_fail.ico create mode 100644 agt_action_success.ico create mode 100644 text_x_chdr.ico create mode 100644 untEditor.dfm create mode 100644 untEditor.pas create mode 100644 untOptions.dfm create mode 100644 untOptions.pas diff --git a/.gitignore b/.gitignore index 8d5d458..e607174 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,10 @@ __history/ # Castalia statistics file *.stat +*.bak +*.compiled +*.o +*.or +*.properties +*.dbg +Article diff --git a/CRules.rc b/CRules.rc new file mode 100644 index 0000000..ae9c4c4 --- /dev/null +++ b/CRules.rc @@ -0,0 +1,6 @@ +Case RCData "Case.txt" +Lang_EnCaps RCData "Lang_EnCaps.txt" +Lang_EnNoCaps RCData "Lang_EnNoCaps.txt" +Lang_RuCaps RCData "Lang_RuCaps.txt" +Lang_RuNoCaps RCData "Lang_RuNoCaps.txt" +Translit RCData "Translit.txt" diff --git a/CRules.res b/CRules.res new file mode 100644 index 0000000000000000000000000000000000000000..eb1da9664826760f9fefb3220f19d0d376e8b369 GIT binary patch literal 2424 zcmb`IS5K5_7>2)1_UK8TAFyW|bY%|+dawr@;6V^kQ3Rx@XmCO7SP*Q8_Gywqx?jI}{PvUQ{qFwa_lp*L#OtI4*VY+J~- zhHT5pww`QD$+nYhyU4au<+`=0q**s9w~}%XDVLCP5h*v4auX>xka8_4m#KtWg-W3H zl6OCOcaZmc@~$KAD)Me7?++?LR;&_ieJaN-SS8&GRi47&B@AxEAO{A|V2}rc=PhFnA4vS1`zg!3!ANgu!DN zJc2(t=dpnolLd0#uIJJC&mrs&d0ZRF2t6l{a==#q+Wpr$4{TDb9=kUs>hD zs^HM9LSPkeKvrR}3WwEh0*=*xCUAI&*MXRJXo#Ue3_KvjARq<G}ut5t`*|Bh@<%;ODw*Zb%d1pu1 z=22>Y1BA!0-6d>y1=~eqyF_f4jO|jfT?)2~!FKW3E&rgG|7$WcL&Dk)7B zO|0gqp;xu^s*b+Y)0_q>+DJv4Xz_cB*-VvNXmKm;Y@?X%w64RV+{`*H$(>!6l<9u- z(D+`i*k`G3zx|f#COW`Q2U*w=þ +?=, +~=¸ +@=" +#=¹ +$=; +^=: +&=? +|=/ diff --git a/Lang_EnNoCaps.txt b/Lang_EnNoCaps.txt new file mode 100644 index 0000000..a65359e --- /dev/null +++ b/Lang_EnNoCaps.txt @@ -0,0 +1,73 @@ +Q=É +W=Ö +E=Ó +R=Ê +T=Å +Y=Í +U=à +I=Ø +O=Ù +P=Ç +{=Õ +}=Ú +A=Ô +S=Û +D= +F=À +G=Ï +H=Ð +J=Î +K=Ë +L=Ä +:=Æ +"=Ý +Z=ß +X=× +C=Ñ +V=Ì +B=È +N=Ò +M=Ü +<=Á +>=Þ +?=, +~=¨ +@=" +#=¹ +$=; +^=: +&=? +q=é +w=ö +e=ó +r=ê +t=å +y=í +u=ã +i=ø +o=ù +p=ç +[=õ +]=ú +a=ô +s=û +d=â +f=à +g=ï +h=ð +j=î +k=ë +l=ä +;=æ +'=ý +z=ÿ +x=÷ +c=ñ +v=ì +b=è +n=ò +m=ü +,=á +.=þ +/=. +`=¸ \ No newline at end of file diff --git a/Lang_RuCaps.txt b/Lang_RuCaps.txt new file mode 100644 index 0000000..fa05d05 --- /dev/null +++ b/Lang_RuCaps.txt @@ -0,0 +1,74 @@ +é=q +ö=w +ó=e +ê=r +å=t +í=y +ã=u +ø=i +ù=o +ç=p +õ={ +ú=} +/=| +ô=a +û=s +â=d +à=f +ï=g +ð=h +î=j +ë=k +ä=l +æ=: +ý=" +ÿ=z +÷=x +ñ=c +ì=v +è=b +ò=n +ü=m +á=< +þ=> +,=? +¸=~ +"=@ +¹=# +;=$ +:=^ +?=& +É=Q +Ö=W +Ó=E +Ê=R +Å=T +Í=Y +Ã=U +Ø=I +Ù=O +Ç=P +Õ=[ +Ú=] +Ô=A +Û=S +Â=D +À=F +Ï=G +Ð=H +Î=J +Ë=K +Ä=L +Æ=; +Ý=' +ß=Z +×=X +Ñ=C +Ì=V +È=B +Ò=N +Ü=M +Á=, +Þ=. +.=/ +¨=` \ No newline at end of file diff --git a/Lang_RuNoCaps.txt b/Lang_RuNoCaps.txt new file mode 100644 index 0000000..1a4ad5e --- /dev/null +++ b/Lang_RuNoCaps.txt @@ -0,0 +1,74 @@ +É=Q +Ö=W +Ó=E +Ê=R +Å=T +Í=Y +Ã=U +Ø=I +Ù=O +Ç=P +Õ={ +Ú=} +/=| +Ô=A +Û=S +Â=D +À=F +Ï=G +Ð=H +Î=J +Ë=K +Ä=L +Æ=: +Ý=" +ß=Z +×=X +Ñ=C +Ì=V +È=B +Ò=N +Ü=M +Á=< +Þ=> +,=? +¨=~ +"=@ +¹=# +;=$ +:=^ +?=& +é=q +ö=w +ó=e +ê=r +å=t +í=y +ã=u +ø=i +ù=o +ç=p +õ=[ +ú=] +ô=a +û=s +â=d +à=f +ï=g +ð=h +î=j +ë=k +ä=l +æ=; +ý=' +ÿ=z +÷=x +ñ=c +ì=v +è=b +ò=n +ü=m +á=, +þ=. +.=/ +¸=` \ No newline at end of file diff --git a/NiceTypes.pas b/NiceTypes.pas new file mode 100644 index 0000000..a3294a7 --- /dev/null +++ b/NiceTypes.pas @@ -0,0 +1,10 @@ +unit NiceTypes; + +interface + +type + TFormatAction = (faSwitchLang, faSwitchReg, faTranslit, faCodeVertical); + +implementation + +end. diff --git a/TNice.dpr b/TNice.dpr new file mode 100644 index 0000000..bc36794 --- /dev/null +++ b/TNice.dpr @@ -0,0 +1,20 @@ +program TNice; + +{$R 'CRules.res' 'CRules.rc'} + +uses + Forms, + untEditor in 'untEditor.pas' {frmEditor}, + untOptions in 'untOptions.pas' {frmMain}, + NiceTypes in 'NiceTypes.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.ShowMainForm := False; + Application.MainFormOnTaskbar := True; + Application.CreateForm(TfrmMain, frmMain); + Application.CreateForm(TfrmEditor, frmEditor); + Application.Run; +end. diff --git a/TNice.dproj b/TNice.dproj new file mode 100644 index 0000000..7d9838d --- /dev/null +++ b/TNice.dproj @@ -0,0 +1,117 @@ + + + {55D456C6-01AF-40F2-914D-AACE40F77644} + 12.0 + TNice.dpr + Debug + DCC32 + + + true + + + true + Base + true + + + true + Base + true + + + true + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) + TNice.exe + 00400000 + x86 + + + false + RELEASE;$(DCC_Define) + 0 + false + + + DEBUG;$(DCC_Define) + + + + MainSource + + + RC + RC +
CRules.res
+
+ +
frmEditor
+
+ +
frmMain
+
+ + + + + + + + + Base + + + Cfg_2 + Base + + + Cfg_1 + Base + +
+ + + Delphi.Personality.12 + + + + + TNice.dpr + + + False + True + False + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + 12 + +
diff --git a/TNice.res b/TNice.res new file mode 100644 index 0000000000000000000000000000000000000000..608c7c590b3c258fd3bea403909520bb79bbdefb GIT binary patch literal 68640 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 A8vp6eolP+6F>)k~Abhnl>arN|PpSNE1rZW}2y4 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 literal 0 HcmV?d00001 diff --git a/untEditor.dfm b/untEditor.dfm new file mode 100644 index 0000000..8b3cca6 --- /dev/null +++ b/untEditor.dfm @@ -0,0 +1,75 @@ +object frmEditor: TfrmEditor + Left = 0 + Top = 0 + BorderIcons = [] + BorderStyle = bsNone + Caption = 'frmEditor' + ClientHeight = 256 + ClientWidth = 888 + Color = clBtnFace + DoubleBuffered = True + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + FormStyle = fsStayOnTop + OldCreateOrder = False + OnCreate = FormCreate + OnDestroy = FormDestroy + OnDeactivate = FormDeactivate + OnShow = FormShow + DesignSize = ( + 888 + 256) + PixelsPerInch = 96 + TextHeight = 13 + object mmCode: TMemo + Left = 0 + Top = 0 + Width = 742 + Height = 256 + Anchors = [akLeft, akTop, akRight, akBottom] + Font.Charset = RUSSIAN_CHARSET + Font.Color = clWindowText + Font.Height = -15 + Font.Name = 'Courier New' + Font.Style = [] + Lines.Strings = ( + 'mmCode') + ParentFont = False + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 0 + WordWrap = False + end + object mmSeparators: TMemo + Left = 741 + Top = 0 + Width = 147 + Height = 256 + Anchors = [akTop, akRight, akBottom] + Font.Charset = RUSSIAN_CHARSET + Font.Color = clWindowText + Font.Height = -15 + Font.Name = 'Courier New' + Font.Style = [fsUnderline] + ParentFont = False + ScrollBars = ssBoth + TabOrder = 1 + WordWrap = False + OnChange = mmSeparatorsChange + OnKeyDown = mmSeparatorsKeyDown + end + object ApplicationEvents1: TApplicationEvents + OnDeactivate = ApplicationEvents1Deactivate + Left = 432 + Top = 112 + end + object Timer1: TTimer + Interval = 100 + OnTimer = Timer1Timer + Left = 184 + Top = 72 + end +end diff --git a/untEditor.pas b/untEditor.pas new file mode 100644 index 0000000..6d66753 --- /dev/null +++ b/untEditor.pas @@ -0,0 +1,250 @@ +unit untEditor; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, AppEvnts, ExtCtrls; + +type + TfrmEditor = class(TForm) + mmCode: TMemo; + mmSeparators: TMemo; + ApplicationEvents1: TApplicationEvents; + Timer1: TTimer; + procedure FormCreate(Sender: TObject); + procedure mmSeparatorsChange(Sender: TObject); + procedure FormDeactivate(Sender: TObject); + procedure ApplicationEvents1Deactivate(Sender: TObject); + procedure Timer1Timer(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure mmSeparatorsKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + private + FSrc: TStringList; + FSourceStr: string; + FSrcWnd: HWND; + FPrevSeparators: TStringList; + procedure DoFormat(const Src, Sep: TStrings; const Dest: TStrings); + protected + procedure CreateParams(var Params: TCreateParams); override; + procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING; + public + procedure SetOptions(const FontName: string; FontSize: Integer; FontColor: TColor; BackColor: TColor); + + property SrcWnd: HWND read FSrcWnd write FSrcWnd; + property SourceStr: string read FSourceStr write FSourceStr; + function ForamtedStr: string; + end; + +var + frmEditor: TfrmEditor; + +implementation + +uses Math; + +{$R *.dfm} + +{ TfrmEditor } + +procedure TfrmEditor.ApplicationEvents1Deactivate(Sender: TObject); +begin + ModalResult := mrCancel; +end; + +procedure TfrmEditor.CreateParams(var Params: TCreateParams); +begin + inherited; + Params.Style := Params.Style or WS_THICKFRAME; +end; + +procedure TfrmEditor.DoFormat(const Src, Sep, Dest: TStrings); + function GetSpaces(const n: Integer): string; + var i: Integer; + begin + if n = 0 then + begin + Result := ''; + Exit; + end; + SetLength(Result, n); + for i := 1 to n do + Result[i] := ' '; + end; + function SplitStr(const src, separator: string; out before, after: string): Boolean; + var n: Integer; + begin + n := Pos(separator, src); + if n = 0 then + begin + Result := False; + Exit; + end; + before := Copy(src, 1, n - 1); + n := n + Length(separator); + after := Copy(src, n, Length(src) - n + 1); + Result := True; + end; +var i, j, n, maxn: Integer; + before, after: string; + SrcCopy: TStringList; +begin + Dest.Clear; + SrcCopy := TStringList.Create; + try + SrcCopy.AddStrings(Src); + for i := 0 to SrcCopy.Count - 1 do Dest.Add(''); + + for j := 0 to Sep.Count - 1 do + begin + maxn := 0; + for i := 0 to SrcCopy.Count - 1 do + begin + n := Pos(Sep.Strings[j], SrcCopy.Strings[i]); + maxn := Max(maxn, n); + end; + + if maxn > 0 then + begin + Dec(maxn); + for i := 0 to SrcCopy.Count - 1 do + begin + if SplitStr(SrcCopy.Strings[i], Sep.Strings[j], before, after) then + begin + SrcCopy.Strings[i] := after; + before := before + GetSpaces(maxn - Length(before)) + Sep.Strings[j]; + Dest.Strings[i] := Dest.Strings[i] + before; + end + else + begin + Dest.Strings[i] := Dest.Strings[i] + SrcCopy.Strings[i]; + SrcCopy.Strings[i] := ''; + end; + end; + end; + + //debug output code +{ + AllocConsole; + WriteLn('Sep: ', Sep.Strings[j]); + WriteLn('Src'); + for i := 0 to SrcCopy.Count - 1 do + Writeln(SrcCopy.Strings[i], '#'); + WriteLn('Dest'); + for i := 0 to Dest.Count - 1 do + Writeln(Dest.Strings[i], '#'); + WriteLn('--------------'); +} + end; + for i := 0 to SrcCopy.Count - 1 do + Dest.Strings[i] := Dest.Strings[i] + SrcCopy.Strings[i]; + finally + FreeAndNil(SrcCopy); + end; +end; + +function TfrmEditor.ForamtedStr: string; +var HasBreak: Boolean; +begin + HasBreak := False; + if Length(FSourceStr)>0 then + begin + HasBreak := (FSourceStr[Length(FSourceStr)] = #13); + if not HasBreak and (Length(FSourceStr)>1) then + HasBreak := (FSourceStr[Length(FSourceStr)-1] = #13) or (FSourceStr[Length(FSourceStr)] = #10); + end; + Result := mmCode.Text; + if not HasBreak then + if Length(Result) > 1 then + if (Result[Length(Result)-1] = #13) and (Result[Length(Result)] = #10) then + Delete(Result, Length(Result) - 1, 2); +end; + +procedure TfrmEditor.FormCreate(Sender: TObject); +begin + FPrevSeparators := TStringList.Create; + FSrc := TStringList.Create; +end; + +procedure TfrmEditor.FormDeactivate(Sender: TObject); +begin + ModalResult := mrCancel; +end; + +procedure TfrmEditor.FormDestroy(Sender: TObject); +begin + FreeAndNil(FPrevSeparators); + FreeAndNil(FSrc); +end; + +procedure TfrmEditor.FormShow(Sender: TObject); +begin + FSrc.Text := FSourceStr; + mmSeparators.Lines.BeginUpdate; + try + mmSeparators.Lines.Clear; + mmSeparators.Lines.AddStrings(FPrevSeparators); + finally + mmSeparators.Lines.EndUpdate; + end; + mmSeparators.SetFocus; + mmSeparators.SelectAll; + DoFormat(FSrc, mmSeparators.Lines, mmCode.Lines); + Left := -1; +end; + +procedure TfrmEditor.mmSeparatorsChange(Sender: TObject); +begin + mmCode.Lines.BeginUpdate; + try + DoFormat(FSrc, mmSeparators.Lines, mmCode.Lines); + finally + mmCode.Lines.EndUpdate; + end; +end; + +procedure TfrmEditor.mmSeparatorsKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin + if (Key = VK_RETURN) and (ssCtrl in Shift) then + begin + FPrevSeparators.Clear; + FPrevSeparators.AddStrings(mmSeparators.Lines); + ModalResult := mrOk; + end; + if (Key = VK_ESCAPE) then + ModalResult := mrCancel; +end; + +procedure TfrmEditor.SetOptions(const FontName: string; FontSize: Integer; + FontColor, BackColor: TColor); +begin + mmCode.Font.Name := FontName; + mmCode.Font.Size := FontSize; + mmCode.Font.Color := FontColor; + mmCode.Color := BackColor; + + mmSeparators.Font.Name := FontName; + mmSeparators.Font.Size := FontSize; + mmSeparators.Font.Color := FontColor; + mmSeparators.Color := BackColor; +end; + +procedure TfrmEditor.Timer1Timer(Sender: TObject); +begin + if Visible then + SetForegroundWindow(Handle); +end; + +procedure TfrmEditor.WMWindowPosChanging(var Message: TWMWindowPosChanging); +var SrcRct: TRect; +begin + inherited; + GetWindowRect(FSrcWnd, SrcRct); + Message.WindowPos.x := SrcRct.Right - Message.WindowPos.cx; + Message.WindowPos.y := SrcRct.Bottom - Message.WindowPos.cy; +end; + +end. diff --git a/untOptions.dfm b/untOptions.dfm new file mode 100644 index 0000000..8d97ffd --- /dev/null +++ b/untOptions.dfm @@ -0,0 +1,539 @@ +object frmMain: TfrmMain + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu] + BorderStyle = bsSingle + Caption = 'TNice ;)' + ClientHeight = 207 + ClientWidth = 662 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + KeyPreview = True + OldCreateOrder = False + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 13 + object GroupBox1: TGroupBox + Left = 8 + Top = 8 + Width = 273 + Height = 161 + Caption = 'Hotkeys' + TabOrder = 0 + object Label1: TLabel + Left = 16 + Top = 24 + Width = 82 + Height = 13 + Caption = 'Switch language:' + end + object Label2: TLabel + Left = 16 + Top = 59 + Width = 60 + Height = 13 + Caption = 'Switch case:' + end + object Label3: TLabel + Left = 16 + Top = 92 + Width = 52 + Height = 13 + Caption = 'To translit:' + end + object Label4: TLabel + Left = 16 + Top = 127 + Width = 64 + Height = 13 + Caption = 'Code aligner:' + end + object imgSwitchLang: TImage + Left = 231 + Top = 18 + Width = 24 + Height = 24 + end + object imgSwitchReg: TImage + Left = 231 + Top = 53 + Width = 24 + Height = 24 + end + object imgTranslit: TImage + Left = 231 + Top = 86 + Width = 24 + Height = 24 + end + object imgCodeAligner: TImage + Left = 231 + Top = 121 + Width = 24 + Height = 24 + end + object hkSwitchLang: THotKey + Left = 104 + Top = 21 + Width = 121 + Height = 19 + HotKey = 8257 + InvalidKeys = [hcNone, hcAlt, hcShiftAlt, hcCtrlAlt] + Modifiers = [hkShift] + TabOrder = 0 + OnChange = hkSwitchLangChange + end + object hkSwitchReg: THotKey + Left = 104 + Top = 56 + Width = 121 + Height = 19 + HotKey = 32833 + InvalidKeys = [hcNone, hcAlt, hcShiftAlt, hcCtrlAlt] + TabOrder = 1 + OnChange = hkSwitchRegChange + end + object hkCodeAligner: THotKey + Left = 104 + Top = 124 + Width = 121 + Height = 19 + HotKey = 32833 + InvalidKeys = [hcNone, hcAlt, hcShiftAlt, hcCtrlAlt] + TabOrder = 2 + OnChange = hkCodeAlignerChange + end + object hkTranslit: THotKey + Left = 104 + Top = 89 + Width = 121 + Height = 19 + HotKey = 32833 + InvalidKeys = [hcNone, hcAlt, hcShiftAlt, hcCtrlAlt] + TabOrder = 3 + OnChange = hkTranslitChange + end + end + object GroupBox2: TGroupBox + Left = 287 + Top = 7 + Width = 370 + Height = 161 + Caption = 'Code aligner' + TabOrder = 1 + object Label5: TLabel + Left = 11 + Top = 80 + Width = 52 + Height = 13 + Caption = 'Font color:' + end + object Label6: TLabel + Left = 163 + Top = 80 + Width = 86 + Height = 13 + Caption = 'Background color:' + end + object imgFontColor: TImage + Left = 11 + Top = 99 + Width = 102 + Height = 29 + Stretch = True + OnClick = imgFontColorClick + end + object imgBackColor: TImage + Left = 163 + Top = 99 + Width = 102 + Height = 29 + Stretch = True + OnClick = imgBackColorClick + end + object cbFont: TComboBox + Left = 11 + Top = 15 + Width = 263 + Height = 22 + Style = csOwnerDrawFixed + TabOrder = 0 + OnDrawItem = cbFontDrawItem + end + end + object Button1: TButton + Left = 582 + Top = 174 + Width = 75 + Height = 25 + Caption = 'Ok' + TabOrder = 2 + OnClick = Button1Click + end + object Button3: TButton + Left = 8 + Top = 176 + Width = 41 + Height = 25 + Caption = 'Exit' + TabOrder = 3 + OnClick = Button3Click + end + object edFontSize: TSpinEdit + Left = 567 + Top = 22 + Width = 81 + Height = 22 + AutoSize = False + MaxValue = 30 + MinValue = 8 + TabOrder = 4 + Value = 11 + OnChange = edFontSizeChange + end + object Button2: TButton + Left = 64 + Top = 176 + Width = 75 + Height = 25 + Caption = 'Default' + TabOrder = 5 + OnClick = Button2Click + end + object imgHKList: TImageList + Height = 24 + Width = 24 + Left = 208 + Top = 160 + Bitmap = { + 494C010102000800300018001800FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000600000001800000001002000000000000024 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000FCFCFC03C9C9CE369090A66F7A7A + 98867676958A8989A076BCBCC243EFEFF0100000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000F7F7F80887879F780F116FF515169AFF2629BEFF3135 + CEFF3236CEFF272AC0FF14179DFF07076CFF6E6E8A92DDDDE122000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000C3C3D23C141569F01317B3FF282EEAFF3F47FBFF515AFFFF5C64 + FFFF5D66FFFF545DFFFF424AFCFF2A31EEFF1317BAFF050769FF9F9FA9600000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000C4F2C84B4A964CC8EDFFEF1F0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000AAAAB7550A0D7FFF1721DFFF1922F4FF1420E2FF242DE5FF343EF2FF3E45 + F7FF3F47F9FF3D44F5FF2F38EBFF1D26E5FF1620EFFF151FE0FF090C87FF8080 + 927F000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000C2EEC548329536ED62D168FF419244DDF4FF + F51B000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000CBCB + D934090D7DFF111DE6FF0912E7FF0810C4FF1821C0FF2026BAFF181FB2FF181D + B8FF1E20BBFF2427BFFF2C30CAFF252CCAFF0C14C7FF060FDEFF0E18E4FF080B + 87FFA0A0AB5F0000000000000000000000000000000000000000000000000000 + 00000000000000000000BDE8C14829932EEC70EE7AFF90FF9CFF5FE168FF4091 + 42DDEFFEF01C0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000001416 + 69F11118D2FF030ADAFF0007B4FF060FBBFF3135D2FF242199F6C4C4DC3BDDDD + ED22D9D9EB26B7B7D8487171AE94212399FF292FBBFF0A11BDFF0006CFFF0C14 + D2FF050869FFDEDEE12100000000000000000000000000000000000000000000 + 000000000000BAE5BE46278D2CEA56E762FF63FF72FF63FE71FF73FF82FF4DDF + 57FF368F3ADCEBFCED1B00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000009A9BBA650E15 + A2FF070ED3FF0002A0FF0003ADFF0109BAFF1017C7FF0809C9FFA0A0D25F0000 + 0000000000000000000000000000CCCCDE33202280F3242AA7FF070AA8FF0309 + C5FF0B11AAFF6162839E00000000000000000000000000000000000000000000 + 0000B8DFBB47218828EC4ADC56FF4EF45EFF62F370FF6FF77CFF57F866FF61FF + 70FF44DD4EFF308C34DDE9FAEB1B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000001B1F73E90F16 + C7FF00019AFF0E128CFF1D23A8FF030AAFFF0004B1FF010AC8FF0206C0FF8A8A + AD7500000000000000000000000000000000DFDFE9201B1F75FF172193FF0003 + 95FF090FBCFF05096BFFEBEBEC1400000000000000000000000000000000B7D8 + BA481F8628EC39D047FF42E251FF6CE877FF87EE90FF84EF8EFF6CEF79FF4DEE + 5CFF57F767FF41D94BFF2D8531DDE7F8E91B0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E7E7EF180A1081FF080D + B1FF000171FF101587FF2C3182F0030B82FF0006A6FF0009AAFF020ABAFF0409 + ADFF8B8BAA74000000000000000000000000000000008687AF7A161F72FF070A + 75FF02069EFF080E89FFB0B0BB4F000000000000000000000000BCD6BE492E82 + 35ED27BF36FF44D552FF80E289FF8EE696FF8AE893FFC7F6CCFF7EE888FF66E7 + 72FF43E452FF4CED5CFF3CCA46FF287B2DDDE4F6E61C00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000AFAFCD500F1598FF0206 + 88FF010560FF030775FFDCDCE7249598C06C00088AFF0008A1FF0007A6FF040B + B0FF080E9AFF8687A179000000000000000000000000D9D9E82611175DFF0B11 + 5CFF000375FF080E8CFF767795890000000000000000C4DEC747549559EB28B4 + 36FF55CE61FF94DF9BFF92E09AFF8FE297FFDDF5DFFF429946FFC4F3C8FF7AE2 + 84FF5DDF6AFF39DA48FF42E552FF33B63DFF267329DCE4F3E51B000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000008C8DB97311169CFF0002 + 66FF03085BFF111379F200000000000000007B7FBF84050CA3FF020AB5FF0008 + BBFF060EBEFF0B138AFF878899780000000000000000000000001B1F65EE0B11 + 65FF000373FF090E96FF595A87A600000000DDECDD224E9252EC51BC5BFF75CF + 7EFFA5DFABFF97DC9DFF97DD9DFFDFF5E1FF299231E5C8ECCB43479F4DFCBCEE + C1FF77DC80FF56D763FF2ECF3DFF37DB46FF2BA936FF236A26DDE4F0E51B0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000008889B9771016A2FF0002 + 7FFF060B83FF181B86EEFDFDFD0200000000000000007D7FD1830910BBFF030B + BEFF0007C1FF0811C0FF0F1781FF8789937800000000000000001E2169E8080E + 79FF01048FFF0A0EAFFF56588BA900000000F1F7F10E66A66ABFA5D8ABFFBADF + BEFFA2D8A7FFA3DAA8FFE1F4E3FF2CA136E3D4F0D72C00000000D0EFD3322993 + 30FDBCEBC1FF71D67BFF4FCE5BFF22C331FF2BCF3AFF249C2EFF236226DDE4EC + E41B000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000A4A4CE5B1116B6FF0003 + 9EFF090D94FF0F128BFFDCDCE523000000000000000000000000797BDF870E14 + C9FF050EC3FF0107C5FF0B12C4FF131D7DFF989AAB67F4F4F60B04085AFF030A + 87FF00039DFF080EB0FF73749D8C0000000000000000F2F9F30D53A85ABCBAE2 + BFFFC2DEC7FFE4F3E5FF2D9C34E1D2EED42D000000000000000000000000CEEE + D132268E2EFDBAE8BEFF6CCF75FF47C453FF16B725FF1EC22EFF1D9829FF235E + 26DDE3EAE31C0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000E0E0EF1F1219ABFF1013 + B6FF13179DFF1D20ACFF8F8FB670000000000000000000000000000000007C7C + F085171EDAFF121DC9FF0B12CAFF1D23C9FF1E2580FF3D3F63CD0C136DFF0B11 + A1FF0F14B6FF0E15ADFFADADC352000000000000000000000000F2F9F20D44A7 + 4CC0C8E8CBFF37A13FE4D0EDD12F000000000000000000000000000000000000 + 0000CBECCE3422892AFDB7E4BCFF67C870FF3EBB49FF09AA18FF10B620FF1691 + 22FF255F29DBE5ECE51A00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000010159FFF3236 + D8FF282BB0FF3034C2FF0F1185FDEBEBED140000000000000000000000000000 + 00007F7EF6842A2DE7FF3036D6FF2228D1FF343BCFFF5056A5FF3238A7FF2126 + B7FF3035D4FF12179BFFEBEBF01400000000000000000000000000000000EFF9 + F01068B26C9ACEEDD13200000000000000000000000000000000000000000000 + 000000000000CCEACD33218329FDB8DFBCFF65BD6FFF38AF44FF009B0DFF04A6 + 12FF148E1FFF386C3ADCE5EDE61B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000008787C87B3C44 + D9FF4649DBFF474ACBFF363AC7FF2E2F81D3EBEBEE1400000000000000000000 + 0000000000009190FE753B3EE6FF464CE4FF3B44DCFF4B50DFFF4347D2FF4448 + DAFF3B43DEFF585AA5AB00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000CCE9CE3323822BFDBADABDFF68B16FFF399F43FF0085 + 0AFF008D08FF3A9B44FF3E6E40D4EFF3EF100000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000FDFDFE022025 + B2FF6369F7FF5C60E6FF6064E6FF3E45C9FF121377F69B9BBD64E5E5E91A0000 + 000000000000F2F2F80D3233A9DA3D3FB7FF5E63EBFF4E53E5FF595FE7FF636A + F9FF2328B0FFDADAE72500000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000CDEBCE3225822CFCBBD7BDFF6BAA71FF3B92 + 44FF04730AFF87BB8DFF346E38D1EFF3EF100000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000B6B7 + DF493C45D3FF8288FCFF787DF7FF767DF6FF5E62E0FF2F33A1FF101372FF1E22 + 6BE41C2156E50B0F4EFE30348DFF4D50C7FF7479F8FF757AF7FF8289FDFF4248 + D6FF8E8FC8720000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000CBEACC3426832DFDBCD6BFFF6FA8 + 74FFB1D2B4FF2D7833D3E5EDE51A000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00008C8DD075484EDFFF949AFEFF989DFDFF9195FCFF898EFAFF777CEDFF6B70 + DCFF696FDAFF7178E6FF8388F6FF8A8FFAFF9A9EFCFF9A9FFFFF4C52E2FF6768 + BC9C000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000CCEBCD3329822FFDC6DE + C8FF5A9E5FD1E5EFE51A00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000A6A6DC5A3136D0FF898EFCFFB2B7FFFFBABDFFFFB7BBFEFFB4B9 + FEFFB5B9FEFFB8BBFFFFBBBFFFFFB7BBFFFF8F95FCFF363AD0FF8A8BCE770000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000CBE9CD344D9C + 53C1E5F2E61B0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000E9E9F6166465CDA3383DD9FF464AD3FF8C91F5FFA9AE + FEFFA9AEFEFF9DA2FDFF8B90F5FF3C44DCFF4F51C5BAD5D5EE2A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000D7D7EC28AAAAE2576C6CD5993C3E + C0DC3B3DC0DD4748C1CF6364C6B1CECEE931EAEAF51500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000060000000180000000100010000000000200100000000000000000000 + 000000000000000000000000FFFFFF00FFFFFFFFFFFF000000000000FF00FFFF + FFFF000000000000FC003FFFFFFF000000000000F8001FFF1FFF000000000000 + F0000FFE0FFF000000000000E00007FC07FF000000000000E00003F803FF0000 + 00000000C01E03F001FF000000000000C00F01E000FF000000000000800781C0 + 007F00000000000080038180003F0000000000008301C100001F000000000000 + 8180C100400F00000000000081C00180E00700000000000081E001C1F0030000 + 00000000C0F001E3F801000000000000C07803FFFC00000000000000C01803FF + FE00000000000000E00007FFFF01000000000000F0000FFFFF83000000000000 + F8001FFFFFC7000000000000FC003FFFFFFF000000000000FF007FFFFFFF0000 + 00000000FFFFFFFFFFFF00000000000000000000000000000000000000000000 + 000000000000} + end + object TrayIcon1: TTrayIcon + PopupMenu = PopupMenu1 + Visible = True + OnClick = TrayIcon1Click + Left = 280 + Top = 160 + end + object PopupMenu1: TPopupMenu + Left = 344 + Top = 160 + object Ext1: TMenuItem + Caption = 'Exit' + OnClick = Ext1Click + end + end + object ColorDialog1: TColorDialog + Left = 576 + Top = 88 + end +end diff --git a/untOptions.pas b/untOptions.pas new file mode 100644 index 0000000..c114e35 --- /dev/null +++ b/untOptions.pas @@ -0,0 +1,783 @@ +unit untOptions; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ComCtrls, StdCtrls, ExtCtrls, NiceTypes, ImgList, Generics.Collections, + Spin, Menus, Registry; + +const + LAYOUT_RU = $419; + LAYOUT_EN = $409; + + LAYOUT_RU_STR = '00000419'; + LAYOUT_EN_STR = '00000409'; + + REG_Key = 'Software\TNice'; + REG_Value_FontName = 'FontName'; + REG_Value_FontSize = 'FontSize'; + REG_Value_FontColor = 'FontColor'; + REG_Value_BackColor = 'BackColor'; + REG_Value_EditorW = 'CodeEditorWidth'; + REG_Value_EditorH = 'CodeEditorHeight'; + REG_Value_Hotkey_SLang = 'HK_SwitchLang'; + REG_Value_Modifier_SLang = 'Mod_SwitchLang'; + REG_Value_Hotkey_SCase = 'HK_SwitchCase'; + REG_Value_Modifier_SCase = 'Mod_SwitchCase'; + REG_Value_Hotkey_Trans = 'HK_Trans'; + REG_Value_Modifier_Trans = 'Mod_Trans'; + REG_Value_Hotkey_CodeVAlign = 'HK_CodeVAlign'; + REG_Value_Modifier_CodeVAlign = 'Mod_CodeVAlign'; + + +type + TCurrentLang = (clEn, clRu); + TCapsState = (csOff, csOn); + + TfrmMain = class(TForm) + GroupBox1: TGroupBox; + hkSwitchLang: THotKey; + Label1: TLabel; + Label2: TLabel; + hkSwitchReg: THotKey; + Label3: TLabel; + hkCodeAligner: THotKey; + Label4: TLabel; + hkTranslit: THotKey; + GroupBox2: TGroupBox; + Button1: TButton; + Button3: TButton; + imgSwitchLang: TImage; + imgSwitchReg: TImage; + imgTranslit: TImage; + imgCodeAligner: TImage; + imgHKList: TImageList; + TrayIcon1: TTrayIcon; + edFontSize: TSpinEdit; + PopupMenu1: TPopupMenu; + Ext1: TMenuItem; + cbFont: TComboBox; + Label5: TLabel; + Label6: TLabel; + imgFontColor: TImage; + imgBackColor: TImage; + ColorDialog1: TColorDialog; + Button2: TButton; + procedure FormCreate(Sender: TObject); + procedure hkSwitchLangChange(Sender: TObject); + procedure hkSwitchRegChange(Sender: TObject); + procedure hkTranslitChange(Sender: TObject); + procedure hkCodeAlignerChange(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure Button1Click(Sender: TObject); + procedure Button3Click(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure TrayIcon1Click(Sender: TObject); + procedure Ext1Click(Sender: TObject); + procedure cbFontDrawItem(Control: TWinControl; Index: Integer; + Rect: TRect; State: TOwnerDrawState); + procedure edFontSizeChange(Sender: TObject); + procedure imgFontColorClick(Sender: TObject); + procedure imgBackColorClick(Sender: TObject); + procedure Button2Click(Sender: TObject); + private + FIsExit: Boolean; + + FLang : array [TCurrentLang, TCapsState] of TDictionary; + FCaps : TDictionary; + FTrans : TDictionary; + + FNewEditorW : Integer; + FNewEditorH : Integer; + + FRegistredHotkey: array [TFormatAction] of Boolean; + procedure RegHK(const Action: TFormatAction; const Key: TShortCut; const Modifiers: THKModifiers); + + procedure SendCtrlKey(const VKey: Word); + + procedure DoSwitchLayout(h: HWND); + function CanSwitchLayoutNow(h: HWND; out ActiveLayout: TCurrentLang): Boolean; + + function SwitchSymbols(const Dic: TDictionary; const Src: string): string; + function ReplaceSymbols(const Dic: TDictionary; const Src: string): string; + function DoVerticalFormat(const SrcWnd: HWND; const Src: string; out FormatedStr: string): boolean; + + procedure ProcessBuffer(const action: TFormatAction); + procedure WMHotkey(var msg: TWMHotKey); message WM_HOTKEY; + + procedure SetColor(img: TImage; color: TColor); + function GetColor(img: TImage): TColor; + public + procedure SetDefaultSettings; + procedure SaveSettings; + procedure LoadSettings; + end; + +var + frmMain: TfrmMain; + +implementation + +uses + Clipbrd, untEditor, Math; + +const HK_Base = 17; +const HK_ID: array [TFormatAction] of Cardinal = (HK_Base + 1, //faSwitchLang + HK_Base + 2, //faSwitchReg + HK_Base + 3, //faTranslit + HK_Base + 4);//faCodeVertical +const HK_IconIndex: array [Boolean] of Integer = (0, 1); + +function EnumFontProc(var LogFont: TEnumLogFontEx; var Metrics: TEnumTextMetricW; FontType: Cardinal; Strings: TStrings): Integer; stdcall; +begin + if (LogFont.elfLogFont.lfPitchAndFamily and FF_MODERN = FF_MODERN) then + Strings.Add(LogFont.elfFullName); + Result := 1; +end; + +procedure GetFontList(str: TStrings); +var sl: TStringList; + DC: HDC; + lf: TLogFont; +begin + sl := nil; + if str = nil then Exit; + str.Clear; + DC := GetDC(0); + try + sl := TStringList.Create; + sl.Sorted := True; + sl.Duplicates := dupIgnore; + + FillChar(lf, SizeOf(lf), 0); + lf.lfPitchAndFamily := DEFAULT_PITCH or FF_MODERN; + EnumFontFamiliesEx(DC, lf, @EnumFontProc, Integer(sl), 0); + + str.Assign(sl); + finally + FreeAndNil(sl); + ReleaseDC(0, DC); + end; +end; + +{$R *.dfm} + +procedure TfrmMain.Button1Click(Sender: TObject); +begin + Hide; +end; + +procedure TfrmMain.Button2Click(Sender: TObject); +begin + SetDefaultSettings; +end; + +procedure TfrmMain.Button3Click(Sender: TObject); +begin + FIsExit := True; + Close; +end; + +function TfrmMain.CanSwitchLayoutNow(h: HWND; out ActiveLayout: TCurrentLang): Boolean; +var layouts: array of HKL; +// layoutname: array [0..KL_NAMELENGTH-1] of WideChar; + i:integer; + hasEn, hasRu: boolean; + currentLayout: HKL; +begin +// SetLength(layouts, 1); + SetLength(layouts, GetKeyboardLayoutList(0, layouts[0])); + GetKeyboardLayoutList(length(layouts),layouts[0]); + + hasEn := False; + hasRu := False; + for i := 0 to Length(layouts) - 1 do + begin + hasEn := hasEn or (Word(layouts[i]) = LAYOUT_EN); + hasRu := hasRu or (Word(layouts[i]) = LAYOUT_RU); + end; + + currentLayout := GetKeyboardLayout(GetWindowThreadProcessId(h)); + if not (hasEn and hasRu) then Exit(False); + if (Word(currentLayout) = LAYOUT_EN) then + begin + ActiveLayout := clEn; + Exit(True); + end; + if (Word(currentLayout) = LAYOUT_RU) then + begin + ActiveLayout := clRu; + Exit(True); + end; + Result := False; +end; + +procedure TfrmMain.cbFontDrawItem(Control: TWinControl; Index: Integer; + Rect: TRect; State: TOwnerDrawState); +var s: string; +begin + if Control = cbFont then + begin + cbFont.Canvas.Brush.Style := bsSolid; + if odSelected in State then + cbFont.Canvas.Brush.Color := clHighlight + else + cbFont.Canvas.Brush.Color := clWindow; + cbFont.Canvas.FillRect(Rect); + + s := cbFont.Items[Index]; + cbFont.Canvas.Font.Name := s; + cbFont.Canvas.Font.Size := edFontSize.Value; + cbFont.Canvas.TextRect(Rect, s, [tfSingleLine, tfVerticalCenter]); + end; +end; + +procedure TfrmMain.DoSwitchLayout(h: HWND); +const KLF_SETFORPROCESS = $00000100; +var currentLayout: HKL; +begin + currentLayout := GetKeyboardLayout(GetWindowThreadProcessId(h)); + if Word(currentLayout) = LAYOUT_EN then + begin + SendMessage(h, WM_INPUTLANGCHANGEREQUEST, 2, + LoadKeyboardLayout('00000419', KLF_ACTIVATE or KLF_SETFORPROCESS)); + end + else + begin + SendMessage(h, WM_INPUTLANGCHANGEREQUEST, 2, + LoadKeyboardLayout('00000409', KLF_ACTIVATE or KLF_SETFORPROCESS)); + end; +end; + +function TfrmMain.DoVerticalFormat(const SrcWnd: HWND; const Src: string; out FormatedStr: string): boolean; +begin + if frmEditor.Visible then + begin + frmEditor.ModalResult := mrCancel; + Result := False; + Exit; + end; + + frmEditor.SetOptions(cbFont.Text, edFontSize.Value, GetColor(imgFontColor), GetColor(imgBackColor)); + frmEditor.SrcWnd := SrcWnd; + frmEditor.SourceStr := Src; + frmEditor.Width := FNewEditorW; + frmEditor.Height := FNewEditorH; + if frmEditor.ShowModal = ID_OK then + begin + FormatedStr := frmEditor.ForamtedStr; + Result := True; + end + else + begin + Result := False; + end; + FNewEditorW := frmEditor.Width; + FNewEditorH := frmEditor.Height; +end; + +procedure TfrmMain.edFontSizeChange(Sender: TObject); +begin + cbFont.ItemHeight := Max(12, (edFontSize.Value + 6)); + edFontSize.Font.Size := 8; + edFontSize.Height := cbFont.Height; + edFontSize.Font.Size := Trunc((edFontSize.Value - 8) * 0.5) + 8; +end; + +procedure TfrmMain.Ext1Click(Sender: TObject); +begin + FIsExit := True; + Close; +end; + +procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := FIsExit; + if not FIsExit then Hide; +end; + +procedure TfrmMain.FormCreate(Sender: TObject); + procedure LoadResToStringList(const sl: TStringList; const resname: string); + var rs: TResourceStream; + begin + rs := TResourceStream.Create(HInstance, resname, RT_RCDATA); + try + sl.LoadFromStream(rs); + finally + FreeAndNil(rs); + end; + end; + procedure LoadResToDic(const dic: TDictionary; const resname: string); overload; + var sl: TStringList; + i: Integer; + begin + sl := TStringList.Create; + try + LoadResToStringList(sl, resname); + for i := 0 to sl.Count - 1 do + dic.Add(sl.Names[i][1], sl.ValueFromIndex[i][1]); + finally + FreeAndNil(sl); + end; + end; + procedure LoadResToDic(const dic: TDictionary; const resname: string); overload; + var sl: TStringList; + i: Integer; + begin + sl := TStringList.Create; + try + LoadResToStringList(sl, resname); + for i := 0 to sl.Count - 1 do + dic.Add(sl.Names[i][1], sl.ValueFromIndex[i]); + finally + FreeAndNil(sl); + end; + end; + procedure AddReverse(const Dic: TDictionary); + var pair: TPair; + lst: TList>; + i: Integer; + begin + lst := TList>.Create; + try + for pair in Dic do lst.Add(Pair); + for i := 0 to lst.Count - 1 do + Dic.AddOrSetValue(lst.Items[i].Value, lst.Items[i].Key); + finally + FreeAndNil(lst); + end; + end; +begin + FLang[clEn, csOff] := TDictionary.Create; + LoadResToDic(FLang[clEn, csOff], 'Lang_EnNoCaps'); + FLang[clEn, csOn] := TDictionary.Create; + LoadResToDic(FLang[clEn, csOn], 'Lang_EnCaps'); + FLang[clRu, csOff] := TDictionary.Create; + LoadResToDic(FLang[clRu, csOff], 'Lang_RuNoCaps'); + FLang[clRu, csOn] := TDictionary.Create; + LoadResToDic(FLang[clRu, csOn], 'Lang_RuCaps'); + + FCaps := TDictionary.Create; + LoadResToDic(FCaps, 'Case'); + AddReverse(FCaps); + + FTrans := TDictionary.Create; + LoadResToDic(FTrans, 'Translit'); + + GetFontList(cbFont.Items); + SetDefaultSettings; + LoadSettings; +end; + +procedure TfrmMain.FormDestroy(Sender: TObject); +var i: TFormatAction; +begin + SaveSettings; + for i := Low(TFormatAction) to High(TFormatAction) do + if FRegistredHotkey[i] then + begin + UnregisterHotKey(Handle, HK_ID[i]); + FRegistredHotkey[i] := False; + end; + + FreeAndNil(FLang[clEn, csOff]); + FreeAndNil(FLang[clEn, csOn]); + FreeAndNil(FLang[clRu, csOff]); + FreeAndNil(FLang[clRu, csOn]); + FreeAndNil(FCaps); + FreeAndNil(FTrans); +end; + +function TfrmMain.GetColor(img: TImage): TColor; +begin + Result := img.Picture.Bitmap.Canvas.Pixels[0, 0]; +end; + +procedure TfrmMain.hkCodeAlignerChange(Sender: TObject); +begin + RegHK(faCodeVertical, hkCodeAligner.HotKey, hkCodeAligner.Modifiers); + imgHKList.GetIcon(HK_IconIndex[FRegistredHotkey[faCodeVertical]], imgCodeAligner.Picture.Icon); +end; + +procedure TfrmMain.hkSwitchLangChange(Sender: TObject); +begin + RegHK(faSwitchLang, hkSwitchLang.HotKey, hkSwitchLang.Modifiers); + imgHKList.GetIcon(HK_IconIndex[FRegistredHotkey[faSwitchLang]], imgSwitchLang.Picture.Icon); +end; + +procedure TfrmMain.hkSwitchRegChange(Sender: TObject); +begin + RegHK(faSwitchReg, hkSwitchReg.HotKey, hkSwitchReg.Modifiers); + imgHKList.GetIcon(HK_IconIndex[FRegistredHotkey[faSwitchReg]], imgSwitchReg.Picture.Icon); +end; + +procedure TfrmMain.hkTranslitChange(Sender: TObject); +begin + RegHK(faTranslit, hkTranslit.HotKey, hkTranslit.Modifiers); + imgHKList.GetIcon(HK_IconIndex[FRegistredHotkey[faTranslit]], imgTranslit.Picture.Icon); +end; + +procedure TfrmMain.imgBackColorClick(Sender: TObject); +begin + ColorDialog1.Color := GetColor(imgBackColor); + if ColorDialog1.Execute then + SetColor(imgBackColor, ColorDialog1.Color); +end; + +procedure TfrmMain.imgFontColorClick(Sender: TObject); +begin + ColorDialog1.Color := GetColor(imgFontColor); + if ColorDialog1.Execute then + SetColor(imgFontColor, ColorDialog1.Color); +end; + +procedure TfrmMain.LoadSettings; +var reg: TRegistry; + n: Integer; +begin + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.KeyExists(REG_Key) then + begin + reg.OpenKeyReadOnly(REG_Key); + if reg.ValueExists(REG_Value_FontName) then + if reg.GetDataType(REG_Value_FontName) = rdString then + begin + n := cbFont.Items.IndexOf(reg.ReadString(REG_Value_FontName)); + if n <> -1 then cbFont.ItemIndex := n; + end; + + if reg.ValueExists(REG_Value_FontSize) then + if reg.GetDataType(REG_Value_FontSize) = rdInteger then + edFontSize.Value := reg.ReadInteger(REG_Value_FontSize); + + if reg.ValueExists(REG_Value_FontColor) then + if reg.GetDataType(REG_Value_FontColor) = rdInteger then + SetColor(imgFontColor, reg.ReadInteger(REG_Value_FontColor)); + + if reg.ValueExists(REG_Value_BackColor) then + if reg.GetDataType(REG_Value_BackColor) = rdInteger then + SetColor(imgBackColor, reg.ReadInteger(REG_Value_BackColor)); + + + if reg.ValueExists(REG_Value_Hotkey_SLang) then + if reg.GetDataType(REG_Value_Hotkey_SLang) = rdInteger then + hkSwitchLang.HotKey := reg.ReadInteger(REG_Value_Hotkey_SLang); + if reg.ValueExists(REG_Value_Modifier_SLang) then + if reg.GetDataType(REG_Value_Modifier_SLang) = rdInteger then + hkSwitchLang.Modifiers := THKModifiers(Byte(reg.ReadInteger(REG_Value_Modifier_SLang))); + + if reg.ValueExists(REG_Value_Hotkey_SCase) then + if reg.GetDataType(REG_Value_Hotkey_SCase) = rdInteger then + hkSwitchReg.HotKey := reg.ReadInteger(REG_Value_Hotkey_SCase); + if reg.ValueExists(REG_Value_Modifier_SCase) then + if reg.GetDataType(REG_Value_Modifier_SCase) = rdInteger then + hkSwitchReg.Modifiers := THKModifiers(Byte(reg.ReadInteger(REG_Value_Modifier_SCase))); + + if reg.ValueExists(REG_Value_Hotkey_Trans) then + if reg.GetDataType(REG_Value_Hotkey_Trans) = rdInteger then + hkTranslit.HotKey := reg.ReadInteger(REG_Value_Hotkey_Trans); + if reg.ValueExists(REG_Value_Modifier_Trans) then + if reg.GetDataType(REG_Value_Modifier_Trans) = rdInteger then + hkTranslit.Modifiers := THKModifiers(Byte(reg.ReadInteger(REG_Value_Modifier_Trans))); + + if reg.ValueExists(REG_Value_Hotkey_CodeVAlign) then + if reg.GetDataType(REG_Value_Hotkey_CodeVAlign) = rdInteger then + hkCodeAligner.HotKey := reg.ReadInteger(REG_Value_Hotkey_CodeVAlign); + if reg.ValueExists(REG_Value_Modifier_CodeVAlign) then + if reg.GetDataType(REG_Value_Modifier_CodeVAlign) = rdInteger then + hkCodeAligner.Modifiers := THKModifiers(Byte(reg.ReadInteger(REG_Value_Modifier_CodeVAlign))); + + if reg.ValueExists(REG_Value_EditorW) then + if reg.GetDataType(REG_Value_EditorW) = rdInteger then + FNewEditorW := reg.ReadInteger(REG_Value_EditorW); + + if reg.ValueExists(REG_Value_EditorH) then + if reg.GetDataType(REG_Value_EditorH) = rdInteger then + FNewEditorH := reg.ReadInteger(REG_Value_EditorH); + end; + finally + FreeAndNil(reg); + end; +end; + +procedure TfrmMain.ProcessBuffer(const action: TFormatAction); + function GetCStr: string; +// var c: TClipboard; + begin + try + Result := Clipboard.AsText; + except + on e: EClipboardException do + begin + Result := ''; + end; + end; + { + c := TClipboard.Create; + try + Result := c.AsText; + finally + c.Free; + end; + } + end; + + procedure SetCStr(const s: string); + var hMem: HGLOBAL; + Data: Pointer; + begin + hMem := GlobalAlloc(GMEM_MOVEABLE, (Length(s)+1)*SizeOf(Char)); + if hMem <> 0 then + begin + Data := GlobalLock(hMem); + if Assigned(Data) then + try + FillChar(Data^, (Length(s)+1)*SizeOf(Char), 0); + Move(s[1], Data^, Length(s)*SizeOf(Char)); + finally + GlobalUnlock(hMem); + end + else + Exit; + + if OpenClipboard(0) then + try + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, hMem); + finally + CloseClipboard(); + end; + end; + end; + +var h: HWND; + i: Integer; + oldBuf, newBuf: string; + wasFormated: boolean; + formatedStr: string; + UpdateID: Cardinal; + ActiveLayout: TCurrentLang; + CapsState: TCapsState; +begin + h := GetForegroundWindow; + if IsWindow(h) then + begin + if action = faSwitchLang then + if not CanSwitchLayoutNow(h, ActiveLayout) then Exit; + + oldBuf := GetCStr; + SetCStr(''); + UpdateID := GetClipboardSequenceNumber; + try + SendCtrlKey(Ord('C')); + for i := 0 to 99 do + begin + if GetClipboardSequenceNumber > UpdateID then Break; + Sleep(10); + end; + newBuf := GetCStr; + if newBuf = '' then Exit; + + wasFormated := True; + case action of + faSwitchLang : begin + if GetKeyState(VK_CAPITAL)=1 then + CapsState := csOn + else + CapsState := csOff; + newBuf := SwitchSymbols(FLang[ActiveLayout, CapsState], newBuf); + DoSwitchLayout(h); + end; + faSwitchReg : newBuf := SwitchSymbols(FCaps, newBuf); + faTranslit : newBuf := ReplaceSymbols(FTrans, newBuf); + faCodeVertical: begin + wasFormated := DoVerticalFormat(h, newBuf, formatedStr); + if wasFormated then newBuf := formatedStr; + end; + end; + + if wasFormated then + begin + SetCStr(newBuf); + SetForegroundWindow(h); + SendCtrlKey(Ord('V')); + Sleep(500); + end; + finally + SetForegroundWindow(h); + SetCStr(oldBuf); + end; + end; +end; + +procedure TfrmMain.RegHK(const Action: TFormatAction; const Key: TShortCut; const Modifiers: THKModifiers); +var M: Cardinal; +begin + if FRegistredHotkey[Action] then + begin + UnregisterHotKey(Handle, HK_ID[Action]); + FRegistredHotkey[Action] := False; + end; + M := 0; + if hkAlt in Modifiers then M := M or MOD_ALT; + if hkCtrl in Modifiers then M := M or MOD_CONTROL; + if hkShift in Modifiers then M := M or MOD_SHIFT; + if hkExt in Modifiers then M := M or MOD_WIN; + if M = 0 then Exit; + if Key = 0 then Exit; + if Key = $8000 then Exit; + FRegistredHotkey[Action] := RegisterHotKey(Handle, HK_ID[Action], M, LoByte(Key)); +end; + +function TfrmMain.ReplaceSymbols(const Dic: TDictionary; const Src: string): string; +var i: Integer; + s: string; +begin + Result := ''; + for i := 1 to Length(src) do + if Dic.TryGetValue(src[i], s) then + Result := Result + s + else + Result := Result + src[i]; +end; + +procedure TfrmMain.SaveSettings; +var reg: TRegistry; +begin + reg := TRegistry.Create; + try + reg.RootKey := HKEY_CURRENT_USER; + if reg.OpenKey(REG_Key, True) then + begin + reg.WriteString(REG_Value_FontName, cbFont.Text); + reg.WriteInteger(REG_Value_FontSize, edFontSize.Value); + reg.WriteInteger(REG_Value_FontColor, GetColor(imgFontColor)); + reg.WriteInteger(REG_Value_BackColor, GetColor(imgBackColor)); + + reg.WriteInteger(REG_Value_Hotkey_SLang, hkSwitchLang.HotKey); + reg.WriteInteger(REG_Value_Modifier_SLang, Byte(hkSwitchLang.Modifiers)); + reg.WriteInteger(REG_Value_Hotkey_SCase, hkSwitchReg.HotKey); + reg.WriteInteger(REG_Value_Modifier_SCase, Byte(hkSwitchReg.Modifiers)); + reg.WriteInteger(REG_Value_Hotkey_Trans, hkTranslit.HotKey); + reg.WriteInteger(REG_Value_Modifier_Trans, Byte(hkTranslit.Modifiers)); + reg.WriteInteger(REG_Value_Hotkey_CodeVAlign, hkCodeAligner.HotKey); + reg.WriteInteger(REG_Value_Modifier_CodeVAlign, Byte(hkCodeAligner.Modifiers)); + + reg.WriteInteger(REG_Value_EditorW, FNewEditorW); + reg.WriteInteger(REG_Value_EditorH, FNewEditorH); + end; + finally + FreeAndNil(reg); + end; +end; + +procedure TfrmMain.SendCtrlKey(const VKey: Word); + procedure SendKeyInput(const VKey: Word; const UpEvent: Boolean); + var input: TInput; + begin + input.Itype := INPUT_KEYBOARD; + input.ki.wScan := 0; + input.ki.time := 0; + input.ki.dwExtraInfo := 0; + input.ki.wVk := VKey; + if UpEvent then input.ki.dwFlags := KEYEVENTF_KEYUP else input.ki.dwFlags := 0; + SendInput(1, input, SizeOf(input)); + end; +var RC, LC: Boolean; + RS, LS: Boolean; +begin + LS := GetAsyncKeyState(VK_LSHIFT) < 0; + RS := GetAsyncKeyState(VK_RSHIFT) < 0; + LC := GetAsyncKeyState(VK_LCONTROL) < 0; + RC := GetAsyncKeyState(VK_RCONTROL) < 0; + if LS then SendKeyInput(VK_LSHIFT, True); + if RS then SendKeyInput(VK_RSHIFT, True); + if LC then SendKeyInput(VK_LCONTROL, True); + if RC then SendKeyInput(VK_RCONTROL, True); + + SendKeyInput(VK_LCONTROL, False); + SendKeyInput(VKey, False); + SendKeyInput(VKey, True); + SendKeyInput(VK_LCONTROL, True); + + if LS then SendKeyInput(VK_LSHIFT, False); + if RS then SendKeyInput(VK_RSHIFT, False); + if LC then SendKeyInput(VK_LCONTROL, False); + if RC then SendKeyInput(VK_RCONTROL, False); +end; + +procedure TfrmMain.SetColor(img: TImage; color: TColor); +begin + img.Picture.Bitmap.Canvas.Pixels[0, 0] := color; +end; + +procedure TfrmMain.SetDefaultSettings; +var n: Integer; +begin + hkSwitchLang.HotKey := VK_PAUSE; + hkSwitchLang.Modifiers := [hkShift]; + hkSwitchLang.OnChange(hkSwitchLang); + + hkSwitchReg.HotKey := VK_SCROLL; + hkSwitchReg.Modifiers := [hkShift]; + hkSwitchReg.OnChange(hkSwitchReg); + + hkTranslit.HotKey := VK_SCROLL; + hkTranslit.Modifiers := [hkCtrl, hkShift]; + hkTranslit.OnChange(hkTranslit); + + hkCodeAligner.HotKey := Ord('D'); + hkCodeAligner.Modifiers := [hkCtrl, hkShift]; + hkCodeAligner.OnChange(hkCodeAligner); + + n := cbFont.Items.IndexOf('Consolas'); + if n = -1 then n := cbFont.Items.IndexOf('Courier New'); + if n = -1 then n := 0; + cbFont.ItemIndex := n; + + imgFontColor.Picture.Bitmap.PixelFormat := pf24bit; + imgFontColor.Picture.Bitmap.Width := 1; + imgFontColor.Picture.Bitmap.Height := 1; + imgFontColor.Picture.Bitmap.Canvas.Pixels[0,0] := clBlack; + + imgBackColor.Picture.Bitmap.PixelFormat := pf24bit; + imgBackColor.Picture.Bitmap.Width := 1; + imgBackColor.Picture.Bitmap.Height := 1; + imgBackColor.Picture.Bitmap.Canvas.Pixels[0,0] := clWhite; + + FNewEditorW := 750; + FNewEditorH := 250; +end; + +function TfrmMain.SwitchSymbols(const Dic: TDictionary; const Src: string): string; +var i: Integer; +begin + SetLength(Result, Length(Src)); + for i := 1 to Length(src) do + if not Dic.TryGetValue(src[i], Result[i]) then Result[i] := src[i]; +end; + +procedure TfrmMain.TrayIcon1Click(Sender: TObject); +begin + Show; + SetForegroundWindow(Handle); +end; + +procedure TfrmMain.WMHotkey(var msg: TWMHotKey); +var act: TFormatAction; +begin + case msg.HotKey of + HK_Base + 1: act := faSwitchLang; + HK_Base + 2: act := faSwitchReg; + HK_Base + 3: act := faTranslit; + HK_Base + 4: act := faCodeVertical; + else + Exit; + end; + ProcessBuffer(act); +end; + +end.