Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by dkounal

  1. Hi, I have a dll with a FMX form inside. Four procedures are exported to create and destroy the form. No other interaction exists. var xform:Txform; function CreatexForm: HWnd; stdcall; begin try if not Assigned(xform) then xform:=Txform.Create(nil); Result:=xform.GetHWnd; except Result:=INVALID_HANDLE_VALUE; end; end; procedure ShowxForm; stdcall; begin if Assigned(xform) then xform.Show; end; procedure HidexForm; stdcall; begin if Assigned(xform) then xform.Hide; end; procedure DestroyxForm; stdcall; begin if Assigned(xform) then FreeAndNil(xform); end; I want to use it from a VCL application that loads the DLL, show the form before closing. The testing VCL application just load DLL, calls CreatexFrom and ShowxForm to show the FMX form from the DLL. I click the system close button in the shown FMX form from the DLL Then I call DestroyxForm, and FreeLibrary and the DLL unloads without problems. I am getting an Exception just when VCL forms that called the DLL closes. I have searched about the subject but I found only results that deal with FMX forms from DLL inside VCL controls or forms. That it is not my case. Any ideas? Tank you in advance
  2. dkounal

    Show a FMX form inside a dll from a VCL application

    The new editor is in FMX, the existing application will take time to change and needs just this FMX form type. Until now it works with the exception when finishing. I am testing it. For the moment I am moving part of the code in a web service using XData.
  3. dkounal

    Show a FMX form inside a dll from a VCL application

    I have a working application in VCL that it does not worth to transform it to FMX. And I need custom interactive forms with controls inside created once by the user and being available to run in both VCL and mobile apps. Until now, I am a bit afraid to invest in FMX. This was a first attempt in windows.
  4. dkounal

    Show a FMX form inside a dll from a VCL application

    Thank you, I did not know it. To be honest I started from your code as it is here. The problem is that even without unloading the DLL the exception happens. It happens inside the Thtmleditor component, when it frees a TGPRegion and I believe it has to do with GDI+ It is mentioned here and here but I am not so experienced to deal with it.
  5. dkounal

    Show a FMX form inside a dll from a VCL application

    As my project is just minimal for the moment I will try the separate process. RemObjects's hydra is really interesting, I will give it a try Thank you
  6. dkounal

    Show a FMX form inside a dll from a VCL application

    It works with the following code I found: procedure TForm1.ShowAppEmbedded(WindowHandle: THandle; Container: TWinControl); var WindowStyle : Integer; FAppThreadID: Cardinal; begin /// Set running app window styles. WindowStyle := GetWindowLong(WindowHandle, GWL_STYLE); WindowStyle := WindowStyle - WS_CAPTION - WS_BORDER - WS_OVERLAPPED - WS_THICKFRAME; SetWindowLong(WindowHandle,GWL_STYLE,WindowStyle); /// Attach container app input thread to the running app input thread, so that /// the running app receives user input. FAppThreadID := GetWindowThreadProcessId(WindowHandle, nil); AttachThreadInput(GetCurrentThreadId, FAppThreadID, True); /// Changing parent of the running app to our provided container control winapi.Windows.SetParent(WindowHandle,Container.Handle); SendMessage(Container.Handle, WM_UPDATEUISTATE, UIS_INITIALIZE, 0); UpdateWindow(WindowHandle); /// This prevents the parent control to redraw on the area of its child windows (the running app) SetWindowLong(Container.Handle, GWL_STYLE, GetWindowLong(Container.Handle,GWL_STYLE) or WS_CLIPCHILDREN); /// Make the running app to fill all the client area of the container SetWindowPos(WindowHandle,0,0,0,Container.ClientWidth,Container.ClientHeight,SWP_NOZORDER); SetForegroundWindow(WindowHandle); end;
  7. dkounal

    Show a FMX form inside a dll from a VCL application

    If I have the FMX form to run as a separate process, in an separate executable, is it possible to embed it in a vcl control (ex tpanel) by using its window's handle?
  8. dkounal

    Show a FMX form inside a dll from a VCL application

    Thank you for your response. I have read not enthusiastic comments about having VCL and FMX together. I have tested the Firemonkey-container but I have usually strange internal compiler errors and I do not feel safe. The FMX form is a user customized form that should be able to run in all environments but for windows I have a VCL app that I do not want to change. I should probably forget FMX and try something else for these forms.
  9. dkounal

    XML Parsing and Processing

    I am using sOmniXmlVendor for mobile app compatibility. The Xml.XMLIntf.IXMLNode.XML is not available. How can I get the xml of an IXMLnode ? or how can I copy an IXMLnode to a new IXMLdocument? Thank you in advance SOLVED: I did the following: function getxml(x:inodexml):string; var srcx:Txmldocument; begin srcx:=Txmldocument.Create(nil); try srcx.xml.Text:=''; srcx.Active:=true; srcx.DOMDocument.appendChild(x.DOMNode); srcx.SaveToXML(result); finally srcx.Free; end; end;
  10. Just to comment that the problem was resolved after removing a Tevent that was used by a function.... And the renovation continues with excellent results and Delphi 10.4.2 now. I also returned back to TThreadedQueue<T> The books from Dalija Prasnikar (Delphi Event-based and Asynchronous Programming) and Primož Gabrijelčič (Delphi High Performance) helped a lot. Thank you all for the help
  11. I fully agree and I looking into it. It is an old project that slowly undergoes changes to be able to be used with the FMX framework too. The problem started when I replaced the messaging part between a thread and the UI that in the past TOmniMessageQueue where used. I can confirm that no access exists for ThreadedQueue that can cause problems. For the sure, the project still uses other ThreadedQueues and Tcriticalsections with other threads and I should check them all. I will check again and I will report. For the moment I have not an error report with cocinasync but it is too early to be sure.
  12. I had the same though, but: 1. I can not reproduced it in any of my computers, nor inside the development IDE. 2. It happens to a small number of computers of clients and in a couple of them it is reprodusable. 3. I got this line of error from Eurekalog and I am not it is the correct line of the error I am testing now the cocinasync Tqueue<T>
  13. Hi, I usually use varchar fields in SQL databases with a big number as max size. When I use a TFDMemTable, does the ftstring size consumes memory as described in its definition? If I declare it as "Add('lab',ftstring,500)", does it consumes in memory 500bytes (or 1000bytes) for each record, or as a Delphi string type is just the content string size ? I have Delphi professional and I can not see its code. Thank you in advance
  14. dkounal

    ftstring vs varchar in TFDMemTable

    Thank you very much. I apologize.
  15. I can not reproduce it in a separate project and it does not happen to all computers in the original Delphi project. I am still looking for a solution.
  16. Using TThreadedQueue<T> in Delphi 10.4.1, I have a couple of computers with windows 10 running an application of mine that have an Access violation error in line 7917 of system.generics.collections as reported by Eurekalog. it is the line: "TMonitor.Enter(FQueueLock);" It is not random. It happens all the time the first time it is used. Can you think of a reason? function TThreadedQueue<T>.PushItem(const AItem: T; var AQueueSize: Integer): TWaitResult; begin TMonitor.Enter(FQueueLock); try Result := wrSignaled; while (Result = wrSignaled) and (FQueueSize = Length(FQueue)) and not FShutDown do if not TMonitor.Wait(FQueueNotFull, FQueueLock, FPushTimeout) then Result := wrTimeout; if FShutDown or (Result <> wrSignaled) then Exit; FQueue[(FQueueOffset + FQueueSize) mod Length(FQueue)] := AItem; Inc(FQueueSize); Inc(FTotalItemsPushed); finally AQueueSize := FQueueSize; TMonitor.Exit(FQueueLock); end; TMonitor.Pulse(FQueueNotEmpty); end;
  17. I have to update an application that has 20 threads running at the same time and each thread is requesting an XML through an http connection. In order to process the received XML, each thread has to use data from 14 TFDMemtables. The Threads are the same running all the time and the TFDMemtables they use are also the same, The TFDMemTables' data are static, received from an external database when application starts, not need to be updated/edited as the application runs. I read that with TFDMemTable you can use clonecursor and have different TFDMemTable object instances with the same data. I though that I could create such a TFDMemTable for each thread before threads start to use them. My question: Can different threads use TFDMemTables object instances (created with data from clonecursor) from an initial TFDMemTable? Is this threadsafe? Thank you in advace
  18. I need to run a piece of code in TTask threads using a thread pool, that runs in every platform and get the results in the main UI thread in a thread safe message object without checking with a timer. Inspired by a post from Remy Lebeau in the Lazarus forum I wrote the following. Comments, suggestions, errors in the code welcome. interface type TTaskdata < T >= class type mydataP = ^T; mytaskproctyp =procedure(a: mydataP) of object; private Data: T; ProcessData: mytaskproctyp; procedure DoProcess; public procedure queue(datatyp: T; taskproc: mytaskproctyp); end; implementation procedure TTaskdata<T>.queue(datatyp: T; taskproc: mytaskproctyp); begin Data := datatyp; ProcessData := taskproc; TThread.queue(nil, DoProcess); end; procedure TTaskdata<T>.DoProcess; begin ProcessData(@Data); end; In an other/main Tform Unit type Dsoup = record nam: string; i: integer; end; // a sample record for send and receiving data to Ttask routine ReturnProc = procedure(mypointer: Ttaskdata<Dsoup>.mydataP) of object; var FCustomPool: TThreadPool; // the theadpool to be used for reusing threads, it should initialiazed in Tform's constructor procedure TForm1.Button1Click(Sender: TObject); // the initial route that will prepare data for Ttask and run it var soup: Dsoup; begin { set in Dsoup all data to send in TTask routine } TTask.Run(dowork(soup, getresults), FCustomPool); end; function TForm1.dowork(const a: Dsoup; p: ReturnProc): tproc; begin Result := // anonymous function to run by Ttask procedure var ff: Ttaskdata<Dsoup>; begin ff := Ttaskdata<Dsoup>.create; try { do all the task job here } ff.queue(a, p); // add result data to be sent with Thread.queue except ff.free; end; end; end; procedure TForm1.getresults(p: Ttaskdata<Dsoup>.mydataP); begin { here come the results from TTask in the main UI thread } end;
  19. dkounal

    A library path manager...

    I can not afford any more the "Can not load package" error message after installations that use DCC command line. I have a long library path with many components installed and an error like the following is presented again: warning MSB6002: The command-line for the "DCC" task is too long. Command-lines longer than 32000 characters are likely to fail. Try reducing the length of the command-line by breaking down the call to "DCC" into multiple calls with fewer parameters per call. this mean that I should remove paths from library path in the IDE and try to compile again and return them back.... a bit annoying.... Also, I hate to go to every combobox selection to add a path. The attached program reads registry and allows you to enable or disable library paths, add paths to all configs or remove from all configs. When saving it produces an .ini file with all paths (even these that are not enabled) to be used in the next time it runs No responsibility for anything, use it at your own risk, keep a backup of 'CurrentUser\SOFTWARE\Embarcadero\BDS\xxx\Library\' before using it, source at request, have a nice day! LibManager.zip
  20. dkounal

    A library path manager...

    That's a good solution too, for many other situations. Agreed and thank you. One day, the limit arrives to this solution, too. I have 3 to 5 letters dirs, but installation programs still change path in updates and add again the path they want..... Not all the components are used at the same time. I can not afford to install and de-install them, to go behind each update to see what happened. I needed something else. Now the limit is the IDE itself.
  21. I need to serialize and de-serialize different records types. I wrote the following code that works ok only for the serialization and to be honest, I have not tested having records with class objects. The opposite, the de-serialization gives me an error " Internal: Cannot instantiate type .... " when calling the TJson.JsonToObject. I believe it has to do with the initialization of the new object but I can not understand the problem Any ideas? Thank you in advance The code is: type Trec4Json<T>=class private fbv:T; public class Function rec2J(a: T):string; class Function J2rec(const a: string; var c:T):boolean; property bv:T read fbv write fbv; end; implementation uses rest.json; { Trec4Json<T> } class function Trec4Json<T>.rec2J(a: T): string; // Record to Json String var b: Trec4Json<T>; begin b := Trec4Json<T>.create; b.bv := a; try result := TJson.ObjectToJsonString(b); finally b.free; end; end; class function Trec4Json<T>.J2rec(const a: string; var c: T): boolean; // Json String to Record var b: Trec4Json<T>; begin try b := TJson.JsonToObject < Trec4Json < T >> (a); c := b.bv; b.free; result := true; except result := false; end; end;
  22. To be honest I usually use the above rec2J to log records with the Codesite express. Now, I need to transfer different type of records in JSON through mqtt protocol. So, I was investigating the J2rec. The idea of using BSON for the mqtt seems also better. Thank you a lot
  23. Thank you very much. I have noticed this library in the past but I did not remember it supports records too.
  24. Sqlite give the possibility to create two different ':memory:' databases and attach tables from the one database to the other. Using firedac with a ':memory:' sqlite database, is it possible to attach TFDmemtables as sqlite (virtual) tables? If so, how? Thank you in advance
  25. dkounal

    Attach tFDmemTables to memory sqlite database

    Thank you very much for your response I have seen this documentation and I have already used TFDlocalSQL with TFDMemTables ONLY The question is: In an existing TFDConnection fot SQLite with TFDTables and TFDQueries attached to it, can I add also a TFDLocalSQL and attach TFDMemTables? I notice for example that multiple results are not supported that "If the application is using base datasets and local datasets connected to the same SQLite connection, the connection must be enabled explicitly before any dataset on this connection is opened/executed/prepared. Otherwise, an exception is raised." I am not having the Enterprise version and I am a bit blind to use it in many cases, like the TFDDatSRow object that is not explained anywhere neither in the book of Jensen. I have also find that in the above link, the examples at the end of the page goes to a Not Found http error Thank you again in advance