Friday, July 30, 2021

Delphi: Inheriting Parent Properties

The ability to inherit Parent properties is very convenient. Let's say you have a form with several controls on that form. If you wanted to change the default font from "Tahoma" to "Segoe UI" wouldn't it be nice to only have to make that change in one spot and voila, the change happens everywhere?

Well that is what inheriting the Parent properties is all about.

Unfortunately, not all the Parent properties get inherited. The font color is one of those properties that gets inherited by some controls but not all controls. I created this short video to show what happens to some of the most used VCL controls when you change the forms Font Color and Font Family.



https://youtu.be/M3VWsqPodJM

So, be careful and don't assume that one single change to the forms properties will get propagated throughout your entire application.

Enjoy!
Semper Fi,
Gunny Mike
https:\\zilchworks.com

Saturday, July 17, 2021

CodeRage 3 Replays - Oldies but Goodies

This morning I was looking for a video on how to debug an application with the Delphi IDE. I came across a two-minute video on YouTube by Francois Gaillard. It was a teaser video intended to pique your interest for the segment he did at Code Rage 3. Unfortunately, there was not a link to the full blown presentation.

I found a link to the Code Rage 3 replays on the way back machine. You can find the original webpage using this link. https://web.archive.org/web/20090815150549/http://conferences.embarcadero.com/coderage/article/38874

There are a lot of really interesting replays from Code Rage 3. Unfortunately, the recordings are done using Adobe Flash which has been discontinued. However all is not lost. You can download a stand-alone Flash Player from the Adobe website using this link 

https://www.adobe.com/support/flashplayer/debug_downloads.html


Delphi Debugging for Dummies by Francois Gaillard


After you download and unzip the replays you will see two ".swf" files. one called Session.swf and one called Session_controller.swf. Make sure to open the Session_controller.swf using the Flash Player program downloaded from the Adobe site. This will give you the the status bar with play and pause buttons along with the thumbtack progress bar.

Below is the list of Code Rage 3 presentation with download links.

Delphi / RAD Studio

C++ Builder

Delphi Prism

JBuilder

Delphi for PHP

InterBase

3rdRail/TurboRuby

Database Tools

General Topics

Sessions Presented in Spanish

Sessions Presented in Portuguese

Enjoy
Semper Fi
Gunny Mike
https://zilchworks.com

The link to the stand-alone Adobe Flash Player came from an article called "How to Play Adobe Flash SWF Files Outside Your Web Browser" on howtogeek.com. https://www.howtogeek.com/438141/how-to-play-adobe-flash-swf-files-outside-your-web-browser/

Saturday, June 5, 2021

Mobile Storage Access (Note to Self)

 I am nowhere near creating apps for the mobile community. That doesn't mean I won't be in the future. So, I'm writing this as a "Note to Self" so when the time comes I'll have a nice handy reference.

If you are currently developing mobile apps you may find this discussion on Delphi-PRAXiS helpful and interesting.

How do users easily bring their desktop data to mobile devices?

You may also want to view the following YouTube video called Storage access with Android 11



Enjoy,
Semper Fi
Gunny Mike
https://zilchworks.com

Sunday, April 25, 2021

Delphi Form/Code Separation (CodeRage 9 2014)

I just re-watched an excellent video by David Schwartz on form/code separation. Schwartz gave this presentation during a 2014 Code Rage 9 session. 

Schwartz says the majority of Delphi Form-to-Form code he has seen uses what he calls "Back-Door" injection. Where all the data movement to and from controls is handled at the form level. This is in contrast with the “normal” use of properties to enforce encapsulation in the movement of data into and out of objects. He discusses "Constructor" injection and "Property" injection pointing out the pros and cons of both. 

I'm one of these "back-door" injection coders. I've never used properties. I'm learning how to use them. Here are my main reasons for not using them in the past:

  • Short how-two Delphi videos... "You can do all of this with no code".
  • They seem overly complicated to type.
  • Ignorance on the benefits provided.
Perhaps the IDE's Code Completion ( Ctrl + Shift + C ) would make creating properties and all the getters and setters a lot easier. I'll look into this. 

Help Wanted: If you know of any tutorials or videos specifically aimed at creating and using Properties please add them in the comments. Thank you.

Demo Code: The link to the demo code at the end of this video is broken. I have a copy of the demo code, Schwartz emailed it to me. I'm waiting for his permission to make it available as a download on this post. It does require the Konopka Signature Controls (formerly Raize components). 

I found this very interesting.

CodeRage9
Have You Embraced Your Inner Software Plumber Yet?
David Schwartz


https://youtu.be/qqKx8fQTTfI

Here are time jumps to specific sections:

