Wednesday, September 10, 2014

Taking the Mystery out of ListView Column Display

Here is a great article about how to display your data in columns using a ListView. Marjan does a fantastic job explaining how to modify the ListView so it displays your data in a nice column display. I'm definitely using this the next time I have a need.

Thank you Marjan!

How to get a ListView to display your values in columns

Enjoy - Semper Fi,
Gunny Mike
end.

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.

Tuesday, May 20, 2014

Changing the Cursor in FireMonkey

I just watched a video on How to Change the Cursor in FireMonkey by Alister Christie. As I watched this video I learned just how much of a Delphi noob I really am. I had no idea you could go from in-line code to class to interface.



Thank you Alister for a great video and mind-opening experience.

Semper Fi,
Gunny Mike
end.

Friday, May 16, 2014

Make the Most of EMBT's DocWiki

I'm just getting ready to explore chapter 3 of Cary Jensen's Delphi in Depth: ClientDataSets and I stopped to research one of the DataSetProvider options - poFetchDetailsOnDemand.

So, I highlighted the poFetchDetailsOnDemand option in the Object Inspector and pushed F1. It brings up the woefully inadequate local help reference. I was expecting to see a list of all the options with their associated meanings.

Then I googled delphi poFetchDetailsOnDemand, not what I was looking for.

So then I googled site:docwiki.embarcadero.com poFetchDetailsOnDemand

Google Search Syntax:
http://google.com/search?q=site%3Adocwiki.embarcadero.com+poFetchDetailsOnDemand

And... poof... perfect... just what I was looking for.

EMBT should redirect the F1-key to do a web search on their DocWiki and do away with the local help.

Enjoy!

Semper Fi,
Gunny Mike
end.

Thursday, April 17, 2014

Are Your Software Sales Where They Should Be?

As an Independent Software Vendor running a one-person, part-time business I'm always wondering if sales are where they should be. If I'm honest with myself I say "No". Trying to understand why can be a very difficult.

I rediscovered this article called "If No Independent Developers Are 100 Times Smarter Than You, Then Why Do Some Get 100 Times the Results?" written by Steve Pavlina when he was President of the Association of Software Professionals.

I remember reading Pavlina's article about 10 years ago and thinking to myself this is something that should be read and re-read often. Unfortunately, I forgot to bookmark the article back then and had a hard time finding it.

Last year I joined the ASP and found this article on one of the resource pages. It's still a good read.

http://asp-software.org/www/misv_resources/business-articles/results/

Enjoy!

Semper Fi,
Gunny Mike
end.

Sunday, March 9, 2014

Get More out of StackOverflow

It's no secret that StackOverflow or SO as it's commonly referred to is one of the best resources for Delphi enthusiasts. We all have some favorite questions, favorite answers and favorite users out there.

What makes StackOverflow so useful are tags. Tags are the single most important feature. Here is a snippet of what you see when you search tags for Delphi:

StackOverflow Tag Search - Delphi


If you mouseover a tag there is a little pop-up that gives a description of the tag along with some very interesting links. One of the most interesting links is the "top users" link. This "top users" link is how you can get more out of StackOverflow.

By following this link you get a list of which users have answered the most questions and which users have asked the most questions relating to this tag. By drilling down onto the users profile, you can see all the answers and questions this user has participated in.

You can very quickly build a list of your favorite StackOverflow Delphi users. Reading answers by these users will most definitely increase your knowledge about Delphi.

Delphi Tags Top Users
http://stackoverflow.com/tags/delphi/topusers
http://stackoverflow.com/tags/delphi-xe5/topusers
http://stackoverflow.com/tags/delphi-xe4/topusers
http://stackoverflow.com/tags/delphi-xe3/topusers
http://stackoverflow.com/tags/delphi-xe2/topusers
http://stackoverflow.com/tags/delphi-xe/topusers
http://stackoverflow.com/tags/delphi-2010/topusers
http://stackoverflow.com/tags/delphi-7/topusers

FireMonkey Tags Top Users
http://stackoverflow.com/tags/firemonkey/topusers
http://stackoverflow.com/tags/firemonkey-fm3/topusers
http://stackoverflow.com/tags/firemonkey-fm2/topusers

Semper Fi,
Gunny Mike
end.

Saturday, March 8, 2014

Delphi Product and Compiler Versions Quick Reference

I was doing some research on Delphi ClientDataSet QC issues at http://qc.embarcadero.com/ and noticed that the Delphi Product Versions are reported as 18.0, 16.4, etc. When an issue is resolved they show the Resolved in Build as XE5 or sometimes they show it as a number such as 17.0.

When I think of Delphi versions I think of XE5, XE4, D7. I don't think of 19, or 18, or 7. Here is an Embarcadero quick reference webpage that lists all the different Product versions for Delphi.

http://docwiki.embarcadero.com/RADStudio/XE5/en/Compiler_Versions

Up Thru Tokyo
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions


Semper Fi,
Gunny Mike
zilchworks.com

Tuesday, January 14, 2014

Embarcadero's Upgrade Policy is Deceiving

I am so frustrated and angry with Embarcadero right now. You have no idea how angry I am. Embarcadero's upgrade pricing policy is deceiving.


I upgraded to XE4 Enterprise from D2010 Professional in May of 2013. I blogged about my decision on May 19, 2013. (You can read about it here)


