Tuesday, April 21, 2020

Screen Text Finder

TL;DR
This is a program that lets you locate a search string on your screen. Performs OCR on your screenshot to achieve that. Download here. Be sure to have all the necessary .dll files and the eng.traineddata in the same folder as the executable.

The long version:
This is a project I did to teach myself Delphi. The reason for that is, well, a lot of leisure time in the time of a pandemic. But the substance of the why is, I wanted to know the only other language that offers a RAD (Rapid Application Development) environment apart from my good old VB6 and the cool new kid on the block C#. I could have done it in C# but I wanted a native executable. The old concern of the user not having .NET framework installed is no longer there, everyone's on Windows 10's bloat (pun intended), but being a VM-based language, I have noticed the binaries taking their time to load for the first time they are executed. Anyway, I wanted to see if Delphi could be my next go-to language for quick and dirty apps just as VB6 was in the good ole days around a decade ago. I had tried Delphi 7 back in the day (7-9 years ago) during the HackHound days, fun days. But it was nothing serious. I mostly used it for generating shellcodes and staring at other people's codes (steve10120, counterstrikewi and others) hoping to implement my own version in the one language I knew back then - you guesssed it, VB6. So, this time, I was determined to go through with it. This is why I chose Delphi. But then I had heard of another phenomenon in Pascal land - Lazarus.
Lazarus is an IDE based on the Free Pascal compiler that is supposed to be the free and open source alternative to Delphi. I tried it. To the credit of Lazarus' developers, the installer is pretty light and the installation is pretty quick and the IDE is snappy to open. So are the compiled binaries. But coming from Visual Studio, any IDE was going to have a hard time impressing me. I used to use CodeSmart by AxTools with VB6. It is an IDE plugin that allowed code completion, intellisense and all that good stuff modern IDEs have by default. And it was pretty helpful. The first time I got a hold of it was the last time I coded in VB6 without it back then. The point is, I've always done serious Windows Desktop development with great IDEs. All this to say, I was not impressed with Lazarus, at all.
I felt Lazarus to be clunky and glitchy and overall not very user-friendly. You can't call it a feature-rich IDE. I have no qualms with the Free Pascal Compiler (FPC) it uses though. Lazarus doesn't seem to have a definitive way of doing things. For, example, I couldn't use generics. Upon searching the freepascal forum, there was so much heat around the topic that I was thoroughly confused. I just gave up on it. The wiki/docs are user-friendly but extremely inadequate. And while Lazarus claims compatibility with Delphi code, I couldn't get the Tesseract library wrapper for Delphi (the tesseract*.pas files) to work no matter how hard I tried. Weird errors popped up when trying to call the Recognize method and that too, not consistently. Sometimes it worked, sometimes it didn't. Sometimes the error is 'External error ?' and sometimes it it 'SIGSEV' or some other garbage nonsense like that. I could not troubleshoot the issue for the life of me. There was no help online. On the topic of errors, I had issues with exception handling as well, in Lazarus; I dunno if that's the IDE or the debugger or whatever else there may be in there. In hindsight, after having completed the project in Delphi 10.3, I can see that the exe size was a bit smaller than the one Delphi produced but other than that, I don't miss anything (the Lazarus-generated executable seems to launch snappier though).
Okay, all that was why I left Lazarus. Now this is after I learned of Delphi releasing a completely free community version of their IDE : version  10.3. I downloaded and installed it. Noticeably larger download size and more time-consuming. The IDE is slower to open than Lazarus but as an IDE, Delphi is just better than Lazarus. The autocomplete and intellisense feel natural and quick unlike Lazarus' which takes like an hour to fetch suggestions. Also, there is an option for dark theme, easier on your eyes. The debugging experience is better. Not quite Visual Studio but definitely better than Lazarus. Now, the Delphi IDE is better than Lazarus but it still has its fair share of oddities and glitches. For example the toolbar layout resets if you hover over one of the menus. The object properties panel has serious sizing issues. Random view and layout resets for no good reasons are rampant. Some properties of VCL components are inconsistent and unreliable. For example, the FormStyle property set  to fsStayOnTop doesn't work as intended. This is unlike say in C#, where as far as I can remember, the property works consistently wonderfully. And in VB6, a simple SetWindowPos with HWND_TOPMOST was all that was needed. But all in all, Delphi development is tolerable and workable.
Whew! That was something. I learnt a lot working on this project. The source can be found on the SRC branch and the binary on the BIN branch of the GitHub repo.

Now, my musings during development:


callbacks/pointers for procedural language, events/delegates for object oriented language
function/procedure for procedural language, methods for object oriented language
global variables for procedural language, interfaces for OOP language

delphi 10.3 community IDE that I'm using right now, is glitchy as well, but not as bad as Lazarus.
documentation/StackOverflow regarding the simplest of topics on Delphi is so hard to find online compared to say VB6 or C# or Java or Python or C or C++. every google search points to delphibasics.co.uk and that site seems to be down 99% of the time. I remember 'counterstrikewi' from HackHound and OpenSC back in the day and the site seems to be his?

TThread.Queue() in delphi == Dispatcher.BeginInvoke() in C#
TThread.Synchronize() in delphi == Dispatcher.Invoke() in C#
class method in delphi == static method of a class in C#

As a language, I think I like delphi/object pascal. Especially for windows desktop development, with delphi, I can talk to the OS more easily compared to say VB6. Calling windows api is a breeze. Function/procedure pointers are easy. Multiple compiler directives for low level stuff. Inline assembly support. A lot of low level stuff if one wants/needs to use it. All the while, I can also make use of pretty high level/abstractive stuff such as OOP and anonymous methods, for-in and generics and parallel/concurrent programming among, I'm sure, a lot of others I don't know yet. And the gem of it all, I get a RAD i.e. Rapid Application freakin' Development AKA drag and drop visual form design with A LOT of VCL form components; not to mention x64 bit support. 

VB6 was fun and low level stuff could be done using all sorts of hacks. There was a great online community for that. The IDE was lightning fast and the executables produced were tiny ~20kB compared to ~2MB from delphi. The development process was result-oriented and very productive, and very quick I think now because I never knew what OOP was back then and VB6 didn't support it either (if I'm correct). With delphi, there's some great pluses and some cons. Anyway, it was great learning a new language with this project. And I totally get why one could consider it as a great, more productive, more readable alternative to C++.

Some areas where Delphi could improve, in my view, in descending order of significance:
  • Online community is not that great. Have to search harder for solutions to dev. related problems. Embarcadero docs most of the time prove inadequate, could use some code samples. Lazarus forum discussions are pretty basic and most of the time useless; the patronizing, self-aggrandizing members don't help - just shut up about how great Lazarus/FPC is. StackOverflow as always is great but not a lot of SO topics on delphi. Almost every google search points to delphibasics.co.uk which is dead. 
  • The filesize is humongous. Gotta do something to trim all that unused VCL stuff.
  • Stay consistent through language revisions. Don't go around implementing breaking changes. It is confusing to newcomers especially given the lack of good online support for the language, cause you know, not a lot of users around.
  • IDE could use some improvements. Learn from Visual Studio. That is the gold standard IMHO.