-
Content Count
22 -
Joined
-
Last visited
Everything posted by Rolf Fankhauser
-
I would like to use Open XML SDK in C++Builder. I found instructions, docs and forums only for VS C++. I tried the Direct Office library for Delphi but it doesn't support C++Builder. Thanks in advance for any hints!
-
How to use Open XML SDK in C++Builder
Rolf Fankhauser replied to Rolf Fankhauser's topic in General Help
Ok, I found Bruno Sonnino's Blog. He shows how to create OpenXML files in Delphi without using the SDK but directly generating the XML code (but it looks rather cumbersome...). I think that should also be possible in C++Builder. So, many thanks to Bruno for this tutorial and sharing the code !! But hints how to use the SDK in C++Builder would be still appreciated... -
Hi, I generate in my application dynamically svg code using a javascript version of GraphViz (viz.js). The nodes are created as follows: <g class="node" id="node1"><title>B Regen</title> <polygon fill="none" stroke="black" points="63.9539,-396 0.0460627,-396 0.0460627,-360 63.9539,-360 63.9539,-396" /> <text font-family="Times,serif" font-size="14" text-anchor="middle" x="32" y="-373.8">B Regen</text> </g> Because I want to show some data of the objects (nodes) on MouseOver I changed the innerText of <title> (which is shown as hint by default by the browser) by the following C++ code: // helpers for interface reference counting // could alternatively use TComInterface instead of DelphiInterface typedef DelphiInterface<IHTMLDocument3> _di_IHTMLDocument3; typedef DelphiInterface<IHTMLElement> _di_IHTMLElement; typedef DelphiInterface<IHTMLElementCollection> _di_IHTMLElementCollection; typedef DelphiInterface<IHTMLWindow2> _di_IHTMLWindow; // Get Data: _di_IHTMLDocument3 doc = CppWebBrowser1->Document; _di_IHTMLElement elem; _di_IHTMLElementCollection collection; _di_IHTMLWindow window; long len; TVariant value; // only for testing OleCheck(doc->getElementById(WideString("svg"), &elem)); if (elem) { elem->getAttribute(WideString("viewBox"), 2, &value); ShowMessage("viewBox: " + value); } // fill the title tags with data to show on Mouse over: OleCheck(doc->getElementsByTagName(WideString("title"), &collection)); collection->get_length(&len); //ShowMessage("Collection length: " + IntToStr(len)); //ShowMessage(Commands->Text); WideString tmp, tmp2; int line; for (long i = 0; i < len; ++i) { TVariant name = i; TVariant index = 0; DelphiInterface<IDispatch> disp; if(SUCCEEDED(collection->item(name, index, &disp))) { DelphiInterface<IHTMLElement> element; if( SUCCEEDED(disp->QueryInterface(IID_IHTMLElement, (LPVOID*)&element))) { element->get_innerText(&tmp); //reading element name line = FindElementInMemo(Commands, Trim(tmp)); //finding the element in a memo if (line != -1) { tmp2 = ExtractParameters(Commands->Strings[line]); //extracting the data to show //if (tmp != WideString("Output")) { if (tmp2 == WideString("")) tmp2 = WideString("a<br>b"); //test to format the data on two lines OleCheck(element->put_innerHTML(tmp2)); //replace the original text of the element name by the element data } } } } All is working but the text is not shown on multiple lines. ExtractParameters returns one line, so I made a test by creating constant data of 2 lines by "a<br>b". I tried with put_innerText and put_innerHTML but without success. Any idea why this doesn't work? Could I define a separate event handler for onmouseover using doc->execScript ? Thanks, Rolf
-
has anyone used the gstreamer libraries with c++ builder?
Rolf Fankhauser replied to DanW's topic in General Help
Did you try to generate import libraries with mkexp? -
In my application I generate a SVG graphic in a TCppWebBrowser by providing GraphViz dot language code that is converted to SVG by a JavaScript version of GraphViz viz.js. File _test.html shows the original HTML page (dot code and JavaScript code) that produces the SVG output shown in file test.html. In the form with the TCppWebBrowser component I added some buttons to zoom in, out and reset to 100%: //--------------------------------------------------------------------------- void __fastcall TFormViewer::btZoomInClick(TObject *Sender) { ZoomFactor *= 1.1; OleVariant ZoomFac = int(ZoomFactor); CppWebBrowser1->ExecWB(63, OLECMDEXECOPT_DONTPROMPTUSER, ZoomFac, 0); } //--------------------------------------------------------------------------- void __fastcall TFormViewer::btZoomOutClick(TObject *Sender) { ZoomFactor *= 0.9; OleVariant ZoomFac = int(ZoomFactor); CppWebBrowser1->ExecWB(63, OLECMDEXECOPT_DONTPROMPTUSER, ZoomFac, 0); } //--------------------------------------------------------------------------- // void __fastcall TFormViewer::btResizeClick(TObject *Sender) { ZoomFactor = 100; OleVariant ZoomFac = int(ZoomFactor); CppWebBrowser1->ExecWB(63, OLECMDEXECOPT_DONTPROMPTUSER, ZoomFac, 0); } This works fine but for huge networks with hundreds of elements I would like to zoom to a specific element by name (in test.html e.g. to "HE M15". My idea is to change the viewBox attribute of the svg object. So, I need to find the element with the specific name (e.g. "HE M15"), read the x, y coordinates of the text and change the viewBox accordingly. Would this be possible by IHTMLWindow2::execScript (JavaScript code) or other tools to access the DOM... or would it be easier to save the html page, load it in a StringList, search the element and coordinates there and change the viewBox attribute, save the file and load it into the TCppWebBrowser component again? __test.html test.html
-
Hi again, I would like to use P4D in my application for Real Time Control (RTC) in a program for simulation of sewer systems. The program needs to calculate 500'000 time steps or more. In each time step a Python script should set some controls according to some discharges in the system. The rules are system-specific and the users should be able to define the rules for their system. A perfect application for a scripting language! So, I created a small application to test the performance of P4D for RTC: a loop with 1 mio iterations. The loop in Delphi: for i:=1 to i_end do begin input := Random * 10.0; if (input > 6.0) or (input < 2.0) then output := 40.0 else output := 20.0 end; The Python script 'loop.py': if (inflow.Value > 6) or (inflow.Value < 2) : outflow.Value = 40 else: outflow.Value = 20 and the Delphi code to execute the script: script.LoadFromFile('loop.py'); for i:=1 to i_end do begin PythonDelphiVar2.Value := Random * 10.0; PythonEngine1.ExecStrings(script); end; The results for Delphi (with different methods to measure the time): Time by Now to run loop: 28 ms Time by GetTickCounts to run loop: 15 ms Time by StopWatch to run loop: 27664 us Time by StopWatch to run loop: 27664600 ns and for P4D: loop started with python script, 1 mio iterations! Time by Now to run loop: 28830 ms Time by GetTickCounts to run loop: 28844 ms Time by StopWatch to run loop: 28828936 us Time by StopWatch to run loop: 28828936500 ns P4D is around 1000 times slower than Delphi! Some ideas to improve the performance would be very welcome. I made some tests with C++Builder running the Python script with the C API. Then Python is very fast: 200 ms for 1 mio iterations. But when I moved this test program from Win 7 to Win 10 it didn't work any more (no error message, silent close of the program when running the script) At the moment I use Lua: advantages: very fast (ca. 300 ms for 1 mio iterations), no use of external dll's, all is included in the main C++Builder application disadvantages: C API rather complicated, not so much modules but growing, no support for Delphi (maybe there is a component...) Regards, Rolf
-
What about additional free open source C++ libraries on GetIt ?
Rolf Fankhauser posted a topic in General Help
I tried to install and use OpenCV under C++Builder 10.3.3 (see stack overflow), until now without success. Wouldn't it possible that Embarcadero could make this important library available via GetIt or at least provide a short installation tutorial with working dll's and import libs ? For Delphi there is a project on GitHub (Delphi-OpenCV) but it's an old version and I don't know if it can be used in C++Builder. At the moment there are 15 C++ libraries available on GetIt. Not very much compared to MS VC (ca. 800) . I don't need 800 but it is rather frustrating if I see an interesting library but install/compiling instructions only for GCC or MS VC or just precompiled packages only for MS VC.. Some libraries are easier to install than OpenCV, e.g. NLopt for non-linear optimization that I tested. Would also be a candidate for GetIt. Maybe I belong to a minority of RAD Studio users because I need many mathematical and scientific libraries and these libraries have low priority for Embarcadero. Then let me know... -
What about additional free open source C++ libraries on GetIt ?
Rolf Fankhauser replied to Rolf Fankhauser's topic in General Help
@oliwe: I have already encountered VTK when I worked shortly with Paraview using some CFD software and VisIt (3D visualization of MRI slices) and recently when I was looking for a graph drawing library. Many programs and libraries are built on top of VTK. At the moment I use Graphviz in C++Builder for drawing graphs/networks. But I use a Javascript implementation of Graphviz viz.js. There is also a COM library WinGraphviz that could be used. -
What about additional free open source C++ libraries on GetIt ?
Rolf Fankhauser replied to Rolf Fankhauser's topic in General Help
Here is an example for install documentation of NLopt It would be nice to have more such documentation for important free open source libraries (with a license allowing commercial use). Installation over GetIt would be perfect but not a must. Installing documentation would be enough. -
Please find attached unit StopWatch for Delphi 7 (StopWatch.pas) This is from Zarko Gajic, possibly not exactly identical to that from System.Diagnostics.
-
Hi all I would like to deploy python with my Delphi application to my customers. So, I downloaded and installed a Windows embeddable package of Python in a subdirectory \python of my project folder. I set the following two lines in the OnCreate event handler of the main form: PythonEngine1.SetPythonHome('\python'); PythonEngine1.LoadDLL; With this setting I can execute Python scripts but I cannot import numpy (ImportError: No module named 'numpy') I can import numpy from the command line, so it seems to be correctly installed: C:\Data\Delphi10-3\TestPythonPerformance\python>python Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import numpy as np >>> I also tested if P4D uses the correct Python distribution with: import sys print (sys.version) and I get: 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] The structure of the Python installation is as follows (under \python): Scripts share Lib site-packages ... matplotlib ... numpy ... pandas ... Do I need to set a module path that P4D finds the modules? Another problem is that importing matplotlib (even on the command line) rises an error that tkinter is not installed. If I try to install tkinter I get an error: ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none) ERROR: No matching distribution found for tkinter Thanks, Rolf
-
Problems using embedded python package for Windows
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
I installed the PyQt5 package: ...\python> cd Scripts ...\python\Scripts> pip install PyQt5 Now matplotlib is working with GUI because there is now Qt as a GUI backend. The window doesn't look really native, Tk looks nicer. -
Problems using embedded python package for Windows
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
I now installed the newest version with python 3.9.4. There is a file python39._pth (I checked it: Indeed, the python35 package didn't have a file python35._pth) So, I changed all according to the instructions. I installed numpy and matplotlib but when I try matplotlib from the command prompt and want to plot I get the following warning: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. Only this backend "agg" is installed, no others. If I try to install Tkinter I get the same error as before with the python35 package: ERROR: Could not find a version that satisfies the requirement Tkinter ERROR: No matching distribution found for Tkinter Can I use a Delphi window as backend? Saving the plot as png or svg and display it in Delphi would be a workaround but rather complicated. -
Problems using embedded python package for Windows
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
Hello SwiftExpat Thanks for the links. I already know the first link. The problem is that I have no such file python35._pth. I will check the other link and possibly download and install the embeddable distribution again. -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
Thanks a lot !! This reference counting is annoying !! Thanks for the link, I will study the article. I supposed that ExtractPythonObjectFrom does increment the reference count. I corrected my code with your above suggestions. You forgot to remove PythonEngine1: var PyInput := PE.PythonEngine1.PyFloat_FromDouble(Input); Performance didn't change -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
Ok, 1 mio iterations in 325 ms (average). That's close to the C-API version and 10 times slower than compiled. That is usable. That's the code: procedure TForm1.btRunScriptedClick(Sender: TObject); var i, i_end: integer; start, stop: TDateTime; start2, stop2: cardinal; sw : TStopWatch; script: TStringList; PyFunc, PyValue, PyArgs: PPyObject; begin sw := TStopWatch.Create; script := TStringList.Create; Memo2.Lines.Append(''); Memo2.Lines.Append('loop started with python script, 1 mio iterations!'); try i_end := 1000000; start := Now; start2 := GetTickCount; sw.Start; script.LoadFromFile('loop_function.py'); PythonEngine1.ExecStrings(script); PyFunc := ExtractPythonObjectFrom(MainModule.calc_outflow); PyArgs := PythonEngine1.PyTuple_New(1); for i:=1 to i_end do begin Input := Random * 10.0; //PyValue := PythonEngine1.PyLong_FromLong(Input); integer version PyValue := PythonEngine1.PyFloat_FromDouble(Input); PythonEngine1.PyTuple_SetItem(PyArgs, 0, PyValue); PyValue := PythonEngine1.PyObject_CallObject(PyFunc, PyArgs); //Output := PythonEngine1.PyLong_AsLong(PyValue); integer version Output := PythonEngine1.PyFloat_AsDouble(PyValue); //Memo2.Lines.Append('Input: ' + IntToStr(Input) + ', Output: ' + IntToStr(Output)); end; stop := Now; stop2 := GetTickCount; sw.Stop; if sw.IsHighResolution = true then Memo2.Lines.Append('Is high resolution!') else Memo2.Lines.Append('Is not high resolution!'); Memo2.Lines.Append(''); Memo2.Lines.Append('Time by Now to run loop: ' + FloatToStr(RoundTo((stop - start)*24*3600*1000, -3)) + ' ms'); Memo2.Lines.Append('Time by GetTickCounts to run loop: ' + IntToStr(stop2 - start2) + ' ms'); Memo2.Lines.Append('Time by StopWatch to run loop: ' + IntToStr(sw.ElapsedMicroseconds) + ' us'); Memo2.Lines.Append('Time by StopWatch to run loop: ' + IntToStr(sw.ElapsedNanoseconds) + ' ns'); finally { with PythonEngine1 do begin if Assigned(PyValue) then Py_DECREF(PyValue); if Assigned(PyArgs) then Py_DECREF(PyArgs); if Assigned(PyFunc) then Py_DECREF(PyFunc); end; } sw.Free; script.Free; end; end; I have some problems with dereferencing the PPyObjects. Therefore I removed them. I got an AV when I run the loop multiple times with dereferencing. But I don't understand why. Without dereferencing I had no problems to run the loop multiple times. -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
I used the following code (not complete) to call the function in C++Builder: PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pValue, *pType, *pTraceback; int i; ... pArgs = PyTuple_New(1); ... for (int j = 0; j < j_end; j++) { i = random(10); pValue = PyInt_FromLong(i); PyTuple_SetItem(pArgs, 0, pValue); pValue = PyObject_CallObject(pFunc, pArgs); } I guess that PPyObject (Delphi) is equivalent to PyObject (C) With ExtractPythonObjectFrom(MainModule.calc_outflow) I would define pFunc, right? I will try it... -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
Yes !! => now 1 mio iterations in 1800ms, not bad. I will try the low level functions of PythonEngine. It seems that they are wrapper of the C-API functions? Next step would be to use P4D in C++Builder because my application for sewer system simulation is written in C/C++ I think there is a tutorial from David I for installation and use? Thanks for your prompt help! -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
@pyscripter The compiler didn't accept the following line proposed by you: var CalcOutFlow: Variant := MainModule.calc_outflow; So, I split it: CalcOutFlow: Variant; (in var block) and CalcOutFlow := MainModule.calc_outflow; But then I get an error on line: Output := CalcOutFlow(Random * 10.0); (the compiler does not understand the bracket) -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
Thanks for the hint! This was my next idea but I didn't yet know how to call the function. I already noticed this when I used the C API. Then I also changed from the script to a function and could improve the speed. For Lua I got an improvement of a factor 10 using a function. -
Poor performance of Python script
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
But the main program needs the value for each iteration, that's the real time control! The Delphi program transmits the input to the python script. The python script calculates the output according to the rule and gives it back to Delphi. This must happen in each iteration (time step). -
Problems using embedded python package for Windows
Rolf Fankhauser replied to Rolf Fankhauser's topic in Python4Delphi
I used the following script (from "deploying p4d.pdf") to list the existing modules: import sys import os print("Python path =", sys.path) print() print("Python modules already imported:") for m in sys.modules.values(): if m: print(" ", m) print() print("PYTHONHOME =", os.getenv('PYTHONHOME')) print("PYTHONPATH =", os.getenv('PYTHONPATH')) Output: Python modules already imported: <module '_datetime' (built-in)> <module 'codecs' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\codecs.pyc'> <module 'builtins' (built-in)> <module 'encodings.aliases' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\aliases.pyc'> <module '_frozen_importlib_external' (frozen)> <module 'io' (built-in)> <module 'time' (built-in)> <module 'encodings.mbcs' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\mbcs.pyc'> <module 'genericpath' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\genericpath.pyc'> <module '_collections_abc' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\_collections_abc.pyc'> <module 'marshal' (built-in)> <module 'sys' (built-in)> <module '_weakrefset' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\_weakrefset.pyc'> <module 'zlib' (built-in)> <module 'os' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\os.pyc'> <module 'ntpath' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\ntpath.pyc'> <module 'stat' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\stat.pyc'> <module 'encodings' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\__init__.pyc'> <module '_bootlocale' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\_bootlocale.pyc'> <module 'ntpath' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\ntpath.pyc'> <module '_weakref' (built-in)> <module 'encodings.latin_1' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\latin_1.pyc'> <module 'abc' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\abc.pyc'> <module 'errno' (built-in)> <module 'site' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\site.pyc'> <module '_codecs' (built-in)> <module '_sitebuiltins' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\_sitebuiltins.pyc'> <module 'zipimport' (built-in)> <module '_thread' (built-in)> <module '_frozen_importlib' (frozen)> <module '_signal' (built-in)> <module '_locale' (built-in)> <module 'encodings.utf_8' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\utf_8.pyc'> <module 'winreg' (built-in)> <module 'sysconfig' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\sysconfig.pyc'> <module 'math' (built-in)> <module 'pyio'> <module 'nt' (built-in)> <module '_stat' (built-in)> <module '_imp' (built-in)> <module '_warnings' (built-in)> <module 'datetime' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\datetime.pyc'> <module '__main__' (built-in)> <module 'io' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\io.pyc'> <module 'encodings.cp1252' from 'C:\\Data\\Delphi10-3\\TestPythonPerformance\\python\\python35.zip\\encodings\\cp1252.pyc'> PYTHONHOME = None PYTHONPATH = None It seems that only modules in python35.zip are imported