

dmitrybv
Members-
Content Count
86 -
Joined
-
Last visited
Everything posted by dmitrybv
-
programmatically determine the edition of RAD Studio 12.3
dmitrybv posted a topic in Delphi IDE and APIs
Hello, How can I programmatically determine the edition of RAD Studio 12.3? In the registry key Computer\HKEY_CURRENT_USER\Software\Embarcadero\BDS\23.0, there is no value named Edition. I have the same question regarding RAD Studio 11.3 and 10.4. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
I tested RAD Studio 12.1 Community Edition. For this edition, the "Detail" properties of the bds.exe contain the value “Personal”. I don’t know what the value Personal means and whether it is related to the concept of Edition at all. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
Yes, in a real application I use the registry branch Computer\HKEY_CURRENT_USER\Software\Embarcadero\BDS\23.0 to get the value for the App parameter that stores the path to bds.exe I try to keep the demo code to a minimum so that it is clear what problem I am discussing here. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
It seems that the solution with "bds.exe /ProductInfo:SKU" is suitable, but it does not work in the classic function of outputting the results of the StdOutput work via CreatePipe. Can you tell me how to correctly redirect the results passed to StdOutput to TMemo? I am trying to use the following code, but TMemo remains empty. At the same time, if you create a BdsGetSKU.Cmd file with the text C:\RADStudio\23.0\bin\bds.exe /ProductInfo:SKU and run it in cmd, the text "Enterprise" is output in cmd. procedure RunConsoleAppAndCaptureOutput(const ACommandLine, AWorkingDir: string; AMemo: TMemo); var SecurityAttr: TSecurityAttributes; ReadPipe, WritePipe: THandle; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; Buffer: array[0..255] of AnsiChar; BytesRead: DWORD; AppRunning: DWORD; Output: TStringStream; CommandLineMutable: array[0..1023] of Char; begin AMemo.Clear; SecurityAttr.nLength := SizeOf(TSecurityAttributes); SecurityAttr.bInheritHandle := True; SecurityAttr.lpSecurityDescriptor := nil; if not CreatePipe(ReadPipe, WritePipe, @SecurityAttr, 0) then begin AMemo.Lines.Add('Failed to create channel.'); Exit; end; FillChar(StartupInfo, SizeOf(StartupInfo), 0); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.hStdOutput := WritePipe; StartupInfo.hStdError := WritePipe; StartupInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := SW_HIDE; StrPLCopy(CommandLineMutable, ACommandLine, Length(ACommandLine) + 1); if not CreateProcess( nil, CommandLineMutable, nil, nil, True, 0, nil, PChar(AWorkingDir), // <- working directory StartupInfo, ProcessInfo ) then begin AMemo.Lines.Add('Failed to start process.'); CloseHandle(ReadPipe); CloseHandle(WritePipe); Exit; end; CloseHandle(WritePipe); Output := TStringStream.Create; try repeat BytesRead := 0; if ReadFile(ReadPipe, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) and (BytesRead > 0) then begin Buffer[BytesRead] := #0; Output.WriteString(String(AnsiString(Buffer))); end; GetExitCodeProcess(ProcessInfo.hProcess, AppRunning); until AppRunning <> STILL_ACTIVE; // Read the rest while ReadFile(ReadPipe, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) and (BytesRead > 0) do begin Buffer[BytesRead] := #0; Output.WriteString(String(AnsiString(Buffer))); end; AMemo.Lines.Text := Output.DataString; finally Output.Free; CloseHandle(ReadPipe); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); end; end; procedure TForm1.Button1Click(Sender: TObject); begin // RunConsoleAppAndCaptureOutput(Edit1.Text, 'C:\RADStudio\23.0\bin', Memo1); // RunConsoleAppAndCaptureOutput('cmd /c dir', 'C:\Windows', Memo1); RunConsoleAppAndCaptureOutput('C:\RADStudio\23.0\bin\bds.exe /ProductInfo:SKU', 'C:\RADStudio\23.0\bin', Memo1); // RunConsoleAppAndCaptureOutput('C:\RADStudio\23.0\Projects\CommandLineInterpreter\BdsGetSKU.Cmd /ProductInfo:SKU', 'C:\RADStudio\23.0\bin', Memo1); end; -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
dcc32.exe does not generate any error. You can understand that something went wrong only at the end of the installation, when bpl packages are registered in the registry for IDE. dcc32.exe does not create bpl packages and then it is already clear. But I want to give the user information about the impossibility of installation before the installation process begins. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
dcc32.exe is present in RAD Studio 12.3 Community Edition. It runs without errors. After running dcc32.exe %ERRORLEVEL% = 0. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
Actually I need to determine the edition of RAD Studio from an external program, from my installer program, in order to understand whether I can use dcc32.exe to compile the library source codes to generate packages for installation or not. RAD Studio 12.3 Community Edition does not support compilation via dcc32.exe. I am trying to understand how I can determine in advance in the LibInstaller program whether I can generate packages and install the library in the IDE or not. -
programmatically determine the edition of RAD Studio 12.3
dmitrybv replied to dmitrybv's topic in Delphi IDE and APIs
1. RTLVersion and RAD Studio Edition (Professional, Enterprise, Community Edition) are different concepts. 2. RTLVersion for RAD Studio 12.3 cannot be called from an external program. -
Description: In Delphi, it's not possible to list units that reference each other in the interface uses section. This limitation significantly hinders class organization within a package. Initially, developers work around this by moving some unit references to the implementation uses section. However, as the class hierarchy becomes more complex, this strategy breaks down. At a certain point, class inheritance and cross-referencing between units can no longer evolve naturally due to circular reference restrictions. Instead of focusing on building a clean and scalable architecture, developers are forced to spend an excessive amount of time carefully juggling interface and implementation references across units to avoid dependency issues. Suggestion: Consider removing the concept of unit as a fundamental structural element in Delphi’s object model, and instead rely entirely on package-based architecture. Classes within the same package should be able to access each other regardless of which unit they reside in, without exposing their internal structure outside the package. If this change is too radical for Delphi’s current model, a more incremental alternative could be introduced: Allow splitting of interface/implementation code across multiple files, which could then be merged by the compiler or a preprocessor into a single internal unit. This would simulate package-level cohesion without breaking existing language design principles.
-
CaretPositionRTTIProp.GetValue(Memo1) raises AV
dmitrybv posted a topic in RTL and Delphi Object Pascal
Hello I can't figure out why the following code causes an AV error. procedure TFormSimpleDraw2.Button2Click(Sender: TObject); var Value: TValue; LType: TRttiType; RttiContext: TRttiContext; CaretPositionProp: TRttiProperty; CaretPosition: TCaretPosition; begin RttiContext := TRttiContext.Create; LType := RttiContext.GetType(Memo1.ClassInfo); CaretPosition := Memo1.CaretPosition; CaretPositionProp := LType.GetProperty('CaretPosition'); Value := CaretPositionProp.GetValue(Memo1); //AV is here end; Embarcadero® RAD Studio 12 Version 29.0.55362.2017 1. Create FMX Form. 2. Put TButton and TMemo on the Form. 3. Write TButton.OnClick as written above 4. Run and click Button -
CaretPositionRTTIProp.GetValue(Memo1) raises AV
dmitrybv replied to dmitrybv's topic in RTL and Delphi Object Pascal
"Just curious — how did you specify the calling convention cdecl? After all, DoGetValue doesn't contain any parameters for specifying the calling convention." -
CaretPositionRTTIProp.GetValue(Memo1) raises AV
dmitrybv replied to dmitrybv's topic in RTL and Delphi Object Pascal
If this issue is related to a bug in RTTI or TMemo, then a new bug report should be added to the Embarcadero Quality Portal. If this issue is related to the fact that the CaretPosition property cannot be read via RTTI, then is there a way to check this. -
Hi All What are the performance profilers for Delphi 12? Under Delphi 10.4 I use AQTime. But it looks like AQTime with Delphi 12 support hasn't been released yet.
-
Class alias for class helper doesn't make class helper visible for compiler.
dmitrybv posted a topic in RTL and Delphi Object Pascal
Class alias for class helper doesn't make class helper visible for compiler. Is it possible to declare class alias for class helper with making class helper visible for compiler? Example Unit1 TControlHelper = class helper for TControl function RefSelf: TControl; end; Unit2 TControlHelper = Unit1.TControlHelper; Unit3 uses Unit2; ... var MyControl: TControl; MyControl.RefSelf //Compiler error. -
Android. TDirectory.GetFiles('/storage/emulated/0/DCIM/Camera') returns an empty list
dmitrybv posted a topic in Cross-platform
Good day. Embarcadero® RAD Studio 12 Version 29.0.55362.2017 Android 13, Samsung S20. I have files taken by the camera in the folder '/storage/emulated/0/DCIM/Camera' on my phone. How to set up the Android application correctly so that I can get a list of these files? When creating an Fmx application by default, the command TDirectory.GetFiles('/storage/emulated/0/DCIM/Camera') returns an empty list. -
Android. TDirectory.GetFiles('/storage/emulated/0/DCIM/Camera') returns an empty list
dmitrybv replied to dmitrybv's topic in Cross-platform
Hello, Dave Thanks for the demo project. Is there a more universal way to view the list of files in Android folders? Regarding the TDirectory.GetDirectories(), TDirectory.GetFiles() methods, I noticed that the TDirectory.GetDirectories('/storage/emulated/0/') method returns a list of folders similar to what is visible in the Files by Google program. Files by Google displays files in folders such as: '/storage/emulated/0/DCIM/Camera' '/storage/emulated/0/DCIM/Screenshots' '/storage/emulated/0/Documents' '/storage/emulated/0/Download' but the TDirectory.GetFiles() method does not return any files when specifying any path. What method should be used in Android to get a list of files in a folder? -
Android. TDirectory.GetFiles('/storage/emulated/0/DCIM/Camera') returns an empty list
dmitrybv replied to dmitrybv's topic in Cross-platform
Is there a Demo project in RAD Studio Samples or on github.com that demonstrates the ability to view photos in the app taken via the camera? Perhaps the TDirectory.GetFile method on Android does not work correctly or the app should request some rights via User Persmissions. -
Android. TDirectory.GetFiles('/storage/emulated/0/DCIM/Camera') returns an empty list
dmitrybv replied to dmitrybv's topic in Cross-platform
TPath.GetCameraPath() returns the following value - '/storage/emulated/0/Android/data/com.embarcadero.EhLib_Fmx_MainDemo/files/DCIM'. When viewing from the program via TDirectory.GetFile, this folder does not contain files. When viewing from the phone, I cannot access the folder ‘/storage/emulated/0/Android/data/com.embarcadero.EhLib_Fmx_MainDemo’ at all. -
Is it possible to declare an identical type for a generic class?
dmitrybv posted a topic in RTL and Delphi Object Pascal
Is it possible to declare an identical type for a generic class? I can't do it. TTypedListFieldLinkEh = EhLib.TableLink.TypedLists.TTypedListFieldLinkEh; TListFieldLinkListEh = EhLib.TableLink.TypedLists.TListFieldLinkListEh; TTypedListItemLinkEh = EhLib.TableLink.TypedLists.TTypedListItemLinkEh; TListRecLinkListEh = EhLib.TableLink.TypedLists.TListRecLinkListEh; TListTableLinkEh = EhLib.TableLink.TypedLists.TListTableLinkEh; TListFieldLinkListEh<T: class, constructor> = EhLib.TableLink.TypedLists.TListFieldLinkListEh<T: class, constructor>; //Compile Error TTypedListItemLinkEh<T: class, constructor> = EhLib.TableLink.TypedLists.TTypedListItemLinkEh<T: class, constructor>; TListRecLinkListEh<T: class, constructor> = EhLib.TableLink.TypedLists.TListRecLinkListEh<T: class, constructor>; TListTableLinkEh<T: class, constructor> = EhLib.TableLink.TypedLists.TListTableLinkEh<T: class, constructor>; -
Is it possible to declare an identical type for a generic class?
dmitrybv replied to dmitrybv's topic in RTL and Delphi Object Pascal
Thank you. This code works: TListFieldLinkListEh<T: class, constructor> = class(EhLib.TableLink.TypedLists.TListFieldLinkListEh<T>); TTypedListItemLinkEh<T: class, constructor> = class(EhLib.TableLink.TypedLists.TTypedListItemLinkEh<T>); TListRecLinkListEh<T: class, constructor> = class(EhLib.TableLink.TypedLists.TListRecLinkListEh<T>); TListTableLinkEh<T: class, constructor> = class(EhLib.TableLink.TypedLists.TListTableLinkEh<T>); In this case, however, a new type is created. But for types created through generics this is not a very big problem. -
GExperts now fixes yet another annoyance in the Delphi IDE: Desktops
dmitrybv replied to dummzeuch's topic in GExperts
Hello. I would like to thank you for supporting GExperts. I am using GExperts_RS12_1.3.25_2024-08-24.exe in RAD Studio 12.3. I use only three functions: SortLines, PreviousIdent, NextIdent. These functions work in RAD Studio 12.3 without errors. -
C:\RADStudio\22.0\bin\dcc64.exe, error F2084: Internal Error: IRR928
dmitrybv posted a topic in Delphi IDE and APIs
Embarcadero® RAD Studio 11 Version 28.0.48361.3236 Please tell me what could be causing this error. C:\RADStudio\22.0\EhLib\Src>C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild EhLibRtl.dproj /t:Build /p:Config=Release /p:platform=Win64 || Pause Microsoft (R) Build Engine version 4.8.9037.0 [Microsoft .NET Framework, version 4.0.30319.42000] Copyright (C) Microsoft Corporation. All rights reserved. Build started 16/03/2025 22:50:46. Project "C:\RADStudio\22.0\EhLib\Src\EhLibRtl.dproj" on node 1 (Build target(s)). CreateProjectDirectories: Creating directory "..\Lib\Win64\Release\". md "..\Lib\Win64\Release\" Creating directory "C:\RADStudio\22.0\EhLib\Dcp\Win64\". md "C:\RADStudio\22.0\EhLib\Dcp\Win64\" Creating directory "..\Hpp\Win64\". md "..\Hpp\Win64\" Creating directory "C:\RADStudio\22.0\EhLib\Bpl\Win64\". md "C:\RADStudio\22.0\EhLib\Bpl\Win64\" BuildVersionResource: C:\RADStudio\22.0\bin\cgrc.exe -c65001 EhLibRtl.vrc -foEhLibRtl.res CodeGear Resource Compiler/Binder Version 1.2.2 Copyright (c) 2008-2012 Embarcadero Technologies Inc. Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0 Copyright (C) Microsoft Corporation. All rights reserved. Deleting file "EhLibRtl.vrc". del "EhLibRtl.vrc" _PasCoreCompile: C:\RADStudio\22.0\bin\dcc64.exe -$D0 -$L- -$Y- --no-config -B -Q -Z -TX.bpl -AGenerics.Collections=System.Generics.Co llections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;Dbi Procs=BDE;DbiErrs=BDE -DRELEASE -E.\Win64\Release -Ic:\radstudio\22.0\lib\Win64\release;C:\Users\BDV\Documents\Embarc adero\Studio\22.0\Imports;C:\RADStudio\22.0\Imports;C:\RADStudio\22.0\EhLib\Dcp\Win64;C:\RADStudio\22.0\include -LEC: \RADStudio\22.0\EhLib\Bpl\Win64 -LNC:\RADStudio\22.0\EhLib\Dcp\Win64 -NU..\Lib\Win64\Release -NSWinapi;System.Win;Dat a.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;System;Xml;Data;Datasnap;Web;Soap; -Oc:\radstudio\22.0\lib\Win64\release; C:\Users\BDV\Documents\Embarcadero\Studio\22.0\Imports;C:\RADStudio\22.0\Imports;C:\RADStudio\22.0\EhLib\Dcp\Win64;C: \RADStudio\22.0\include -Rc:\radstudio\22.0\lib\Win64\release;C:\Users\BDV\Documents\Embarcadero\Studio\22.0\Imports; C:\RADStudio\22.0\Imports;C:\RADStudio\22.0\EhLib\Dcp\Win64;C:\RADStudio\22.0\include -Uc:\radstudio\22.0\lib\Win64\r elease;C:\Users\BDV\Documents\Embarcadero\Studio\22.0\Imports;C:\RADStudio\22.0\Imports;C:\RADStudio\22.0\EhLib\Dcp\W in64;C:\RADStudio\22.0\include --description:"EhLib RunTime Package" -JL -NBC:\RADStudio\22.0\EhLib\Dcp\Win64 -NH..\H pp\Win64 -NOC:\RADStudio\22.0\EhLib\Dcp\Win64 EhLibRtl.dpk Embarcadero Delphi for Win64 compiler version 35.0 Copyright (c) 1983,2021 Embarcadero Technologies, Inc. Rtl\EhLibUtils.pas(2076): error F2084: Internal Error: IRR928 [C:\RADStudio\22.0\EhLib\Src\EhLibRtl.dproj] Done Building Project "C:\RADStudio\22.0\EhLib\Src\EhLibRtl.dproj" (Build target(s)) -- FAILED. Build FAILED. "C:\RADStudio\22.0\EhLib\Src\EhLibRtl.dproj" (Build target) (1) -> (_PasCoreCompile target) -> Rtl\EhLibUtils.pas(2076): error F2084: Internal Error: IRR928 [C:\RADStudio\22.0\EhLib\Src\EhLibRtl.dproj] 0 Warning(s) 1 Error(s) Time Elapsed 00:00:00.85 Press any key to continue . . . When compiling via IDE, no error occurs. -
TValue.IsType<String> for Variant(Interface) is very slow.
dmitrybv posted a topic in RTL and Delphi Object Pascal
Hello. The following code takes 0.1 seconds on my computer. In my opinion, this is too slow. procedure TFormSimpleDraw2.Button4Click(Sender: TObject); var ItfcVarValue: TValue; Itfc: IInterface; VarValue: Variant; Res: Boolean; begin Itfc := TInterfacedObject.Create; VarValue := Itfc; ItfcVarValue := TValue.From<Variant>(VarValue); var TimeSpan := TThread.GetTickCount64; Res := ItfcVarValue.IsType<String>; Memo1.Lines.Add(FloatToStr((TThread.GetTickCount64 - TimeSpan) / 1000) + ' sec; Result = ' + Res.ToString(TUseBoolStrs.True)); end; Result in Memo1 Memo1.Text = 0.109 sec; Result = False Most likely the reason is related to the occurrence of an internal exception which is then suppressed somewhere. ---- procedure TFormSimpleDraw2.Button5Click(Sender: TObject); var Res: Boolean; ItfcVarValue: TValue; begin ItfcVarValue := TValue.From<IInterface>(TInterfacedObject.Create); var TimeSpan := TThread.GetTickCount64; Res := ItfcVarValue.IsType<String>; Memo1.Lines.Add(FloatToStr((TThread.GetTickCount64 - TimeSpan) / 1000) + ' sec; Result = ' + Res.ToString(TUseBoolStrs.True)); end; Memo1.Text = 0 sec; Result = False -
How to check that TValue.Type is array of TValue
dmitrybv posted a topic in RTL and Delphi Object Pascal
Hello How to check that TValue.Type is array of TValue function ValueIsValueArray(const V: TValue): Boolean; begin Result := V.TypeInfo = System.TypeInfo(array of TValue); //?? end; -
How to check that TValue.Type is array of TValue
dmitrybv replied to dmitrybv's topic in RTL and Delphi Object Pascal
Since I only use dynamic arrays I used the following solution: function ValueIsArrayOfValues(const V: TValue): Boolean; begin Result := V.TypeInfo = TypeInfo(TArray<TValue>); end;