00:41 Overview:
14:35 Summary

External References:

Saturday, April 24, 2021

Delphi Tip of the Day - Toggle Visibility On/Off

I'm porting over one of my Delphi 5 VCL, desktop applications to FMX. The target audience are Windows and macOS users. I'm not focused on mobile at this juncture. I'm spending quite a bit of time on the User Experience (UX). I guess you would call this approach "Desktop UX First".

I want to give the user the option of showing or hiding panels. I've decided to place this functionality in two places:

  1. On the main menu as an option.
  2. On the bottom tool bar as a button.
The first thing that came to mind was testing the "IsChecked" state of the main menu option. I slept on it and came back to the drawing board the next day. Instead of thinking about trapping clicks, I thought about what the intent of the click really was. And the answer is to show or hide the panel.

If the user clicks either the main menu option or the toolbar button I want the panel to show or hide. Both of these options need to work together behind the scenes. The intent of either click focuses on the "visibility" of the panel. And wouldn't you know, TPanel has a Visible property.

Visible is a boolean value, meaning it has only two states. True/False. And in Delphi there is a very cleaver way to toggle the state of a boolean value. This can be a little tricky to wrap your had around at first. However, once you understand it, you'll love it.

Boolean Value becomes not Boolean Value;
Boolean Value (True) becomes not Boolean Value (True);
Boolean Value (False) becomes not Boolean Value (False);
Boolean Value := not Boolean Value;

Panel.Visibile becomes not Panel.Visibile;
Panel.Visibile (True) becomes not Panel.Visibile (True);
Panel.Visibile (False) becomes not Panel.Visibile (False);
Panel.Visibile := not Panel.Visibile;

The statement Panel.Visibile := not Panel.Visibile; 
toggles the value, back and forth between True and False.

Let's see how to put this to use in the real world. In Delphi create a new FMX application. 
Click File > New > Multi-Device Application - Delphi and choose Blank Application.

Add the following components:
TMainMenu
TPanel x2
TToolbar
TButton
TSplitter
TStatusBar

Structure the components so they are parented like this:



Your form should look similar to this:


The goal is to toggle the Left Panel visibility. When you first run the application the form opens with the default settings. We want both the MenuItem (Show Left Panel) and the ToolBar Button to work together.




Hiding the Left Panel the form changes accordingly.


Regardless of which method was used to Show/Hide the left panel both items stay in synch by calling on procedure ToggleLeftPanelOnOff.

I'm testing the Sender to make sure it was invoked by either a TMenuItem or a TButton control before I toggle the panel visibility. Although it's not displayed here this allows for calling ToggleLeftPanelOnOff from inside the form's OnShow method in essence setting the correct values without toggling the panels visibility.

