Sunday, June 9, 2019

Say what you mean and mean what you say!

How often are you or your words misinterpreted? Do you even know? Would someone tell you? Or would you go on with life thinking everything is just honky dory. Only to find out later things were not just fine, you only thought they were.

I attended a Toastmasters Leadership Institute training session and was introduced to a "word exercise". This was the first-time I ever heard this done, or given any thought to how a simple phrase could possibly be misinterpreted. It never dawned on me that someone might take to mean what I said differently than I meant it.

Read this sentence to yourself: "I never said I thought your idea was bad."

Fairy straightforward, right. How did this sound to you? Is this something you may have even said to someone? I know I've said this or something very similar to someone.

Let's see how many different ways this can be interpreted. Read each sentence below putting emphasis on the "bolded" word below.

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

"I never said I thought your idea was bad."

Interesting right? Yeah that was the same reaction I had. It never occurred to me that someone might see or hear what I say in a different context than they way I mean it.

That explains a lot. Today, we are constantly texting or emailing people. It's not always your fault if you or what you say gets taken the wrong way. It depends on the way it gets interpreted by the recipient.

So even if you say what you mean and mean what you say it might still be taken differently.


Semper Fi,
Gunny Mike

Your feedback, and comments are always welcome. Don't forget to subscribe for email notifications of new posts.

Saturday, March 9, 2019

Delphi Tip of the Day - Forward Declarations. Solving the Chicken or the Egg Problem.

Today's Delphi Tip of the Day is about resolving "which came first, the chicken or the egg". Because Delphi is a strongly typed language you can't refer to something until it's been defined. However, there are situations where you want to refer to something NOW, but unfortunately it hasn't been defined yet.

In other words "I want the egg of that chicken. I know that chicken hasn't laid that egg yet. However, since I know that chicken is going to lay that egg (trust me I know), let me have that egg now."

This is where forward declarations come into play.

I was brought here by something that came up while reading Pawel Glowacki's book Expert Delphi. I'm on page 233 from Chapter 7 - Sensing the world. Pawel discusses the TSensorManager class in the System.Sensors unit.

There is main TSensorManager class that acts as a gateway to all sensor information. It has a Current: TSensorManager class property that is used to reference all sensor information. At the top of the System.Sensors unit, you can find a TSensoryCategory enumerated type that provides the top level categorization of all possible sensors: 

At this point my head was about to explode so I decided to open the System.Sensors unit and have a look at the actual code Pawel was referring to. Then it hit me.

What the hell is this empty class doing here? How can you have an empty class?
TSensorManager = class;
I remember going down this empty class learning path a while ago. But do you think I can remember what it was, or means. No. Obviously, I had not associated a nice, simple "word picture" to the meaning of this empty class. Because if I had, I would have remembered.

So now I have the nice, easy to remember, "Oh that's Delphi's way of resolving the chicken or the egg thing" word picture.

Have a look at this type definition snippet from the System.Sensors unit:"

  //other type declarations
  TSensorManager = class; //←-- egg reference
  TCustomSensor = class abstract
    public type
      TProperty = (UniqueID, Manufacturer, Model, SerialNo, Name, Description);
      FOnDataChanged: TNotifyEvent;
      FOnSensorRemoved: TNotifyEvent;
      FOnStateChanged: TNotifyEvent;
      FManager: TSensorManager; //←-- egg reference
      FStarted: Boolean;
    // other class definitions
  //other type declarations

  TSensorManager = class abstract  //←--- chicken reference
  public type
    TFilters = TDictionary‹string tsensorfilter=""›;
  private class var
    FCurrentManager: TSensorManager;
    class function InternalGetSensorManager: TSensorManager; static;
    class constructor Create;
    class destructor Destroy;
  protected type
    TSensorManagerType = class of TSensorManager;
    // other class definitions

  //other type declarations

The problem arises because there's a private field declaration in the TCustomerSensor class that references the TSensorManager class that doesn't exist yet. It's the damn "chicken or the egg" thing.

To get around this Delphi allows what is called a forward declaration.

This is not by any means the complete class definition. The complete class definition must be declared somewhere inside the same type declarations where the forward declaration resides.

Here are a couple useful links:

Special Characters:
The  "‹" and "›" in the source code sections were created using the Alt + Keypad method.

Semper Fi
Gunny Mike

Monday, March 4, 2019

Delphi Tip of the Day - What is the "A" prefix I see used on parameters?

