procedure LoadModules; var i: Integer; begin for i := 0 to Length(Module) - 1 do begin if Module[i].Handle > 0 then FreeModule(Module[i]); if LoadModule(Module[i]) then DetermineModuleType(Module[i]); end; end; function LoadModule(var M: TModule): boolean; var B: String; C: Integer; begin with M do begin Handle := LoadLibrary(PWideChar(FileName)); if Handle > 0 then begin @SetLanguage := GetProcAddress(Handle, 'SetLanguage'); IncAndUpdateProgress; // - @SendLanguageData := GetProcAddress(Handle, 'SendLanguageData'); IncAndUpdateProgress; @GetName := GetProcAddress(Handle, 'GetName'); IncAndUpdateProgress; // , // if @GetName <> nil then begin B := GetName; C := Pos(ControlCodeMarker, B); if C > 0 then begin Name := Copy(B, C + 1, Length(B)); ControlCode := Copy(B, 1, C - 1); ControlCodeFormated := FormatControlCode(ControlCode); end else begin Name := B; ControlCode := MainForm.LanguageData[133]; end; end else begin Name := MainForm.LanguageData[114]; ControlCode := MainForm.LanguageData[133]; end; if (@OpenWindow <> nil) and (@CloseWindow <> nil) then WindowState := closed else WindowState := window_does_not_exist; if (@Sleep <> nil) and (@WakeUp <> nil) then ModuleState := working else ModuleState := module_cant_sleep; LoadStatistics; // Result := true; end else Result := false; end; end; function DetermineModuleType(var M: TModule): TModuleType; begin with M do begin MType := undetermined; if (@SetLanguage = nil) and ... (* nil *) then MType := erroneous_or_empty else begin if (@SetSource <> nil) or (@NextData <> nil) or (@Progress <> nil) or (@RestartParsing <> nil) then MType := parser else begin if (@GetData <> nil) and (@SendData <> nil) then MType := input_and_output else if (@GetData <> nil) and (@SendData = nil) then MType := only_input else if (@GetData = nil) and (@SendData <> nil) then MType := only_output else if (@GetData = nil) and (@SendData = nil) then MType := no_input_and_no_output; end; end; Result := MType; end; end;
TIOThread = class(TThread) public const SleepTime = 1000; var Module: TModule; SelfID: Integer; constructor Create(M: TModule; ID: Integer); protected procedure Execute; override; end;
procedure TIOThread.Execute; procedure GetData; var M: String; begin M := String(Module.GetData); if M <> SCM_No_Message then Synchronize( procedure begin Pool.AddRecord(M, SelfID); end); end; procedure SendData; var i: Integer; begin with Pool do if not Empty then begin for i := 0 to Length(Records) - 1 do with Records[i] do if not ModuleGot[SelfID] and (AuthorID <> SelfID) then begin Module.SendData(PChar(Text)); ModuleGot[SelfID] := true; end; Synchronize( procedure begin CheckAndDeleteOddRecords; end); end; end; begin inherited; while not Terminated do begin case Module.MType of only_input: GetData; only_output: SendData; input_and_output: begin SendData; GetData; end; end; Sleep(SleepTime); end; end;
TPoolRecord = record Text: String; AuthorID: Integer; ModuleGot: array of Boolean; end; TPool = class Records: array of TPoolRecord; Empty: Boolean; procedure AddRecord(RecordText: String; RecordAuthor: Integer); procedure CheckAndDeleteOddRecords; constructor Create; procedure Show; end; procedure TPool.AddRecord(RecordText: String; RecordAuthor: Integer); var i, RL: Integer; begin RL := Length(Records); SetLength(Records, RL + 1); with Records[RL] do begin Text := RecordText; AuthorID := RecordAuthor; SetLength(ModuleGot, OutputModulesCount); for i := 0 to OutputModulesCount - 1 do if i = AuthorID then ModuleGot[i] := true else ModuleGot[i] := false; end; with MainForm, MainForm.ChatBox.Lines do case RecordAuthor of - 1: Add(User.Name + ': ' + RecordText); else if RecordText = SCM_Dont_Know_Answer then begin if DontKnowCheckBtn.Checked then Add(LanguageData[156]); end else Add(AVirtual.Name + ': ' + RecordText); end; Empty := false; end; procedure TPool.CheckAndDeleteOddRecords; function ItsOdd(ID: Integer): Boolean; var i: Integer; begin ItsOdd := true; with Records[ID] do for i := 0 to Length(ModuleGot) - 1 do if not ModuleGot[i] then begin ItsOdd := false; exit; end; end; procedure DeleteRecord(ID: Integer); var i: Integer; begin for i := ID to Length(Records) - 2 do Records[i] := Records[i + 1]; SetLength(Records, Length(Records) - 1); end; var i: Integer; begin if not Empty then begin for i := Length(Records) - 1 downto 0 do if ItsOdd(i) then DeleteRecord(i); if Length(Records) = 0 then Empty := true; end; if MainForm.PoolShowBtn.Checked then Show; end;
library ; uses System.SysUtils, System.Classes, SystemControlMessagesUnit in '..\..\AmigaVirtual\SystemControlMessagesUnit.pas', MainFormUnit in 'MainFormUnit.pas', const ControlCode = ++; Name = ControlCode + '> '; Help = '' + #13 + ''; var FormState: (closed, opened); Buffer, VirtualName: String; NewMessageGot: Boolean; function GetName: PChar; stdcall; begin Result := PChar(Name); end; function GetHelp: PChar; stdcall; begin Result := PChar(Help); end; procedure OpenWindow; stdcall; begin if MainForm = nil then MainForm := TMainForm.Create(nil); MainForm.Show; FormState := opened; end; procedure CloseWindow; stdcall; begin if FormState = opened then begin MainForm.Close; FormState := closed; MainForm.Release; MainForm := nil; end; end; procedure SendData(Data: PChar); stdcall; begin Buffer := Data; end; function GetData: PChar; stdcall; begin if NewMessageGot then begin Result := PChar(Buffer); NewMessageGot := false; end else Result := PChar(SCM_No_Message); end; procedure Start; stdcall; begin NewMessageGot := false; if MainForm = nil then MainForm := TMainForm.Create(nil); end; procedure SetVirtual(Name: PChar); stdcall; begin VirtualName := Name; end; procedure LoadData; stdcall; begin // end; procedure SaveData; stdcall; begin // end; exports GetName, GetHelp, OpenWindow, CloseWindow, SendData, GetData, Start, SetVirtual, LoadData, SaveData; begin end.
SetLanguage: function(Language: PChar): boolean; stdcall; SendLanguageData: function(Data: array of PChar): boolean; stdcall; GetName: function: PChar; stdcall; GetHelp: function: PChar; stdcall; Start: procedure; stdcall; Sleep: function: boolean; stdcall; WakeUp: procedure; stdcall; OpenWindow: procedure; stdcall; CloseWindow: procedure; stdcall; SetVirtual: procedure(Name: PChar); stdcall; SaveData: procedure; stdcall; LoadData: procedure; stdcall; Reset: procedure; stdcall; SetNewMainWindow: procedure(Position, Size: TPoint); stdcall; GetTimerInterval: function: Integer; stdcall; SendData: procedure(Data: PChar); stdcall; GetData: function: PChar; stdcall; SetSource: procedure(SourcePath: PChar); stdcall; NextData: function: PChar; stdcall; Progress: function: Real; stdcall; RestartParsing: procedure; stdcall;
type CResult = (no_collision, collision); function CheckModulesCollision: CResult; var i, j: Integer; CC: String; begin Result := no_collision; with ModulesList do for i := 0 to Items.Count - 1 do if Checked[i] then begin CC := FindModuleByFileName(ExtractDLLName(Items[i])).ControlCode; for j := 0 to Items.Count - 1 do if Checked[j] and (i <> j) and (CC = FindModuleByFileName(ExtractDLLName(Items[j])).ControlCode) then Result := collision; end; end;
procedure TMainForm.DownloadFilesButtonClick(Sender: TObject); var Dir, FileName: String; begin SetCurrentDir(ProgramPath); Dir := Category[ContentCategoryBox.ItemIndex]; Dir := UpCase(Dir[1]) + Copy(Dir, 2, Length(Dir)); if not DirectoryExists(Dir) then CreateDir(Dir); SetCurrentDir(Dir); FileName := ContentList.Items[ContentList.ItemIndex]; if FileExists(FileName) then MessageDlg(LanguageData[172], mtInformation, [mbOk], 0) else begin DownloadFile(SiteProtocol + OfficialWebsite + ExchangeCenterPage + '?c=' + Category[ContentCategoryBox.ItemIndex] + '&f=' + FileName + '&l=' + LanguageData[0], FileName); // LanguageData[0] if Copy(FileName, Length(FileName) - 2, 3) = 'zip' then UnzipFiles(FileName, GetCurrentDir); case ContentCategoryBox.ItemIndex of 0: UpdateModulesList; 1: UpdateVirtualsList; end; SetStatusMessage(LanguageData[173] + ' ' + ProgramPath + Dir + '\'); end; end; procedure TMainForm.DownloadFile(From, SaveTo: String); var LoadStream: TMemoryStream; begin Downloading := true; LoadStream := TMemoryStream.Create; IdHTTP.Get(TIdURI.URLEncode(From), LoadStream); LoadStream.SaveToFile(SaveTo); LoadStream.Free; Downloading := false; SplashScreen.Close; end;
procedure TMainForm.DeployDefaultLanguages; procedure DeployLanguage(LanguageName: String); var ResHandle, MemHandle: THandle; MemStream: TMemoryStream; ResPtr: PByte; ResSize: Longint; ResName: String; i: Integer; begin ResName := ''; for i := 1 to Length(LanguageName) do ResName := ResName + UpCase(LanguageName[i]); ResName := ResName + '_LP'; ResHandle := FindResource(HInstance, PWideChar(ResName), RT_RCDATA); if ResHandle = 0 then begin ShowMessage('Default language "' + LanguageName + '" not found. (' + ResName + ')'); exit; end; MemHandle := LoadResource(HInstance, ResHandle); ResPtr := LockResource(MemHandle); MemStream := TMemoryStream.Create; ResSize := SizeOfResource(HInstance, ResHandle); MemStream.SetSize(ResSize); MemStream.Write(ResPtr^, ResSize); MemStream.Seek(0, 0); MemStream.SaveToFile(LangFilesDir + '/' + LanguageName + LanguageFileExtension); FreeResource(MemHandle); MemStream.Destroy; end; begin if not DirectoryExists(LangFilesDir) then CreateDir(LangFilesDir); DeployLanguage('Russian'); DeployLanguage('English'); end;
procedure TMainForm.ChangeLanguageTo; function LanguageDataLoaded: Boolean; var T: TextFile; B: RawByteString; begin SetCurrentDir(ProgramPath + LangFilesDir); if FileExists(Language + LanguageFileExtension) then begin AssignFile(T, Language + LanguageFileExtension); Reset(T); SetLength(LanguageData, 1); LanguageData[0] := Language; while not eof(T) do begin SetLength(LanguageData, Length(LanguageData) + 1); ReadLn(T, B); LanguageData[Length(LanguageData) - 1] := UTF8ToWideString(B); end; CloseFile(T); if Length(LanguageData) - 1 >= LangFileMinSize then Result := true else Result := false; end else Result := false; end; procedure SetCaptions; begin with HelpForm do begin LoadHelpTexts; if CurrentTopic < HelpLast then OpenTopic(CurrentTopic) else OpenTopic(0); end; AddModulesHelpToMainProgramHelp; ChangeModulesLanguageToProgramLanguage; AuthorizationTab.Caption := LanguageData[18]; // - ... CloudSaveNow.Caption := LanguageData[181]; CloudLoadNow.Caption := LanguageData[182]; end; procedure CheckMenuItem; var Item: TMenuItem; begin for Item in LanguageMenu.Items do if Item.Name = LanguageData[0] + 'Lang' then Item.Checked := true; end; begin if LanguageDataLoaded then begin if not Silent then SetStatusMessage(LanguageData[2] + ' ' + LanguageData[0]) else FormCaption.Caption := LanguageData[1]; SetCaptions; end else begin if Language <> SavedLanguage then ChangeLanguageTo(SavedLanguage) else ChangeLanguageTo(DefaultLanguage); MessageDlg(LanguageData[3] + #13 + LanguageData[2] + ' ' + LanguageData[0] + '.', mtError, [mbOk], 0); end; CheckMenuItem; end;
procedure TMainForm.UpdateProgram; procedure DeployBAT; var bat: TextFile; begin if not FileExists(ProgramPath + 'update.bat') then begin AssignFile(bat, ProgramPath + 'update.bat'); Rewrite(bat); WriteLn(bat, 'taskkill /im av.exe'); WriteLn(bat, 'sleep 1'); // Windows XP WriteLn(bat, 'timeout /t 1 /nobreak'); // Windows 7+ WriteLn(bat, 'del av.exe'); WriteLn(bat, 'move ' + ZipsDir + '\av.exe %1'); WriteLn(bat, 'del /S /Q ' + ZipsDir); WriteLn(bat, 'start av.exe'); // WriteLn(bat, 'pause'); CloseFile(bat); end; end; begin DownloadFile(SiteProtocol + OfficialWebsite + '/av.zip', ProgramPath + 'av.zip'); UnzipFiles(ProgramPath + 'av.zip', ProgramPath + ZipsDir); DeployBAT; SetCurrentDir(ProgramPath); ShellExecute(Handle, nil, 'update.bat', PChar(ProgramPath), nil, SW_SHOW); end;
Source: https://habr.com/ru/post/316830/
All Articles