Advertisement
Danatela

MultiPlug2

Oct 21st, 2013
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 20.09 KB | None | 0 0
  1. package PluginInterface;
  2.  
  3. {$R *.res}
  4. {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
  5. {$ALIGN 8}
  6. {$ASSERTIONS ON}
  7. {$BOOLEVAL OFF}
  8. {$DEBUGINFO ON}
  9. {$EXTENDEDSYNTAX ON}
  10. {$IMPORTEDDATA ON}
  11. {$IOCHECKS ON}
  12. {$LOCALSYMBOLS ON}
  13. {$LONGSTRINGS ON}
  14. {$OPENSTRINGS ON}
  15. {$OPTIMIZATION OFF}
  16. {$OVERFLOWCHECKS OFF}
  17. {$RANGECHECKS OFF}
  18. {$REFERENCEINFO ON}
  19. {$SAFEDIVIDE OFF}
  20. {$STACKFRAMES ON}
  21. {$TYPEDADDRESS OFF}
  22. {$VARSTRINGCHECKS ON}
  23. {$WRITEABLECONST OFF}
  24. {$MINENUMSIZE 1}
  25. {$IMAGEBASE $400000}
  26. {$DEFINE DEBUG}
  27. {$ENDIF IMPLICITBUILDING}
  28. {$IMPLICITBUILD ON}
  29.  
  30. requires
  31.   vcl,
  32.   rtl;
  33.  
  34. contains
  35.   UClassManager in 'UClassManager.pas',
  36.   UPlugin in 'UPlugin.pas';
  37.  
  38. end.
  39.  
  40. unit UClassManager;
  41. { ============================================= }
  42.  
  43. { ============================================= }
  44. interface
  45. { ============================================= }
  46. uses
  47.   Classes;
  48.  
  49. type
  50.   TClassManager = class(TList);
  51.  
  52. function ClassManager: TClassManager;
  53.  
  54. { ============================================= }
  55. implementation
  56. { ============================================= }
  57. var
  58.   Manager: TClassManager;
  59.  
  60. function ClassManager: TClassManager;
  61. begin
  62.   Result := Manager;
  63. end;
  64.  
  65. { ============================================= }
  66. initialization
  67. { ============================================= }
  68. Manager := TClassManager.Create;
  69.  
  70. { ============================================= }
  71. finalization
  72. { ============================================= }
  73. Manager.Free;
  74.  
  75. end.
  76.  
  77. { ============================================= }
  78. unit UPlugin;
  79. { ============================================= }
  80.  
  81. { ============================================= }
  82. interface
  83. { ============================================= }
  84.  
  85. type
  86.   IPluginHost = interface;
  87.   TPlugin = class
  88.   public
  89.     Host: IPluginHost;
  90.     class function Name: string; virtual; abstract;
  91.     class function Group: string; virtual; abstract;
  92.     class function Pos: integer; virtual; abstract;
  93.     class function UserGroups: string; virtual; abstract;
  94.     class function AutoLoad: Boolean; virtual; abstract;
  95.     class function Hidden: Boolean; virtual; abstract;
  96.     procedure Exec(App, Scr: Integer; _Login, _Password, _DataSource, _PicturesDir: string); virtual; abstract;
  97.   end;
  98.  
  99.   TPluginClass = class of TPlugin;
  100.   IPluginHost = interface
  101.     function RegisterPlugin(PluginClass: TClass): boolean;
  102.     procedure RunPlugin(PluginName: string);
  103.   end;
  104.  
  105.  
  106. { ============================================= }
  107. implementation
  108. { ============================================= }
  109.  
  110. end{ ========================================= }.
  111.  
  112. package TestPlugin;
  113.  
  114. {$R *.res}
  115. {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
  116. {$ALIGN 8}
  117. {$ASSERTIONS ON}
  118. {$BOOLEVAL OFF}
  119. {$DEBUGINFO ON}
  120. {$EXTENDEDSYNTAX ON}
  121. {$IMPORTEDDATA ON}
  122. {$IOCHECKS ON}
  123. {$LOCALSYMBOLS ON}
  124. {$LONGSTRINGS ON}
  125. {$OPENSTRINGS ON}
  126. {$OPTIMIZATION OFF}
  127. {$OVERFLOWCHECKS OFF}
  128. {$RANGECHECKS OFF}
  129. {$REFERENCEINFO ON}
  130. {$SAFEDIVIDE OFF}
  131. {$STACKFRAMES ON}
  132. {$TYPEDADDRESS OFF}
  133. {$VARSTRINGCHECKS ON}
  134. {$WRITEABLECONST OFF}
  135. {$MINENUMSIZE 1}
  136. {$IMAGEBASE $400000}
  137. {$DEFINE DEBUG}
  138. {$ENDIF IMPLICITBUILDING}
  139. {$IMPLICITBUILD ON}
  140.  
  141. requires
  142.   rtl,
  143.   vcl,
  144.   PluginInterface;
  145.  
  146. contains
  147.   TestUnit in 'TestUnit.pas' {TestForm},
  148.   UTestPlugin in 'UTestPlugin.pas';
  149.  
  150. end.
  151.  
  152. unit UTestPlugin;
  153.  
  154. interface
  155.  
  156. uses
  157.   UClassManager, UPlugin;
  158.  
  159. type
  160.   TTestPlugin = class(TPlugin)
  161.     class function Name: string; override;
  162.     class function Group: string; override;
  163.     class function Pos: integer; override;
  164.     class function UserGroups: string; override;
  165.     class function AutoLoad: Boolean; override;
  166.     class function Hidden: Boolean; override;
  167.     procedure Exec(App, Scr: Integer; _Login, _Password, _DataSource, _PicturesDir: string); override;
  168.   end;
  169.  
  170. implementation
  171.  
  172. uses
  173.   TestUnit, Forms;
  174.  
  175. class function TTestPlugin.Name: string;
  176. begin
  177.   Result := 'Тестовый плагин';
  178. end;
  179.  
  180. class function TTestPlugin.Group: string;
  181. begin
  182.   Result := 'Справочники'
  183. end;
  184.  
  185. class function TTestPlugin.Pos: integer;
  186. begin
  187.   Result := 100;
  188. end;
  189.  
  190. class function TTestPlugin.UserGroups: string;
  191. begin
  192.   Result := '1';
  193. end;
  194.  
  195. class function TTestPlugin.AutoLoad: Boolean;
  196. begin
  197.   Result := false;
  198. end;
  199.  
  200. class function TTestPlugin.Hidden: Boolean;
  201. begin
  202.   Result := false;
  203. end;
  204.  
  205. procedure TTestPlugin.Exec(App, Scr: Integer; _Login, _Password, _DataSource, _PicturesDir: string);
  206. begin
  207.   if not Assigned(TestForm) then
  208.     Application.CreateForm(TTestForm, TestForm);
  209. end;
  210.  
  211. initialization
  212.   ClassManager.Add(TTestPlugin);
  213.  
  214. finalization
  215.   ClassManager.Remove(TTestPlugin);
  216.  
  217. end.
  218.  
  219. unit MainUnit;
  220.  
  221. interface
  222.  
  223. uses
  224.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  225.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Data.DB, Data.Win.ADODB,
  226.   Vcl.Menus, DbLogDlg, Generics.Collections,
  227.   Inifiles, Types, StrUtils, UPlugin;
  228.  
  229. type
  230.   TMainForm = class(TForm, IPluginHost)
  231.     MainMenu: TMainMenu;
  232.     Edit1: TMenuItem;
  233.     Undo1: TMenuItem;
  234.     Repeat1: TMenuItem;
  235.     Cut1: TMenuItem;
  236.     Copy1: TMenuItem;
  237.     Paste1: TMenuItem;
  238.     PasteSpecial1: TMenuItem;
  239.     Find1: TMenuItem;
  240.     Replace1: TMenuItem;
  241.     GoTo1: TMenuItem;
  242.     Links1: TMenuItem;
  243.     Object1: TMenuItem;
  244.     N3: TMenuItem;
  245.     N4: TMenuItem;
  246.     N5: TMenuItem;
  247.     Window1: TMenuItem;
  248.     Tile1: TMenuItem;
  249.     Cascade1: TMenuItem;
  250.     ArrangeAll1: TMenuItem;
  251.     Hide1: TMenuItem;
  252.     Show1: TMenuItem;
  253.     N6: TMenuItem;
  254.     Help1: TMenuItem;
  255.     Contents1: TMenuItem;
  256.     SearchforHelpOn1: TMenuItem;
  257.     HowtoUseHelp1: TMenuItem;
  258.     About1: TMenuItem;
  259.     DataBase: TMenuItem;
  260.     Connect: TMenuItem;
  261.     CloseConnection: TMenuItem;
  262.     Exit2: TMenuItem;
  263.     N8: TMenuItem;
  264.     ADOMainConnection: TADOConnection;
  265.     N1: TMenuItem;
  266.     ScanPlugins: TMenuItem;
  267.     ADOUserQuery: TADOQuery;
  268.     DetachPlugins: TMenuItem;
  269.     N2: TMenuItem;
  270.     Next1: TMenuItem;
  271.     CloseTimer: TTimer;
  272.     JrnQuery: TADOQuery;
  273.     ScheduleTimer: TTimer;
  274.     DocumentsMenuItem: TMenuItem;
  275.     MaterialsMenuItem: TMenuItem;
  276.     GrMaterialsMenuItem: TMenuItem;
  277.     PlansMenuItem: TMenuItem;
  278.     CatalogsMenuItem: TMenuItem;
  279.     ManagingMenuItem: TMenuItem;
  280.     procedure FormCreate(Sender: TObject);
  281.     procedure Exit2Click(Sender: TObject);
  282.     procedure ScanPluginsClick(Sender: TObject);
  283.     procedure CloseConnectionClick(Sender: TObject);
  284.     procedure ConnectClick(Sender: TObject);
  285.     procedure Tile1Click(Sender: TObject);
  286.     procedure Cascade1Click(Sender: TObject);
  287.     procedure ArrangeAll1Click(Sender: TObject);
  288.     procedure Hide1Click(Sender: TObject);
  289.     procedure DetachPluginsClick(Sender: TObject);
  290.     procedure FormShow(Sender: TObject);
  291.     procedure CloseTimerTimer(Sender: TObject);
  292.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  293.     procedure ScheduleTimerTimer(Sender: TObject);
  294.     function RegisterPlugin(PluginClass: TClass): boolean;
  295.   private
  296.     Handles: TList<HModule>;
  297.     MenuDict: TDictionary<string, TMenuItem>;
  298.     PicturesDir: string;
  299.     FirstScheduleFlag, SecondScheduleFlag: boolean;
  300.     ImportPlanMenuItem: TMenuItem;
  301.     procedure RescanPluginsDir;
  302.     procedure RefreshPluginsList;
  303.     procedure PlugClick(Sender: TObject);
  304.     procedure ReadIniFile;
  305.     procedure OkButtonClickNoClose(Sender: TObject);
  306.     function BuildDbParams(ConnectionString: string): TDictionary<string, string>;
  307.     function BuildConnectionString(DBParams: TDictionary<string, string>): string;
  308.     function GetUserGroup: integer;
  309.     procedure ClearPlugins;
  310.     procedure RunFlagCloser;
  311.     procedure RunPlugin(PluginName: string);
  312.     { Private declarations }
  313.   public
  314.     { Public declarations }
  315.   end;
  316.  
  317. var
  318.   MainForm: TMainForm;
  319.  
  320. implementation
  321.  
  322. {$R *.dfm}
  323.  
  324. uses LoginUnit, OleAuto, SplashUnit, UClassManager;
  325.  
  326. procedure TMainForm.Cascade1Click(Sender: TObject);
  327. begin
  328.   Cascade;
  329. end;
  330.  
  331. procedure TMainForm.CloseConnectionClick(Sender: TObject);
  332. begin
  333.   ADOMainConnection.Close;
  334. end;
  335.  
  336. procedure TMainForm.CloseTimerTimer(Sender: TObject);
  337. begin
  338.   if FileExists('flagClose.txt') then begin
  339.     Close;
  340.     RunFlagCloser;
  341.   end;
  342. end;
  343.  
  344. procedure TMainForm.ConnectClick(Sender: TObject);
  345. begin
  346.   if ADOMainConnection.Connected then
  347.     ADOMainConnection.Close;
  348.   while not ADOMainConnection.Connected do
  349.     case LoginForm.ShowModal of
  350.       mrOk: try
  351.         OkButtonClickNoClose(Sender);
  352.       except
  353.         on Ex: EOleException do MessageDlg(Ex.Message, mtError, [mbRetry], 0);
  354.         on Ex: Exception do MessageDlg(Ex.Message, mtError, [mbRetry], 0);
  355.       end;
  356.       mrCancel: Exit;
  357.     end;
  358. end;
  359.  
  360. procedure TMainForm.DetachPluginsClick(Sender: TObject);
  361. begin
  362.   ClearPlugins;
  363. end;
  364.  
  365. procedure TMainForm.Exit2Click(Sender: TObject);
  366. begin
  367.   Close;
  368. end;
  369.  
  370. function TMainForm.BuildDbParams(ConnectionString: string): TDictionary<string, string>;
  371. var
  372.   s: string;
  373.   Pair: TStringDynArray;
  374. begin
  375.   Result := TDictionary<string, string>.Create;
  376.   for s in SplitString(ConnectionString, ';') do if PosEx('=', s) > 0 then begin
  377.     Pair := SplitString(s, '=');
  378.     Result.Add(Pair[0], Pair[1]);
  379.   end;
  380. end;
  381.  
  382. procedure TMainForm.ArrangeAll1Click(Sender: TObject);
  383. begin
  384.   ArrangeIconicWindows(Handle);
  385. end;
  386.  
  387. function TMainForm.BuildConnectionString(DBParams: TDictionary<string, string>): string;
  388. var
  389.   Pair: TPair<string, string>;
  390. begin
  391.   Result := '';
  392.   for Pair in DBParams do
  393.     Result := Result + ';' + Pair.Key + '=' + Pair.Value;
  394.   Result := RightStr(Result, Length(Result) - 1);
  395. end;
  396.  
  397. procedure TMainForm.ReadIniFile;
  398. var
  399.   IniFile: TIniFile;
  400.   DBParams: TDictionary<string, string>;
  401. begin
  402.   IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI'));
  403.   try
  404.     DBParams := BuildDbParams(ADOMainConnection.ConnectionString);
  405.     DBParams['Data Source'] := IniFile.ReadString('Main', 'DataBase', DBParams['Data Source']);
  406.     DBParams['User ID'] := IniFile.ReadString('Main', 'Login', DBParams['User ID']);
  407.     ADOMainConnection.ConnectionString := BuildConnectionString(DBParams);
  408.     LoginForm.LoginEdit.Text := DBParams['User ID'];
  409.     PicturesDir := IniFile.ReadString('Main', 'PicturesDir', '');
  410.   finally
  411.     IniFile.Free;
  412.   end;
  413. end;
  414.  
  415. procedure TMainForm.OkButtonClickNoClose(Sender: TObject);
  416. var
  417.   IniFile: TIniFile;
  418. begin
  419.   if FileExists('flagClose.txt') then begin
  420.     RunFlagCloser;
  421.     Application.Terminate;
  422.     Exit;
  423.   end;
  424.   if ADOMainConnection.Connected then
  425.     ADOMainConnection.Close;
  426.   ADOMainConnection.Open(LoginForm.LoginEdit.Text, LoginForm.PasswordEdit.Text);
  427.   if ADOUserQuery.Active then
  428.     ADOUserQuery.Close;
  429.   ADOUserQuery.Open;
  430.   if ADOUserQuery['UserActive'] = 0 then
  431.     raise Exception.Create('Пользователь неактивен, вход в систему запрещается');
  432.   with JrnQuery, Parameters do begin
  433.     ParamValues['pOperType;pUserName;pChanges'] := VarArrayOf([3, UpperCase(LoginForm.LoginEdit.Text), 'Вход в систему']);
  434.     ExecSQL;
  435.   end;
  436.   CloseTimer.Enabled := True;
  437.   {
  438.   IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI'));
  439.   try
  440.     IniFile.WriteString('Main', 'Login', LoginForm.LoginEdit.Text);
  441.   finally
  442.     IniFile.Free;
  443.   end;
  444.   }
  445. end;
  446.  
  447. procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
  448. begin
  449.   if ADOMainConnection.Connected then with JrnQuery, Parameters do begin
  450.     ParamValues['pOperType;pUserName;pChanges'] := VarArrayOf([4, UpperCase(LoginForm.LoginEdit.Text), 'Выход из системы']);
  451.     ExecSQL;
  452.   end;
  453. end;
  454.  
  455. procedure TMainForm.FormCreate(Sender: TObject);
  456. begin
  457.   LoginForm := TLoginForm.Create(Self);
  458.   ReadIniFile;
  459.   while not ADOMainConnection.Connected do
  460.     case LoginForm.ShowModal of
  461.       mrOk: try
  462.         OkButtonClickNoClose(Sender);
  463.       except
  464.         on Ex: EOleException do MessageDlg(Ex.Message, mtError, [mbRetry], 0);
  465.         on Ex: Exception do MessageDlg(Ex.Message, mtError, [mbRetry], 0);
  466.       end;
  467.       mrCancel: begin
  468.         Close;
  469.         Application.Terminate;
  470.         Abort;
  471.       end;
  472.     end;
  473.   MenuDict := TDictionary<string, TMenuItem>.Create;
  474.   MenuDict.Add('Документы', DocumentsMenuItem);
  475.   MenuDict.Add('Материалы', MaterialsMenuItem);
  476.   MenuDict.Add('Группы материалов', GrMaterialsMenuItem);
  477.   MenuDict.Add('Планы', PlansMenuItem);
  478.   MenuDict.Add('Справочники', CatalogsMenuItem);
  479.   MenuDict.Add('Администрирование', ManagingMenuItem);
  480.   Handles := TList<HModule>.Create;
  481.   RescanPluginsDir;
  482. end;
  483.  
  484. procedure TMainForm.FormShow(Sender: TObject);
  485. var
  486.   Pair: TPair<string, TMenuItem>;
  487.   I: Integer;
  488.   Plugin: TPlugin;
  489. begin
  490.   for Pair in MenuDict do
  491.     for I := 0 to Pair.Value.Count - 1 do begin
  492.       if Pair.Value.Items[I].Caption = '-' then
  493.         Continue;
  494.       Plugin := TPlugin(ClassManager[Pair.Value.Items[I].Tag]).Create;
  495.       if Plugin.AutoLoad then
  496.         PlugClick(Pair.Value.Items[I]);
  497.     end;
  498. end;
  499.  
  500. procedure TMainForm.Hide1Click(Sender: TObject);
  501. begin
  502.   ActiveMDIChild.Hide;
  503. end;
  504.  
  505. procedure TMainForm.RefreshPluginsList;
  506. var
  507.   Pair: TPair<string, TMenuItem>;
  508.   I: integer;
  509. begin
  510.   for I := 0 to ClassManager.Count - 1 do
  511.     RegisterPlugin(ClassManager[i]);
  512.   for Pair in MenuDict do
  513.     Pair.Value.Visible := Pair.Value.Count > 0;
  514. end;
  515.  
  516. procedure TMainForm.RescanPluginsDir;
  517. var
  518.   SearchRec : TSearchRec;
  519.   Pair: TPair<string,TMenuItem>;
  520.   function CountFiles(Mask: string): Integer;
  521.   var
  522.     Rec : TSearchRec;
  523.   begin
  524.     Result := 0;
  525.     if FindFirst(Mask, faAnyFile, Rec) = 0 then
  526.     begin
  527.       repeat
  528.         // Exclude directories from the list of files.
  529.         if ((Rec.Attr and faDirectory) <> faDirectory) then
  530.           Inc(Result);
  531.       until FindNext(Rec) <> 0;
  532.       FindClose(Rec);
  533.     end;
  534.   end;
  535. begin
  536.   ClearPlugins;
  537.    //ищем первый файл
  538.   Handles.Add(LoadPackage('PluginInterface.bpl'));
  539.   if FindFirst('Plugins\*.bpl', faAnyFile, SearchRec) = 0 then begin
  540.     SplashForm := TSplashForm.Create(Self);
  541.     with SplashForm do begin
  542.       ProgressBar.Max := CountFiles('Plugins\*.bpl');
  543.       Show;
  544.       repeat
  545.         LoadingLabel.Caption := 'Загружается плагин: ' + SearchRec.Name;
  546.         ProgressBar.Position := ProgressBar.Position + 1;
  547.         Update;
  548.         Application.ProcessMessages;
  549.         Handles.Add(LoadPackage('Plugins\' + SearchRec.name));
  550.       until FindNext(SearchRec) <> 0;
  551.        //Загружаем последующий
  552.       FindClose(SearchRec);  //Закрываем поиск
  553.       RefreshPluginsList;  // Добавляем плагины в меню
  554.       Close;
  555.       Free;
  556.     end;
  557.     SplashForm := nil;
  558.   end;
  559. end;
  560.  
  561. procedure TMainForm.ScanPluginsClick(Sender: TObject);
  562. begin
  563.   RescanPluginsDir;
  564. end;
  565.  
  566. procedure TMainForm.ScheduleTimerTimer(Sender: TObject);
  567. begin
  568.   if (Time > EncodeTime(0, 0, 0, 0)) and (Time < EncodeTime(0, 1, 30, 0)) then begin
  569.     FirstScheduleFlag := False;
  570.     SecondScheduleFlag := False;
  571.   end;
  572.   if (Time > EncodeTime(9, 0, 0, 0)) and (Time < EncodeTime(9, 1, 30, 0)) then if not FirstScheduleFlag then begin
  573.     FirstScheduleFlag := True;
  574.     PlugClick(ImportPlanMenuItem);
  575.   end;
  576.   if (Time > EncodeTime(13, 0, 0, 0)) and (Time < EncodeTime(13, 1, 30, 0)) then if not SecondScheduleFlag then begin
  577.     SecondScheduleFlag := True;
  578.     PlugClick(ImportPlanMenuItem);
  579.   end;
  580. end;
  581.  
  582. procedure TMainForm.Tile1Click(Sender: TObject);
  583. begin
  584.   Tile;
  585. end;
  586.  
  587. function TMainForm.RegisterPlugin(PluginClass: TClass): boolean;
  588. var
  589.    //Объявление функции, которая будет возвращать имя плагина
  590.   s: string;
  591.   UsrGrps: TList<integer>;
  592.    //Новый пункт меню
  593.   Item, GrItem : TMenuItem;
  594.   I: Integer;
  595.   Res: TResourceStream;
  596. begin
  597.   Item := TMenuItem.Create(MainMenu);  //Создаём новый пункт меню
  598.   if TPluginClass(PluginClass).Name <> '' then begin
  599.     Item.Caption := TPluginClass(PluginClass).Name;
  600.     if Item.Caption = 'Импорт планов' then
  601.       ImportPlanMenuItem := Item;
  602.     Item.Visible := not TPluginClass(PluginClass).Hidden;
  603.     { TODO: разобраться, как загружать ресурсы в пакет
  604.     try
  605.       Res := TResourceStream.Create(MyHandle, 'bitmap', RT_RCDATA);
  606.       Item.Bitmap.LoadFromStream(Res);
  607.       SplashForm.ShowBitmapFromStream(Res);
  608.     except
  609.  
  610.     end;
  611.     }
  612.     UsrGrps := TList<integer>.Create;
  613.     for s in SplitString(TPluginClass(PluginClass).UserGroups, ',') do
  614.       UsrGrps.Add(StrToInt(s));
  615.      //Если всё прошло, идём дальше...
  616.     if (UsrGrps.Count = 0) or (UsrGrps.IndexOf(GetUserGroup) > -1) then begin
  617.       if not MenuDict.ContainsKey(TPluginClass(PluginClass).Group) then begin
  618.         GrItem := TMenuItem.Create(MainMenu);
  619.         GrItem.Caption := TPluginClass(PluginClass).Group;
  620.         MainMenu.Items.Add(GrItem);
  621.         MenuDict.Add(TPluginClass(PluginClass).Group, GrItem);
  622.       end;
  623.       Item.Tag := ClassManager.Count - 1;
  624.       Item.onClick:=PlugClick;  //Даём ссылку на обработчик
  625.       for I := MenuDict[TPluginClass(PluginClass).Group].Count + 1 to TPluginClass(PluginClass).Pos - 1 do begin
  626.         GrItem := TMenuItem.Create(MainMenu);
  627.         GrItem.Caption := '-';
  628.         MenuDict[TPluginClass(PluginClass).Group].Add(GrItem);
  629.       end;
  630.       if MenuDict[TPluginClass(PluginClass).Group].Count + 1 = TPluginClass(PluginClass).Pos  then
  631.         MenuDict[TPluginClass(PluginClass).Group].Add(Item)  //Добавляем пункт меню
  632.       else begin
  633.         MenuDict[TPluginClass(PluginClass).Group].Delete(TPluginClass(PluginClass).Pos  - 1);
  634.         MenuDict[TPluginClass(PluginClass).Group].Insert(TPluginClass(PluginClass).Pos  - 1, Item);
  635.       end;
  636.     end;
  637.   end;
  638.   Result := True;
  639. end;
  640.  
  641. function TMainForm.GetUserGroup: integer;
  642. begin
  643.   if ADOUserQuery.Active then
  644.     ADOUserQuery.Close;
  645.   ADOUserQuery.Parameters.ParamByName('pOraUser').Value := UpperCase(LoginForm.LoginEdit.Text);
  646.   ADOUserQuery.Open;
  647.   Result := ADOUserQuery['GrNrec'];
  648.   ADOUserQuery.Close;
  649. end;
  650.  
  651. procedure TMainForm.ClearPlugins;
  652. var
  653.   I: Integer;
  654.   Pair: TPair<string, TMenuItem>;
  655. begin
  656.   for I := 0 to Handles.Count - 1 do
  657.     UnloadPackage(Handles[I]);
  658.   Handles.Clear;
  659. end;
  660.  
  661. procedure TMainForm.RunFlagCloser;
  662. var
  663.   StartupInfo: _STARTUPINFOW;
  664.   ProcessInfo: _PROCESS_INFORMATION;
  665.   Exe: string;
  666. begin
  667.   FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  668.   StartupInfo.cb := SizeOf(StartupInfo);
  669.   Exe := 'FlagCloser.exe';
  670.   UniqueString(Exe);
  671.   CreateProcess(nil, PChar(Exe), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo);
  672. end;
  673.  
  674. procedure TMainForm.PlugClick(Sender: TObject);
  675. var
  676.   //Объявление функции, которая будет выполнять плагин
  677.   Plugin: TPlugin;
  678.   //Хендл dll
  679.   DBParams: TDictionary<string, string>;
  680.   MyTag: Integer;
  681.   Found: Boolean;
  682.   I: Integer;
  683.   procedure LogToFile(FileName, Str: string);
  684.   var
  685.     F: TextFile;
  686.   begin
  687.     if not FileExists(FileName) then
  688.       FileClose(FileCreate(FileName));
  689.     AssignFile(F, FileName);
  690.     Append(F);
  691.     Writeln(F, Str);
  692.     Flush(F);
  693.     CloseFile(F);
  694.   end;
  695.   procedure LaunchPlug;
  696.   begin
  697.     with JrnQuery, Parameters do begin
  698.       ParamValues['pOperType;pUserName;pChanges'] := VarArrayOf([5, UpperCase(LoginForm.LoginEdit.Text), 'Запуск плагина "' + Plugin.Name + '"']);
  699.       ExecSQL;
  700.     end;
  701.     Plugin.Exec(Integer(Application), Integer(Screen), LoginForm.LoginEdit.Text, LoginForm.PasswordEdit.Text, DBParams['Data Source'], PicturesDir);
  702.   end;
  703. begin
  704.   with (Sender as TMenuItem) do begin
  705.     Plugin := TPlugin(ClassManager[Tag]).Create;  //Загружаем dll
  706.     Plugin.Host := Self;
  707.     MyTag := Tag;
  708.   end;
  709.   //Загружаем функции
  710.   DBParams := BuildDbParams(ADOMainConnection.ConnectionString);
  711.   LogToFile('log.txt', 'Запуск плагина ' + Plugin.Name);
  712.   LaunchPlug;
  713. end;
  714.  
  715. procedure TMainForm.RunPlugin(PluginName: string);
  716. begin
  717.   //
  718. end;
  719.  
  720. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement