diff --git a/.gitignore b/.gitignore index 19864c6..054549d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ # # Resource files are binaries containing manifest, project icon and version info. # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. -#*.res +*.res # # Type library file (binary). In old Delphi versions it should be stored. # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. diff --git a/README.md b/README.md index 057e5a2..0ca1d4a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,27 @@ # calculator -Simple and fast calculator + +Простой и быстрый калькулятор для выполнения простых вычислений. + +## Возможности + +- Поддержка простых вычислений (`+`, `-`, `*`, `/`, `(`, `)`); +- Автоматическое удаление из формулы лишних символов (пробелы, буквы) - просто + копируйте и вставляйте формулы из любого места без необходимости их обработки; +- Горячая клавиша для отображения и скрытия окна программы (`Ctrl+1`); +- Никакого Electron'а. Быстрая работа и малое поребление памяти. + +## Сборка + +Запустите `src/make.bat`. Проект осуществляет сборку исполняемого файла в +`bin/calculator`. + +## ToDo + +- [ ] Подобрать имя проекта получше +- [ ] Добавить поддержку Linux +- [ ] Добавить настройки горячей клавиши вызова +- [ ] Добавить английский язык + +## Использованные сторонние библиотеки + +- [3926 Free "Farm-Fresh Web Icons"](https://www.fatcow.com/free-icons) diff --git a/src/calculator.ico b/src/calculator.ico new file mode 100644 index 0000000..69d84fa Binary files /dev/null and b/src/calculator.ico differ diff --git a/src/calculator.lpi b/src/calculator.lpi new file mode 100644 index 0000000..0bd5cbf --- /dev/null +++ b/src/calculator.lpi @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="LCL"/> + </Item1> + </RequiredPackages> + <Units Count="4"> + <Unit0> + <Filename Value="calculator.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Calculator"/> + </Unit0> + <Unit1> + <Filename Value="mainformunit.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="MainFormUnit"/> + </Unit1> + <Unit2> + <Filename Value="support.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Support"/> + </Unit2> + <Unit3> + <Filename Value="hotkeysunit.pas"/> + <IsPartOfProject Value="True"/> + </Unit3> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="..\bin\calculator"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <CodeGeneration> + <SmartLinkUnit Value="True"/> + <Optimizations> + <OptimizationLevel Value="3"/> + </Optimizations> + </CodeGeneration> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <StripSymbols Value="True"/> + </Debugging> + <LinkSmart Value="True"/> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/src/calculator.lpr b/src/calculator.lpr new file mode 100644 index 0000000..fd72d6b --- /dev/null +++ b/src/calculator.lpr @@ -0,0 +1,17 @@ +program Calculator; + +{$mode objfpc}{$H+} + +uses + Interfaces, Forms, MainFormUnit, Support, hotkeysunit; + +{$R *.res} + +begin + Application.Title:='Калькулятор'; + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; +end. + diff --git a/src/hotkeysunit.pas b/src/hotkeysunit.pas new file mode 100644 index 0000000..a5e052b --- /dev/null +++ b/src/hotkeysunit.pas @@ -0,0 +1,21 @@ +unit HotkeysUnit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Windows; + +procedure AssociateHotkeys(h: THANDLE); + +implementation + +procedure AssociateHotkeys(h: THANDLE); +begin + // Hotkey Ctrl+1 + RegisterHotKey(h, GlobalAddAtom('Min/Restore hotkey'), MOD_CONTROL, VK_1); +end; + +end. + diff --git a/src/mainformunit.lfm b/src/mainformunit.lfm new file mode 100644 index 0000000..362a4cf --- /dev/null +++ b/src/mainformunit.lfm @@ -0,0 +1,282 @@ +object MainForm: TMainForm + Left = 312 + Height = 58 + Top = 109 + Width = 320 + BorderIcons = [biSystemMenu] + Caption = 'Калькулятор' + ClientHeight = 58 + ClientWidth = 320 + Constraints.MaxHeight = 58 + Constraints.MinHeight = 58 + FormStyle = fsSystemStayOnTop + OnClose = FormClose + OnCreate = FormCreate + OnShow = FormShow + LCLVersion = '1.6.0.4' + object QueryEdit: TEditButton + Left = 4 + Height = 23 + Top = 4 + Width = 312 + Align = alTop + BorderSpacing.Around = 4 + ButtonHint = 'Очистить' + ButtonWidth = 23 + Flat = True + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000230000 + 0033000000330000003300000033000000330000003300000033000000330000 + 0033000000330000003300000033000000330000003300000023A9988AC0B5A2 + 92FFB3A090FFB39F8FFFB39F8FFFB39F8FFFB39F8FFFB3A08FFFB4A190FFB7A4 + 93FFBBA797FFBCA998FFBBA797FFB8A494FFB6A393FFA9988AC0B5A292FFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E3 + E5FF8F9092FF8A8B8CFF8F9092FFECEEEEFFFFFFFFFFB6A393FFB4A090FFFFFD + FCFFFBF8F5FFFAF7F4FFFAF7F4FFFAF7F4FFFAF7F4FFFBF8F5FFFFFEFBFF8786 + 84FFFFFFFFFF838282FFFFFFFFFF888786FFFFFFFFFFB5A291FFB4A191FFF8F3 + EFFFF6F1ECFFF5EFEAFFF5EFEAFFF5EFEAFFF5EFEAFFF7F1ECFFFEF8F3FF7E7B + 78FF817E7AFFE9E4E0FF817E7AFF7F7D79FFFFFCF8FFB6A292FFB5A292FFF1EA + E5FFF3EBE3FFF1E9E1FFF1E9E1FFF1E9E1FFF1E9E1FFF3EBE2FFF9F1E8FF827D + 79FFFFFFF6FF7F7A77FFFFFFF6FF837F7AFFF9F1ECFFB6A393FFB6A393FFE8E3 + DBFFF0E6DCFFEFE5DAFFEFE5DAFFEFE5DAFFEFE5DAFFEFE5DBFFF3E9DEFFD0C7 + BFFF817B76FF7B7771FF817B76FFD1C8C0FFECE7E0FFB6A393FFB7A495FFE1DB + D4FFDED8D1FFDED7D0FFDED7D0FFDED7D0FFDED7D0FFDED7D0FFDFD8D1FFE2DB + D4FFE5DED7FFE7DFD8FFE5DED7FFE2DCD4FFE2DCD5FFB7A595FFB9A797EFB7A5 + 95FFB6A394FFB6A393FFB6A393FFB6A393FFB6A393FFB6A393FFB6A394FFB7A4 + 94FFB7A494FFB8A595FFB7A494FFB7A494FFB7A595FFB9A797B0FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + MaxLength = 0 + NumGlyphs = 1 + OnButtonClick = QueryEditButtonClick + OnChange = QueryEditChange + OnKeyPress = QueryEditKeyPress + PasswordChar = #0 + TabOrder = 0 + end + object ResultEdit: TEdit + Left = 4 + Height = 23 + Top = 31 + Width = 312 + Align = alTop + BorderSpacing.Around = 4 + TabOrder = 1 + Text = '0,00' + end + object TrayIcon: TTrayIcon + PopUpMenu = TrayPopupMenu + Icon.Data = { + 7E04000000000100010010100000010020006804000016000000280000001000 + 0000200000000100200000000000000400006400000064000000000000000000 + 0000FFFFFF000000002300000033000000330000003300000033000000330000 + 00330000003300000033000000330000003300000033000000330000002CFFFF + FF00FFFFFF00969696C09F9F9FFF9E9E9EFF9E9E9EFF9E9F9FFF9E9E9EFF9E9E + 9EFF9E9F9FFF9E9E9EFF9D9E9FFF9D9E9FFF9D9E9EFF9F9F9FFF9E9E9EE1FFFF + FF00FFFFFF009F9F9FFFFFFEFEFFFBFAFAFFFEFDFDFFFEFDFDFFFDFCFCFFFEFD + FDFFFEFDFEFFFBFCFDFFF9FCFFFFF9FCFFFFF9FAFCFFFFFEFEFF9F9F9FFFFFFF + FF00FFFFFF009E9E9EFFF7F6F6FFF2F1F0FF8D8A88FF6D6B68FFF7F6F5FF8D8B + 89FF6C6B69FFF2F6F9FFE49F55FFE49F55FFEEF2F5FFF7F6F7FF9E9E9EFFFFFF + FF00FFFFFF009D9E9EFFF4F3F2FFEDECEBFFF2F1F0FFF3F3F2FFF0F0EFFFF3F2 + F1FFF3F3F3FFEDF1F6FFEEAD66FFE4A25BFFE9EDF2FFF4F4F3FF9D9E9EFFFFFF + FF00FFFFFF009E9E9EFFF3F2F0FFE9E8E7FF8E8C8AFF6E6C6AFFEDECEBFF8F8D + 8AFF6E6C6BFFE9ECF0FFF0AC62FFF0AC62FFE5E8ECFFF2F2F1FF9E9E9EFFFFFF + FF00FFFFFF009E9E9EFFF0EEEEFFE4E2E2FFE9E7E7FFEAE8E9FFE8E6E6FFE9E7 + E8FFEAE8E9FFE6E5E7FFE5E6EBFFE4E6EBFFE2E2E4FFF0EEEEFF9E9E9EFFFFFF + FF00FFFFFF009E9F9FFFEEEDEDFFE0DEDDFF918E8AFF716F6BFFE5E2E2FF918F + 8CFF706E6CFFE4E2E2FF918F8CFF706E6AFFE1DFDEFFEEEDEEFF9E9F9FFFFFFF + FF00FFFFFF009F9F9FFFEEECECFFDDD9D5FFE4DED6FFE5DFD7FFE0DDD9FFE0DE + DDFFE1DFDEFFE1DDD9FFE5DFD7FFE5DFD6FFDDD9D5FFEEEDECFF9F9F9FFFFFFF + FF00FFFFFF009F9F9FFFEDECEAFFDAD5CEFF1F7FFFFF2266FFFFDDD8D1FF928F + 8CFF716F6CFFDED8D2FF2080FFFF2265FFFFDAD5CEFFEEECEAFF9F9F9FFFFFFF + FF00FFFFFF00A0A1A1FFF1F0F0FFF1EFEDFFF6F1ECFFF6F2ECFFF2F1EFFFF1F1 + F2FFF2F2F3FFF2F1EFFFF6F2ECFFF6F2ECFFF1F0EDFFF1F0F0FFA0A1A1FFFFFF + FF00FFFFFF00A2A3A5FF7C7E7FFF7B7D80FF7C7E80FF7C7E81FF7B7E81FF7B7E + 82FF7B7E82FF7B7E81FF7C7E81FF7C7E80FF7B7D80FF7C7E7FFFA2A3A5FFFFFF + FF00FFFFFF00A0A3A7FFFFCA8BFFF9C27EFFF9C27FFFF9C280FFF9C280FFF9C2 + 80FFF9C280FFF9C280FFF9C280FFF9C27FFFF9C27EFFFFCA8BFFA0A3A7FFFFFF + FF00FFFFFF009EA2A6FFF9D0A4FFE8A760FFE7A762FFE7A863FFE7A863FFE7A8 + 63FFE7A863FFE7A863FFE7A863FFE7A762FFE8A760FFF9D0A4FF9EA2A6FFFFFF + FF00FFFFFF009FA2A5FFFDDBB6FFF8DAB8FFF8DAB9FFF8DAB9FFF8DAB9FFF8DA + B9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB8FFFDDBB6FF9FA2A5FFFFFF + FF00FFFFFF00A3A4A5EF9FA2A5FF9EA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1 + A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9EA1A5FF9FA2A5FFA3A4A5EFFFFF + FF00000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000 + } + Visible = True + OnClick = TrayIconClick + end + object TrayPopupMenu: TPopupMenu + Images = ImageList16px + left = 32 + object ShowHideMenuItem: TMenuItem + Caption = 'Показать/Скрыть' + Bitmap.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF000000 + 0023000000330000003300000033000000330000003300000033000000330000 + 0033000000330000003300000033000000330000002CFFFFFF00FFFFFF009696 + 96C09F9F9FFF9E9E9EFF9E9E9EFF9E9F9FFF9E9E9EFF9E9E9EFF9E9F9FFF9E9E + 9EFF9D9E9FFF9D9E9FFF9D9E9EFF9F9F9FFF9E9E9EE1FFFFFF00FFFFFF009F9F + 9FFFFFFEFEFFFBFAFAFFFEFDFDFFFEFDFDFFFDFCFCFFFEFDFDFFFEFDFEFFFBFC + FDFFF9FCFFFFF9FCFFFFF9FAFCFFFFFEFEFF9F9F9FFFFFFFFF00FFFFFF009E9E + 9EFFF7F6F6FFF2F1F0FF8D8A88FF6D6B68FFF7F6F5FF8D8B89FF6C6B69FFF2F6 + F9FFE49F55FFE49F55FFEEF2F5FFF7F6F7FF9E9E9EFFFFFFFF00FFFFFF009D9E + 9EFFF4F3F2FFEDECEBFFF2F1F0FFF3F3F2FFF0F0EFFFF3F2F1FFF3F3F3FFEDF1 + F6FFEEAD66FFE4A25BFFE9EDF2FFF4F4F3FF9D9E9EFFFFFFFF00FFFFFF009E9E + 9EFFF3F2F0FFE9E8E7FF8E8C8AFF6E6C6AFFEDECEBFF8F8D8AFF6E6C6BFFE9EC + F0FFF0AC62FFF0AC62FFE5E8ECFFF2F2F1FF9E9E9EFFFFFFFF00FFFFFF009E9E + 9EFFF0EEEEFFE4E2E2FFE9E7E7FFEAE8E9FFE8E6E6FFE9E7E8FFEAE8E9FFE6E5 + E7FFE5E6EBFFE4E6EBFFE2E2E4FFF0EEEEFF9E9E9EFFFFFFFF00FFFFFF009E9F + 9FFFEEEDEDFFE0DEDDFF918E8AFF716F6BFFE5E2E2FF918F8CFF706E6CFFE4E2 + E2FF918F8CFF706E6AFFE1DFDEFFEEEDEEFF9E9F9FFFFFFFFF00FFFFFF009F9F + 9FFFEEECECFFDDD9D5FFE4DED6FFE5DFD7FFE0DDD9FFE0DEDDFFE1DFDEFFE1DD + D9FFE5DFD7FFE5DFD6FFDDD9D5FFEEEDECFF9F9F9FFFFFFFFF00FFFFFF009F9F + 9FFFEDECEAFFDAD5CEFF1F7FFFFF2266FFFFDDD8D1FF928F8CFF716F6CFFDED8 + D2FF2080FFFF2265FFFFDAD5CEFFEEECEAFF9F9F9FFFFFFFFF00FFFFFF00A0A1 + A1FFF1F0F0FFF1EFEDFFF6F1ECFFF6F2ECFFF2F1EFFFF1F1F2FFF2F2F3FFF2F1 + EFFFF6F2ECFFF6F2ECFFF1F0EDFFF1F0F0FFA0A1A1FFFFFFFF00FFFFFF00A2A3 + A5FF7C7E7FFF7B7D80FF7C7E80FF7C7E81FF7B7E81FF7B7E82FF7B7E82FF7B7E + 81FF7C7E81FF7C7E80FF7B7D80FF7C7E7FFFA2A3A5FFFFFFFF00FFFFFF00A0A3 + A7FFFFCA8BFFF9C27EFFF9C27FFFF9C280FFF9C280FFF9C280FFF9C280FFF9C2 + 80FFF9C280FFF9C27FFFF9C27EFFFFCA8BFFA0A3A7FFFFFFFF00FFFFFF009EA2 + A6FFF9D0A4FFE8A760FFE7A762FFE7A863FFE7A863FFE7A863FFE7A863FFE7A8 + 63FFE7A863FFE7A762FFE8A760FFF9D0A4FF9EA2A6FFFFFFFF00FFFFFF009FA2 + A5FFFDDBB6FFF8DAB8FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DA + B9FFF8DAB9FFF8DAB9FFF8DAB8FFFDDBB6FF9FA2A5FFFFFFFF00FFFFFF00A3A4 + A5EF9FA2A5FF9EA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1 + A5FF9DA1A5FF9DA1A5FF9EA1A5FF9FA2A5FFA3A4A5EFFFFFFF00 + } + ImageIndex = 0 + ShortCut = 16433 + OnClick = ShowHideMenuItemClick + end + object ExitMenuItem: TMenuItem + Caption = 'Выход' + Bitmap.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000120000003200000033000000330000 + 0033000000330000003300000033000000330000003300000033000000330000 + 0033000000330000003300000033365D7B79497BA2FC68A4D9FF5C5C5CFF5C5C + 5CFF5E5B5AFF5E5A59FF5D5A5AFF5B5A5BFF5A5B5BFF5A5B5BFF5A5B5BFF5B5A + 5AFF5C5956FF576876FF4E7EA4FF4C80ACFF5082ABFF65A2D5FF5E5B5C005F5A + 5C00635859003F69A5FF756667FF706869FF6D6969FF6C6A69FF6C6A69FF6C6A + 68FF6E6762FF4C89BAFF4E85B2FF4D83AEFF5D8CB2FF629ED1FF66565D006955 + 5C0010866D0013826BFF009346FF715C62FF6A6263FF676463FF666463FF6764 + 62FF68615BFF4F8ABBFF5086B4FF4F84B1FF6895B9FF5F9BCDFF000000300000 + 003300000033008C46FF4FDDB0FF008D43FF6B585EFF655E60FF636160FF6260 + 5FFF645D57FF518DBEFF528AB7FF5187B4FF739FC2FF5D97C9FF008B4BF2008A + 47FF008845FF008441FF00DAA2FF60D9B3FF008D42FF68545AFF625B5CFF605C + 5AFF605852FF5490C2FF558CBAFF4E81ADFF7EA6C8FF5A94C4FF008A47FF63ED + D0FF00D4A0FF00D29EFF00CC9CFF00CD9CFF6FDCBDFF009346FF615457FF5C57 + 56FF5B534DFF5794C5FF588EBCFF47749BFF88AFCFFF5790C0FF008A47FF61E1 + D0FF60DDCAFF63DCC8FF00C49BFF00C69CFF82E1C8FF009447FF5C5054FF5853 + 53FF574F4AFF5A96CAFF5B8FBEFF22B9F7FF95B5D3FF548DBCFF008D4CEF008A + 47FF008844FF00853FFF00C1A0FF97E3D1FF008F43FF5A484EFF565051FF5351 + 4FFF524B45FF5B9ACDFF5C91C1FF20B7F5FF9EBCD7FF5189B8FF008F4E00008F + 4C00008E4900008B44FFA0E8DAFF009144FF55434AFF524B4DFF4F4D4EFF4F4D + 4CFF4D4641FF5E9CD2FF5C95C5FF5990C1FFA6C4DFFF4E86B5FF00904C000091 + 47001A866E0017866DFF009647FF523F45FF4F4749FF4D494AFF4C4A4AFF4C48 + 48FF4A423DFF60A0D5FF5D98C9FF5894C6FFAFCCE6FF4B83B0FF009242005276 + AF004E77AB004D7BB0FF4C3D3BFF4A4343FF484544FF484644FF484644FF4745 + 42FF433C36FF5FA1D8FF5C9ACCFF5896C9FFB8D3EBFF4980ACFF4F79AB004C7A + A7004A7BA6004A7FACFF443831FF433B37FF433D38FF433D38FF433D38FF423B + 36FF3C332CFFB9DAF5FF7FB0DAFF5495CCFFC0DAEFFF467CA8FF4B7CA6004A7C + A5004A7CA6004A7EA8B04A82AEFF4A83B0FF4A83B0FF4A83B0FF4A83B0FF4A82 + AFFF447DA9FF709CBFFFB9D5EBFFB3D1EAFFC1DBF2FF4279A5FF4A7CA5004A7C + A5004A7CA5004A7CA5004A7EA7004A7EA8004A7EA8004A7EA8004A7EA800497D + A7004579A400709BBE00B5D2EA00C3DAEF58CDE3F5FB3F75A1FF + } + ImageIndex = 1 + OnClick = ExitMenuItemClick + end + end + object ImageList16px: TImageList + left = 64 + Bitmap = { + 4C69020000001000000010000000FFFFFF00A3A4A5EF9FA2A5FF9EA1A5FF9DA1 + A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9DA1A5FF9EA1 + A5FF9FA2A5FFA3A4A5EFFFFFFF00FFFFFF009FA2A5FFFDDBB6FFF8DAB8FFF8DA + B9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DAB9FFF8DA + B8FFFDDBB6FF9FA2A5FFFFFFFF00FFFFFF009EA2A6FFF9D0A4FFE8A760FFE7A7 + 62FFE7A863FFE7A863FFE7A863FFE7A863FFE7A863FFE7A863FFE7A762FFE8A7 + 60FFF9D0A4FF9EA2A6FFFFFFFF00FFFFFF00A0A3A7FFFFCA8BFFF9C27EFFF9C2 + 7FFFF9C280FFF9C280FFF9C280FFF9C280FFF9C280FFF9C280FFF9C27FFFF9C2 + 7EFFFFCA8BFFA0A3A7FFFFFFFF00FFFFFF00A2A3A5FF7C7E7FFF7B7D80FF7C7E + 80FF7C7E81FF7B7E81FF7B7E82FF7B7E82FF7B7E81FF7C7E81FF7C7E80FF7B7D + 80FF7C7E7FFFA2A3A5FFFFFFFF00FFFFFF00A0A1A1FFF1F0F0FFF1EFEDFFF6F1 + ECFFF6F2ECFFF2F1EFFFF1F1F2FFF2F2F3FFF2F1EFFFF6F2ECFFF6F2ECFFF1F0 + EDFFF1F0F0FFA0A1A1FFFFFFFF00FFFFFF009F9F9FFFEDECEAFFDAD5CEFF1F7F + FFFF2266FFFFDDD8D1FF928F8CFF716F6CFFDED8D2FF2080FFFF2265FFFFDAD5 + CEFFEEECEAFF9F9F9FFFFFFFFF00FFFFFF009F9F9FFFEEECECFFDDD9D5FFE4DE + D6FFE5DFD7FFE0DDD9FFE0DEDDFFE1DFDEFFE1DDD9FFE5DFD7FFE5DFD6FFDDD9 + D5FFEEEDECFF9F9F9FFFFFFFFF00FFFFFF009E9F9FFFEEEDEDFFE0DEDDFF918E + 8AFF716F6BFFE5E2E2FF918F8CFF706E6CFFE4E2E2FF918F8CFF706E6AFFE1DF + DEFFEEEDEEFF9E9F9FFFFFFFFF00FFFFFF009E9E9EFFF0EEEEFFE4E2E2FFE9E7 + E7FFEAE8E9FFE8E6E6FFE9E7E8FFEAE8E9FFE6E5E7FFE5E6EBFFE4E6EBFFE2E2 + E4FFF0EEEEFF9E9E9EFFFFFFFF00FFFFFF009E9E9EFFF3F2F0FFE9E8E7FF8E8C + 8AFF6E6C6AFFEDECEBFF8F8D8AFF6E6C6BFFE9ECF0FFF0AC62FFF0AC62FFE5E8 + ECFFF2F2F1FF9E9E9EFFFFFFFF00FFFFFF009D9E9EFFF4F3F2FFEDECEBFFF2F1 + F0FFF3F3F2FFF0F0EFFFF3F2F1FFF3F3F3FFEDF1F6FFEEAD66FFE4A25BFFE9ED + F2FFF4F4F3FF9D9E9EFFFFFFFF00FFFFFF009E9E9EFFF7F6F6FFF2F1F0FF8D8A + 88FF6D6B68FFF7F6F5FF8D8B89FF6C6B69FFF2F6F9FFE49F55FFE49F55FFEEF2 + F5FFF7F6F7FF9E9E9EFFFFFFFF00FFFFFF009F9F9FFFFFFEFEFFFBFAFAFFFEFD + FDFFFEFDFDFFFDFCFCFFFEFDFDFFFEFDFEFFFBFCFDFFF9FCFFFFF9FCFFFFF9FA + FCFFFFFEFEFF9F9F9FFFFFFFFF00FFFFFF00969696C09F9F9FFF9E9E9EFF9E9E + 9EFF9E9F9FFF9E9E9EFF9E9E9EFF9E9F9FFF9E9E9EFF9D9E9FFF9D9E9FFF9D9E + 9EFF9F9F9FFF9E9E9EE1FFFFFF00FFFFFF000000002300000033000000330000 + 0033000000330000003300000033000000330000003300000033000000330000 + 0033000000330000002CFFFFFF004A7CA5004A7CA5004A7CA5004A7CA5004A7E + A7004A7EA8004A7EA8004A7EA8004A7EA800497DA7004579A400709BBE00B5D2 + EA00C3DAEF58CDE3F5FB3F75A1FF4B7CA6004A7CA5004A7CA6004A7EA8B04A82 + AEFF4A83B0FF4A83B0FF4A83B0FF4A83B0FF4A82AFFF447DA9FF709CBFFFB9D5 + EBFFB3D1EAFFC1DBF2FF4279A5FF4F79AB004C7AA7004A7BA6004A7FACFF4438 + 31FF433B37FF433D38FF433D38FF433D38FF423B36FF3C332CFFB9DAF5FF7FB0 + DAFF5495CCFFC0DAEFFF467CA8FF009242005276AF004E77AB004D7BB0FF4C3D + 3BFF4A4343FF484544FF484644FF484644FF474542FF433C36FF5FA1D8FF5C9A + CCFF5896C9FFB8D3EBFF4980ACFF00904C00009147001A866E0017866DFF0096 + 47FF523F45FF4F4749FF4D494AFF4C4A4AFF4C4848FF4A423DFF60A0D5FF5D98 + C9FF5894C6FFAFCCE6FF4B83B0FF008F4E00008F4C00008E4900008B44FFA0E8 + DAFF009144FF55434AFF524B4DFF4F4D4EFF4F4D4CFF4D4641FF5E9CD2FF5C95 + C5FF5990C1FFA6C4DFFF4E86B5FF008D4CEF008A47FF008844FF00853FFF00C1 + A0FF97E3D1FF008F43FF5A484EFF565051FF53514FFF524B45FF5B9ACDFF5C91 + C1FF20B7F5FF9EBCD7FF5189B8FF008A47FF61E1D0FF60DDCAFF63DCC8FF00C4 + 9BFF00C69CFF82E1C8FF009447FF5C5054FF585353FF574F4AFF5A96CAFF5B8F + BEFF22B9F7FF95B5D3FF548DBCFF008A47FF63EDD0FF00D4A0FF00D29EFF00CC + 9CFF00CD9CFF6FDCBDFF009346FF615457FF5C5756FF5B534DFF5794C5FF588E + BCFF47749BFF88AFCFFF5790C0FF008B4BF2008A47FF008845FF008441FF00DA + A2FF60D9B3FF008D42FF68545AFF625B5CFF605C5AFF605852FF5490C2FF558C + BAFF4E81ADFF7EA6C8FF5A94C4FF000000300000003300000033008C46FF4FDD + B0FF008D43FF6B585EFF655E60FF636160FF62605FFF645D57FF518DBEFF528A + B7FF5187B4FF739FC2FF5D97C9FF66565D0069555C0010866D0013826BFF0093 + 46FF715C62FF6A6263FF676463FF666463FF676462FF68615BFF4F8ABBFF5086 + B4FF4F84B1FF6895B9FF5F9BCDFF5E5B5C005F5A5C00635859003F69A5FF7566 + 67FF706869FF6D6969FF6C6A69FF6C6A69FF6C6A68FF6E6762FF4C89BAFF4E85 + B2FF4D83AEFF5D8CB2FF629ED1FF5C5C5CFF5C5C5CFF5E5B5AFF5E5A59FF5D5A + 5AFF5B5A5BFF5A5B5BFF5A5B5BFF5A5B5BFF5B5A5AFF5C5956FF576876FF4E7E + A4FF4C80ACFF5082ABFF65A2D5FF000000330000003300000033000000330000 + 0033000000330000003300000033000000330000003300000033000000330000 + 0033365D7B79497BA2FC68A4D9FF000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000120000003200000033 + } + end +end diff --git a/src/mainformunit.pas b/src/mainformunit.pas new file mode 100644 index 0000000..bb36777 --- /dev/null +++ b/src/mainformunit.pas @@ -0,0 +1,143 @@ +unit MainFormUnit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, LazFileUtils, Forms, Controls, Graphics, Dialogs, EditBtn, + StdCtrls, ExtCtrls, Menus, Windows, fpExprPars, lazutf8; + +type + TMainForm = class(TForm) + ExitMenuItem: TMenuItem; + ImageList16px: TImageList; + ShowHideMenuItem: TMenuItem; + TrayPopupMenu: TPopupMenu; + ResultEdit: TEdit; + QueryEdit: TEditButton; + TrayIcon: TTrayIcon; + procedure ExitMenuItemClick(Sender: TObject); + procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + procedure FormCreate(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure QueryEditButtonClick(Sender: TObject); + procedure QueryEditChange(Sender: TObject); + procedure QueryEditKeyPress(Sender: TObject; var Key: char); + procedure ShowHideMenuItemClick(Sender: TObject); + procedure TrayIconClick(Sender: TObject); + procedure ShowHideForm; + private + procedure WM_HotKeyHandler(var Message: TMessage); + message WM_HOTKEY; + end; + +var + MainForm: TMainForm; + +implementation + +uses Support, HotkeysUnit; + +{$R *.lfm} + +procedure TMainForm.WM_HotKeyHandler(var Message: TMessage); +begin + if (LOWORD(Message.lParam) = MOD_CONTROL) and (HIWORD(Message.lParam) = VK_1) then + ShowHideMenuItemClick(MainForm); + inherited; +end; + +procedure TMainForm.QueryEditChange(Sender: TObject); +var + t: integer; + parser: TFPExpressionParser; + parserResult: TFPExpressionResult; +begin + if length(QueryEdit.Text) = 0 then begin + ResultEdit.Text := '0,00'; + exit; + end; + + t := QueryEdit.SelStart; + QueryEdit.Text := ClearExpression(QueryEdit.Text); + QueryEdit.SelStart := t; + + parser := TFPExpressionParser.Create(nil); + try + parser.BuiltIns := [bcMath]; + parser.Expression := UTF8StringReplace(QueryEdit.Text,',','.',[rfReplaceAll]); + parserResult := parser.Evaluate; + ResultEdit.Text := formatfloat('0.00', ArgToFloat(parserResult)); + except + on E: Exception do + ResultEdit.Text := E.Message; + end; + parser.Free; +end; + +procedure TMainForm.QueryEditKeyPress(Sender: TObject; var Key: char); +begin + if Key = #13 then + QueryEdit.Text := ResultEdit.Text; +end; + +procedure TMainForm.ShowHideMenuItemClick(Sender: TObject); +begin + ShowHideForm; +end; + +procedure TMainForm.TrayIconClick(Sender: TObject); +begin + ShowHideForm; +end; + +procedure TMainForm.ShowHideForm; +begin + if MainForm.Visible then + MainForm.Hide + else + begin + if MainForm.WindowState = wsMinimized then + MainForm.WindowState := wsNormal; + MainForm.Show; + end; +end; + +procedure TMainForm.FormCreate(Sender: TObject); +begin + FormatSettings.DecimalSeparator := ','; + MainForm.Left := Screen.Width - MainForm.Width - 16; + MainForm.Top := Screen.Height - MainForm.Height - 64; + AssociateHotkeys(Handle); +end; + +procedure TMainForm.FormShow(Sender: TObject); +begin + QueryEdit.SetFocus; + QueryEdit.SelectAll; +end; + +procedure TMainForm.QueryEditButtonClick(Sender: TObject); +begin + QueryEdit.Text := ''; + QueryEdit.SetFocus; +end; + +procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); +begin + CloseAction := caHide; +end; + +procedure TMainForm.ExitMenuItemClick(Sender: TObject); +begin + TrayIcon.Hide; + try + UnregisterHotKey(Handle, 1); + GlobalDeleteAtom(1); + except; + end; + Application.Terminate; +end; + +end. diff --git a/src/make.bat b/src/make.bat new file mode 100644 index 0000000..7c24600 --- /dev/null +++ b/src/make.bat @@ -0,0 +1 @@ +lazbuild calculator.lpi diff --git a/src/support.pas b/src/support.pas new file mode 100644 index 0000000..6ef732d --- /dev/null +++ b/src/support.pas @@ -0,0 +1,31 @@ +unit Support; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils; + +function ClearExpression(input: string): string; // Удаление лишних символов из выражения + +implementation + +function ClearExpression(input: string): string; +var + i: integer; +begin + // Замена десятичного разделителя с точки на запятую + Result := stringreplace(input, '.', ',', [rfReplaceAll, rfIgnoreCase]); + + // Удаление всех лишних символов + i := 1; + while i <= length(Result) do + if not ((Result[i]) in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '+', '-', '*', '/', '(', ')']) then + Delete(Result, i, 1) + else + i := i + 1; +end; + +end. +