David's Blog

Subscribe to David's Blog feed David's Blog
Thoughts from David Cornelius
Updated: 5 hours 39 min ago

Programming Delphi for Various Platforms and Versions

Sat, 2017-04-22 12:55

Delphi has come a long ways since it was first released in 1995. It now compiles 32-bit or 64-bit, still creates console or Windows applications but now also can create Android and iOS apps if you have the FireMonkey library and cross-platform tools, you can create Android and iOS apps.

There are a lot of compiler directives that can be used in your code to selectively compile different sections of code depending on the platform or options being used. There are also symbols defined for each version of Delphi.

To test some of these symbols before I found clear documentation like the links given above, I wrote a program to list out the symbols defined when compiled under different versions of Delphi, and later added other conditional symbols to list out other capabilities of the executing environment. I recently revisited this program, pulled all the compiler directives out of the main form into a generic unit, and added a couple new applications using this new unit to the project group. I have put this set of programs up on GitHub under the name DelphiVersions.

As of the date of the writing of this blog entry, this compiles under Delphi 10 Seattle and includes each of the following:

  • Windows VCL 32-bit
  • Windows VCL 64-bit
  • Windows Console 32-bit
  • Windows Console 64-bit
  • Windows FireMonkey 32-bit
  • Windows FireMonkey 64-bit

 

Here are some screen shots:

Categories: Developer Blogs

Broadening My Skill Set

Sun, 2016-01-31 11:06

As an independent software developer, I make my living writing scripts and applications for others. In order to maximize my opportunities, I need to be a master of many environments. Since much of my career has involved Windows applications, I am spending quite a bit of effort in other areas.

Several months ago, I converted a Windows server application to a Linux module for a client. That was a lot of fun and a good departure from my usual coding. Another great experience was helping a client who is rewriting a retirement analysis package as a web-based application using an ASP.NET server and JavaScript on the front end. That work taught me a lot about the Bootstrap and Durandal frameworks. I have some possible C# work coming up in the future and a friend recently asked me to teach him Python. Finally, and on a very different platform, there’s a possibility I’ll get to work on some PLC components–that sounds intriguing!

Fortunately, I love learning new technologies. There are so many cool ways to do things, so many programming languages, so many frameworks and tools. It’s impossible to know all of them, but in my position, I must be aware of the most popular ones–or at least the ones where I can find paying clients! More and more, those clients are expecting expertise in building web apps. That, of course, means JavaScript and several different frameworks. With Bootstrap under my belt, I’m now concentrating on AngularJS.

One problem with simply going through a tutorial book and learning the syntax of a language is that it doesn’t give me real-world experience. One way to get experience is to work at a company that allows you to grow into new areas of expertise. Barring that, another way is to donate time to a local non-profit organization that you can later point to as an example of your work. It’s time-consuming, but if you can swing it, opportunities like that can be a win-win for both sides.

Some people wonder why contractors charge so much, but when you think of the constant learning time that must be invested to stay relevant, not to mention a cushion for time off, it’s actually quite a challenging endeavor. If one can manage it, the benefits of being your own boss and picking your own projects and tools are quite rewarding.

Categories: Developer Blogs

Preventing Multiple Application Instances in Delphi with TMutex

Tue, 2015-10-20 11:27

Having worked in Delphi for many years, I’ve seen the development tool and it’s RTL evolve significantly, yet remain resilient in backwards compatibility. Early on, to prevent your application from running multiple times, there were generally two different approaches:

  1. Search for the name of your app’s main form by name, or
  2. Search for a “mutex” created by your app.

There are other ways, but these two are the most popular I’ve seen. They both still work. The first one requires your application to actually show the main form–which obviously doesn’t work for console applications. I’m writing an application that can be scheduled to run unattended and in that case will not be showing the main form, so I am using the second method. The last time I used this technique, I called CreateMutex which has a wrapper function in Delphi’s RTL (see this forum for an example).

While reading about the threading and synchronizing topics in Delphi I found the TMutex class introduced way back in Delphi XE. I decided to put it to use, if for no other reason than for educational purposes. It turns out I like it better as it’s more object-oriented.

I won’t go into much detail as this is a fairly old topic with several examples and Windows API documentation that is still valid. So here’s a code example:

program MutexExample;

uses
  Vcl.Forms, Vcl.Dialogs,
  System.SyncObjs, // defines TMutex
  Winapi.Windows,  // defines ERROR_SUCCESS
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var
  AppMutex: TMutex = nil;
  MutexErr: Integer = 0;

procedure CheckSecondInstance;
const
  // any unique name will work--I chose to create a GUID
  UNIQUE_MUTEX_NAME = '{AD12094E-7308-4067-8CAC-565A1FF3ADDC}';