Today's Delphi Tip of the Day is all about consistent naming conventions. Consistency in the Delphi and Object Pascal language makes it easier to read and comprehend the code.

I have often wondered why the "A" prefix is used on Delphi parameters. Instead of just accepting it as some esoteric thing as I have done for the past twenty years, I googled around and found an answer. Have a look at the following code snippet:
constructor TPerson.Create(AFirstName, ALastName: string);
  FirstName := AFirstName;
  LastName  := ALastName;
The "A" in "AFirstName" and "ALastName" denotes an Argument as in the above constructor code example.

Typical naming conventions that are used are:
A := Argument
F := Field
T := Type
E := Exception
I := Interface
L := Local Variable
G := Global Variable
The key is to be consistent in all your code. If we as a Delphi community are consistent then it makes it much easier to communicate with each other.

#delphi #tipoftheday #capecodgunny

Gunny Mike

Sunday, February 24, 2019

Expert Delphi - Code Errata

For the past month I have been making my way through Pawel Gloawcki's book Expert Delphi. I love this book. I am having fun and learning so much. I completed the "Game of Memory" application from Chapter 4, and it works pretty good.

I initially ran into an issue running The Game of Memory on my Galaxy S9+. In portrait mode, if I selected "6 Pairs" it rendered two columns of six. However, only the top portion of the bottom two tiles displayed. I changed the TILE_MARGIN constant from 2 to 4 and it fixed the render problem.

I moved onto Chapter 5 - Firemonkey in 3D. I discovered an error from page 162 that took me over an hour to track down. I finally figured it out. The program is supposed to display a red 3D Pyramid. However, I was only getting a blank screen. I discoverd one of the private properties was not getting set.

  TWireframe = class(TControl3d)
    FDrawColor: TAlphaColor;
    FEdges: TEdges;
    FPoints3D: TPoints3D;
    FDisplayed: Boolean;
    constructor Create(AOwner: TComponent) ; override;
    destructor Destroy; override;
    procedure Render; override;
    property DrawColor: TAlphaColor read FDrawColor write FDrawColor;
    property Points3D: TPoints3D read FPoints3D;
    property Edges: TEdges read FEdges;
    property Displayed: Boolean read FDisplayed write FDisplayed;

It is the code for the constructor where the error is:

The private boolean field FDisplayed was not getting set to true.

constructor TWireframe.Create(AOwner: TComponent);
  FPoints3D := TPoints3D.Create;
  FEdges := TEdges.Create;
  FDrawColor := TAlphaColorRec.Red;

As soon as I added this code to the constructor it worked like it was supposed to.

constructor TWireframe.Create(AOwner: TComponent);
  FPoints3D := TPoints3D.Create;
  FEdges := TEdges.Create;
  FDrawColor := TAlphaColorRec.Red;
  FDisplayed := True; // This is missing on page 162 of the book

It probably wouldn't have taken me so long to figure this out if I was a more seasoned Delphi programmer. Oh well, it is what it is. So, for any of you who are reading or plan to read "Expert Delphi" keep this little tidbit in mind when you get to Chapter 5.

I have submitted an errata to the folks at

Gunny Mike

Saturday, December 8, 2018

Code Rage 2018 Replay: What's New With RAD Studio 10.3 Rio

I was unable to attend Code Rage 2018 this year. I'd like to thank Embarcadero for making the replays available. In this video, Sarina Dupont, David Millington, and Marco Cantu discuss what's new with RAD Studio 10.3 Rio. I like the new changes to the IDE.

Code Rage 2018: RAD Studio 10.3 Rio Product Address

Q&A Slide 

10.3 Rio is now available!

IDE Main Window:

IDE and Project Options:

GetIt, Compile and other dialogs:


Delphi inline variables & type inference:

Delphi RTL Improvements:

High DPI perMonitorV2 & GetSystemMetrics:

High DPI Image List:

Gunny Mike

Wednesday, November 28, 2018

The 20-Second Hug

program TwentySecondHug;


{$R *.res}


    Writeln('The 20-Second Hug');
    Writeln('Copyright (C) 2018 by Michael J. Riley');
    Writeln('(May be freely distributed worldwide)');
    Writeln('#20SecondHug #20SecondHugs #PilotLight ');
    Writeln(' Instructions ');
    Writeln(' 1. Squeeze recipient.');
    Writeln(' 2. Don''t let go until this window closes.');
    Sleep (20000); //Stay awake don't miss this part;
      { TODO 1 :
      Translate instructions into other languages.
      Ask Delphi programmers for help by putting
      translations in blog comments. }
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);