Here is the program code:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.Menus;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    StatusBar1: TStatusBar;
    pnlLeft: TPanel;
    pnlMain: TPanel;
    splLeft: TSplitter;
    tbarMain: TToolBar;
    btnTBarLeft: TButton;
    mnuFile: TMenuItem;
    menuOptions: TMenuItem;
    mnuShowLeftPanel: TMenuItem;
    mnuClose: TMenuItem;
    procedure mnuCloseClick(Sender: TObject);
    procedure mnuShowLeftPanelClick(Sender: TObject);
    procedure btnTBarLeftClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
   procedure ToggleLeftPanelOnOff(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.btnTBarLeftClick(Sender: TObject);
begin
  ToggleLeftPanelOnOff(Sender);
end;

procedure TForm1.mnuCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TForm1.mnuShowLeftPanelClick(Sender: TObject);
begin
  ToggleLeftPanelOnOff(Sender);
end;

procedure TForm1.ToggleLeftPanelOnOff(Sender: TObject);
begin
  // ==================================================================
  // Only toggle visibility if invoked by a menuitem or button click.
  // ==================================================================
  if (Sender is TMenuItem) or (Sender is TButton) then
    pnlLeft.Visible := not pnlLeft.visible;

  // ==================================================================
  // Set menuitem and button properties
  // ==================================================================
  if pnlLeft.Visible then
  begin
    mnuShowLeftPanel.IsChecked := True;
    btnTBarLeft.StyleLookup := 'arrowlefttoolbutton';
  end
  else
  begin
    mnuShowLeftPanel.IsChecked := False;
    btnTBarLeft.StyleLookup := 'arrowrighttoolbutton';
  end;

end;

end.

Here is the text version of the Form:


object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Toggle Demo'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
  object StatusBar1: TStatusBar
    Position.Y = 458.000000000000000000
    ShowSizeGrip = True
    Size.Width = 640.000000000000000000
    Size.Height = 22.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 1
  end
  object pnlLeft: TPanel
    Align = Left
    Size.Width = 161.000000000000000000
    Size.Height = 458.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 2
  end
  object pnlMain: TPanel
    Align = Client
    Size.Width = 475.000000000000000000
    Size.Height = 458.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 3
    object tbarMain: TToolBar
      Align = Bottom
      Position.Y = 418.000000000000000000
      Size.Width = 475.000000000000000000
      Size.Height = 40.000000000000000000
      Size.PlatformDefault = False
      TabOrder = 0
      object btnTBarLeft: TButton
        Align = Left
        Size.Width = 40.000000000000000000
        Size.Height = 40.000000000000000000
        Size.PlatformDefault = False
        StyleLookup = 'arrowlefttoolbutton'
        TabOrder = 0
        Text = 'btnTBarLeft'
        OnClick = btnTBarLeftClick
      end
    end
  end
  object splLeft: TSplitter
    Align = Left
    Cursor = crHSplit
    MinSize = 20.000000000000000000
    Position.X = 161.000000000000000000
    Size.Width = 4.000000000000000000
    Size.Height = 458.000000000000000000
    Size.PlatformDefault = False
  end
  object MainMenu1: TMainMenu
    Left = 304
    Top = 224
    object mnuFile: TMenuItem
      Text = 'File'
      object mnuClose: TMenuItem
        Locked = True
        Text = 'Close'
        OnClick = mnuCloseClick
      end
    end
    object menuOptions: TMenuItem
      Text = 'Options'
      object mnuShowLeftPanel: TMenuItem
        Locked = True
        IsChecked = True
        Text = 'Show Left Panel'
        OnClick = mnuShowLeftPanelClick
      end
    end
  end
end


Enjoy,
Gunny Mike

Thursday, April 8, 2021

Turbo Boost Your Delphi Knowledge - Become a Docwiki Ninja Warrior

I've made a commitment to learn FireMonkey. My flagship software product, Zilch Standard, turned 30 years old in 2021 and I still don't have a macOS version. I've got macOS consumers who buy my Windows® software and then email asking if there's a version that runs on their mac computer. This inevitably leads to me issuing a refund. So, I have a pretty strong incentive to learn FireMonkey.

"I feel like I'm sitting in the cockpit of an airplane."

I tried going down the FireMonkey learning path before but unfortunately I didn't get very far. Learning FireMonkey makes me feel like I'm sitting in the cockpit of an airplane. There's so many things that are unfamiliar. The scope of it all is overwhelming. There's so much to learn. I don't know where to look first. What about the help? It's just an [F1] key press away!

I don't know about you but I get frustrated at the built-in help that comes with Delphi? Does this sound familiar? You're frantically trying to figure something out... pressing [F1] all over the place, and hopelessly rummaging around through Delphi's built-in help. Sometimes it's great and gives you what you exactly what are looking for. Often times you are left feeling like you just read a bunch of cryptic tea leaves. 

Where do you turn at this point? The Facebook Delphi groups? Stackoverflow?  Your stash of Delphi books? Delphi's dockwiki?

In the past I've rarely thought to use Delphi's docwiki. In my mind I felt like it was the same rehashed [F1], cryptic leaves stuff. Well, that changed last night. 

It turns out, I wasn't using the dockwiki in a meaningful way. I figured out how to exploit the value of the docwiki. I'm going to show you how to become a docwiki ninja warrior.

"I'll show you how to become a Delphi Docwiki Ninja"

It all started last night when I wanted to learn more about FormFactor. I wrote a simple FMX application that displays the ClientHeight, ClientWidth, FormFactor.Width, and FormFactor.Height in the OnResize event handler. I was curious why the FormFactor values never changed as the form was resized, so I wanted to learn more. That's when I highlighted FormFactor in the Object Inspector and pushed [F1] .


This brought up the built-in help for FormFactor. This is one of those cryptic tea leaves help reference.



This wasn't very helpful. I may have done some googling to learn more but couldn't find anything that talked about FormFactor. What it is? How it's used? Why it's used? So I posted my question to StackOverflow

Someone commented and said "Please look at the documentation. It seems to concern iOS only, and changes according target device selection."

How did he find that docwiki page? That's not the docwiki page I found. In fact I couldn't find the dockwiki page referenced in StackOverflow comment. Turns out I didn't understand how to use the dockwiki. I was stuck in the API library and couldn't got out!

I was stuck in the API library and couldn't get out!

That's when I discovered how to become a Docwiki Ninja Warrior. This takes less than a minute to setup and I believe it will save you hours looking for information about Delphi that is relevant to what you are looking for. For illustrative purposes I'm sticking with my original pursuit of FormFactor.

Step 1: From inside the IDE click Help > RAD Studio Docwiki


Step 2: This opens the RAD Studio docwiki page in your default browser.
Step 3: Right-click on Library Reference > Open link in new tab 


Step 4: This opens the Library docwiki page in a new browser tab.
Step 5: Right-click on Code Example > Open link in a new tab.


At this point you should have three tabs in your browser each dedicated to separate docwiki sections. And now the fun begins.

Step 6: Enter FormFactor in the search box for tab 1 RAD Studio and press [Enter]. I'm horrible at spelling so I usually just copy and paste the value I need. I just highlighted FormFactor in the IDE code editor and pasted it in the search box. 





Step 7: Switch to tab 2 Library docwiki page and paste or enter FormFactor in the search box and press [Enter].





Step 8: Switch to tab 3 Code Examples docwiki and paste or enter FormFactor in the search box and press [Enter].


"So, what did I learn about FormFactor?"

FormFactor is only used used when you are creating an iOS application. This is awesome. I learned enough about FormFactor to satisfy my current need. Because I'm focused right now on learning how to use FireMonkey to create desktop applications for Windows and macOS, FormFactor is not relevant to my current situation. This lets me know I can skip a thorough investigation about FormFactor for the time being. It also lets me know that ignoring FormFactor at this time is okay since it does not apply to desktop applications for Windows or macOS. I don't need to be concearned about FOMO (fear of missing out).


However, if FormFactor was something I was interested in, the three different docwikis provide ample links to related, relevant, information in one convenient location. 

Oh yeah, make sure to play around with the "Advanced" link on the special search results pages.

There you have it. I am so glad I stumbled upon this. It will surely be very helpful in my quest to learn FireMonkey. 

Enjoy!
Semper Fi,
Gunny Mike

Sunday, March 28, 2021

Video: What's New in 10.4.2 - With Timestamp Jumps

 I just watched the "What's New with 10.4.2" Embarcadero video. It sounds like there was a lot of quality code fixes put in place. One thing that surprised me is the ability to open the Form Designer and Code Editor in separate windows. Each fully functionable and editable.

The video is over 4 hours long. the first 43+ minutes are the new feature presentations. The remaining 3+ hours is a question and answer session. I have not listened to the Q&A. McKeeth did create a separate google docs of the Q&A.


Here are the topics with timestamp jumps.

Introduction
https://youtu.be/AZ4ba9Tf3qE
Jim McKeeth

Overview of RAD Studio 10.4
https://youtu.be/AZ4ba9Tf3qE?t=65
Sarina DuPont

What's New  in 10.4.2
https://youtu.be/AZ4ba9Tf3qE?t=284
Sarina DuPont

Best-in-Class Windows Application Support
https://youtu.be/AZ4ba9Tf3qE?t=314
Marco Cantu

New TControlList VCL Component
https://youtu.be/AZ4ba9Tf3qE?t=401
Marco Cantu

New TNumberBox VCL Component
https://youtu.be/AZ4ba9Tf3qE?t=497
Marco Cantu

MSIX and Windows Store Support
https://youtu.be/AZ4ba9Tf3qE?t=529
Marco Cantu

More VCL Improvements
Upgraded Konopka Components (KSVC)
Enhanced TEdgeBrowser VCL Component
https://youtu.be/AZ4ba9Tf3qE?t=582
Marco Cantu

Demo TNumberBox
https://youtu.be/AZ4ba9Tf3qE?t=688
Jim McKeeth

Demo TControlList
https://youtu.be/AZ4ba9Tf3qE?t=849
Jim McKeeth

New Developer Productivity and UX Features
https://youtu.be/AZ4ba9Tf3qE?t=1157
David Millington

Demo IDE & Code Insight (LSP)
https://youtu.be/AZ4ba9Tf3qE?t=1602
David Millington

Form Designer & Code Editor in separate windows
https://youtu.be/AZ4ba9Tf3qE?t=1680
David Millington

Expanded FireMonkey Platforms Support
https://youtu.be/AZ4ba9Tf3qE?t=1963
Marco Cantu

New Delphi Compiler Enhancements
https://youtu.be/AZ4ba9Tf3qE?t=2115
Marco Cantu

C++ Changes
https://youtu.be/AZ4ba9Tf3qE?t=2193
David Millington

General Quality Enhancements
https://youtu.be/AZ4ba9Tf3qE?t=2291
David Millington & Marco Cantu

RAD 10.4.2 SKUs
https://youtu.be/AZ4ba9Tf3qE?t=2551
Marco Cantu


Enjoy,
Gunny Mike
Semper Fi
https://zilchworks.com