Sunday, July 13, 2014

Video: Effectively Using Raize Components by Ray Konopka

I forgot what the RzMenuController from Raize Component did so I went back and watched the video Ray did at CodeRage 7 to remind me. Then I decided to make this list of links that jumps to a specific item for the next time I forget how to do something with one of these controls.

Effectively Using Raize Components by Ray Konopka
  1. Edit Button (4:04)
  2. Menu Button (5:55)
  3. Menu Controller (7:18)
  4. Tray Icon (9:26)
  5. Line Component (11:29)
  6. Progress Display (12:24)
  7. LED Display (14:27)
  8. DBGrid (15:35)
  9. Track Bar (19:23)
  10. Radio Group (24:42)
  11. Persistence Property Store (27:05)

Enjoy - Semper Fi
Gunny Mike
end.

Friday, July 11, 2014

How to Replace Global Variables by Using a Static Class

One of the first things I used to do when creating a new Delphi application was add a copy of the almighty global.pas unit to the project. I'd immediately go in to this file and start tweaking this and tweaking that so it would work with my new application. And, I made sure to ALWAYS add Globals to the uses clause of every new form I created.

My Delphi buddy Bob Wight, who is Scottish and speaks with a very heavy brogue, called his "Globs". Which stood for globs.pas. I remember him saying, "The programmer's life. Another day, another global." It sounds really cool with his Scottish accent.

Anyway, I thought this was the normal way of doing stuff. I thought every Delphi programmer did this. I never challenged it. Not ever.

Now, as I'm re-learning Delphi all over again for the first time, I hear several Delphi people, in the various Delphi hangouts, say stuff like, "Never use global variables" and "Pretend like global variables don't exist".

I'm thinking to myself... "Okay how the heck do you program if you can't use global variables?"

So, last weekend learned how to replace global variables in my Delphi application by using what is called a static class. It turns out that a static class can simply exist without having to be instantiated. That is pretty cool.

A static class can have constants, variables, functions and procedures. Its like having global variables on steroids. I have replaced my globasl.pas file with a file called ApplicationInfo.pas. I've included a copy of this file below.

This is a fairly new concept for me and it will no doubt go through some changes and refactoring. But so far, I'm liking it.

Here's a couple ways I'm implementing the use of my TAppInfo static class.


The cool part is the Intelisense... I just type TApp and hit [Ctrl] + [Space] and I can pick the item I want. No more "Globs" for this Marine!

ApplicationInfo.pas

Enjoy - Semper Fi,
Gunny Mike
end.

Sunday, July 6, 2014

Just had to share - XE4 includes Beyond Compare

Wow, I just discovered that Delphi XE4 comes with Beyond Compare.

I right-clicked on the project-name from within Project Manager with the intent of choosing the Show in Explorer option when I noticed the Compare option at the bottom. I was pleasantly surprised to see Launch Beyond Compare.

There are two ways to launch Beyond Compare from within the IDE:

 

Makes me think I should spend more time exploring the IDE.

Enjoy - Semper Fi,
Gunny Mike
end.

Friday, July 4, 2014

Choose the Right Folder for Your Application Data

I'm in the process of updating an older program that will now use a local database. I followed my typical "old school" habits and quietly went about my way thinking "I'll just plop the database in a folder called Data that resides in the same location as the exe file. No big deal."

I figured, I'll just use the reliable ExtractFilePath(Application.ExeName) to get the location of where this Data folder needs to go. Right?

Wrong!

I had forgotten to think about how Delphi's "debug" and "release" paths will play into this scenario. Not to mention 32Bit and 64Bit targets. I'm only focused on creating a Windows product at the moment, so for me this means there are a minimum of five paths:

Source
Source\Win32\Debug
Source\Win32\Release
Source\Win64\Debug
Source\Win64\Release

I know I could use "Post-Build" commands (Project > Options > Build Events) to make sure the files are copied from the $(PROJECTDIR) to the $(OUTPUTDIR). However, I was thinking that this is not a very efficient way to go about it. Did I really want to have five copies of a 140MB database cluttering up my hard drive. The answer is no.

So I posed the question "Looking for best practice for using single-user local database." to the Delphi Community on Google+ (https://plus.google.com/u/0/105522328114529031567/posts/Q8go8eWRAfz)

I received several comments and the consensus was to use an application specific subfolder of CommonAppData. Fair enough. CommonAppData it is. What the heck is CommonAppData?

I tend to be a "Show Me" guy I decided to dive into this head long and found out that CommonAppData actually refers to the folder called C:\ProgramData.

Then I wondered what all the other "AppData" type folders were. So I wrote a simple little program to help figure this out. It turns out there are 17 different AppData folders on my computer. I've included a copy of my program for you to use.

AppData Only: Sorted by Path Column

DFM:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Paths'
  ClientHeight = 411
  ClientWidth = 804
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnResize = FormResize
  OnShow = FormShow
  DesignSize = (
    804
    411)
  PixelsPerInch = 96
  TextHeight = 13
  object StringGrid1: TStringGrid
    Left = 16
    Top = 39
    Width = 772
    Height = 354
    Anchors = [akLeft, akTop, akRight, akBottom]
    ColCount = 3
    FixedCols = 0
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goFixedRowClick]
    ParentFont = False
    TabOrder = 0
    OnFixedCellClick = StringGrid1FixedCellClick
  end
  object Button1: TButton
    Left = 16
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Close'
    TabOrder = 1
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 97
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Get Folders'
    TabOrder = 2
    OnClick = Button2Click
  end
  object CheckBox1: TCheckBox
    Left = 184
    Top = 12
    Width = 97
    Height = 17
    Caption = 'AppData Only'
    TabOrder = 3
    OnClick = Button2Click
  end
end


Program:



Enjoy - Semper Fi,
Gunny Mike
end.