begin
  // try to create a mutex; don't need any security rights
  AppMutex := TMutex.Create(nil, True, UNIQUE_MUTEX_NAME);

  // check to see if it was successful
  MutexErr := GetLastError;

  // if not, previous instance of application already created the mutex
  if MutexErr <> ERROR_SUCCESS then
    ShowMessage(Application.Title + ' is already running.');
end;

begin
  // initialize app like normal, but don't start it yet
  Application.Initialize;
  Application.Title := 'Simple Mutex Example';

  // run our check here
  CheckSecondInstance;
  try
    // if the mutex was successfully created, this is the first instance of this app
    if MutexErr = ERROR_SUCCESS then begin
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end;
  finally
    // if a mutex was successfully created (and our app ran),
    // be sure to free it to release the mutex
    if Assigned(AppMutex) then
      AppMutex.Free;
  end;
end.

Categories: Developer Blogs

Make the New Welcome Screen in Delphi Usable

Thu, 2015-10-08 01:14

Why is it that when companies have a good thing, they have to go mess it up by changing its design? I’ve seen this in many different industries but since change happens so much more quickly in software, I seem to be annoyed much more often with changes in user interface. Of course, there are glaring examples like the ribbon in the Office products and the Windows 8 start screen (which I actually liked when using it on a tablet).

But today I’m talking about the Welcome screen in Delphi XE8 and newer. Way back in Delphi 2005 or 2007 (I forget when exactly), a new welcome screen was displayed when Delphi started and provided a nice collection of resources and helpful links to documentation. One of the features of this new interface was an editable list of favorite projects that could be put into “favorite groups” and made for a nice, quick link to lots of different projects. The font was small and it utilized the space pretty well. I used it a lot and since I work on lots of small projects, this was very useful.

I’ve recently upgraded to the latest version of Delphi and have found this useful interface has been completely revamped with a big banner ad and large-font shortcuts with big icons to things I can already get to with a few keyboard strokes. Yes, there’s still a list of favorite projects, but you can’t create groups any more and the scrollable region for them is so small that with the number of projects I work on, it’s practically useless.

Why is this better???

Fortunately, the welcome screen is written in HTML and easily found in the Welcomepage folder of your Delphi installation. (Your Delphi is installed, by default, under C:\Program Files (x86)\Embarcadero\Studio\<BDS-Version>). As has been mentioned elsewhere, it’s pretty easy to remove the banner (why we have to have advertisements inside our development tool is beyond me) so that was the obvious first step. But I wanted to go further. I have no need for the links to create a new project or the links to the tutorials. I can get to those easily enough. For my day-to-day work, I need quick access to the projects I’m working on.

So I cut it down to two lists: Favorite Projects and Recent Projects. I still like the old interface better–and I briefly tried copying the welcomepage from an older version, but it crashed violently, so didn’t spend much time going down that path.

Here’s a step-by-step list of how you can modify the Welcome Screen in your installation of Delphi, but first a disclaimer: Be sure and make a backup of your welcome page before you begin (I mention this in the steps below, but emphasize it here as well). Also, it really helps to understand HTML and CSS when editing these files in case things look a little different in your installation. These steps are mostly for Delphi 10 Seattle and the XE8 version is a little different. Also, you might be reading this using a newer version of Delphi and the file may have changed again (I would count on it). On the other hand, it’s just the start screen and Delphi functions fine without it.

  1. First, locate the welcome page. As I mentioned above, the root folder for the welcome page files is simply Welcomepage under your Delphi installation. The “default.htm” file in this root folder is, to my knowledge not used. Instead, choose the 2-character abbreviation for your installed language and find the file there. For example, I use the English version of Delphi so found my copy of the welcome page for Delphi 10 Seattle in C:\Program Files (x86)\Embarcadero\Studio\17.0\Welcomepage\en.
  2. Make a backup of the file so if you mess anything up, you can always easily recover by going back to it.
  3. Now, pull up your favorite HTML editor, but there might be a catch. If you installed Delphi in the default folder, it’s under Program Files (x86) and can only be edited by the administrator account. There’s a trick used by Windows to prevent side-stepping this with some editors that even if you run as Administrator, it is only editing a “shadow copy” of the file. It’s weird to me, but I just ended up using Notepad as it seems to save the right file. If you were smart and didn’t install Delphi under Program Files, then you don’t have to worry about this.
  4. Remove the banner ad. Find the <div> tag with id=”topbanner” and delete everything until the matching <\div> tag. I removed 10 lines in mine. Now with the banner ad removed, there’s no use keeping the Javascript around that spends time getting it online. So look for the function, tryShowOnlineBanners(). You should find the definition and the place where it is called in that same file–it’s not defined or used externally. That function calls another function, showOnlineBanners() and you can remove that as well. I deleted 25 more lines.
  5. Now it’s time to get rid of the new projects and tutorials short cuts. In XE8, the Favorites are across the bottom, in Delphi 10 Seattle, it’s between the new projects (on top) and tutorials (on bottom). In Delphi 10 Seattle’s Welcome page, look for <div class=”section”> tags that contain “Projects” and “Tutorials” and remove those sections of the HTML (but not the one in the middle that contains “Favorite Projects”). In Delphi XE8’s welcome page, do the same thing but realize the <div> tags may be in a different place. New projects call the Javascript function newProject() but it’s in an external file, so it’s best to leave it alone. The tutorials call the local Javascript function, doStartTotorial() so that can go (isn’t it fun cutting out code?).
  6. With Delphi up, you can look at the welcome screen and even make changes on the fly, right-click, and Refresh to see your changes instantly. After the last edit, you’ll notice the Favorite Projects is a small scrolling box in the top of left column of the page with nothing below it. So we need to adjust the height. Looking at the HTML, you’ll see the Favorite Projects and Recent Projects sections with a few different CSS classes in use. You’d think this is where we need to modify things, but it turns out some Javascript further down the page overwrites the heights dynamically. In the resizePanels() function, the height property of the favorite-projects class is decreased by 388 whereas the recent-projects height is only decreased by 44. Let’s use 44 in both cases so they’re the same height.
  7. We’re close but there’s a bunch of space at the bottom. It turns out there’s an extra box down there (with an id of “load_html”) we aren’t using the same way anymore. It’s height is adjusted in the setFrameHeight() function. I found changing the reduction in the height property from 184 down to 70 filled the screen nicely.

Hopefully, nothing got messed up too badly and you have a nice clean list of projects that you can quickly get to rather than scrolling through a tiny box or hunting through folders if it scrolled off the recent projects list. Let me know in the comments if you found something different or if I skipped a step. Also, feel free to drop me a line of thanks either in the comments or on the contact page of my site, CorneliusConcepts.com if this helped you work more efficiently!

Categories: Developer Blogs

dbForge Data Generator for SQL Server

Tue, 2015-08-18 14:28

DevArt Software has been busy at producing a great number of database tools and components for both Delphi and Visual Studio developers over the last few years. They’re still coming out with new ones as well. One of the most recent additions is dbForge Data Generator for SQL Server. I purchased version 1.0 in April, 2015 and they’ve been hard at work improving and adding features–they’re already at version 3.5! You can read about their features on their web site linked above, but I’d like to highlight a few I think are notable and have been very useful to me.

As you would expect from a data generator, they support all the basic column types. But they don’t stop there. Character strings, for example, could have several different purposes, from storing a person’s name to an address or to a unique ID. All these choices of generators are available through a drop-down list. But wait–there’s more! They even look at the field names and make good guesses about which type you want and pre-select them for you to make it easier. But wait–there’s more! What if you want only names usually used by males? Or females? They have those separated out or combined as you wish. But wait–there’s more! You can also choose from First Names, Middle Names (which include initials), just initials, Last Names, Nicknames, or even a Full Name. But wait–there’s more! There are also Honorific Prefixes (Mr. Dr., etc.) and Honorific Suffixes (Ph.D, III, etc.). But wait–there’s more! I also saw in the list DE First Names, DE Last Names, DE Honorific Prefixes. I believe these are Germanic versions of the samples you might use in the U.S. Examples of these are Wolfhard, Swena, and Christoph for First Names, Zurbriggen, Ittenbach, Schelling, and Günther for Last Names, and Herr, Frau, and Doktor for Titles.

There are 10 different phone number generators (5 each for US and UK), social security numbers for both US and Canada, sample job titles, email addresses, courtesy titles, ethnic groups, and even sample twitter accounts! And that’s just the list of generators in the Personal category! Let’s say you wanted some random business names, or ISO codes, or stock ticker codes? They have those, too. Drug names, time zones, bank routing numbers, clothing sizes, colors, ISBNs and UPCs and VINs, shipping methods, product categories and names, and many more. For programmers, there are also random file paths, image names, document titles, IPv4 and IPv6 addresses.

Maybe you don’t need fake “real” data. Maybe all you need is some random text to fill the database. Of course there is Lorem Ipsum text, random strings of characters or numbers or both. One I used a lot was Weighted List. This allows you to enter list of allowed values and tell it to generate a certain percentage of each value in the generated rows. For example, one table I was working with held a list of “constituents” which could either be people or organizations. A field called KEY_INDICATOR of CHAR(1) could only be ‘I’ (for individual) or ‘O’ (for organization). My weighted list held these two values with it generating many more individuals than organizations.

Finally, if all else fails, you can always resort to regular expressions. And if one of the built-in generators is close but not quite what you need, select it and see if it’s one of the ones that are simply preset regular expressions. I needed to generate a random death date in a VARCHAR field but was unsure how to structure the regular expression to give a valid date. I first selected a date field (the generators are type-sensitive) and selected the Regular Expression generator. Then I copied that, switched back to my VARCHAR death field, and pasted it in–voila!

This tool is also smart enough to deal with foreign keys. When selecting a random value for a field that is a foreign key to another table, you have the option of selecting one of those values instead of random data (which could break a table relationship). It also generates “child” tables before “parent” tables. For example, if you are generating data for an Address table and a People table where the People table links to records in the Address table, it will automatically generate Address records first so they’ll be available to fill foreign key references in the People table.

Another nice feature is forcing randomly generated data to be unique. This is especially nice considering foreign keys. In my People-Address example, you would might want all the AddressID references in the People table to be unique–unless the table includes spouses as separate records that share the same address. But this is where things can start to get a little muddy. I’m not sure any random database generator could cover every situation, and I found I had to write some SQL to do some additional processing after the bulk of the data was generated.

For example, in the table I was working with that had a random death date, I wanted most of the people records to be alive, so I set the percentage of null values (another great feature for making the data seem real) rather high which would generate very few death dates. There’s another field in that table called DECEASED. The generator doesn’t (yet) have a way to set the value of a field based on another randomly generated value in the same record, so I defaulted the value for the DECEASED field to 0 (false) and wrote a short SQL statement to set DECEASED to -1 (true) where DEATH_DATE was not NULL.

There were a few other instances that I had to do this. One parent-child table relationship had a two-way linking with both tables holding the ID of the other. There’s no way that I could tell do that with this tool, especially since one of them was a VARCHAR holding an INT ID of the other and therefore needed to be CAST.

When I had my data generators all setup and saved to a .DGEN file, I was ready to run it. In the first several runs, I was running it directly against the database so the data was there immediately–along with errors at first. But it can also generate all the INSERT statements to an editor window or to a saved .SQL file. This allows you to not only add your own custom SQL statements before running it, but also to send the whole script to someone who doesn’t have dbForge Data Generator installed.

I have been very happy with this purchase. I really appreciate DevArt’s licensing structure (which is becoming quite common among software companies). The purchase price automatically gives you one year of updates after which you can renew that purchase subscription for a reduced rate. I am looking forward to even more enhancements in the months and years to come!

Categories: Developer Blogs

Career Developers and Passionate Technologists

Tue, 2015-08-11 13:57

Programmers can be grouped into two broad categories: 1) Career Developers, and 2) Passionate Technologists. Career Developers will pick a language and a job and be very good at what they do, produce excellent work for their employer, and live happily ever after. Passionate Technologists will be constantly seeking different ways of doing things, learn a new language every year, keep old computer parts and reuse them in strange projects around the house, continually tinker with electronic gadgets of all sorts, and be considered the geekiest person around by all their friends and family. OK, perhaps that’s a bit of an exaggeration and there can certainly be overlapping traits found in either group, but I’ll bet most programmers can see themselves sliding over to one side or the other–or maybe they’re a career developer at work but a passionate technologist at home.

Now before you fire up that email to me, let me be clear that I’m only contrasting two extremes. In no way do I want to insinuate that career developers cannot also be passionate about what they do. There are many great programmers that are very happy in their niche, are able to see the big picture, and yet stay focused on a product. This is a very good thing.

If you’re running a business that needs some dedicated product development over a long period of time, you probably want a career developer on your team. If you have short-term needs that don’t fit easily into a predefined job description, or need to integrate two systems that don’t talk the same language, or just bought a computer but don’t know what to do with it, call a technologist, someone who has breadth of experience, likes exploring new areas, thinks outside the box, and is always ready to learn something new.

I have found myself in both camps at different periods of my life but am leaning more and more toward the broad technologist side. Not that I’m losing focus on software development, but after being involved with so many different types of businesses and seeing such a wide variety of needs and solutions, I find myself naturally seeing the broader scope of things–no longer is my only tool a hammer and every problem a nail.

For a long time, I was all about Pascal. First Turbo Pascal, then Borland Pascal for DOS, then Delphi. These tools were ahead of their time being incredibly productive and leading innovation in software development. But other products have closed the gap by adding similar features and sometimes new angles to crafting software. And as the web has become ubiquitous and platforms have diversified, no longer is Windows on every desktop. In fact, no longer is the “desktop” to be assumed for any software platform.

Delphi has had a hard time adjusting to this and has adopted a technology to enable it to cross over into the iOS and Android platforms (it’s had web support for a long time), but it’s no longer the obvious advantage–unless all you know is Delphi. That’s where being someone not encumbered by the history and culture of a business or a certain technology can be exactly what that business needs to innovate and stay relevant in a constantly changing technological world.

If you’ve been reading my blogs the last couple of years, it’s obvious I’ve made an effort to move outside of the “Delphi box” by learning .NET, Android, and JavaScript. I’ve done quite a bit of HTML and PHP in the past, but have been updating those skills by adding CSS and HTML5 features. There are many other languages and technologies out there–and I hope to have time to tackle some of them. Alas, I’m not independently wealthy so must continue in some focused areas

Being a passionate technologist–whether focused or broad-minded–takes a lot of time and effort. But it’s not possible to maintain the momentum without an underlying desire for learning and embracing new ideas. And being at least part geek!

Categories: Developer Blogs

Linux, Lazarus, and Lots of scripting

Tue, 2015-06-09 16:58

A friend of mine runs a business selling a Windows application for a niche market. Of course he has a web site with lots of information and a way to download a trial of his software and then pay and register it. Since he’s a technical person, likes writing code, likes to keep overhead low, and his needs are fairly simple, he wrote the registration program himself. He’s most fluent in Delphi so it was natural to write the registration program in Delphi‐‐an old, but very functional version of Delphi, Delphi 2007.

So naturally he needed a Windows server and after a little research, decided it wouldn’t be that hard to host it himself out of his house. With a static IP address and stable power source, he’s had this setup for quite some time with very little trouble.

Well, since he already has a static address and server running, why not host his own web site as well? That’s running under Linux. No problem, just add a second server and redirect the ports. (I actually don’t know which came first, the web server or the registration server.)

With the business running well and support calls low, he and his wife want to do some traveling. An extended weekend isn’t any problem. A week away with someone looking after the place is doable. But what if a server goes down? Will anyone else be able to get it back up? What is the cost of potentially losing a customer because they can’t find the web site or register the software?

These questions have been eating at him for a while and he finally decided to move them to a remotely hosted server. But since neither his web site nor his registration program are that heavily used, it would be a waste of resources and money to rent two servers‐‐he should combine them into one. The web site needs to stay on Linux. The registration program, even though it’s in Delphi, could be re-written to work under Linux using Free Pascal. And using Lazarus as the IDE, the environment would be familiar. Finally, the Firebird database has no problem moving across platforms.

After looking at several options for remotely hosted virtual servers, it was clear the new Linux server would be running CentOS. Moving the web site over was not going to be difficult, but setting up the database and development environment would take some research. Not being very familiar with commands on Linux, he asked if I could help. Together, we got a virtual machine running CentOS and started the process of figuring out everything needed to get things going.

The first thing installed was the Firebird database engine and TurboBird, a Linux-based database tool that allows manipulation and querying of Firebird databases. We soon ran into problems and so downloaded Lazarus and the source for TurboBird to compile it thinking it may be something specific to our install. This is where the fun began!

I don’t remember all the problems we had, but there were missing links to libraries, indications of insufficient permissions, and other error messages, leaving us scratching our heads and wondering if we had bitten off more than we could chew. I told him I’d go into hiding for a couple of days and figure out what was wrong.

What I found is that we were using a 64-bit version of Linux and trying to get a 32-bit version of Firebird and TurboBird working. I’ve should’ve known to check this near the beginning of the process as I’ve run into this type of problem in the past trying to get Windows applications to talk to Oracle databases using the wrong driver, but this is a different OS with different software producing different errors‐‐it totally escaped me.

There were other little odd things here and there that needed tidying up. For example, the version of Firebird he is using with his application is a couple of versions behind the current one and it requires an older version of a standard C++ library that is not included by default on the latest CentOS. The service manager, xinetd, needed to be installed and started. And a link to the specific Firebird library needed to be made. These would not be issues on Windows platforms, so it was easy to get tripped up multiple times.

But the thing I love about Linux is that you can run a command line to accomplish just about anything. When I emerged from hiding after a couple of days, I had a bash script that uninstalled the wrong versions of the software, downloaded and installed the right versions, installed git, and downloaded the project I had started. All he had to do was type in a couple of passwords, load the project into the Lazarus IDE, and compile it.

When it was all done, it was very satisfying to run the script and watch the magic happen!

Categories: Developer Blogs

Windows Services with Oxygene

Fri, 2015-06-05 17:11

Some of my blog entries are just to remind myself how to do things later–and on several occasions they’ve been useful in that regard. I hope they are also useful to others that may encounter similar struggles. This is another one of those articles which I will likely refer back to at some point.

I’ve been doing more and more with .NET and using Oxygene makes the transition from Delphi a little more familiar. One of the things I’ve been working on lately is a set of plug-ins to a Delphi application that provide additional functionality. And with Hydra, I can write those plug-ins in either Delphi or Oxygene. Recently, I wanted one of my plug-ins to talk to a service on a remote server. The first step, of course, is to write the service for the remote server and learn how to get it installed.

Because Microsoft Visual Studio Community 2013 has such a large developer base, there are many resources to help you accomplish this (that’s the beauty of working in .NET rather than Delphi). But just a few nuances here and there for someone that doesn’t do this very often slowed me down a little. Finding just the right web reference or book chapter takes time, so once I find that, I tend to want to write it down.

New Project

First of all, Visual Studio makes it pretty simple to get started: just select the “Windows Service” new project template.

This gives you a project to start with that includes Main.pas, the main section of the code you’ll be working with, Program.pas, which you can likely ignore but is necessary, and ProjectInstaller.pas.

Add Installer

The first thing to do is right-click on Main and View Designer. Look in the Properties window and click on Add Installer, a small link at the bottom. This adds a couple of components to the ProjectInstaller and allows you to easily name and describe your service.

Service Properties

Now in the ProjectInstaller designer view, click on the serviceInstaller component and set the DisplayName and Description properties. These will show up in the Services control panel after it’s installed. Here’s also where you can set the StartType (Manual, Automatic, or Disabled) and other properties affecting how the service behaves with Windows. If you then view the code for ProjectInstaller.Designer.pas, you’ll see the properties you set listed in the InitializeComponent method.

Before you leave the ProjectInstaller, you need to check one more thing. Look at the properties for the other component in designer mode, serviceProcessInstaller. An important property is Account. By default, it’s set to User, but in most cases it can be either LocalService or LocalSystem. I’ll leave it to the reader to research the differences and choose what is most appropriate for your situation. For this simple test, setting it to LocalService is easiest.

Event Logging

Since a service does not typically interact with users but runs silently in the background, it’s a good idea to provide some way to check to make sure it is running. There is an automatic way of doing this and all it takes is one line in the constructor of Main.pas: AutoLog := true;. This will add to the System Event Log when the service is started, stopped, paused, or resumed. You can add your own custom logging by using the EventLog component on by rolling your own.

Now even though this service doesn’t do anything useful, it’s got the basics to be compiled, run, installed, and started with logging to see it actually happen. So compile the project and move to the final step.

Install the Service

When a service is ready to install, use the command-line utility InstallUtil. This utility comes with the .NET framework. Normally, there is no path to the .NET framework tools, but both Visual Studio and Oxygene provide command shells you can launch that provide the path. However, you need to know which version of the .NET framework you used to build your project because the shells are specific to the version of the framework and if you run the wrong one, you’ll get errors. Oxygene comes with one for .NET 2.0 but the default framework for new projects (as of this writing) is .NET 4.0. I have copied the batch file that is installed with Oxygene (C:\Program Files (x86)\RemObjects Software\Oxygene\bin\OxygenePrompt.bat) and separated them so I now have one for each of the two framework versions. (By the way, to tell which version your project is using, view the Application tab of the project’s properties and you’ll see it under Target Framework.) Once you have the correct command shell ready, be sure to Run as Administrator because standard users cannot install/uninstall Windows services.

With the command shell running as administrator, navigate to the bin\Release folder for your service and type InstallUtil MyServiceName.exe (where “MyServiceName” is the name of your project). Open the Services control panel (or refresh if it was already open) and you should see your new service. You can start or stop it just like other services (although if you’ve followed this example, it doesn’t yet do anything once started).

Start/Stop, Check the Log

Now that the service is built and installed, start the service then go to the Windows Event Viewer. You should see events in both the Application and System sections of the Windows Logs.

Now, it’s time to go back to Main.pas and add some useful code when it starts!

Categories: Developer Blogs

How to Break Delphi’s Object Repository

Mon, 2015-06-01 18:46

I’m a long time Delphi user and have taken advantage of the Object Repository quite a bit. It’s really handy to take a unit or project that might be useful somewhere else but in a slightly different form and add it to the repository. Later, when you need to use that bit of code, you can select it from the repository right from within Delphi and it will make a copy of that code in your new project.

