Advertisement
Vladislav8653

курса4

Jun 12th, 2023
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 27.82 KB | None | 0 0
  1. unit MainUnit;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Imaging.pngimage,
  8.   Vcl.StdCtrls, Vcl.Imaging.jpeg, FMX.Media,  ShellApi, Vcl.Menus;
  9.  
  10. type
  11.   TWelcomeWindow = class(TForm)
  12.     Logo: TImage;
  13.     SendButton: TButton;
  14.     GetButton: TButton;
  15.     Info: TMainMenu;
  16.     N1: TMenuItem;
  17.     N2: TMenuItem;
  18.     Telegram: TImage;
  19.     GitHub: TImage;
  20.     VK: TImage;
  21.     LinkedIn: TImage;
  22.     procedure SendButtonClick(Sender: TObject);
  23.     procedure GetButtonClick(Sender: TObject);
  24.     procedure N1Click(Sender: TObject);
  25.     procedure N2Click(Sender: TObject);
  26.     procedure TelegramClick(Sender: TObject);
  27.     procedure VKClick(Sender: TObject);
  28.     procedure GitHubClick(Sender: TObject);
  29.     procedure LinkedInClick(Sender: TObject);
  30.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  31.   private
  32.     { Private declarations }
  33.   public
  34.   end;
  35.  
  36. var
  37.   WelcomeWindow: TWelcomeWindow;
  38.  
  39. implementation
  40.  
  41. uses SendWindow, GetWindow;
  42.  
  43. {$R *.dfm}
  44.  
  45. procedure TWelcomeWindow.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  46. begin
  47.   CanClose := Application.MessageBox('Вы действительно хотите выйти?', 'Выход', MB_YESNO + MB_ICONQUESTION) = ID_YES;
  48. end;
  49.  
  50. procedure TWelcomeWindow.GetButtonClick(Sender: TObject);
  51. begin
  52.     GetParcel.ShowModal;
  53. end;
  54.  
  55. procedure TWelcomeWindow.TelegramClick(Sender: TObject);
  56. begin
  57.     ShellExecute(Handle, 'open', 'https://t.me/kirks_wah_wah', Nil, Nil, SW_SHOW);
  58. end;
  59.  
  60. procedure TWelcomeWindow.VKClick(Sender: TObject);
  61. begin
  62.     ShellExecute(Handle, 'open', 'https://vk.com/cortad810', Nil, Nil, SW_SHOW);
  63. end;
  64.  
  65. procedure TWelcomeWindow.GitHubClick(Sender: TObject);
  66. begin
  67.     ShellExecute(Handle, 'open', 'https://github.com/Vladislav8653', Nil, Nil, SW_SHOW);
  68. end;
  69.  
  70. procedure TWelcomeWindow.LinkedInClick(Sender: TObject);
  71. begin
  72.     ShellExecute(Handle, 'open', 'https://www.linkedin.com/in/alex-melnikov-691a67257/', Nil, Nil, SW_SHOW);
  73. end;
  74.  
  75. procedure TWelcomeWindow.N1Click(Sender: TObject);
  76. Const
  77.     STR1 = 'Здравствуйте, дорогой пользователь. Эта программа передает информацию (текст) с одного ПК на другой (другие).';
  78.     STR2 = 'Для того, чтобы использовать Ваш компьютер как приёмник, нажмите кнопку "получить".';
  79.     STR3 = 'Для того, чтобы использовать Ваш компьютер как передатчик, нажмите кнопку "передать"';
  80.     A = #13#10;
  81. begin
  82.     Application.MessageBox(STR1 + A + STR2 + A + STR3, 'Помощь', 0);
  83. end;
  84.  
  85. procedure TWelcomeWindow.N2Click(Sender: TObject);
  86. begin
  87.     Application.MessageBox('Арефин Владислав гр.251004', 'Разрабочик', 0);
  88. end;
  89.  
  90. procedure TWelcomeWindow.SendButtonClick(Sender: TObject);
  91. begin
  92.     SendParcel.ShowModal;
  93. end;
  94.  
  95. end
  96.  
  97. =========================================================================
  98. unit SendWindow;
  99.  
  100. interface
  101.  
  102. uses
  103.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  104.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Bass, Vcl.Menus,
  105.   Vcl.Imaging.jpeg, Vcl.ExtCtrls, Vcl.ComCtrls;
  106.  
  107. type
  108.   TSendParcel = class(TForm)
  109.     InputEdit: TEdit;
  110.     VarOfChose: TComboBox;
  111.     InfoLabel: TLabel;
  112.     TextLabel: TLabel;
  113.     OpenDialog1: TOpenDialog;
  114.     GoButton: TButton;
  115.     Logo: TImage;
  116.     Info: TMainMenu;
  117.     ExtendedInfo: TPopupMenu;
  118.     N1: TMenuItem;
  119.     N2: TMenuItem;
  120.     N3: TMenuItem;
  121.     N4: TMenuItem;
  122.     SaveDialog1: TSaveDialog;
  123.     ProgressBar: TProgressBar;
  124.     GoBinaryButton: TButton;
  125.     PSLabel: TLabel;
  126.     procedure VarOfChoseChange(Sender: TObject);
  127.     procedure GoButtonClick(Sender: TObject);
  128.     procedure InputEditChange(Sender: TObject);
  129.     procedure InputEditKeyPress(Sender: TObject; var Key: Char);
  130.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  131.     procedure N2Click(Sender: TObject);
  132.     procedure N4Click(Sender: TObject);
  133.     procedure N3Click(Sender: TObject);
  134.     procedure GoBinaryButtonClick(Sender: TObject);
  135.     procedure CreateListOfSound (Data : String);
  136.   private
  137.     { Private declarations }
  138.   public
  139.     { Public declarations }
  140.   end;
  141.  
  142. type
  143.     PList = ^TNode;
  144.     TNode = record
  145.         Next : PList;
  146.         Data : Integer;
  147.     end;
  148.  
  149.     PNode = ^TTreeNode;
  150.     TTreeNode = record
  151.         ch: Char;
  152.         freq: Integer;
  153.         left, right: PNode;
  154.     end;
  155.  
  156.     TPriorityQueue = record
  157.         nodes: array of PNode;
  158.         count: Integer;
  159.     end;
  160.  
  161.     TCharFrequency = record
  162.         ch: Char;
  163.         freq: Integer;
  164.     end;
  165.  
  166.     THuffmanCode = record
  167.         codeMap: array [Char] of string;
  168.   end;
  169.  
  170. var
  171.   SendParcel: TSendParcel;
  172.   Path, Data : String;
  173.   List : PList;
  174.   IsFileOpen : Boolean;
  175.  
  176. implementation
  177.  
  178. {$R *.dfm}
  179.  
  180. uses MainUnit, GetWindow;
  181.  
  182. procedure InitializePriorityQueue(var pq: TPriorityQueue);
  183. begin
  184.     SetLength(pq.nodes, 256);
  185.     pq.count := 0;
  186. end;
  187.  
  188. procedure Enqueue(var pq: TPriorityQueue; node: PNode);
  189. var
  190.     i: Integer;
  191. begin
  192.     i := pq.count;
  193.     while (i > 0) and (node.freq < pq.nodes[i - 1].freq) do
  194.     begin
  195.         pq.nodes[i] := pq.nodes[i - 1];
  196.         Dec(i);
  197.     end;
  198.     pq.nodes[i] := node;
  199.     Inc(pq.count);
  200. end;
  201.  
  202. function Dequeue(var pq: TPriorityQueue): PNode;
  203. begin
  204.     if pq.count > 0 then
  205.     begin
  206.         Result := pq.nodes[0];
  207.         Dec(pq.count);
  208.         Move(pq.nodes[1], pq.nodes[0], pq.count * SizeOf(PNode));
  209.     end
  210.     else
  211.         Result := nil;
  212. end;
  213.  
  214. procedure BuildHuffmanTree(const text: string; var root: PNode);
  215. var
  216.     freq: array [Char] of Integer;
  217.     ch: Char;
  218.     i: Integer;
  219.     node: PNode;
  220.     pq: TPriorityQueue;
  221. begin
  222.     for ch := Low(Char) to High(Char) do
  223.         freq[ch] := 0;
  224.  
  225.     for i := 1 to Length(text) do
  226.         Inc(freq[text[i]]);
  227.  
  228.     InitializePriorityQueue(pq);
  229.  
  230.     for ch := Low(Char) to High(Char) do
  231.     begin
  232.         if freq[ch] > 0 then
  233.         begin
  234.             New(node);
  235.             node.ch := ch;
  236.             node.freq := freq[ch];
  237.             node.left := nil;
  238.             node.right := nil;
  239.             Enqueue(pq, node);
  240.         end;
  241.     end;
  242.  
  243.     while pq.count > 1 do
  244.     begin
  245.         New(node);
  246.         node.left := Dequeue(pq);
  247.         node.right := Dequeue(pq);
  248.         node.freq := node.left.freq + node.right.freq;
  249.         Enqueue(pq, node);
  250.     end;
  251.  
  252.     root := Dequeue(pq);
  253. end;
  254.  
  255. procedure EncodeData(node: PNode; const str: string; var huffmanCode: THuffmanCode);
  256. begin
  257.     if node = nil then
  258.         Exit;
  259.  
  260.     if (node^.left = nil) and (node^.right = nil) then
  261.         huffmanCode.codeMap[node^.ch] := str
  262.     else
  263.     begin
  264.         EncodeData(node^.left, str + '0', huffmanCode);
  265.         EncodeData(node^.right, str + '1', huffmanCode);
  266.     end;
  267. end;
  268.  
  269. procedure DecodeData(node: PNode; var index: Integer; const sb: string);
  270. begin
  271.     if node = nil then
  272.         Exit;
  273.     if (node^.left = nil) and (node^.right = nil) then
  274.     begin
  275.         Write(node^.ch);
  276.         Exit;
  277.     end;
  278.     Inc(index);
  279.     if sb[index] = '0' then
  280.         DecodeData(node^.left, index, sb)
  281.     else
  282.         DecodeData(node^.right, index, sb);
  283. end;
  284.  
  285. procedure FreeTree(node: PNode);
  286. begin
  287.     if node = nil then
  288.         Exit;
  289.     FreeTree(node^.left);
  290.     FreeTree(node^.right);
  291.     Dispose(node);
  292. end;
  293.  
  294. function CreateHuffmanTree(const text: string) : String;
  295. var
  296.     root: PNode;
  297.     huffmanCode: THuffmanCode;
  298.     sb: TStringBuilder;
  299.     i, index: Integer;
  300.     ch: Char;
  301.     StrForSpeaker, BinaryStr : String;
  302. begin
  303.     if text = '' then
  304.         Exit;
  305.     BuildHuffmanTree(text, root);
  306.     FillChar(huffmanCode, SizeOf(huffmanCode), 0);
  307.     EncodeData(root, '', huffmanCode);
  308.     for ch := Low(Char) to High(Char) do
  309.     begin
  310.         if huffmanCode.codeMap[ch] <> '' then
  311.         begin
  312.             StrForSpeaker := StrForSpeaker + ch + huffmanCode.codeMap[ch];
  313.         end;
  314.     end;
  315.     sb := TStringBuilder.Create;
  316.     for i := 1 to Length(text) do
  317.         sb.Append(huffmanCode.codeMap[text[i]]);
  318.     BinaryStr := sb.ToString;
  319.     FreeTree(root);
  320.     sb.Free;
  321.     CreateHuffmanTree := (StrForSpeaker + '~' +BinaryStr);
  322. end;
  323.  
  324. procedure AddinList(var List: PList; Freq: Integer);
  325. var
  326.     NewItem, Head: PList;
  327. begin
  328.     New(NewItem);
  329.     NewItem^.Data := Freq;
  330.     NewItem^.Next := nil;
  331.     if List = nil then
  332.         List := NewItem
  333.     else
  334.     begin
  335.         Head := List;
  336.         while Head^.Next <> nil do
  337.             Head := Head^.Next;
  338.         Head^.Next := NewItem;
  339.     end;
  340. end;
  341.  
  342. procedure DeleteList(var List: PList);
  343. var
  344.     CurrentNode, NextNode: PList;
  345. begin
  346.     CurrentNode := List;
  347.     while CurrentNode <> nil do
  348.     begin
  349.         NextNode := CurrentNode^.Next;
  350.         Dispose(CurrentNode);
  351.         CurrentNode := NextNode;
  352.     end;
  353.     List := nil;
  354. end;
  355.  
  356. procedure TSendParcel.FormClose(Sender: TObject; var Action: TCloseAction);
  357. begin
  358.     InputEdit.Visible := False;
  359.     TextLabel.Visible := False;
  360.     GoButton.Visible := False;
  361.     PSLabel.Visible := False;
  362.     GoButton.Enabled := False;
  363.     GoBinaryButton.Visible := False;
  364.     GoBinaryButton.Enabled := False;
  365.     ProgressBar.Visible := False;
  366.     VarOFChose.ItemIndex := -1;
  367.     DeleteList(List);
  368.     InputEdit.Text := '';
  369. end;
  370.  
  371. procedure PlaySound (Frequancy : Cardinal);
  372. Const
  373.     Duration = 500;
  374. begin
  375.    Winapi.Windows.Beep(Frequancy, Duration);
  376. end;
  377.  
  378. procedure BinaryBeep(Str : String);
  379. Var
  380.     I : Integer;
  381. Const
  382.     ZERO = 400;
  383.     ONE = 7000;
  384. begin
  385.     For I := Low(Str) To High(Str) Do
  386.     begin
  387.         If Str[I] = '1' then
  388.             AddinList(List, ONE)
  389.         else
  390.             AddinList(List, ZERO);
  391.     end;
  392. end;
  393.  
  394. procedure TSendParcel.GoBinaryButtonClick(Sender: TObject);
  395. Var
  396.     Huffman, BinaryPart : String;
  397.     I, Proc, DataLength, Counter: Integer;
  398.     Element : AnsiChar;
  399.     Repeats : Set of Char;
  400. begin
  401.     Data := InputEdit.Text;
  402.     If Length(Data) > 4 then
  403.     begin
  404.         For I := Low(Data) to High(Data) Do
  405.         begin
  406.             If not(Data[I] in Repeats) then
  407.             begin
  408.                 Element := AnsiChar(Data[I]);
  409.                 Include(Repeats, Element);
  410.                 Inc(Counter);
  411.                 If Counter > 4 then
  412.                 begin
  413.                     GoBinaryButton.Enabled := False;
  414.                     exit;
  415.                 end;
  416.             end;
  417.         end;
  418.     end;
  419.     Huffman := CreateHuffmanTree(Data);
  420.     For I := Low(Huffman) to High(Huffman) Do
  421.     begin
  422.         If Huffman[I] = '~' then
  423.         begin
  424.             BinaryPart := Copy(Huffman, I + 1, (Length(Huffman) - I + 1));
  425.             Huffman := Copy(Huffman, 1, (I - 1)) ;
  426.             break;
  427.         end;
  428.     end;
  429.     CreateListOfSound(Huffman);
  430.     BinaryBeep(BinaryPart);
  431.     ProgressBar.Visible := True;
  432.     I := 0;
  433.     DataLength := Length(Data);
  434.     while List <> nil do
  435.     begin
  436.         PlaySound(List^.Data);
  437.         List := List^.Next;
  438.         Proc := ((I * 100) div DataLength - 1);
  439.         ProgressBar.Position := Proc;
  440.         Application.ProcessMessages;
  441.         Inc(I);
  442.     end;
  443.     ProgressBar.Position := 100;
  444. end;
  445.  
  446. procedure TSendParcel.CreateListOfSound (Data : String);
  447. var
  448.     BaseAsciiCode, Gap, I: Integer;
  449.     IsEnNow : Boolean;
  450. Const
  451.     MIN_FREQ = 500;
  452.     STEP = 50;
  453.     MIN_ASCII_EN = 32;
  454.     MAX_ASCII_EN = 125;
  455.     MIN_ASCII_RU = 1040;
  456.     MAX_ASCII_RU = 1103;
  457.     RU_SIGN = 6000;
  458.     EN_SIGN = 7000;
  459. begin
  460.     IsEnNow := False;
  461.     DeleteList(List);
  462.     For I := Low(Data) to High(Data) Do
  463.     begin
  464.         If (Ord(Data[I]) >= MIN_ASCII_EN) and (Ord(Data[I]) <= MAX_ASCII_EN) then
  465.         begin
  466.             If not(IsEnNow) then
  467.                 AddinList(List, EN_SIGN);
  468.             Gap := Ord(Data[I]) - MIN_ASCII_EN;
  469.             AddinList(List, MIN_FREQ + STEP * Gap);
  470.             IsEnNow := True;
  471.         end;
  472.         If (Ord(Data[I]) >= MIN_ASCII_RU) and (Ord(Data[I]) <= MAX_ASCII_RU) then
  473.         begin
  474.              If IsEnNow then
  475.                 AddinList(List, RU_SIGN);
  476.             Gap := Ord(Data[I]) - MIN_ASCII_RU;
  477.             AddinList(List, MIN_FREQ + STEP * Gap);
  478.             IsEnNow := False;
  479.         end;
  480.     end;
  481. end;
  482.  
  483. procedure TSendParcel.GoButtonClick(Sender: TObject);
  484. var
  485.     DataLength, I, Proc : Integer;
  486. begin
  487.     Data := InputEdit.Text;
  488.     DataLength := Length(InputEdit.Text);
  489.     CreateListOfSound(Data);
  490.     ProgressBar.Visible := True;
  491.     I := 0;
  492.     while List <> nil do
  493.     begin
  494.         PlaySound(List^.Data);
  495.         List := List^.Next;
  496.         Proc := ((I * 100) div DataLength - 1);
  497.         ProgressBar.Position := Proc;
  498.         Application.ProcessMessages;
  499.         Inc(I);
  500.     end;
  501.     ProgressBar.Position := 100;
  502. end;
  503.  
  504. procedure TSendParcel.InputEditChange(Sender: TObject);
  505. var
  506.     Repeats : Set of Char;
  507.     I, Counter: Integer;
  508.     Element : AnsiChar;
  509. begin
  510.     Repeats := [];
  511.     Data := InputEdit.Text;
  512.     If Length(Data) > 0 then
  513.     begin
  514.         GoButton.Enabled := True;
  515.         GoBinaryButton.Enabled := True;
  516.         PSLabel.Visible := True;
  517.         N3.Enabled := True;
  518.     end
  519.     else
  520.     begin
  521.         GoButton.Enabled := False;
  522.         GoBinaryButton.Enabled := False;
  523.         PSLabel.Visible := False;
  524.         N3.Enabled := False;
  525.     end;
  526.     ProgressBar.Position := 0;
  527.     Counter := 0;
  528.     If Length(Data) > 4 then
  529.     begin
  530.         For I := Low(Data) to High(Data) Do
  531.         begin
  532.             If not(Data[I] in Repeats) then
  533.             begin
  534.                 Element := AnsiChar(Data[I]);
  535.                 Include(Repeats, Element);
  536.                 Inc(Counter);
  537.                 If Counter > 4 then
  538.                 begin
  539.                     GoBinaryButton.Enabled := False;
  540.                     break;
  541.                 end;
  542.             end;
  543.         end;
  544.     end;
  545. end;
  546.  
  547. procedure TSendParcel.InputEditKeyPress(Sender: TObject; var Key: Char);
  548. begin
  549.     If (Key = #13) and (GoButton.Enabled) then
  550.         GoButton.Click
  551. end;
  552.  
  553. function Open (): String;
  554. Begin
  555.     With SendParcel Do
  556.     Begin
  557.         If OpenDialog1.Execute Then
  558.         Begin
  559.             Path := OpenDialog1.Filename;
  560.             IsFileOpen := True;
  561.         End
  562.         Else
  563.             IsFileOpen := False;
  564.     End;
  565.     Open := Path;
  566. End;
  567.  
  568. function Save (): String;
  569. Begin
  570.     With SendParcel Do
  571.     Begin
  572.         SaveDialog1.Title := 'Сохранить текст';
  573.         SaveDialog1.Filter := 'txt|*.txt';
  574.         If SaveDialog1.Execute Then
  575.         Begin
  576.             Path := SaveDialog1.Filename;
  577.             IsFileOpen := True;
  578.         End
  579.         Else
  580.             IsFileOpen := False;
  581.     End;
  582.     Save := Path;
  583. End;
  584.  
  585. function GetString(Var FileOutput: TextFile): String;
  586. Var
  587.     IsRight : Boolean;
  588.     Str : String;
  589. Begin
  590.     IsRight := True;
  591.     Try
  592.         Readln(FileOutput, Str);
  593.         Str := Trim (Str);
  594.     Except
  595.         IsRight := False;
  596.     End;
  597.     If IsRight then
  598.     Begin
  599.         GetString := Str;
  600.     End;
  601. End;
  602.  
  603. procedure TSendParcel.N2Click(Sender: TObject);
  604. Var
  605.     FileInput : TextFile;
  606.     PlayData : String;
  607. begin
  608.     OpenDialog1.Title := 'Выбрать текст';
  609.     OpenDialog1.Filter := 'txt|*.txt';
  610.     IsFileOpen := False;
  611.     Path := Open();
  612.     AssignFile(FileInput, Path);
  613.     Reset(FileInput);
  614.     If (IsFileOpen) then
  615.         PlayData := GetString(FileInput);
  616.     CloseFile(FileInput);
  617.     If (PlayData <> '') then
  618.     Begin
  619.         VarOfChose.ItemIndex := 0;
  620.         InputEdit.Text := PlayData;
  621.         InputEdit.Visible := True;
  622.         TextLabel.Visible := True;
  623.         GoButton.Visible := True;
  624.         GoBinaryButton.Visible := True;
  625.         PSLabel.Visible := True;
  626.     End;
  627. end;
  628.  
  629. procedure TSendParcel.N3Click(Sender: TObject);
  630. Var
  631.     FileOutput: TextFile;
  632.     IsCorrect : Boolean;
  633. begin
  634.     IsCorrect := True;
  635.     Path := Save();
  636.     If (IsFileOpen) Then
  637.     Begin
  638.         try
  639.             AssignFile(FileOutput, Path);
  640.             Rewrite(FileOutput);
  641.             Write(FileOutput, Data);
  642.         except
  643.             IsCorrect := False;
  644.             Application.MessageBox('Запись в файл не удалась.', 'Ошибка', MB_ICONSTOP);
  645.         end;
  646.         if IsCorrect then
  647.         Begin
  648.             Application.MessageBox('Запись файла выполнена успешно.', 'Результат', 0);
  649.             CloseFile(FileOutput);
  650.         End;
  651.     End;
  652. end;
  653.  
  654. procedure TSendParcel.N4Click(Sender: TObject);
  655. Const
  656.     STR1 = 'Выберите, какой тип данных вы хотите передать с помощью звуковых волн.';
  657.     STR2 = 'Для этого кликните на серенькое окошко справа от строки и снизу от фотографии.';
  658.     STR3 = 'P.S. Передача фотографий пока не доступна.';
  659.     A = #13#10;
  660. begin
  661.     Application.MessageBox(STR1 + A + STR2 + A + STR3, 'Помощь', 0);
  662. end;
  663.  
  664. procedure TSendParcel.VarOfChoseChange(Sender: TObject);
  665. Const
  666.     STR_INPUT = 0;
  667.     IMAGE_INPUT = 1;
  668. begin
  669.     if VarOFChose.ItemIndex = STR_INPUT then
  670.     begin
  671.         InputEdit.Visible := True;
  672.         TextLabel.Visible := True;
  673.         GoButton.Visible := True;
  674.         GoBinaryButton.Visible := True;
  675.         N2.Enabled := True;
  676.     end;
  677.     if VarOFChose.ItemIndex = IMAGE_INPUT then
  678.     begin
  679.          MessageBox(SendParcel.Handle, Pchar('Дорогой пользователь, функция передачи картинок будет реализована в ближайшем будущем. Спасибо за понимание.'), 'Извинения', MB_ICONINFORMATION);
  680.          VarOfChose.ItemIndex := -1;
  681.          N2.Enabled := False;
  682.          N3.Enabled := False;
  683.     end;
  684. end;
  685.  
  686. end.
  687. =========================================================================
  688. unit GetWindow;
  689.  
  690. interface
  691.  
  692. uses
  693.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  694.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  695.   Vcl.Imaging.pngimage, Vcl.ExtCtrls, MainUnit, Bass, BassEnc, BassEnc_MP3,
  696.   Vcl.ComCtrls, Vcl.Menus, Vcl.MPlayer;
  697.  
  698.  
  699. type
  700.   TFft = array [0 .. 1023] of Single;
  701.  
  702.   TGetParcel = class(TForm)
  703.     RecordButton: TButton;
  704.     StopRecordButton: TButton;
  705.     Logo: TImage;
  706.     ShowResultsButton: TButton;
  707.     ResultEdit: TEdit;
  708.     PlayButton: TButton;
  709.     OpenDialog: TOpenDialog;
  710.     SaveDialog: TSaveDialog;
  711.     MainMenu: TMainMenu;
  712.     PopupMenu: TPopupMenu;
  713.     N1: TMenuItem;
  714.     N2: TMenuItem;
  715.     N3: TMenuItem;
  716.     N4: TMenuItem;
  717.     Timer: TTimer;
  718.     IndicateGraph: TPaintBox;
  719.     MediaPlayer: TMediaPlayer;
  720.     Procedure Draw(HWND: THandle; DrawData: TFft; X, Y: Integer);
  721.     procedure FormDestroy(Sender: TObject);
  722.     procedure RecordButtonClick(Sender: TObject);
  723.     procedure StopRecordButtonClick(Sender: TObject);
  724.     procedure PlayButtonClick(Sender: TObject);
  725.     procedure ShowResultsButtonClick(Sender: TObject);
  726.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  727.     procedure N4Click(Sender: TObject);
  728.     procedure N2Click(Sender: TObject);
  729.     procedure TimerTimer(Sender: TObject);
  730.     procedure IndicateGraphPaint(Sender: TObject);
  731.     procedure N3Click(Sender: TObject);
  732.     procedure FormCreate(Sender: TObject);
  733.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  734.   private
  735.     { Private declarations }
  736.   public
  737.     { Public declarations }
  738.   end;
  739. var
  740.   GetParcel: TGetParcel;
  741.   Channel: HRECORD;
  742.    // визуализация
  743.   DrawPeaks: array [0 .. 164] of Longint;
  744.   DrawFallOff: array [0 .. 164] of Longint;
  745.    // конец
  746.   WasSMTHPlayed, IsRecording : Boolean;
  747.  
  748. implementation
  749.  
  750. {$R *.dfm}
  751. uses SendWindow;
  752.  
  753. function RecordingCallback(Handle: HRECORD; buffer: Pointer; length: DWORD; user: Pointer): boolean; stdcall;
  754. begin
  755.     Result := True;
  756. end;
  757.  
  758. procedure ListenSurrounding ();
  759. var
  760.     IsCorrect : Boolean;
  761. begin
  762.     IsCorrect := False;
  763.     if BassEncMP3_IsAvailable and BASS_IsAvailable then
  764.        IsCorrect := True
  765.     else
  766.         MessageBox(GetParcel.Handle, Pchar('Что-то пошло неверным образом..'), 'Извинения', MB_ICONSTOP);
  767.     If IsCorrect then
  768.     begin
  769.         if not BASS_RecordInit(-1) then
  770.             Application.MessageBox('Не получается получить доступ к записывающему устройству.', 'Ошибка', MB_ICONSTOP)
  771.         else
  772.         begin
  773.             Channel:= BASS_RecordStart(44100, 2, 0, @RecordingCallback, nil);
  774.             if Channel = 0 then
  775.                 Application.MessageBox('Невозможно начать запись.', 'Ошибка', MB_ICONSTOP)
  776.             else
  777.             begin
  778.                 BASS_Encode_MP3_StartFile(Channel, '', BASS_ENCODE_AUTOFREE or BASS_UNICODE, PChar('запись.mp3'));
  779.             end;
  780.         end;
  781.     end;
  782. end;
  783.  
  784. procedure TGetParcel.PlayButtonClick(Sender: TObject);
  785. begin
  786.     MediaPlayer.FileName:= ('запись.mp3');
  787.     MediaPlayer.Open;
  788.     MediaPlayer.Play;
  789.     WasSMTHPlayed := True;
  790. end;
  791.  
  792. procedure TGetParcel.RecordButtonClick(Sender: TObject);
  793. begin
  794.     IsRecording := True;
  795.     ListenSurrounding();
  796.     StopRecordButton.Enabled := True;
  797.     RecordButton.Enabled := False;
  798.     Timer.Enabled := True;
  799. end;
  800.  
  801. procedure TGetParcel.ShowResultsButtonClick(Sender: TObject);
  802. begin
  803.     ResultEdit.Visible := True;
  804.     ResultEdit.Text := Data; // к сожалению, так
  805. end;
  806.  
  807. procedure TGetParcel.StopRecordButtonClick(Sender: TObject);
  808. begin
  809.     BASS_ChannelStop(Channel);
  810.     BASS_RecordFree;
  811.     RecordButton.Enabled := True;
  812.     PlayButton.Enabled := True;
  813.     ShowResultsButton.Enabled := True;
  814.     RecordButton.Caption := 'Повторить прослушивание';
  815.     N4.Enabled := True;
  816.     StopRecordButton.Enabled := False;
  817.     Timer.Enabled := False;
  818.     IsRecording := False;
  819. end;
  820.  
  821. procedure TGetParcel.TimerTimer(Sender: TObject);
  822. var
  823.     FFTFata: TFft;
  824. begin
  825.     BASS_ChannelGetData(Channel, @FFTFata, BASS_DATA_FFT1024);
  826.     Draw(IndicateGraph.Canvas.Handle, FFTFata, 0, -5);
  827. end;
  828.  
  829. procedure TGetParcel.FormClose(Sender: TObject; var Action: TCloseAction);
  830. begin
  831.     StopRecordButton.Enabled := False;
  832.     PlayButton.Enabled := False;
  833.     ShowResultsButton.Enabled := False;
  834.     ResultEdit.Visible := False;
  835.     ResultEdit.Text := '';
  836.     RecordButton.Caption := 'Прослушать окружение';
  837.     N4.Enabled := False;
  838.     If WasSMTHPlayed then
  839.         MediaPlayer.Stop;
  840. end;
  841.  
  842. procedure TGetParcel.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  843. begin
  844.     If IsRecording then
  845.     begin
  846.         CanClose := False;
  847.         Application.MessageBox('Пожалуйста, завершите запись, прежде чем выйти.', 'Ошибка', MB_ICONSTOP);
  848.     end;
  849. end;
  850.  
  851. procedure TGetParcel.FormCreate(Sender: TObject);
  852. begin
  853.     WasSMTHPlayed := False;
  854. end;
  855.  
  856. procedure TGetParcel.FormDestroy(Sender: TObject);
  857. begin
  858.     BASS_RecordFree;
  859.     BASS_Free;
  860. end;
  861.  
  862. procedure TGetParcel.IndicateGraphPaint(Sender: TObject);
  863. begin
  864.     IndicateGraph.Canvas.Pen.Color := clBlack;
  865.     IndicateGraph.Canvas.Brush.Color := clWhite;
  866.     IndicateGraph.Canvas.Rectangle(0, 0, IndicateGraph.Width,
  867.     IndicateGraph.Height);
  868. end;
  869.  
  870. procedure TGetParcel.N2Click(Sender: TObject);
  871. var
  872.     ChannelFile : File of HRECORD;
  873. Const
  874.     STR1 = 'Дорогой пользователь, пока считывание дескриптора канала с файла не имеет смысла, так как он не используется(ввиду нерабочей функции приема информации). Знайте, что Вы все сделали верно и логика сработала правильно, просто не ожидайте дальнейших действий.';
  875. begin
  876.     AssignFile(ChannelFile, Path);
  877.     OpenDialog.Title := 'Выбрать дескриптор канала';
  878.     OpenDialog.Filter := 'channel|*.channel';
  879.     If(OpenDialog.Execute) Then
  880.     Begin
  881.         try
  882.             Path := OpenDialog.FileName;
  883.             Reset(ChannelFile, Path);
  884.             While(Not(Eof(ChannelFile))) Do
  885.             Begin
  886.                 Read(ChannelFile, Channel);
  887.             End;
  888.         except
  889.              MessageBox(GetParcel.Handle, Pchar('Чтение файла не удалось.'), 'Извинения', MB_ICONSTOP);
  890.         end;
  891.         CloseFile(ChannelFile);
  892.         //PlayButton.Enabled := True;
  893.         //ShowResultsButton.Enabled := True;
  894.         Application.MessageBox(STR1, 'Успех', 0);
  895.     End;
  896. end;
  897.  
  898. procedure TGetParcel.N3Click(Sender: TObject);
  899. Const
  900.     STR1 = 'Чтобы начать прослушивать окружение, нажмите кнопку "Прослушать окружение".';
  901.     STR2 = 'Чтобы закончить прослушивать окружение, нажмите кнопку "Закончить слушать".';
  902.     STR3 = 'По нажатию кнопки "Результат" поле под картинкой будет заполнено раскодированной из звука информацией*.';
  903.     STR4 = '* - раскодирование информации не работает. Информация в поле соответствует последней закодированной. К сожалению, это главная проблема этой программы и головная боль разработчика.';
  904.     A = #13#10;
  905. begin
  906.     Application.MessageBox(STR1 + A + STR2 + A + STR3 + A + A + A + STR4, 'Помощь', 0);
  907. end;
  908.  
  909. procedure TGetParcel.N4Click(Sender: TObject);
  910. var
  911.     ChannelFile : File of HRECORD;
  912.     Str : String;
  913. begin
  914.     SaveDialog.Title := 'Сохранить дескриптор канала';
  915.     SaveDialog.Filter := 'channel|*.channel';
  916.     If (SaveDialog.Execute) then
  917.     Begin
  918.         Path := SaveDialog.FileName;
  919.         Str := ExtractFileExt(Path);
  920.         If(Str = '') Then
  921.             Path := Path + '.channel';
  922.         Rewrite(ChannelFile, Path);
  923.         Seek(ChannelFile, 0);
  924.         Truncate(ChannelFile);
  925.         Write(ChannelFile, Channel);
  926.         CloseFile(ChannelFile);
  927.         Application.MessageBox('Готово!', 'Успех', 0);
  928.     End;
  929. end;
  930.  
  931.  
  932. procedure TGetParcel.Draw(HWND: THandle; DrawData:TFft; X, Y: Integer);
  933. var
  934.   I, YPos: Longint;
  935.   YVal: Single;
  936. begin
  937.     IndicateGraph.Canvas.Pen.Color := clBlack;
  938.     IndicateGraph.Canvas.Brush.Color := clWhite;
  939.     IndicateGraph.Canvas.Rectangle(0, 0, IndicateGraph.Width, IndicateGraph.Height);
  940.     IndicateGraph.Canvas.Pen.Color := clRed;
  941.     for I := 0 to 163 do
  942.     begin
  943.         YVal := Abs(DrawData[I]);
  944.         YPos := Trunc((YVal) * 500);
  945.         if YPos > IndicateGraph.Height then
  946.             YPos := IndicateGraph.Height;
  947.         if YPos >= DrawPeaks[I] then
  948.             DrawPeaks[I] := YPos
  949.         else
  950.             DrawPeaks[I] := DrawPeaks[I] - 1;
  951.         if YPos >= DrawFallOff[I] then
  952.             DrawFallOff[I] := YPos
  953.         else
  954.             DrawFallOff[I] := DrawFallOff[I] - 3;
  955.         IndicateGraph.Canvas.Pen.Color := clBlue;
  956.         IndicateGraph.Canvas.MoveTo(X + I * (3 + 1), Y + IndicateGraph.Height - DrawPeaks[I]);
  957.         IndicateGraph.Canvas.LineTo(X + I * (3 + 1) + 3, Y + IndicateGraph.Height - DrawPeaks[I]);
  958.         IndicateGraph.Canvas.Pen.Color := clRed;
  959.         IndicateGraph.Canvas.Brush.Color := clRed;
  960.         IndicateGraph.Canvas.Rectangle(X + I * (3 + 1), Y + IndicateGraph.Height - DrawFallOff[I], X + I * (3 + 1) + 3, Y + IndicateGraph.Height);
  961.       end;
  962. end;
  963. end.
  964.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement