artem_niko Posted July 3, 2019 Share Posted July 3, 2019 Hello! I want load BPL, as plugin, where I create, in this BPL, one Frame1 with component of TUniLabel1. I need load this BPL, that then press on TUniButton on my MainForm and then set TUniLabel1.Caption:=<value from MainForm>. This is my code in MainForm, he succsess work and load BPL: procedure TMainForm.LoadModuleFromBPL; var UniFormLoadedModule: TUniFrame; AClass: TPersistentClass; LoadedBPL: HModule; begin LoadedBPL := LoadPackage(ExtractFilePath(ParamStr(0)) + 'Test.bpl'); if LoadedBPL <> 0 then begin AClass := GetClass('TUniFrame1'); UniFormLoadedModule:=TComponentClass(AClass).Create(UniTabSheet1) as TUniFrame; UniFormLoadedModule.Parent:=UniTabSheet1; UniPageControl1.ActivePage := Ts; end; end; This is code in my Frame1, in my BPL: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIFrame, uniGUIBaseClasses, uniLabel; type TUniFrame1 = class(TUniFrame) UniLabel1: TUniLabel; procedure UniFrameReady(Sender: TObject); private { Private declarations } public { Public declarations } end; implementation uses MainModule, ServerModule, Main, UnitPDFViewer; {$R *.dfm} procedure TUniFrame1.UniFrameReady(Sender: TObject); begin UniLabel1.Caption:=UniMainModule.LoggedUser; end; initialization RegisterClass(TUniFrame); end. He does not work because when I compile my BPL, I give this error: "[dcc32 Error] E2223 $DENYPACKAGEUNIT 'UniGUIVars' cannot be put into a package" What I must do? Quote Link to comment Share on other sites More sharing options...
artem_niko Posted January 7, 2020 Author Share Posted January 7, 2020 Hello to all! At the moment, I do that what. This is code of my Package1.bpl: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIFrame, uniGUIBaseClasses, uniLabel; type TUniFrame1 = class(TUniFrame) UniLabel1: TUniLabel; procedure UniFrameCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; implementation {$R *.dfm} procedure TUniFrame1.UniFrameCreate(Sender: TObject); begin UniLabel1.Caption:=TimeToStr(MainForm.nowTime); end; initialization RegisterClass(TUniFrame); end. And this is code in my MainForm, in my Application: unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniButton, uniGUIBaseClasses, uniEdit, uniPageControl, uniGUIFrame, uniPanel, uniTimer; type TMainForm = class(TUniForm) UniEdit1: TUniEdit; UniButton1: TUniButton; UniPageControl1: TUniPageControl; UniTabSheet1: TUniTabSheet; UniTimer1: TUniTimer; procedure UniButton1Click(Sender: TObject); procedure UniTimer1Timer(Sender: TObject); procedure UniEdit1Change(Sender: TObject); private FPackageHandle: Integer; { Private declarations } public nowTime: TDateTime; { Public declarations } end; function MainForm: TMainForm; implementation {$R *.dfm} uses uniGUIVars, MainModule, uniGUIApplication; function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end; procedure TMainForm.UniButton1Click(Sender: TObject); var AClass: TClass; AFrame: TUniFrame; begin FPackageHandle:=0; if FPackageHandle = 0 then begin FPackageHandle:=LoadPackage('Package1.bpl'); AClass:=GetClass('TUniFrame1'); if Assigned(AClass) {and AClass.InheritsFrom(TUniFrame)} then begin AFrame:=TCustomFrameClass(AClass).Create(UniTabSheet1) as TUniFrame; AFrame.Parent:=UniTabSheet1; AFrame.Align:=alClient; AFrame.Show; end; end; end; procedure TMainForm.UniEdit1Change(Sender: TObject); begin nowTime:=StrToTime(UniEdit1.Text); end; procedure TMainForm.UniTimer1Timer(Sender: TObject); begin UniEdit1.Text:=TimeToStr(Now); end; initialization RegisterAppFormClass(TMainForm); end. I have not get errors and my App and Package1.bpl successfuly compiling and my UniFrame1 creating in my App. What I want? I want this: in my App exist something global variables with something values and I want tranfer this values of this variables, for example, to UniLabel1.Caption in my created UniFrame1. What I must do, that it is work? Please, help me, who know how do this! Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 22, 2021 Author Share Posted August 22, 2021 Hello! Can anybody help me create connect between MainProject and BPL, using UniGUI? In attach two project. What I want? I want connect BPL in MainProject and get in connected BPL global value from MainProject (from UniEdit1). Please, help me with this question! 🙏 Test.zip Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 22, 2021 Share Posted August 22, 2021 Aqui está um exemplo de trabalho para você. projeto bpl.zip Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 22, 2021 Share Posted August 22, 2021 Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 22, 2021 Share Posted August 22, 2021 Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 22, 2021 Share Posted August 22, 2021 Se você quiser comunicação entre os objetos envolvidos, eles devem ter métodos que podem ser lidos ou escritos. Se você está no quadro e quer obter valor a partir do principal, você deve ter um método público no principal que lhe dá acesso e assim por diante. 1 Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 23, 2021 Author Share Posted August 23, 2021 17 hours ago, herculanojs said: Se você quiser comunicação entre os objetos envolvidos, eles devem ter métodos que podem ser lidos ou escritos. Se você está no quadro e quer obter valor a partir do principal, você deve ter um método público no principal que lhe dá acesso e assim por diante. Excellent, dear @herbernlopez! It's working! 🙏😃 Thank's! If I will have some question about this theme, I ask you! Now, I'm going think about new architecture of my project! P.S. And I still have a couple of questions: 1. If I add any forms, etc. to the BPL, will they receive a string value from my frame, which was connected as a BPL in the main project? 2. What is the best way to develop a BPL: launch the IDE separately or use the menu in the screenshot above and add it as a file in the main project, working in one IDE? 3. How to recompile the BPL so that it can be loaded again in the main project without restarting the main project? I see the algorithm of actions as follows: 1. Make changes to the BPL (add some components, code, expand its functionality); 2. Compile the BPL file somewhere; 3. Copy the compiled BPL to the folder where the main project looks for my BPL files; 4. I click on the button in the main project and my BPL is loaded again, but the main project does not close and does not restart. There are two problems right now that I cannot fix: 1. It is not possible to unload all packages and classes first (added the DoUnloadPackage function to the main project); 2. And it is not possible to compile the BPL itself, tk. if you tell it the directory where to save, for example, like here: then a message is displayed that cannot be compiled. I believe this is due to the fact that the main project does not unload the loaded BPL file that I am trying to update. In general, please help with the elimination of problem number 1, or maybe problem number 2 will go away by itself later. If not for question # 3, everything works, BPL is loaded, but you have to restart the main project, which is wrong ... 🤔 Test_new.zip Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 25, 2021 Share Posted August 25, 2021 On 8/22/2021 at 9:32 PM, Артем said: Excellent, dear @herbernlopez! It's working! 🙏😃 Thank's! If I will have some question about this theme, I ask you! Now, I'm going think about new architecture of my project! P.S. And I still have a couple of questions: 1. If I add any forms, etc. to the BPL, will they receive a string value from my frame, which was connected as a BPL in the main project? 2. What is the best way to develop a BPL: launch the IDE separately or use the menu in the screenshot above and add it as a file in the main project, working in one IDE? 3. How to recompile the BPL so that it can be loaded again in the main project without restarting the main project? I see the algorithm of actions as follows: 1. Make changes to the BPL (add some components, code, expand its functionality); 2. Compile the BPL file somewhere; 3. Copy the compiled BPL to the folder where the main project looks for my BPL files; 4. I click on the button in the main project and my BPL is loaded again, but the main project does not close and does not restart. There are two problems right now that I cannot fix: 1. It is not possible to unload all packages and classes first (added the DoUnloadPackage function to the main project); 2. And it is not possible to compile the BPL itself, tk. if you tell it the directory where to save, for example, like here: then a message is displayed that cannot be compiled. I believe this is due to the fact that the main project does not unload the loaded BPL file that I am trying to update. In general, please help with the elimination of problem number 1, or maybe problem number 2 will go away by itself later. If not for question # 3, everything works, BPL is loaded, but you have to restart the main project, which is wrong ... 🤔 Test_new.zip 944,84 kB · 0 downloads You have to see how you will implement your scenario to avoid such problems. 1) You can upload the BPL and after using it download it. This would avoid the issue of not being able to update. Without downloading the BPL, unfortunately, you will not be able to perform its update, and would have to be dropping the application to be able to perform this maintenance. So you have to think carefully about the construction of the project. You can also place updates in a verification directory for the application to read. When it finds a new update, it prompts open sessions to exit or sets a time for automatic termination. After the end of all sessions, then the application unloadpackages the loaded BPLs and properly replaces the new ones. Do not place the application running directly in the Delphi working directory where you compile the BPLs. Try to leave the test application running in another location. Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 26, 2021 Author Share Posted August 26, 2021 13 hours ago, herculanojs said: Вы должны посмотреть, как вы будете реализовывать свой сценарий, чтобы избежать таких проблем. 1) Вы можете загрузить BPL и после его использования загрузить его. Это позволит избежать проблемы невозможности обновления. Без загрузки BPL, к сожалению, вы не сможете выполнить его обновление, и вам придется отказаться от приложения, чтобы иметь возможность выполнять это обслуживание. Поэтому вам придется тщательно подумать о строительстве проекта. Можно также поместить обновления в каталог проверки для чтения приложением. Когда он находит новое обновление, он предлагает открытым сеансам выйти или устанавливает время для автоматического завершения. После окончания всех сеансов приложение выгружает загруженные BPL и корректно заменяет новые. Не размещайте приложение, выполняемое непосредственно, в рабочий каталог Delphi, в котором компилируются BPL. Попробуйте оставить тестовое приложение запущенным в другом месте. Good day! Thank you very much for the answer. Do you mean to unload the BPL immediately after loading it in the main project? Can you show an example when uploading BPL? Because the code that I used, it does not work. Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 26, 2021 Share Posted August 26, 2021 17 hours ago, Артем said: Good day! Thank you very much for the answer. Do you mean to unload the BPL immediately after loading it in the main project? Can you show an example when uploading BPL? Because the code that I used, it does not work. You cannot download a package while using resources from the package. Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 6 hours ago, herculanojs said: You cannot download a package while using resources from the package. I'm already understand this. Can you show how you unload package? How right do this. In future, I will show to user message when new package will be create and then user make unload package and load again. But I need example how unload package. Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 function unloadPackage() Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 3 minutes ago, herculanojs said: function unloadPackage() This? procedure TMainForm.DoUnloadPackage(Module: HModule); var i: Integer; M: TMemoryBasicInformation; begin { Make sure there aren't any instances of any of the classes from Module instantiated, if so then free them. (This assumes that the classes are owned by the application) } for i := Application.ComponentCount - 1 downto 0 do begin VirtualQuery( GetClass(Application.Components[i].ClassName), M, SizeOf(M)); if (Module = 0) or (HMODULE(M.AllocationBase) = Module) then Application.Components[i].Free; end; UnRegisterModuleClasses(Module); UnLoadPackage(Module); end; procedure TMainForm.UniButton1Click(Sender: TObject); var hm:Hmodule; FrC : TUniFrameClass; Frame : TUniFrame; begin hm := LoadPackage('Package1.bpl'); if hm <> 0 then begin if FindClass('TUniFrameTest') <> nil then begin FrC := TUniFrameClass(FindClass('TUniFrameTest')); if FrC <> nil then begin frame := FrC.Create(self); frame.Align := alClient; frame.Parent := UniTabSheet1; if frame <> nil then begin if IsPublishedProp(frame,'GlobalValue') then SetPropValue(frame,'GlobalValue',UniEdit1.Text); end; end; end; end else begin //Unload package: DoUnloadPackage(hm); end; end; Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 2 minutes ago, Артем said: Este? procedure TMainForm.DoUnloadPackage(Module: HModule); var i: Integer; M: TMemoryBasicInformation; begin { Make sure there aren't any instances of any of the classes from Module instantiated, if so then free them. (This assumes that the classes are owned by the application) } for i := Application.ComponentCount - 1 downto 0 do begin VirtualQuery( GetClass(Application.Components[i].ClassName), M, SizeOf(M)); if (Module = 0) or (HMODULE(M.AllocationBase) = Module) then Application.Components[i].Free; end; UnRegisterModuleClasses(Module); UnLoadPackage(Module); end; procedure TMainForm.UniButton1Click(Sender: TObject); var hm:Hmodule; FrC : TUniFrameClass; Frame : TUniFrame; begin hm := LoadPackage('Package1.bpl'); if hm <> 0 then begin if FindClass('TUniFrameTest') <> nil then begin FrC := TUniFrameClass(FindClass('TUniFrameTest')); if FrC <> nil then begin frame := FrC.Create(self); frame.Align := alClient; frame.Parent := UniTabSheet1; if frame <> nil then begin if IsPublishedProp(frame,'GlobalValue') then SetPropValue(frame,'GlobalValue',UniEdit1.Text); end; end; end; end else begin //Unload package: DoUnloadPackage(hm); end; end; UnRegisterModuleClasses(Module); UnLoadPackage(Module); I think that alone is enough. Now as I already informed you, you won't be able to release a package while resources of it are being used. You instantiated a frame inside the package and are using it in a form. As long as this frame is not destroyed, this package cannot be released. To work with packages which will have form, frames, etc. must plan the application well in advance. Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 2 minutes ago, herculanojs said: UnRegisterModuleClasses(Module); UnLoadPackage(Module); I think that alone is enough. Now as I already informed you, you won't be able to release a package while resources of it are being used. You instantiated a frame inside the package and are using it in a form. As long as this frame is not destroyed, this package cannot be released. To work with packages which will have form, frames, etc. must plan the application well in advance. Ok, I'm understand you. So, if in my main project create new TabSheet for my BPL, I must close this TabSheet and this action remove all components and resources, using from loaded BPL? Is it will be another? Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 6 minutes ago, Артем said: Ok, eu entendo você. Então, se no meu projeto principal criar novo TabSheet para o meu BPL, devo fechar este TabSheet e essa ação remover todos os componentes e recursos, usando de BPL carregado? Será outra coisa? I think it would be the steps: 1) Load package - loadpackage() 2) Create tabsheet - with frame 3) Close tabsheet 4) release package - unloadpackage() Or as I mentioned, you can create a control that identifies that there are new resources (bpls) that must be loaded, if the user is using any of these new bpls. Then inform him that he should reload the application for a new update. You don't need to scan components loaded in the package. Once you destroy the frame, the package can be released. Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 3 minutes ago, herculanojs said: I think it would be the steps: 1) Load package - loadpackage() 2) Create tabsheet - with frame 3) Close tabsheet 4) release package - unloadpackage() Or as I mentioned, you can create a control that identifies that there are new resources (bpls) that must be loaded, if the user is using any of these new bpls. Then inform him that he should reload the application for a new update. You don't need to scan components loaded in the package. Once you destroy the frame, the package can be released. Then it turns out that when switching between different TabSheet, which I have loaded BPLs, I have to globally somewhere in the main project to store the name of the BPL, which is located on the selected tab? Or, all the same, when you delete a dynamically created TabSheet, all components, including the BPL loaded on it, will also be deleted and that's it? Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 4 minutes ago, Артем said: Então acontece que ao alternar entre diferentes TabSheet, que eu carreguei BPLs, eu tenho que globalmente em algum lugar no projeto principal para armazenar o nome do BPL, que está localizado na guia selecionada? Ou, mesmo assim, quando você excluir um TabSheet criado dinamicamente, todos os componentes, incluindo o BPL carregado nele, também serão excluídos e é isso? If you are going to download the package, you must somehow keep the ID (hmodule) identifying the package associated with TabShett or the resource that loaded the package, in order to have the reference to release the package. Just closing and destroying the resource does not free the package from memory. Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 2 minutes ago, herculanojs said: If you are going to download the package, you must somehow keep the ID (hmodule) identifying the package associated with TabShett or the resource that loaded the package, in order to have the reference to release the package. Just closing and destroying the resource does not free the package from memory. MainProject.zip Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 27, 2021 Share Posted August 27, 2021 Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 33 minutes ago, herculanojs said: MainProject.zip 39.42 kB · 0 downloads Very big thank's! At this moment, this is that what I want make Quote Link to comment Share on other sites More sharing options...
artem_niko Posted August 27, 2021 Author Share Posted August 27, 2021 Last question) In BPL, I can't create UniForm1 (as Free form)? Because in BPL not existing MainModule and that's why I can't write: function UniForm1: TUniForm1; begin Result := TUniForm1(UniMainModule.GetFormInstance(TUniForm1)); end; Quote Link to comment Share on other sites More sharing options...
herculanojs Posted August 30, 2021 Share Posted August 30, 2021 On 8/26/2021 at 10:24 PM, Артем said: Última pergunta) No BPL, não posso criar o UniForm1 (como formulário livre)? Porque no BPL não existe MainModule e é por isso que eu não posso escrever: function UniForm1: TUniForm1; begin Result := TUniForm1(UniMainModule.GetFormInstance(TUniForm1)); end; I think you have to understand the working dynamics of uniGUI forms regardless of bpl issue, as well as keep in mind that to deal with BPL you must work with object-oriented view and not procedural programming as is customary in Delphi. Bpl is nothing more than the box where things will be. If there is a form in bpl, you have to understand how uniGUI handles forms in order to create that form class that you pasted into bpl. You will create something derived from what is in bpl. Gives a look at object-oriented concepts Quote Link to comment Share on other sites More sharing options...
artem_niko Posted February 18, 2022 Author Share Posted February 18, 2022 Again hello to all! I'll try to describe the situation. At the moment, BPL is loaded into UniTabSheet, everything is ok. Now, if I start the main project, include my BPL in it, and then make some changes to it and I need to re-enable it in the main project, then I cannot, because an error is given that the BPL has already been loaded. What I need? I needed what I could without stopping the main project i.e. without rebooting it, reconnect the updated BPL again. With this in mind, I have a few questions that I need help with: 1. How to reconnect BPL without restarting the main project? Help to add the package unloading code, at least by its name. 2. If, in one browser, you start two project sessions, then if my BPL was already loaded in the first project, then the second user cannot upload or download it, because. a message is displayed that the BPL has already been loaded. On the one hand, this check is correct, it will not be possible to download the package a second time. But, on the other hand, the second user, in his session, may not need to work with the previously loaded BPL, or vice versa. How can I make sure that both users can download the BPL as they need it and so that it does not depend on whether someone downloaded the BPL or not? After all, each user has his own session after authorization goes. Test_new_2.zip Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.