-
Content Count
1053 -
Joined
-
Last visited
-
Days Won
23
Everything posted by aehimself
-
My solution to something like this was to create a frame which contains only one row. Add basic functionality, like a grip and the resize code, initialization method, validation method, etc. Create as many variants as descendants of said frame as needed to handle different input / visual needs. Then, create one form with an alClient scrollbox and an alBottom panel with an OK and a cancel button. Give an array of data as an input to this form so it knows how many and what kind of frames it has to create in the ScrollBox. When the user clicks OK, you can see if all data is valid (because the validator is in the parent frame) so you can deny exiting. It ended up like this: I still need the resizing logic, though, it was a recent request 🙂
-
I learned that the hard way. In our country Quantum IDE hard-drives tended to fail often and suddenly (during power up the continuous click-click-click noise; I guess the arm was unable to move the heads?) but they were cheap so everyone used that. I lost ALL of my source codes of ALL of my applications one day. Thankfully, back in those days I wrote applications for myself and to a small number of people so I simply could say well, we use the latest version and no further improvements...
-
Having a completely separate import application for each "client" seems to be a huge waste of resources. One half of each application is the same (the output part) so I'd have went on a totally different design approach. Have ONE import application with multiple import formats, descended from the same class... so your application is using the TMyImport class, and TMyImport_ABC0001 is a descendant of this. The single application then instantiates the correct class based on the channel where the data is coming from. Would make your lives a lot, lot more easy. It might sound like a lot of work, but one-by-one, slowly the change can be done. Just make sure you prepare TMyImport and the output part well enough 🙂 Also, why to map C:\development to V:...? What difference does it make on which drive letter I'm changing my source code on? Please don't tell me you have hardcoded paths... 🙂 Based on the example you gave, my script should work jus fine. Set C:\ as the root folder so it will try to refresh C:\Development (V:) and C:\imports (I:) too.
-
Well, you can create a folder somewhere and just add junctions with mklink (e.g.: MKLINK /D GitRepo1 I:\SomeSecretApplicaition\Git) to all of the git repositories you have. That will fool the script and will work on all of them. Or, modify the script and call :CHECK manually on each, instead of the for loop: CALL :CHECK D:\Doom CALL :CHECK Q:\Quake CALL :CHECK B:\BloodBorne I understand nothing of this, especially the whole virtual drive part. Maybe it's better this way. At work we have one huge repository, with all the sources in it. Client, server, web, framework. All has it's separate folder. At home I have a different repository for my frameworks, they are located in my _DelphiComponents folder; far away from the applications which are using them. But, with this script everything can be refreshed at once, so no problem.
-
It's pretty undocumented, but kind of easy to understand. Feel free to modify it to your needs: @ECHO OFF SET GITDIR=C:\LocalWork\_DelphiComponents SET OLDDIR=%CD% FOR /F "tokens=1 delims=" %%a IN ('DIR /B /A:D %GITDIR%') DO CALL :CHECK "%%a" GOTO :END :CHECK CD /D %GITDIR%\%~1 > nul 2>&1 IF ERRORLEVEL 1 GOTO :eof "C:\Program Files\Git\cmd\git.exe" fetch > nul 2>&1 IF ERRORLEVEL 1 GOTO :eof ECHO/|SET /P=%~1... "C:\Program Files\Git\cmd\git.exe" status > "%TEMP%\gitstatus.tmp" 2>&1 IF ERRORLEVEL 1 (ECHO querying status failed! & GOTO :DELEOF) TYPE "%TEMP%\gitstatus.tmp" | FIND /I "is behind" > nul 2>&1 IF ERRORLEVEL 1 (ECHO up to date. & GOTO :DELEOF) TYPE "%TEMP%\gitstatus.tmp" | FIND /I "nothing to commit, working tree clean" > nul 2>&1 IF ERRORLEVEL 1 (SET STASHED=1) ELSE (SET STASHED=0) IF %STASHED%==0 GOTO :PULL "C:\Program Files\Git\cmd\git.exe" stash > nul 2>&1 IF ERRORLEVEL 1 (ECHO could not stash changes! & GOTO :DELEOF) :PULL "C:\Program Files\Git\cmd\git.exe" pull --rebase > nul 2>&1 IF ERRORLEVEL 1 (ECHO could not download updates!) ELSE (ECHO update successful.) IF %STASHED%==0 GOTO :DELEOF "C:\Program Files\Git\cmd\git.exe" stash pop > nul 2>&1 IF ERRORLEVEL 1 ECHO could not restore changes! :DELEOF IF EXIST "%TEMP%\gitstatus.tmp" DEL "%TEMP%\gitstatus.tmp" GOTO :eof :END CD /D %OLDDIR% PAUSE For me it now outputted... All you have to do is to change the path to the folder, where your Git repositories are. The script will check all folders within the root and if it's a Git repository it will do it's work. If you need help, feel free to ask.
-
Nice article, it's always good to learn something new! What I meant is that - according to what you said - "No attack happens before a ping". I translated that as - if there's no reply, most hackers won't even bother with other ports as they will consider the target unreachable. Know about it but never got further than installing it. When I had some free time I really wanted to do a scan of my home network to see what can be improved from security perspective. Now we are talking! This looks absolutely terrific and terrifying at the same time. Just like human presence on the Internet. People can always know more about you than you want them to, especially if they know where to look! I am a bit afraid of these stuff. I mean, real hacks were performed with Metasploit, it just sounds too "dark web"-ish just to satisfy one's childish interest in the topic. Ethical hacking is still hacking and noone will know your purpose once you start collecting tools to fool around. I guess I'll have an other look on Kali Linux. That seems to be a more... ethical choice for someone like me 🙂 Anyway thank you for the resources. It's not only a hint on how to make our environment safer but what protection we can or should implement in the software we write! P.s.: it just hit me.... isn't metasploit a part of Kali...?
-
Boolean short-circuit with function calls
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Indeed. From C#, the only things I'd like to have in Delphi are: - Changing code while debugging (I know, possible because of JIT in .NET, so not going to happen but still, it's really-really useful) - Faster and more precise error insight and code completion (although, I regularly have to use my script to delete .vs folders because it goes nuts...) - Linq - Ternary operators I can live without everything else. -
No. Git bash is just an alternate shell to cmd with Linux-like commands. Yo can run git from your old and rusty cmd directly (ShellExecute / CreateProcess from Delphi) and it will work just as good as from Git Bash. I have a .cmd file to check all of my local git repositories and if there is an update upstream it pull-rebases all local branches, taking care of automatic stashing if necessary - it only stops for merge conflicts. Just double-click it and everything is as fresh as they are on their official repository.
-
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Yep, that was exactly my idea when I made the shots about .Read and .Extract and I saw that they can output to TBytes directly... 🙂 -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
I'm not ignoring it but I doubt I'll change my coding style because of this. It's all a matter of personal taste... and while nil-ing a local variable is indeed useless right before exiting a method... I already got used to it and the overhead is negligible. -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Kind of a habit, I'm always using FreeAndNil. At least If Assigned(something) works properly 🙂 -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
I'm using this helper method to unzip the first file from a Base64 encoded string: Function UnzipBase64(inEncodedString: String): TBytes; Var ms: TMemoryStream; tb: TBytes; zip: TZipFile; zipstream: TStream; header: TZipHeader; Begin ms := TMemoryStream.Create; Try tb := TNetEncoding.Base64.DecodeStringToBytes(inEncodedString); ms.Write(tb, Length(tb)); ms.Position := 0; zip := TZipFile.Create; Try zip.Open(ms, zmRead); If zip.FileCount = 0 Then Raise Exception.Create('ZIP file is valid, but it does not contain any files!'); zipstream := nil; zip.Read(0, zipstream, header); Try zip.Close; SetLength(Result, zipstream.Size); zipstream.Read(Result, zipstream.Size); Finally FreeAndNil(zipstream); End; Finally FreeAndNil(zip); End; Finally FreeAndNil(ms); End; End; Could be shortened as far as I see, but it shows what you want. Open a zip file from stream, and extract a file from it to an other stream. -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Do you mean Zip64? "The original .ZIP format had a 4 GiB (232 bytes) limit on various things (uncompressed size of a file, compressed size of a file, and total size of the archive), as well as a limit of 65,535 (216) entries in a ZIP archive. In version 4.5 of the specification (which is not the same as v4.5 of any particular tool), PKWARE introduced the "ZIP64" format extensions to get around these limitations, increasing the limits to 16 EiB (264 bytes)." -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
I'd kill for those, they are truly a missing feature. -
Delphi’s TZipFile working on a stream
aehimself replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
It does: However - as I mentioned - Delphi's TZIPFile still has it's limitations which ZipForge for example overcame already. This includes but (possibly) not limited to LZMA compression, proper Zip64 support and replacing one file inside the ZIP archive. -
I'd choose SynEdit. Supports syntax highlighting, code folding and even completion. I made my own SQL syntax highlighter based on a TRichEdit component but it seriously started to lag when the script was around 3000 lines (full parsing and recoloring needed 300 ms, which is way too noticeable when it runs after each keypress...). Although I could have optimized the logic (move parsing to a BG thread, only recolor when a closer was entered, only parse changed lines, etc) I just pulled SynEdit from GitHub and I'm very happy with it ever since. I don't like having a full package installed in my IDE for one project only, but seeing how smooth and fluid that implementation is compared to mine... well, it will stay forever, I suppose 🙂
-
Boolean short-circuit with function calls
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Yes, I phrased myself incorrectly. I am pretty damn sure it would cause havoc now, after these many years. What I meant in the beginning to fix it [...], thanks for pointing that out. All I know is I had an imagination on how things should work and an urgent bug to fix. Caused me a serious headache. I'm sorry if I offended anyone by calling Earl a bug 🙂 -
Boolean short-circuit with function calls
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
It makes no sense, especially if a compiler directive instructs otherwise. My guess is that there is some badly written structure behind the scenes and it would be too much effort to "fix" it now. This is typically when we start to name our bugs, celebrate their birthday, call them a feature and see where they evolve to 🙂 -
BRCC32? 🙂 Seriously, though. I have a batch script which crawls through a directory structure and creates a .RC file based on what it finds. As a final step it launches BRCC32 thisfile.rc and deletes the unnecessary .RC file. Works like a charm.
-
Boolean short-circuit with function calls
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/expressions_xml.html "Note: If either operand involves a Variant, the compiler always performs complete evaluation (even in the {$B} state)." It's a feature. -
I pushed Opens to a background thread and the UI froze at the first .RecordCount call. The solution was to add .Fetch after .Open in the worker, and the scrollbar still had only 3 positions. I manually had to handle the WM_SCROLL message and had a custom UpdateScrollBar which called SetScrollInfo. Some of this code might be obsolete already if DBGrid got an update since 10-10.1... never really checked.
-
Boolean short-circuit with function calls
aehimself replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Introduce a Variant in the check. I was hitting my head for days when I finally found out that Delphi always evaluates a boolean fully, if a variant comparison is present. -
Sounds like a backdoor. If the code is already running on your system, it can do anything as most of us have UAC turned off I presume. This is one more thing very charming about Linux. To be honest, Delphi IDE and my VCL applications are the ones keeping me on Windows. No virtualbox, no home-devserver in my case would catch up with the speed I desire. I almost had Delphi 10.2 running with Wine. Basic "Memo1.Lines.Add" things worked, but anything more complicated made everything go boom 😞
-
Sligthly offtopic. Really? Never heard of this "pattern" so far. Also seems a bit strange. Most of the network devices block ICMP requests by default, aborting all malicious attempt. Or am I missing something? P.s.: This question lacks sarcasm, irony and whatsoever. I am genuinely interested in this topic but my knowledge is limited, unfortunately.
-
I decided to use Delphi's own TDBGrid for one of my projects; I personally don't like installing a full 3rd party suite for a single component if I can just fix the built-in up... Long story short, I did exactly what @Lars Fosdal advised - just added the very same Unicode character to the TField's displayname (I think that's the property...?). No complaints from users, they all like it. I don't use the standard grid, but as TDBGrid descends from it I suppose it's very, very, very limited too. The only reason I don't break out of my comfort zone and look for a cheap alternative is that I managed to fix most of the inconveniences already. If I'd go back in time I'd slap myself a couple of times not even to start with it. It was just waaaaay too much effort 😞 P.s.: my favorite "feature" is that the vertical progress bar had 3 positions: first record is active: topmost. Last record is active: downmost. Everything else inbetween - progress bar is at 50%. I seen no other component with this "design" yet.