Jump to content

dummzeuch

Members
  • Content Count

    3019
  • Joined

  • Last visited

  • Days Won

    108

Everything posted by dummzeuch

  1. dummzeuch

    Is there a Delphi "subprocess" library?

    That was the problem with this topic from the beginning. What exactly is a "subprocess in python"? What does it do, if it is "more than DOS / command line stuff"?
  2. I have used something similar, but not for normal types but for nested types. unit UnitA; interface uses MyTypes; type TSomeType = class(TSomeOtherClass) public type TSomeNestedType = MyTypes.SomeType; end; The idea is to reference the nested type instead of the type declared in MyTypes, so if the nested type was changed later to something else (but similar enough as to not require code changes), the other code doesn't need to be updated. Hm, thinking about it now, with a more modern Delphi than 2007 (which I used when I wrote this), I would probably use Generics instead.
  3. dummzeuch

    Stand alone EXE

    Turn off (remote) Debug symbols in the linker options, if it is turned on.
  4. Just for completeness, there are also some lists on version information on the Delphi Wiki: https://delphi.fandom.com/wiki/Delphi_Release_Dates https://delphi.fandom.com/wiki/CompilerVersion_Constant https://delphi.fandom.com/wiki/Delphiversions.inc https://delphi.fandom.com/wiki/RTLVersion_Constant https://delphi.fandom.com/wiki/Borland_Compiler_Conditional_Defines https://delphi.fandom.com/wiki/Delphi_Build_Numbers I (and a few others) try to keep them more or less up to date, but I just noticed that some have lapsed again. Having seen that there are other lists that seem to be better maintained I'm considering just pointing there instead. The whole Wiki is mostly outdated anyway, the original maintainer(s) having disappeared.
  5. I inherited most of it, the part that I wrote was based on the existing code, so I can't take the credit.
  6. The difference between updates and patches seems to be that updates change the version number on the about dialog and patches don't. If installed via GetIt, patches are listed in the registry and will be shown in the about dialog as an additional information, but that does not happen if you don't use GetIt for the installation. Both can switch some executables, which then will get a new version number, but you have to know for which executables to look to see that difference. I have code in GExperts that identifies the current update and patch level in case some workaround or fix is necessary. I thought about making a small stand alone tool from this, but never came around doing it. That code is in https://sourceforge.net/p/gexperts/code/HEAD/tree/trunk/Source/Framework/GX_GetIdeVersion.pas In case anybody is interested.
  7. dummzeuch

    Watch me coding in Delphi on YouTube

    Break out the crayons and draw away. We don't need no stinkin' AI.
  8. dummzeuch

    Tool to sort units used in project by dependency

    You could try the nightly build or get the source code and compile it yourself (I do that once in a while, it's not rocket science but more complex than with GExperts). But I don't know whether this might solve the problem.
  9. dummzeuch

    Tool to sort units used in project by dependency

    cnpack has a tool to remove unused units from the uses list. It's not perfect, but a good starting point.
  10. I just now stumbled upon a small bug in a unit from Jedi Math which we are using. Any references to that library that google found seem to be rather outdated (some even talk about CVS access to the source code). Project Jedi on Github does not mention Jedi Math at all. Does anybody know whether this library is still being maintained? And if yes, who to contact and where?
  11. dummzeuch

    Is jedimath still maintained?

    No, I mean the Jedi Math library linked from https://wiki.delphi-jedi.org/wiki/JEDI_Math . It definitely looks unmaintained to me, but I thought I'd ask anyway.
  12. dummzeuch

    Thread leaks report (FastMM4)

    There are none. Free can always be called on nil instance. I wasn't talking bout calling free for an object, but what you were describing next: As I said: Wrong example on my part. I apologize.
  13. dummzeuch

    Thread leaks report (FastMM4)

    Ouch, yes you are right! I chose the wrong example. But there are always more complex examples where this won't work. (Unfortunately I can't think of one right now. GetMem/FreeMem should also work fine.)
  14. dummzeuch

    Thread leaks report (FastMM4)

    I see no problem with raising an exception in a constructor, provided you write the destructor in a way that can handle a partly constructed instance. Since you can't prevent any system or RTL exception to be raised from within the constructor, you'll have to handle that case anyway. Always keep in mind that an exception in a constructor will cause the destructor being called immediately. So don't do this: constructor TBla.Create; begin inherited; FSomeHelperObject := TSomeClass.Create; end; destructor TBla.Destroy; begin FSomeHelperObject.Free; // <== this might cause an AV if FSomeHelperObject hasn't been assigend inherited; end; But do this instead: destructor TBla.Destroy; begin if Assigned(FSomeHelperObject) then FSomeHelperObject.Free; inherited; end; (Or use FreeAndNil, which basically does the same internally.) You can easily test if your destructor can handle this case by temporarily putting a raise exception.Create('test') as the first statement in your constructor (before even calling inherited Create). I'm sure we are all guilty of writing wrong destructors at some time though.
  15. I just had the need for a safer version of Delphi's GetEnumName, which checks whether the enum value passed to it is actually valid. This is what I came up with: // P must point to the length field (that is the first byte) of a ShortString function AfterShortString(const P: Pointer): Pointer; inline; begin Result := Pointer(IntPtr(P) + PByte(P)^ + 1); end; function SafeGetEnumName(TypeInfo: PTypeInfo; Value: Integer): string; var P: Pointer; T: PTypeData; begin if TypeInfo^.Kind = tkInteger then begin Result := IntToStr(Value); Exit; end; T := GetTypeData(GetTypeData(TypeInfo)^.BaseType^); if (TypeInfo = System.TypeInfo(Boolean)) or (T^.MinValue < 0) then begin // LongBool/WordBool/ByteBool have MinValue < 0 and // arbitrary content in Value; Boolean has Value // in [0, 1] } Result := BooleanIdents[Value <> 0]; if SameText(HexDisplayPrefix, '0x') then Result := LowerCase(Result); end else begin if (Value < T.MinValue) or (Value > T.MaxValue) then Result := Format('OutOfBounds(%d)', [Value]) else begin P := @T^.NameList; while Value <> 0 do begin P := AfterShortString(P); Dec(Value); end; {$IFDEF UNICODE} Result := _UTF8ToString(P); {$ELSE} Result := PShortString(P)^; {$ENDIF} end; end; end; (read on in the blog post)
  16. Hm, yes. But GetEnumName doesn't work for enums with explicitly assigned values. program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.TypInfo; type TBla = (a5 = 5, a7 = 7); TBlub = (b5, b7); begin WriteLn(GetEnumName(TypeInfo(TBlub), Ord(b5))); WriteLn(GetEnumName(TypeInfo(TBla), Ord(a5))); end [dcc32 Error] Project1.dpr(19): E2134 Type 'TBla' has no type info
  17. dummzeuch

    F1 context help to WinAPI ?

    I had totally forgotten about that. I also don't quite remember why I used this particular sort algorithm, probably because I was tired of Quicksort and Cocktail Sort sounded more interesting. Or maybe I just selected a random sort algorithm from my dzlib.
  18. dummzeuch

    F1 context help to WinAPI ?

    Delphi Help Expert
  19. dummzeuch

    Quality Portal going to be moved

    Maybe Embarcadero really care about the old bug reports so they stayed with JIRA in order to make it easier to import the old reports into the new system? Of course that's pure speculation.
  20. dummzeuch

    Variable might not have been initialized

    No. That line is only executed if the condition in the if statement three lines above it is true. Let me adapt the code to make this clear: if FWorkOrderManager.GetWorkOrderDataByIndex(WorkOrdersSelectedRow - 1, Data) then begin // evaluates file index FileIndex := ARow - 1; // <--- Here FileIndex is initialized, but only if the condition above was true end; if (FileIndex < 0) or (FileIndex >= TWorkOrderData.FILE_DATA_SIZE) then Exit; // <--- here FileIndex mith not have been initialized if the condition above was false. And that's what the compiler says.
  21. dummzeuch

    Variable might not have been initialized

    Which again highlights the value of a code formatter. I'm so used to that that I overlooked the if statement. 😞
  22. dummzeuch

    Variable might not have been initialized

    I usually solve this kind of warnings with a compiler specific ifdef that adds an assignment for the variable in question. In this case I'm not sure this is possible as there already is an unconditional assignment. {$IF CompilerVersion=nn} // Delphi xxx complains here about FileIndex not being initialized FileIndex := 0; {$IFEND} FileIndex := ARow - 1; I make it compiler version specific just in case a newer compiler does no longer complain. The downside is that it clutters the code with such workarounds, but I look at a specific code section a lot less than I see unnecessary hints and warnings.
  23. dummzeuch

    Variable might not have been initialized

    Looks like a compiler bug (but isn't, see Uwe's Answer!). I've seen similar warnings / hints. It's even worse when you use different Delphi versions: One complains about a variable not being initialized, so you fix that by adding a superfluous assignment, then the other complains about a value assigned to that variable not being used. The annoying bit is that I usually want my code to compile without hints and warnings so I can spot new problems right away.
  24. dummzeuch

    Essential Delphi Addins survey

    What's the purpose of this survey?
  25. dummzeuch

    Essential Delphi Addins survey

    Probably this: https://github.com/HashLoad/delphi-docker Never heard about it either.
×