Gunny Mike

Sunday, August 12, 2018

Delphi Book Collection

One week after I wrote about Warren Buffet's 25-5 rule I created my own "Top 5" list. However, this time I put a little twist on it. Instead of creating a to-do list of things I wanted to accomplish in the next six months, I created a list of the top 5 things I have accomplished within my lifetime. It took me about five or six days but I finally came up with my list.

#4 on my list: "Creating a software product back in 1991 that still generates sales today."

If you check the list of Delphi releases you'll notice that Delphi didn't exist in 1991. Turbo Pascal was the tool I used to create that first version of my software. Here is a picture of Zilch v1.11. Unfortunately, I do not have a copy of my very first version 1.0.

Zilch Version 1.11 (Version 1.0 not available)

Learning Turbo Pascal was fun. I owe my passion and desire for computer programming to Jeff Duntemann. He wrote a book called "Complete Turbo Pascal". It was that book that taught me everything I needed to know about computer programming, and the Pascal language. In fact, the reports within my software are pulled using the double-linked list example in his book. Duntemann does a brilliant job of explaining this concept.

That book is by far my absolute favorite programming book. I used several snippets of code, and in some cases entire routines from the examples in his book. Like the linked list routines. I remember getting close to being done. My software was about a month away from being released as shareware. And it dawned on me, "Holy crap. I've used a bunch of code from this book and it's copyrighted. Can I do this?" So I called Jeff and the conversation went something similar to this...

Me: Mr. Duntemann.

Jeff: Yes.

Me: You don't know me. My name is Michael Riley. I'm a US Marine developing software in my spare time.

Jeff: That's good. I like Marines.

Me: Mr. Duntemann, I've...

Jeff: Please call me Jeff not Mr. Duntemann.

Me: Okay. I've been using your book "Complete Turbo Pascal" to learn how to write my software. And I've embedded several of the code snippets into my software. The're all over the place. I've even used the complete linked-list code routines. Am I allowed to do this? Can I use your code in my own software?

Jeff: Of course. That's why I wrote the damn book.

Me: Whew, that's a relief. You have no idea how worried I was. I really like how you explained double linked lists.

Jeff: I get quite a few calls from people telling me they have my book and asking to explain something. I remember the phone ringing at 1 in the morning one time and I was explaining linked lists to this guy. I remember using a kite metaphor. You see it's like a kite with a tail, and attached to that tail is another kite with a tail. And attached to that tail is another kite. Kites and tails with attached kites keep going on and on and on.

I love this guy. That was 1991 and Jeff and I have been friends ever since. One of these days I'm going to have to get Jeff to sign this book. I've completely destroyed the spine. I even had to use clear shipping tape to hold the spine together.

Complete Turbo Pascal Third Edition - Jeff Duntemann

My books have been scattered all over my basement office. When I want one I go searching from pile to pile. Moving stuff, looking around. It's frustrating and not very productive. Arrrgh!

It's been like this for a long time. It's not just books that are unorganized. It's me. It's everything. Besides, the older I get the harder it is to keep track of stuff. Stuff I need to do. When it needs to get done. Who I owe it to. Who owes me stuff. All that stuff.

So, I dusted off my old Franklin Planner that I haven't used since 2010. Inserted the new planner pages on Wednesday night and started using it the next day. Life is so much better now. I set a task for organizing my basement home office on Saturday. Then I decided to gather up all my Delphi books and put them on one single bookshelf. Wow, I have quite the collection.

Click to enlarge image

And guess what? All those books are tied to my #4 lifetime accomplishment: "Creating a software product back in 1991 that still generates sales today".

However, it not about what I did. It's about people. The people who helped me while I was in the midst of doing the thing I did. Like I said, I owe my #4 to Jeff Duntemann. Without him this never would have happened. Look what it's lead to. It's because of Jeff that I stayed enthused, and stayed passionate. Passionate enough to buy 32 Delphi books over the past 28 years. Not to mention the eBooks sitting on my computer. Thank you Jeff.

Don't worry I've told this to Jeff already. He's not hearing this for the first time reading it here. What kind of guy do you think I am.

I have a challenge for you! I want you to create your own "Top 5" list of lifetime achievements.

It doesn't matter if it takes you a week, or two weeks, or longer. Just do it. Then sit and think about your accomplishments. Think long enough about them until you discover who helped you get there. And then, reach out to them and let them know.

Gunny Mike