My upgrade decision was mostly made based on Embarcadero stating that the upgrade to XE4 is only valid for users of D2010 and higher. I did not want to miss out on an opportunity. It only stood to reason that when XE5 came out Embarcadero would only allow upgrade pricing from XE and higher.


Like all of you, I received all the year end marketing emails from Embarcadero. Needless to say, I did not take advantage of these year end offers.


I continued to receive upgrade notifications from Embarcadero. So, I decided to follow the embedded links within the email and now I discover that Embarcadero is allowing upgrades to XE5 to users of D2009 and higher.


THIS IS AN OUTRAGE


If I had waited a few short months I could have spent my upgrade money and received XE5. Now, I have XE4 Enterprise and it's going to cost me another 1,500 dollars to upgrade to XE5. This has got me so angry I don't know what to do. (I'm one pissed off Marine)


I'm a die-hard Delphi fanatic like most of you are. I have a love/hate relationship with Delphi mainly because it takes so dang long to learn how to do something in Delphi and after you figure out how to do it you say to yourself... "It shouldn't have taken that long."


I'm starting to really resent Embarcadero for what I consider to be deceptive marketing and upgrade policies.


I am not a happy camper right now.


Gunny Mike
end.

Sunday, November 10, 2013

Everyone Needs A Miyagi

Today is the Marine Corps' 238th birthday. Although I've been out of the Marine Corps since 1999 there's a saying that all Marines live by... "You can take the man out of the Marine Corps but you can't take the Marine Corps out of the man."

I just received a traditional "Happy Birthday" text response on my phone from Mitch Perry, one of my best friends of my Marine Corps days. I love this guy. Here's what he said...
"Same to you bud! I am sitting here drinking coffee in my dress blue coat, I might be losing it... HELP? Oh oh oh life goes on !"
So this got me thinking back to my earlier days in the Marine Corps. When you spend 20 years in the Marines you meet a lot of people. When I was a young Marine on my first four year enlistment I met a Marine named Staff Sergeant Reggie Wournos. Reggie was my Miyagi.

Reggie was one of the most squared away Marines I ever met. He taught me the Marine Corps version of "Wax on... Wax off", "Paint the fence" and "Sand the floor".

I'm not the only one that Reggie helped along the way. He took several of us young Marines under his wing and nurtured us along. If you ask the entire group of enlisted Marines from Headquarters and Maintenance Squadron 16, GSE - MCAS Tustin you will find you get the same type of response.  Here's a picture. Reggie is front row left in the bottom photograph.

This would be an awesome story if it ended right here, but it doesn't. For those of you that don't know how military life works, everybody moves on to new locations after 2-3 years. So, you get to hang with the same group of guys for a year or two and then you, or they, or both move on.

A few years later I'm working at MCAS Cherry Point, North Carolina. I had been promoted a couple times and now I was a sergeant. I have a new boss named Gunnery Sergeant Bill Wallace. You guessed it he's Miyagi #2. Wallace taught me a different set of skills. Wallace had the reputation both inside and outside of our organization as the "guy who's got his shit together".

So, you could say I was a lucky guy to have two Miyagi's. But if you can believe it, this gets even better.

In 2008 a bunch of us from GSE (the 1980 group) decide to get together in Memphis for a weekend. Most of us haven't seen each other in 25+ years. It was a pretty awesome time. So, I made public toast to Reggie thanking him for his early mentoring and telling him that he was my Miyagi. Everyone felt the same... Reggie is just one of those guys.

Later that evening I was having a private conversation with Reggie. We were both retired, me as a Gunnery Sergeant and Reggie as Chief Warrant Officer 4. I thanked him for being my Miyagi which he humble tried to deny. Then I asked him who his Miyagi was?

He looked at me and said "Bill Wallace".

Happy Birthday Marines
Semper Fi
Gunny Mike
zilchworks.com

Saturday, August 24, 2013

The One Manual Every Delphi Programmer Should Have!


I have always stayed away from using Delphi's DBGrid because it gave me the feeling of being in the cockpit of an airplane without a clue, as to what all the controls are, or even where to look first. I've decided to roll up my sleeves and get over my fear and anxiety of Delphi's DBGrid.

I'm currently using XE4 and I've been struggling with data validation within a DBGrid as you can see from a recent SO post How to get the value that caused the TDBGridInplaceEdit error?

After reading the answer I got from @bummi, I started googling related topics. Then I remembered I have a copy of Borland's Delphi 7 Developer's Guide.


Delphi 7 Developer's Guide

I quickly turned to Chapter 25 and found all the information I need to know, written in a friendly and very informative way. It's perfect. Each topic builds upon the previous topic giving a full treatment of the subject matter. Here is the table of contents for Chapter 25 of Borland's Delphi 7 Developer Guide:

Chapter 25Page
Working with field components 25-1
Dynamic field components 25-2
Persistent field components 25-3
    Creating persistent fields 25-4
    Arranging persistent fields 25-5
    Defining new persistent fields 25-5
        Defining a data field 25-6
        Defining a calculated field 25-7
        Programming a calculated field 25-8
        Defining a lookup field 25-9
        Defining an aggregate field 25-10
    Deleting persistent field components 25-11
    Setting persistent field properties and events 25-11
        Setting display and edit properties at design time 25-11
        Setting field component properties at runtime 25-13
        Creating attribute sets for field components 25-13
        Associating attribute sets with field components 25-14
        Removing attribute associations 25-14
        Controlling and masking user input 25-15
        Using default formatting for numeric, date, and time fields 25-15
        Handling events 25-16
Working with field component methods at runtime 25-17
Displaying, converting, and accessing field values 25-18
    Displaying field component values in standard controls 25-18
    Converting field values 25-19
    Accessing field values with the default dataset property 25-20
    Accessing field values with a dataset’s Fields property 25-21
    Accessing field values with a dataset’s FieldByName method 25-21
Setting a default value for a field 25-22
Working with constraints 25-22
    Creating a custom constraint 25-22
    Using server constraints 25-23
Using object fields 25-23
    Displaying ADT and array fields 25-24
    Working with ADT fields 25-25
        Using persistent field components 25-25
        Using the dataset’s FieldByName method 25-25
        Using the dateset’s FieldValues property 25-25
        Using the ADT field’s FieldValues property 25-26
        Using the ADT field’s Fields property 25-26
    Working with array fields 25-26
        Using persistent fields 25-26
        Using the array field’s FieldValues property 25-27
        Using the array field’s Fields property 25-27
    Working with dataset fields 25-27
        Displaying dataset fields 25-27
        Accessing data in a nested dataset 25-28
    Working with reference fields 25-28
        Displaying reference fields 25-28
        Accessing data in a reference field 25-29

I've already printed out Chapter 25 and plan to study it this weekend. The manual is 1,106 pages long. I plan on printing the chapters I need as I go. And yes I did buy paper that's already punched with 3-holes.

I don't care what version of Delphi you are using this manual is relevant and will make your life easier. Download your copy of Borland's Delphi 7 Developer Guide now!

If we could only get EMBT to create an updated version of this Delphi classic!

Semper Fi,
Gunny Mike
end.

Sunday, August 11, 2013

Format Numbers with an ElevateDB Function

There are times when I want numeric data coming out of a database formatted with a thousands separator and set number of decimal places. I'd rather see large numbers formatted as 123,740.00 rather than 123740. To me formatted numbers are just easier to read. Unfortunately, ElevateDB does not have a built in function similar to Microsoft's CONVERT.

However, you can create your own CONVERT function within ElevateDB quite easily. ElevateDB has two statements that make the job of formating numbers fairly easy. The first is the LABEL statement and the second is the LEAVE statement. The LABEL statement lets you set up a block of code. For example:
MyFistLabel:
BEGIN
  Do Something1;
  Do Something2;
  Do Something3;
  Do Something4;
  Do Something5;
END; --MyFistLabel
The LEAVE statement lets you exit a block of code. For Example:
MyFistLabel:
BEGIN
  Do Something1;
  Do Something2;
  Do Something3;
  IF Something3 = Done THEN
    LEAVE MyFistLabel
  END IF;
  Do Something4;
  Do Something5;
END; --MyFistLabel
So let's set out to create a function that formats numbers. This function will have two input parameters Value and Decimals. Value is the number to be formatted and Decimals is the number of decimal places. I built this function using two labels. One label that handles zero decimal places and one label that handles non zero decimal places. Here is the stubbed out concept:
----------------------------------------------------------------
ProcessZeroDecimals:
----------------------------------------------------------------
BEGIN
  -- Exit if Decimals parameter is other than 0 (zero)
  IF DECIMALS <> 0 THEN LEAVE ProcessZeroDecimals; END IF;
  -- Perform if Decimals parameter is equal to 0 (zero)
  Code Goes Here
  Code Goes Here
  Code Goes Here
----------------------------------------------------------------
END;--ProcessZeroDecimals:
----------------------------------------------------------------

----------------------------------------------------------------
ProcessNonZeroDecimals:
----------------------------------------------------------------
BEGIN
  -- Exit if Decimals parameter is equal to 0 (zero)
  IF DECIMALS = 0 THEN LEAVE ProcessNonZeroDecimals; END IF;
  -- Perform if Decimals parameter is other than 0 (zero)
  Code Goes Here
  Code Goes Here
  Code Goes Here
----------------------------------------------------------------
END; --ProcessNonZeroDecimals:
----------------------------------------------------------------
By testing the value of Decimals first we will either decide to LEAVE the code block or perform the code within that code block. The use of LABEL combined with the LEAVE statement makes for a very elegant solution. Here is the complete ElevateDB funtion:
CREATE FUNCTION "fFormatThousands"
(
 INOUT "Value" DECIMAL(19,4)
,INOUT "Decimals" INTEGER
)
RETURNS VARCHAR(20) COLLATE UNI_WI
BEGIN

DECLARE Separator VARCHAR(1);
DECLARE Str1      VARCHAR(30);
DECLARE Str2      VARCHAR(30);

DECLARE StrLength  INTEGER;
DECLARE ZeroPad    INTEGER;
DECLARE DecimalPos INTEGER;

DECLARE i INTEGER;
DECLARE j INTEGER;

SET Separator = ',';
SET Str1      = '';
SET Str2      = '';
SET ZeroPad   = 0;

CASE DECIMALS
  WHEN 0 THEN SET Value = ROUND(Value to 0);
  WHEN 1 THEN SET Value = ROUND(Value to 1);
  WHEN 2 THEN SET Value = ROUND(Value to 2);
  WHEN 3 THEN SET Value = ROUND(Value to 3);
  WHEN 4 THEN SET Value = ROUND(Value to 4);
  ELSE
    BEGIN
      SET Value = ROUND(Value to 2);
      SET Decimals = 2;
    END;
END CASE;
SET Str1 = CAST(Value as VARCHAR);

----------------------------------------------------------------
ProcessZeroDecimals:
----------------------------------------------------------------
BEGIN
  -- Exit if Decimals parameter is other than 0 (zero)
  IF DECIMALS <> 0 THEN LEAVE ProcessZeroDecimals; END IF;
  -- Perform if Decimals parameter is equal to 0 (zero)
  SET StrLength = LENGTH(Str1);
  SET Str2 = '';
  SET i = 0;
  SET j = StrLength;
  WHILE j > 0 DO
    SET Str2 = SUBSTRING(Str1, j for 1) + Str2;
    SET i = i + 1;
    SET j = j - 1;
    IF (i MOD 3 = 0) AND (j > 0) THEN
      SET Str2 = Separator + Str2;
    END IF;
  END WHILE;
----------------------------------------------------------------
END;--ProcessZeroDecimals:
----------------------------------------------------------------

----------------------------------------------------------------
ProcessNonZeroDecimals:
----------------------------------------------------------------
BEGIN
  -- Exit if Decimals parameter is equal to 0 (zero)
  IF DECIMALS = 0 THEN LEAVE ProcessNonZeroDecimals; END IF;
  -- Perform if Decimals parameter is other than 0 (zero)
  SET DecimalPos = POSITION('.' IN Str1);
  IF DecimalPos = 0 then
    CASE Decimals
      WHEN 1 THEN SET Str1 = Str1 + '.0';
      WHEN 2 THEN SET Str1 = Str1 + '.00';
      WHEN 3 THEN SET Str1 = Str1 + '.000';
      WHEN 4 THEN SET Str1 = Str1 + '.00000';
    END Case;
  END IF;
  SET StrLength = LENGTH(Str1);
  SET DecimalPos = POSITION('.' IN Str1);
  SET ZeroPad = Decimals - (StrLength - DecimalPos);
  SET Str2 = SUBSTRING(Str1, DecimalPos for Decimals+1);
  SET i = 0;
  SET j = DecimalPos -1;
  WHILE j > 0 DO
    SET Str2 = SUBSTRING(Str1, j for 1) + Str2;
    SET i = i + 1;
    SET j = j - 1;
    IF (i MOD 3 = 0) AND (j > 0) THEN
      SET Str2 = Separator + Str2;
    END IF;
  END WHILE;
  CASE ZeroPad
    WHEN 1 THEN SET Str2 = Str2 + '0';
    WHEN 2 THEN SET Str2 = Str2 + '00';
    WHEN 3 THEN SET Str2 = Str2 + '000';
    WHEN 4 THEN SET Str2 = Str2 + '0000';
  END CASE;
----------------------------------------------------------------
END; --ProcessNonZeroDecimals:
----------------------------------------------------------------

RETURN str2; 

END
VERSION 1.00!
Here is the fFormatThousands function at work against the DBDemos database.
SELECT
 OrderNo
,CustNo
,fFormatThousands(ItemsTotal,2) as "Items Total"
,fFormatThousands(AmountPaid,2) as "Amount Paid"
,fFormatThousands(ItemsTotal - AmountPaid,2) as "Balance Due"
FROM orders
ORDER BY
ItemsTotal - AmountPaid DESC;

 
Semper Fi,
Gunny Mike
end.

Tuesday, July 23, 2013

David I to Discuss Mobile & Mac at the 2013 ISVCon

The 2013 Independent Software Vendor Conference (ISVCon), scheduled for September 27-29, 2013 at the Atlantis Casino Resort in Reno, Nevada, has released information about the panel discussions and seminars that will be presented. Designed to deliver the latest marketing ideas to small software development firms, this year’s conference includes:
  • “Sell Software on Facebook” by Nico Westerdale of BitsDuJour – Can independent software vendors (ISVs) make money selling software on Facebook? Yes. More than half of the people in the US have Facebook accounts. Learn practical ways to build your fanbase, and create posts that generate traffic.
  • “Conversations to Create More Customers” by Jessica Dewell of Red Direction – Move more software customers through your company’s sales cycle by changing from reactive conversations (such as answering email inquiries) to proactive conversations (such as listening and starting conversations.)
  • “Growing your ISV business to Multi-Device with Mobile and Mac” by David Interstimone (David I) of Embarcadero – Discover how to increase software sales by supporting a mix of client devices, UI approaches, OS versions, and emerging form factors.
  • “Connected Apps: The New Normal” by Leyla Seka of Salesforce.com – Learn to build and deploy connected apps as your software development business evolves from the desktop/laptop world to the cloud and mobile environments.
  • “33 High Tech Business Myths, and How They Can Hurt Your Company” by Gary Elfring of Elfring Fonts Inc. – Gain insights into distinguishing between valid business ideas and the myths, folklore, and misinformation that can hurt your company.
  • “Google AdWords – Winning the War and Making It Work” by Aaron Weiner of Software Promotions – Learn how recent AdWords changes will impact your account’s performance, and how you can overcome any problems.
Other seminar titles include:
  • Practical Roadmap to High Performing Websites
  • Secondary Offer Networks
  • The Cloud for ISVs
  • Avoiding Problems When Hiring and Working with Freelancers
Visit http://www.isvcon.org/speakers.php to read about new seminars that will be added during the summer.

Sign up for the conference by September 22 to take advantage of ISVCon’s $820.50(US) registration fee. Registration includes three days of intense education and networking opportunities plus a Thursday evening reception, and break rooms full of snacks and helpful representatives from the conference’s sponsors.

Previously known as the Software Industry Conference (SIC), ISVCon carries on a 22 year tradition of supporting independent software developers’ business and marketing efforts with seminars, presentations, and networking opportunities.

ISVCon is owned and presented by The Association of Software Professionals. Sponsors for ISVCon 2013 include FastSpring, Avangate, Tightrope Interactive, Software Promotions, Greentram Software, and The Association of Software Professionals. Visit http://www.isvcon.org/ for more information about attending ISVCon 2013. Or visit http://www.isvcon.org/sponsors.php for information about sponsoring the conference.

Semper Fi
Gunny Mike
end.

Saturday, July 20, 2013

Complete List of Delphi Code Examples From Docwiki

Update 2023-02-28: Embarcadero has updated their docwick to be more user friendly when it comes to Delphi code examples. Here is a link to all the Delphi 11 code examples;

I was looking through the list of code examples from the Embarcadero Docwiki site and I was a little frustrated because they are broken up by Delphi versions. I was thinking it would be nice to have one complete list of all the code examples in one place. So, I put together a complete list of Delphi Example code links.

Enjoy!

Code ExampleVersion
ActiveControl2010
ActivePage2010
ActnMgrBar2010
AddChildObjectFirst2010
ADOQuery2010
AdvancedCharacterControl2010
AdvancedTCharacterControl2010
AfterEdit2010
AfterInsert2010
AfterOpen2010
AfterPost2010
AllowGrayed2010
AppendRecord2010
AppModalForms2010
ArrangeIcons2010
AssertErrorProc2010
AutomaticReferenceCountingXE4
AutoPopup2010
AutoSize2010
BeforeDisconnect2010
BeforeGetRecords2010
BeforePost2010
BeginUpdate2010
BevelInner2010
BinHexMethods2010
BlockRead2010
BorderIcons2010
BoundsXE3
BoundsRect2010
BringToFront2010
BrushCopy2010
ButtonControlChecked2010
BytesOf2010
CalendarXE
Cascade2010
CenterPointXE3
CharacterCasing2010
CharacterSurrogates2010
CharacterTypes2010
Chat Room SocketXE2
ChDir2010
CheckListBoxCheckAll2010
ClassesGetClass2010
ClassParent2010
ClientDataSet2010
ClientDataSetAddIndex2010
ClientDataSetMoveBy2010
ClientHeight2010
ClientWndProcXE
ClipboardAssign2010
ClipRect2010
ColorGridXE2
ColorToRGB2010
CommandText2010
CompareStr2010
CompConversion2010
CompilerVersion2010
ComponentCountProperty2010
ComponentToString2010
ControlMargins2010
ControlsGetShortHint2010
ControlsTDragState2010
CopyMode2010
CopyToClipboard2010
CreateDataSet2010
CreateFormInPackageXE2
CreateFromBitmapAndMaskXE2
CreateFromStreamXE2
CropForms2010
CustomForms2010
CustomSort2010
CutToClipboard2010
DateTime2010
DateTimeCompare2010
DateTimeGen2010
DateTimeInfo2010
DateTimeRecode2010
DateTimeToStr2010
DateToStr2010
DateUtils2010
DayOfWeek2010
DBBitType2010
DBImage2010
DecodeDate2010
DefAttributes2010
DefaultHandlerXE
DelayedLoading2010
DialogHandle2010
DirectoriesAndFilesEnumeraion2010
DirectoryExists2010
DirectoryOperations2010
DirList2010
DirListBoxDrive2010
DirListBoxUpdate2010
DisableControls2010
DiskFree2010
Docking2010
DownNumGlyphs and UpNumGlyphsXE
DrawGridCol2010
DrawGridSelection2010
DrawGridTopRow2010
DSProxyGeneratorXE
DTStartEnd2010
DTTransform2010
DTTry2010
DTValid2010
DynamicLinkLibXE
EditMask2010
EditText2010
EncodeDate2010
EncodeTime2010
EqualRectXE3
Event RTTI InvocationXE2
ExceptionHandling2010
ExeName2010
ExpandFileName2010
ExtractFileName2010
FetchParams2010
FetchPooler2010
FileAttributes2010
FileExists2010
FileGetAttr2010
FileListBox2010
FileListBoxIndexOf2010
FileOpen2010
FileOperations2010
FileRead2010
FileSearch2010
FileSelectBtnEdit2010
FileToGrid2010
FilterComboBoxFilter2010
FilterIndex2010
FindComponent1XE2
FindComponent2010
FindField2010
FindFirst2010
FindKeyXE
FindText2010
FirstIndent2010
FishFacts2010
Float Type HelpersXE4
FloodFill2010
FlowPanels2010
FMX.AlphaColorToPixelXE3
FMX.AlphaColorToScanlineXE3
FMX.DelphiLocationDemo SampleXE4
FMX.FindClosestPixelFormatXE3
FMX.Float4ToPixelXE3
FMX.TMeshXE3
FMXAttachTAnimationXE2
FMXEmbeddedFormXE2
FMXGradientXE2
FMXGradientPointXE2
FMXInteractiveGesturesXE3
FMXPrintingXE2
FMXTBitmapCanvasXE2
FMXTBitmapClearXE2
FMXTBitmapManipulationFunctionsXE2
FMXTBitmapPixelsXE2
FMXTBitmapScanLineXE2
FMXTBitmapStartLineXE2
FMXTBrushXE2
FMXTCanvasDrawArcXE2
FMXTCanvasDrawFunctionsXE2
FMXTCanvasFillFunctionsXE2
FMXTCanvasSaveCanvasXE2
FMXTCustomButtonRepeatClickXE2
FMXTFmxObjectAnimateColorXE2
FMXTFmxObjectAnimateFloatXE2
FMXTFontXE2
FMXTimerAnimationXE2
FMXTLangXE2
FMXTMemoLinesPropertyXE2
FMXTMemoSelTextPropertyXE2
FMXTOpenDialogXE3
FMXTPopupMenuXE2
FMXTStringGridBackgroundColorXE2
FMXTStyleManagerXE2
FontDialogOnApply2010
ForceDirectories2010
FormatCount2010
FormatDateTime2010
FormatFloat2010
FormCount2010
FormStyle2010
FrameRect2010
Generics Collections TArrayXE4
Generics Collections TDictionaryXE4
Generics Collections TListXE4
Generics Collections TObjectListXE4
Generics Collections TObjectQueueXE4
Generics Collections TObjectStackXE4
Generics Collections TQueueXE4
Generics Collections TStackXE4
Generics Defaults TComparerXE4
Generics Defaults TCustomComparerXE4
Generics Defaults TDelegatedComparerXE4
Generics Defaults TDelegatedEqualityComparerXE4
Generics Defaults TEqualityComparerXE4
GenericsTList2010
GetAliasNames2010
GetAsHandle2010
GetBookmark2010
GetCharsetValues2010
GetComponent2010
GetDeviceContext2010
GetFormImage2010
GetHitTestInfoAt2010
GetImplementedInterfacesXE2
GetItemPath2010
GetModuleName2010
GetNextItem2010
GetPrevChild2010
GetStaticRect2010
GetTextBuf2010
Getting RTTI for Rooted Types2010
GridLineWidth2010
GuidToString2010
HandleMessageExample2010
HasFormat2010
HeaderControlSection2010
HeaderSection2010
HexEncoding2010
HideForTime2010
HideScrollBars2010
HideSelection2010
HotKey2010
HTTP GetXE2
ImageListGetBitmap2010
IMouseStartPan2010
IndexName2010
IndexOfName2010
InflateRectXE3
IniFilesTMemIniFile2010
InputBox2010
InputQuery2010
InsertControlXE
InsertObject2010
InsertRecord2010
Integer Type HelpersXE4
IntersectRectXE3
IntToHex2010
IntToStr2010
IOUtilsFileAttr2010
IsLeapYear2010
ItemRect2010
KeyPreviewProperty2010
LabeledEdit2010
LastOSError2010
LineTo2010
ListGroups2010
LoadFromClipBoard2010
LoadFromFile2010
LoadFromResourceName2010
LoadFromStream2010
LowerCase2010
MatchesMask2010
MaxFontSize2010
MDIChildren2010
MediaPlayer2010
MemMgr2010
MessageBox2010
MessageDlg2010
MessageDlgConfirmationXE2
MessageDlgInformationXE2
MessageDlgPos2010
Messages2010
MinimizeExample2010
MinPointXE3
MultiplyRectXE3
NamedThread2010
ObjectInvokeXE
ObjectsXE
OffsetXE3
OnActionExecute2010
OnActionUpdate2010
OnActivate22010
OnActivate2010
OnActiveControlChange2010
OnActiveFormChange2010
OnCloseQuery2010
OnDock2010
OnDragOver2010
OnDrawCell2010
OnDrawItem2010
OnDrawPanel2010
OnDropDown2010
OnEndDrag2010
OnException2010
OnExit2010
OnGestureXE
OnGetEditMask2010
OnGetEditText2010
OnHelp2010
OnHint2010
OnKeyDown2010
OnKeyPress2010
OnMessage2010
OnMouseMove2010
OnMoved2010
OnPaint2010
OnPopup2010
OnResize2010
OnResizeRequest2010
OnRowMoved2010
OnScroll2010
OnSelectCell2010
OnSelectionChange2010
OnSetTextXE
OnSettingChange2010
OnShortCut2010
OnShowHint2010
OpenStringXE
OpOverloads2XE
OpOverloadsXE
PageControlChange2010
PageControlChanging2010
PageControlPages2010
PageSize2010
ParamCount2010
PathOperations2010
Pixels2010
PlainTextProperty2010
Polygon2010
Polyline2010
PooledRDMUpdateRegistry2010
PopulateTabSheets2010
PopupMenu2010
PrinterAborted2010
PrinterOrientation2010
PrinterPageNumber2010
PrinterPageWidth2010
PrintExample2010
PrintToFile2010
PrintVarType2010
ProcessMessages2010
ProgressBarPosition2010
ProviderBeforeGetRecords2010
PtInCircleXE3
PtInRectXE3
RadioGroupItems2010
RandG2010
RandGXE2
ReadComponentResFile2010
ReadWriteFile2010
RecordCount2010
Rectangle2010
RegisterComponents2010
ReplaceText2010
RichEditFont2010
RotatedFont2010
RoundRect2010
Rtti.TRttiTypeXE2
Rtti.TVirtualInterfaceXE2
RTTIFormNameCaption2010
RuntimeErrors2010
SavePictureDialog2010
SaveToFile2010
ScanLine2010
ScrollBarIncrement2010
ScrollBarMargin2010
SelectDirectory2010
SelStart2010
SelText2010
Set8087CW2010
SetEnumProp2010
SetIncludeExclude2010
SetRoundModeXE2
SetSelTextBuf2010
SetTextBuf2010
ShortCut2010
ShortCutToKey2010
ShortCutToText2010
ShortDateFormatEdit2010
ShortStringToStringXE4
ShowAccelChar2010
ShowCaption2010
ShowException2010
ShowHint2010
ShowModal22010
ShowModal2010
SimplePanelProperty2010
SleepSortXE2
Splitter2010
StdCtrlsProp2010
StrCat2010
StrComp2010
StrDispose2010
StreamAdvancedRdWr2010
StreamCharRdWr2010
StreamStrRdWr2010
StrECopy2010
StringGridColCount2010
StringGridMouseToCell2010
StringGridRows2010
StringReadWrite2010
SubClassWndProc2010
SubItemsEnabled2010
SuggestEdit2010
Synchronize2010
System InitializeFinalize2010
System Ptr2010
System ReallocMem2010
SystemAbs2010
SystemAddr2010
SystemAppend2010
SystemArcTan2010
SystemAssert2010
SystemAssigned2010
SystemConcat2010
SystemCos2010
SystemDelete2010
SystemEof2010
SystemEoln2010
SystemExit2010
SystemExp2010
SystemFileSize2010
SystemFillChar2010
SystemFrac2010
SystemFreeMem2010
SystemGetDir2010
SystemHalt2010
SystemHi2010
SystemInc2010
SystemInsert2010
SystemInt2010
SystemIOResult2010
SystemLo2010
SystemLow2010
SystemMkDir2010
SystemMove2010
SystemOdd2010
SystemOrd2010
SystemPos2010
SystemPred2010
SystemReadln2010
SystemRename2010
SystemReset2010
SystemRewrite2010
SystemRmDir2010
SystemRound2010
SystemRunError2010
SystemSeekEof2010
SystemSeekEoln2010
SystemSin2010
SystemSizeOf2010
SystemSqrt2010
SystemStr2010
SystemStrEnd2010
SystemStrIComp2010
SystemStrLCat2010
SystemStrLComp2010
SystemStrLCopy2010
SystemStrLIComp2010
SystemSwap2010
SystemTimeToDateTime2010
SystemTrunc2010
SystemTruncate2010
SystemVal2010
SystemVarClear2010
SysUtilsByteLength2010
SysUtilsFileGetSetDate2010
SysUtilsFormat2010
SysUtilsFormatFloat2010
SysUtilsStrLower2010
SysUtilsStrMove2010
SysUtilsStrPCopy2010
SysUtilsStrPos2010
SysUtilsStrRScan2010
SysUtilsStrScan2010
SysUtilsStrToFloat2010
SysUtilsStrToInt2010
SysUtilsStrToIntDef2010
SysUtilsStrToTime2010
SysUtilsTimeToStr2010
TabControlChange2010
TabSheetCaption2010
TabSheetPageControl2010
TabVisible2010
TActionOnExecute2010
TActionOnUpdate2010
TAlignment2010
TAnimateActive2010
TAppCreateForm2010
TAppEventsOnHint2010
TAppEventsOnIdle2010
TAppEventsOnMessage2010
TAppEventsOnMinimize2010
TAppEventsOnRestore2010
TApplicationIcon2010
TApplicationOnHelp2010
TApplicationRestore2010
TApplicationTitle2010
TaskDialogs2010
TBaseItemEditText2010
TBinaryReader and TBinaryWriterXE
TBitBtnCopyImageXE
TBitBtnKindXE
TBitBtnLayoutXE
TBitsOpenBit2010
TButtonedEdit2010
TCanvasAngleArcXE
TCanvasArc2010
TCanvasArcToXE
TCanvasChord2010
TCharacterCasing2010
TCharacterSurrogates2010
TCharacterTypes2010
TComboBox2010
TComboBoxCanvas2010
TComboBoxEx2010
TComboBoxSelLength2010
TControlAlign2010
TControlColor2010
TControlCursor2010
TControlParent2010
TControlPerform2010
TControlTop2010
TCoolBarBands2010
TCountdownEvent2010
TCountdownEventXE
TCustomConnectionDataSets2010
TCustomEditAutoSize2010
TCustomFormCanvas2010
TCustomFormIcon2010
TCustomFormMenu2010
TCustomMemoLines2010
TDataSetActive2010
TDataSetAfterCancel2010
TDataSetAfterDelete2010
TDataSetAppend2010
TDataSetBeforeInsert2010
TDataSetCancel2010
TDataSetRefresh2010
TDirectoryExists2010
TEncoding2010
TextFloatMethods2010
TFieldFieldName2010
TFieldGetData2010
TFindDialogOptions2010
TFontQualityXE
TFontStyle2010
TFormAction2010
TFormCanvas2010
TFormOnClose2010
TFormOnDestroy2010
TFormOnHide2010
TFormOnPaint2010
TGraphic2010
TGridXE3
ThreadSynchronize2010
TIconAssignTo2010
TileMode2010
TImageCanvas2010
TimeSpanAddSubtract2010
TJPEGImageAssign2010
TLabelCanvas2010
TLightweightEvent2010
TLightweightEventXE
TLightweightSemaphore2010
TLightweightSemaphoreXE
TListAdd2010
TListBoxCanvas2010
TListBoxSorted2010
TListIndexOf2010
TListItemsInsert2010
TListItemSubItems2010
TListLast2010
TListPack2010
TListRemove2010
TListSort2010
TListViewCanvas2010
TListViewOnColumnClick2010
TMatchCollectionCountXE
TMediaPlayerEject2010
TMenuItemInsert2010
TMenuItems2010
TMetafileCreate2010
TMouse2010
TMutexAcquireXE
TObjectDispatch2010
TObjectDispatchInvokeXE
TOleContainer2010
TOpenDialogFileName2010
TOpenDialogTitle2010
TOpenTextFileDialog2010
TopIndex2010
TOutlineNode2010
TPageControlCanvas2010
TParamsAssign2010
TParamsItems2010
TPerlRegExComputeReplacementXE
TPerlRegExEscapeRegExCharsXE
TPerlRegExGroupsXE
TPerlRegExMatchAgainXE
TPerlRegExMatchedLengthXE
TPerlRegExMatchedOffsetXE
TPerlRegExMatchedTextXE
TPerlRegExNamedGroupXE
TPerlRegExOnReplaceXE
TPerlRegExReplaceXE
TPerlRegExReplacementXE
TPerlRegExStartXE
TPerlRegExStateXE
TPerlRegExStoreGroupsXE
TPerlRegExStudyXE
TPerlRegExSubjectXE
TPictureGraphic2010
TPoint3DCrossProductXE3
TPoint3DDotProductXE3
TPointXE3
TPointFXE3
TProgressBarStepIt2010
TransparentColor2010
TReaderXE4
TRectBottomRightXE3
TRectContainsXE3
TRectEmptyXE3
TRectHeightXE3
TreeNodeAddChildObject2010
TreeNodeCustomSort2010
TreeNodesAddObject2010
TreeViewAddChild2010
TreeViewToListBox2010
TRegExReplaceXE
TRegistry2010
TRttiRecordTypeXE2
TrySystemTimeToDateTimeXE
TSaveTextFileDialog2010
TScreenCursor2010
TSendMailXE2
TSmallPointXE3
TSpinWait2010
TSpinWaitXE
TStatusBarCanvas2010
TStreamReadBuffer2010
TStringBuilderClickCount2010
TStringGridCanvas2010
TStringListAdd2010
TStringListSorted2010
TStringsAssign2010
TStringsEncodingXE
TStringsMove2010
TTable.EmptyTableXE
TTabSheetPageControl2010
TTcpClientSendStream2010
TTcpServer2010
TThreadList2010
TThreadPriority2010
TThreadYieldXE
TTimerFWindowHandle2010
TToolBarCanvas2010
TToolButtonCreate2010
TTrayIcon2010
TTreeCustomSort2010
TTreeGetNodeAt2010
TTreeNodesDelete2010
TTreeSelected2010
TTreeViewCanvas2010
TUpDownOnClick2010
TValueCast2010
TVCustomDraw2010
TVCustomDrawItem2010
TVector3DAddScaleXE3
TVector3DAddVector3DXE3
TVector3DCalcPlaneNormalXE3
TVector3DCrossProductXE3
TVector3DDistanceXE3
TVector3DDotProductXE3
TVector3DLengthXE3
TVector3DNormalizeXE3
TVector3DPointProjectXE3
TVector3DReflectXE3
TVector3DScaleXE3
TVectorDotProductXE3
TVectorLengthXE3
TVectorReflectXE3
TVGetImageIndex2010
TVirtualMethodInterceptorXE
TWinControlHandle2010
TWriterXE4
TXMLDocument use case2010
TXMLDocument xml declaration2010
TXMLDocumentAddChild2010
TXMLDocumentAsyncLoadState2010
TXMLDocumentChildNodes2010
TXMLDocumentCreateElement2010
TXMLDocumentCreateNode2010
TXMLDocumentDOMDocument2010
TXMLDocumentDOMVendor2010
TXMLDocumentGeneratePrefix2010
TXMLDocumentGetDocBinding2010
TXMLDocumentIsEmptyDoc2010
TXMLDocumentLoadFromFile2010
TXMLDocumentLoadFromStream2010
TXMLDocumentLoadFromXML2010
TXMLDocumentNode2010
TXMLDocumentNodeIndentStr2010
TXMLDocumentParseOptions2010
TXMLDocumentRefresh2010
TXMLDocumentRegisterDocBinding2010
TXMLDocumentResync2010
TXMLDocumentSaveToFile2010
TXMLDocumentSaveToStream2010
TXMLDocumentSaveToXML2010
TypInfoGetEnumName2010
UnDock2010
UnicodeConversion2010
UnionRectXE3
UpCase2010
UpperCase2010
UsingDialogs2010
UsingGUIDs2010
UsingPictureDialogs2010
VariantArrayLockUnlock2010
VariantArrays2010
VariantStrings2010
VariantsVarToDateTime2010
VCL.TMouseEventXE3
VertScrollBar2010
ViewStyleProperty2010
WizardInterfaceXE
ZLibCompressDecompress2010

Semper Fi,
Gunny Mike
zilchworks.com