-
Content Count
1053 -
Joined
-
Last visited
-
Days Won
23
Everything posted by aehimself
-
How do you organize developing new features in big projects?
aehimself replied to Mike Torrettinni's topic in General Help
Deleted. Post went to the wrong place...? -
How do you organize developing new features in big projects?
aehimself replied to Mike Torrettinni's topic in General Help
Modularity is the key. And the beauty of inheritance makes it really-really easy. Since I started to chip my code to as small blocks as possible, separate classes of course; I realized that I started to move more and more of these one-class units to my Framework folder, out of an applications folder. And they simply all work together. -
Why should I use good source control versioning system?
aehimself replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Overkill and requires a heavy backend. Git is free and you can create your upstream repository on a backed up fileshare. More than enough, especially if you are new to source control. -
While I have no experience with C++ builder, nor FMX, but if the "ScrollBox" component is available, you can use that. Place one on your form, set the Align to alClient and put your components on the scrollbox instead of the form.
-
Help with string extraction function
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
When I made a parser like this I was working with indexes returned by String Helpers. Look for the first opener, look for the first closer from the opener. Make sure there are no quotes (or even number of quotes) in between. Make sure there are equal amount of openers and equal amount of closers in between. I'm not saying it was the fastest solution, but it worked 🙂 And it handled nested sections correctly, too. -
Yep, you have so much freedom you can easily do Var tb: TBytes; a: Integer; Begin SetLength(tb, 5); For a := 0 To 5 Do tb[a] := 1; End; or... Var pc: PChar; Begin GetMem(pc, 5 + 1); StrPCopy(pc, 'abcde', 5); End; or even: Var obj: TObject; proc: TProcedure; Begin proc := addr(obj); proc; End; Just because you have the possibility of doing something it doesn't mean you are supposed to or should. Btw, I thought this forum is a politic-free area. Please take those ideologies to Reddit.
-
Because - TCheckListBox.Items is TStrings, and .Values are supported by TStrings. I would not be surprised if this was not meant to be used as value storage; due to the reason you just very asked.
-
In a more advanced project (especially after a UI change or refactoring) you'll quickly realize why separating the UI and data storage/handling extremely important. In your example, let's say a user doesn't like CheckListBox and wants you to change it to something else. Apart from the visual changes, you'll have to re-code your business logic as well. It is not that important in "personal use" applications, but lately I have a separate class for data storage everywhere. The UI only displays, validation, (de)serialization, everything is handled by the class itself.
-
I don't feel fine storing information in the UI. I'd rather create a separate TList<TMyValue> and add the values to it as I'm adding the checkboxes. This way the index of the CheckBox will be equal to the index of it's value in the TList.
-
@Lars Fosdal Isn't importing RTTI is a huge bloat to parse JSON? A bit more manual work, but for example all class properties could be read and filled from a TJSONObject(TJSONObject.ParseJSONValue(contentsting)).
-
These overloaded methods are like 4 lines. I really would like to have an employer who pays me double for 4 extra lines per feature request. In a real world scenario, overloaded methods usually point from one to the other (or call the "real" one with proper adjustments) so we can argue that this was for demonstration only, but in real life - multiple overloaded methods will not consume even 10 minutes of your time if done smartly.
-
Agreed. A destructor might be called even when the object creation is incomplete... so it must have proper "defenses" in place. Let's just think on the standard way of local object handling... myobject := TMyObject.Create; Try myobject.DoStuff; Finally myobject.Free; End; What happens if an exception is raised in the destructor? Uncaught exceptions and 99% of the times memory leaks. No, it might not. If it does, it's a bug. If it's an external component, report it to the developer. If it is yours, fix it. I might be fresh in the area, but what is the purpose of this? I would simply call it a bad code as up until now, I never really had the need to put inherited anywhere else than the very last line of a custom object destructor.
-
No; that was not my intention to mean that. Obviously fixing at one place is more convenient and time effective, no one doubts that. All I wanted to say was that I don't really have a dependency (or rather - uses) list, which clearly says which application is using the particular unit I am working in. I think I'll write a recursive crawler to discover any custom units in the uses clauses of all my applications. As a result, I can enter a unit name and see which applications I have to rebuild. An other way is to distribute each unit as a separate library and my auto updater will take care of the updates of said files. This, however, increases the number of files my application is using and the attack surface of course. Even the beginner Hacker Henry will know to check the exports of MyEncryptor.dll and launch a brute force attack on encrypted data. And however I don't deal with credit card / bank account numbers or personal data; I like to prepare for the worst. Anyhow, we are sliding off the original topic. This is just one thing to consider with the cherished "Write once, use anywhere" method - which is THE WAY to go.
-
I started to see this at my biggest project. I broke it in the smallest pieces possible (random number generator, pseudorandom generator, encrypter, (de)serializer, hell I have a separate class for the application itself). Whenever I start a new project, I realize that most of these modules are now in my "Common" folder. It just started to become logical not to write a code again (or copy-and-paste) if I already wrote it once. The only bad thing in this is that if I make a bugfix in one of the units I have to recompile 4-5 applications now instead of one 🙂
-
D10.4 Slow IDE option dialogs in HyperV guest
aehimself replied to mvanrijnen's topic in Delphi IDE and APIs
On my laptop it's relatively slow too (~3-4 seconds). I guess it's Delphi's way of showing the dialogs since the "skinning" thing. It was the same in 10.3. -
For not that important applications I'm using MessageDlg, but for more advanced ones I always use my own "message dialog". Fully customizable, with a short (and if needed) an extended version of the message which is visible if the user clicks the down arrow. It uses the system's icons, but follows themeing correctly. I included a class function "Confirm" which returns a boolean and displays the dialog in "confirm" mode (question icon, yes and no buttons visible) and a .Error class procedure, which takes an exception and dumps as much information as possible in the extended text. I'm also planning to add a "Report" button to errors, which would send me an e-mail with the information collected; I was just too lazy to to do so until now (and I did not look for a component. Worst case, I'll implement my own lightweight SMTP client, idk yet). Based on this logic I also created a multi-input form, where my application can request multiple inputs validated (number only, can be null, predefined values from a combobox, multi-line text, etc. The problem is, this input form became so versatile and useful, most of my applications are heavily depending on it now. So yeah, I completely support @haentschman in this. Just write your own, and you will have a truly cross-platform solution satisfying all your needs.
-
How to increase the distance between TCheckBox glyph and caption text?
aehimself replied to PeterPanettone's topic in VCL
In my opinion, just because there's a possibility to do something doesn't mean you should use it 🙂 I do understand and agree with you on this. But it's not for the others, it's because of my own self. I just don't want to produce code I don't like or as "time-resistant" as I can think of. Whilst it's a good thing it's a curse as well... I can easily waste hours on a single "Hello World" application this way. -
How to increase the distance between TCheckBox glyph and caption text?
aehimself replied to PeterPanettone's topic in VCL
No insult taken. My attention may have slipped - I did not see the static part and for that I apologize. For the record, my intention was not to argue: I just had to refactor too many lines of code (written 10-15 years ago) which broke or misbehaved on specific modern systems. The days-weeks wasted there taught me to proudly waste hours when I write fresh code which will still work the same way everywhere in the foreseeable future. Do I still have "hacks" like this in production? Hell yes, I do. Do I hate myself for it when I see it? That's a question for a different topic 🙂 -
Control TDataSet strings encoding (auto encode to utf-8)
aehimself replied to Max Terentiev's topic in Databases
@rcaspers I had no idea you can "override" default TField types. Would have made my life a lot easier a couple of years ago! @Max Terentiev You can easily do the conversion by TEncoding.Convert, GetBytes and GetString. However, the easiest solution would be to upgrade the component you are using to one, which actually supports Unicode. If they are all TDataSet descendants, you should face no issues. If upgrading is not an option, I'd create a TFieldHelper with an .AsUnicodeString property. Getter would read the fields value as a byte array, and return it as a String with TEnoding.Unicode.GetString(fieldbytearray); Setter would accept a string, convert it to a byte array with TEncoding.Unicode.GetBytes and strore this instead of the string. -
How to increase the distance between TCheckBox glyph and caption text?
aehimself replied to PeterPanettone's topic in VCL
I might not phrased myself correctly - forgive me; English is not my native language. The point is, you know exactly what I meant by "distancing". Let's play adults and not starting to argue on choice of words. -
How to increase the distance between TCheckBox glyph and caption text?
aehimself replied to PeterPanettone's topic in VCL
Nothing, really. As smart people say "if it works it ain't stupid". It's a perfect quick-and-dirty solution which will achieve what you want in this, very specific project and configuration. Lately I like to think in general solutions, that's all. And that is custom drawing. -
How to increase the distance between TCheckBox glyph and caption text?
aehimself replied to PeterPanettone's topic in VCL
Holy Frank, this smells. I already learned not to use whitespaces for distancing back in high school. And while it might work - can you please check if the above functions correctly if "Width = 30" for example? -
One more memory leak and FastMM4
aehimself replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
That was exactly my purpose 🙂 Don't worry, this is only for testing and satisfying my curiosity. I guess this will be the cause of the "leak". Today, I attempted to check the addresses of pc and s, and I can not seem to trigger a memory leak, nor access violation even with StrPCopy(pc, s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s); maybe today I have more free continuous unused memory than the last time... It makes sense, though. If by accident I managed to corrupt the pointer itself, the release will not happen at the right place (or maybe not happen at all?). I just cannot seem to find what the 3rd leaked allocation might be. Anyway, memory corruption is no job for an allocation detection tool. I just found it strange that sometimes even these were triggered. -
One more memory leak and FastMM4
aehimself replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
We are getting close to the next release so time is not that much to spare, but I managed to run my test. DeLeaker shows about the same results with 1, 2 and 5 copies of "s". I am no expert with memory leak detection in Delphi, but can someone explain this to me? No leaks, however (on a Unicode Delphi) this used up twice as much space as it was reserved. Fine, it's not a leak (as it is properly released), it's corruption. But why StrPCopy(pc, s + s); already pops up as leak in this case? -
Ummm.... Why make a string? Why not getting rid of Allowed and setting Result directly? Why going through character by character if Regex can validate the whole string at once? If I'm not mistaken you'll achieve the same with this one line: Result := Regexs.IsMatch(svalue.Trim, '^[Ø¡-ÙŠA-Za-z0-9$&+=?@#~<>.^*()%!\s]+$');