If you’re wondering why not use a library or even the popular Delphi IDE plug-in, GExperts, with its “librarian” feature, I do. A code library is static and GExperts is best for small code snippets. But sometimes you just need to copy and modify a large chunk of code. For this, I have found Delphi’s Object Repository to be a great tool. And actually, anyone who creates projects in Delphi’s IDE uses the standard repository objects that come with Delphi, namely the “New Project,” perhaps without realizing it.

I write a lot of plug-in modules for a point-of-sale software called Retail Pro. Its plug-in API requires building COM servers that adhere to a set of interfaces. There’s a lot of structure to be setup for each plug-in and several properties that interact to accomplish a retailer’s goal. Each interface is typically implemented as a single Delphi unit and while it has the same basic structure (since it implements an interface) it will have different method implementations and property values. It’s hard to remember all the different nuances that each API call can have and how they can be used inside Retail Pro. So what I’ve done is create a repository unit for each interface and copied all the documentation for that interface into the unit using XML Documentation. Then I’ve added it to the Delphi Object Repository.

When I need to build a new plug-in for Retail Pro, I create a new plug-in project and then add the interface units I need to implement from the repository. This jump-starts my project with all the code in place, complete with documentation and even TODO items that I can just fill in and compile. Of course, the end solution involves quite a bit more than that, but a lot of work has been saved.

So, now that you’re convinced this is a cool tool to add to your collection, it should come with a little warning: it’s fairly easy to break and there’s not much documentation. There are a couple of references here and there that talk about Delphi’s repository setup when it’s installed, but it took some searching to find out where additional items added by the user are stored.

The folder for Delphi’s built-in repository (that doesn’t change) is in its installation folder under Program Files (x86), or if you’re still on a 32-bit system, just Program Files. Since Windows Vista came out with it’s increase protection of the Program Files folders, the editable copy of the repository is located in a user directory, probably under either %APPDATA%\CodeGear\BDS\<version> or %APPDATA%\Embarcadero\BDS\<version>, depending on your version of Delphi, and is named RADStudioRepository.xml. (Really old versions of Delphi stored these settings in delphi32.dro under Delphi’s bin folder.)

The structure of the RADStudioRepository.xml file can, of course, be changed with your favorite text or XML editor. That in itself could break the object repository, but it can actually be done using Delphi itself. (Dislaimer: I’ve only tested this with Delphi 2010, not anything newer. It’s possible the following has been prevented in newer versions of the IDE.) When you’re adding an item, you can optionally specify an icon. The help for this screen says that you can use a bitmap of any size but it will be cropped to 60 x 40 pixels. I happened to choose 24×24 bit icons for several items added one day. I noticed immediately the New Item... menu option no longer showed the category of repository items I had just added. Restarting Delphi, I got an “invalid image size” error every time I selected File | New | Other... which rendered all my user entries in the repository inaccessible.

I looked at Delphi’s own repository settings and saw that many of them were 32×32 bit. So I manually edited the XML file for the entries I had entered and changed them to point to 32×32 bit icons, restarted Delphi, and it worked. (You can also simply leave the icon path empty in the XML or not add one in the first place–the icon is optional.)

Surprisingly, an invalid path or filename to the icon does not break the repository, it’s just when it tries to actually load an icon with a resolution it’s not expecting (or one that’s evidently not supported) that causes it to throw up an error.

Categories: Developer Blogs

Raspberry Pi Distractions

Sat, 2015-02-28 08:39

I’ve been spending a lot of my spare time with RemObjects products (mostly Oxygene and Hydra) over the last several months and haven’t kept up my blog on those subjects like I intended. But another distraction is taking an increasing interest as more of a fun hobby than a dire need that will make me money.

I got a Raspberry Pi.

Actually, this is a picture of my second Raspberry Pi and there are two more on the way.

Now, I probably don’t have to explain what this is to most readers, but just in case someone doesn’t know, these are small, inexpensive single-board, system-on-a-chip computers that are designed to be easy to connect to a wide variety of devices, sensors, and controllers. They’re great fun to tinker with, learn on, and experiment with–and there are many, many web sites with instructions to build everything from a Lego robot to a home surveillance system to a multi-node, password-hacking super computer array!

My interests are fairly modest: I simply want to have a remote camera to watch the front porch from my back-of-the-house office. Oh, and it would be cool to set next year’s Christmas lights to music. And I might setup a torrent server. And maybe a voice-activated office lighting controller. And… My family might never see again.

I will likely blog some of what I do but one of the first things I want to write down so I don’t forget is actually a fix for an annoyance in Linux. The Raspberry Pi computers run Linux, of course, and every Linux distribution I’ve tried comes setup to blank the screen after a bit. Now this is good if you have a computer that you walk away from and forget to shut down or something, but the projects I have slated would either not have a screen attached at all or would need to have a small screen that is always on. So the first thing I had to figure out was how to disable the screen saver. This turned out to be surprisingly difficult to get right.

There are two parts: 1) the command-line, and 2) the graphical user interface. Everything in Linux can be customized and different from one system to another, so whatever I write here must include the disclaimer that it may be different on your system. If you install Raspbian, a popular distribution for Linux on Raspberry Pi, then the following should work for you. In any case, the main reason for me documenting it here is so that I will remember how to set it up on subsequent installs!

First the command line. This, more than anything, should be standard for every Linux system that runs the Bash command line shell (and should be simple to adjust to a different one). The system-wide start file, /etc/bash.bashrc, is where you want to add one line:
setterm -blank 0 -powerdown 0

This will 1) set the time interval to blank the screen (-blank) to zero which will disable it, and 2) keep the monitor from powering down (-powerdown). You may also need to use -powersave, but these two have worked for me on a couple of monitors.

Next, the graphical user interface (GUI) where you have friendly icons and can use the mouse has its own screen saver, separate from the command-line terminal. The GUI environment on Linux is called X and there are quite a variety of settings. On top of that, you have the desktop window environment. Since Raspbian comes default with LXDE, I’ll mention only this one. The start-up file for LXDE is:
\etc\xdg\lxsession\LXDE\autostart.

There are two things to do: 1) disable the screen saver, and 2) disable the EnergyStar features.

The first part seems easy enough, simply comment out the line that starts the screen saver (you can just as well delete it if you want; I keep it there to remind me what it had been if I ever decide I want to turn it back on):
; @xscreensaver

This, you might think, should be enough to disable the screen saver. And, well, it does. However, the X11 system has additional built-in screen-saver capabilities, so you need to do a couple of extra steps:
@xset s noblank
@xset s off

Finally, disable EnergyStar features of your monitor so it won’t go into a power-save mode even though your screen saver is off:
@xset -dpms

There are numerous forums and blogs all over the internet with various ways to do this and indeed they work for those situations. After trying several, I settled on the steps above and wrote them down so that it will save me time looking them up.

Hopefully, it helps you as well!

Categories: Developer Blogs

Diving into .NET

Fri, 2014-06-27 21:01

I recently watched most of a dotnetConf, a virtual conference on .NET hosted by Microsoft. All the sessions were recorded and there’s a lot of good and relevant content.

I was programming Win32 apps in Delphi while listening and I felt myself yearning for the cool technologies they were discussing. Yeah, Delphi has grown up a bit, but it’s no longer the leader, it’s following and getting further and further behind the rest of the development community.

Several of the sessions concentrated on ASP.NET and one in particular caught my eye because it’s a framework that makes it easy to build not just web sites, but web apps that dynamically resize for a variety of form factors with cool techniques like shrinking a list of menu items down into a “hamburger” icon. The name implies it’s an extension to ASP.NET itself: ASP.NET Web API.

The speakers mentioned multiple times how Microsoft is working with a lot of open standards and JavaScript libraries and even making ASP.NET to be more portable by opening it up to run on Mac and Linux machines. There is also support for popular frameworks and libraries such as jQuery, Angular, Backbone, Knockout, and Bootstrap–a demo of this last one showing adding themes was cool to watch.

ASP.NET has much better and easier support for encrypting web pages (which you SHOULD DO for any login or data-centric site).

Testing and deploying ASP.NET web sites has been made much easier than in “the old days.” Not only are the tools simpler, but Microsoft provides built-in connections for Azure, not surprisingly. But if you want to make sure your site will work on a remote domain name without actually deploying to a remote site, there’s a nifty domain name called, localtest.me, that anyone can use. Read about it–it’s genius!

Finally, I learned about another Microsoft resource, Microsoft Virtual Academy. There are many free courses to help get you started in many different subject areas–progrmaming Windows phones, SQL Server, business strategies, HTML5, licensing, virtualization, and many more.

These will be great sites that I visit often as I get more and more into .NET for my own enjoyment and education. I’m using the RemObjects suite of .NET tools which is a great way to shift my Delphi experience to a more popular development environment. Plus, with Hydra, I can blend the two technologies into one application and slowly swap out modules until I’ve completely migrated the application. I don’t know if I’ll ever need to completely replace Delphi as I’ll more likely build something in ASP.NET using DataAbstract with RemObject’s Relativity Server hooked to my ElevateDB database. But at least I can connect to complicated APIs like Amazon Web Services from a Delphi application right now! That’s something I simply could not do before.

Categories: Developer Blogs