Monday, September 16, 2013

Developing Android apps with Delphi XE5 on an ancient Nook Color

With this release I thought I would play around with some of the new android support available. Of course its much more fun if you have a device to play around with, but I wasn't about to run out and get one since I already have an IPad that I switched to after almost two years with my nook color. Which got me thinking, the nook color runs android...so would it be a viable option for development? The answer is yes! Well in a way.

Exploring the forums at xda-dev found that I could boot 4.3.x jellybean on my nook using the SD expansion card. So I figured, what can I loose? So I spent a few hours installing my nook and figuring out the magic trick for enabling developer mode (go to about and click the build number several times...eventually it will tell you 3 more taps away from enabling developer mode..keep tapping).

Once this was done and the developer mode enabled, I hooked it up via USB cable and it showed up in the IDE as a viable target. I grabbed the 3d firemonkey demo and compiled it to the device and it ran flawlessly. Of course the nook color doesn't have a camera, or some other hardware, but for general GUI or 3d programs, it appears to run very well in this mode.

One thing I haven't yet been able to do is get a program running in debug mode, it always times out (even with a simple hello world app), but so far it runs well with everything else I have thrown at it. I really enjoy the easier path to deployment from my laptop (windows). It really is easy.

Thursday, October 04, 2012

TypeScript brings types to Javascript

One of the things that I generally get frustrated with when I have to code in Javascript is the lack of safety that strongly typed languages such as Delphi bring to the table. Most of the tools, while they offer basic language helpers, do not do much about the structure of your javascript application. There is no "code insight" for Javascript function parameters...at least not for MY code.

One of the latest offerings from Microsoft, as presented by Anders Hejlsberg, is TypeScript. It appears to me that TypeScript is a game changer in the world of Javascript development.

TypeScript is an extension to Javascript. Everything you can do in Javascript, you can also do in TypeScript. TypeScript "compiles" to Javascript, so there is no special plugins that need to be deployed. Its all about adding the missing "type" and providing code gen helpers to make your code cleaner and easier to understand. Its all about adding that little bit more information that will make your (Javascript) applications much easier to maintain.

Looking over what TypeScript does, it makes sense. Its simple enough that it shouldn't take long to learn to apply.

If you do any Javascript development, take a look at TypeScript.

Wednesday, September 05, 2012

Metro Icons for Delphi XE3

In playing around with Delphi XE3 and the new Metro UI wizards, I found I needed a few icons to explore with. After a little searching, I discovered a gem in the free utility MetroStudio.

This application allows you to quickly create Metro-ized icons from either a collection of over 1400 symbols, or even a symbol from a font installed on your machine.
For example, the lightning bolt can be used as a tile:
or as a tool bar image:
Execute


I haven't gotten that far into it yet, but another thing I find missing for the FireMonkey version that appears to be an oversight is the lack of a flow layout panel that flows from top to bottom, left to right. The default flow layout panel flows left to right or right to left. Unfortunately this makes laying out a metro style application a manual process, and doesn't easily allow for the addition of dynamic content which would flow appropriately based on screen dimensions.

Friday, October 15, 2010

Delphi Tip : Avoiding Project101

It is inevitable. In my hurry to test something I created yet another console application and started entering some code. Funny thing how the project numbers keep mounting, and I have no recollection what any of these small test applications do since every default project goes into the same directory.

The solution turned out to be quite simple. Remove the WRITE access to the default project directory for my development user account. Now when I go to save, I am presented by the following dialog:



This gives me one last warning that the project doesn't yet have a home...I can now decide where to place it and what it will be called. Actually, I can't even RUN the application until it has a home...

Granted this means that there will probably be another directory with a hundred ProjectN programs... but I'll know I put them there on purpose.

Friday, December 19, 2008

Delphi Wizard Framework - SetAllowDeletion

In my previous posts about my wizard framework, I discussed some of the original design decisions, as well as how to perform simple forward navigation.

The Delphi Wizard Framework is currently being hosted by google code hosting, which I briefly reviewed in a previous post.

One of the problems that I ran into quickly after starting this system was the issue of displaying a wizard form that doesn't allow user input but is there to show the user that something is being performed, to please wait patiently. The wizard framework as it navigates from one form to another automatically adds the last form displayed to the deleted queue and sends itself a message which will free all the forms in the queue. This works great and performing cleanup, but can cause access violations if someone wants to do something like the following:

begin
fWizMgr.NavigateToPage('TStatuspage');
if not Supports(fWizMgr.CurrForm,IWizPerformStatus,StatusForm) then
raise Exception.Create('form does not support IWizPerformStatus');
for ix := 0 to 100 do
begin
StatusForm.DoWork(ix);
StatusForm.ShowProgress(ix);
Application.ProcessMessages;
end;
fWizMgr.NavigateToPage('TResultspage',false);
end;

Now the intentions here are good, but the second the ProcessMessages is handled by the system the form which is executing this code is going to be freed, which will ultimately generate an exception. The solution to this is to use the framework method SetAllowDeletion to delay the deletion of the current form until later. Using it the correct method of the above routine should look like the following:

begin
fWizMgr.SetAllowDeletion(false);
try
fWizMgr.NavigateToPage('TStatuspage');
if not Supports(fWizMgr.CurrForm,IWizPerformStatus,StatusForm) then
raise Exception.Create('form does not support IWizPerformStatus');
for ix := 0 to 100 do
begin
StatusForm.DoWork(ix);
StatusForm.ShowProgress(ix);
Application.ProcessMessages;
end;
fWizMgr.NavigateToPage('TResultspage',false);
finally
fWizMgr.SetAllowDeletion(True);
end;
end;

Sunday, December 14, 2008

The Delphi Wizard Framework - Navigation

In a previous entry, I discussed some of the design decisions that allowed me to reach the current solution. One more decision which greatly impacted the design of the framework... I wanted to make sure that it could be data driven.

One of the projects that I was working on at the time was an editor for an XML datafile. For simplicity sake, the file had a structure something like the following:

<data>
<book>
<author>
<name>Steven King</name>
</author>
</book>
<movie>
<director>
<name>Stanley Kubrick</name>
</director>
</movie>
</data>

The goal of the program was to create an editor that could handle each child element. I created two forms, one named tBookWizardForm and another named tMovieWizardForm. Invoking these pages from the first page of the wizard looked something like the following:

procedure EditChild(ChildNode:IXmlNode);
var
NodeAware : IXmlNodeAware;
begin
fWizMgr.NavigateToPage('T'+ChildNode.NodeName+'WizardForm');
if Supports(fWizMgr.CurForm,IXmlNodeAware,NodeAware) then
NodeAware.SetXmlNode(ChildNode);
end;

Note in this example: The call to NavigateToPage automatically inserts the current page into the "to be deleted" list so there is no need to perform any manual cleanup.

The interface IXmlNodeAware actually exists in another unit which is shared by both wizard forms, it looks like the following:

type
IXmlNodeAware = interface
['{F78DF157-CBAF-48A3-BC4C-CE338514C898}']
Procedure SetXmlNode(Node:IXmlNode);
end

This would automatically perform the dispatch to the proper wizard form, if it ran into a node which it did not understand, it would generate an exception which would be handled and displayed by the wizard manager (displays a dialog that states that the requested form was not registered).

In my next post, I will cover SetAllowDeletion, and why one would need to use it.

Wednesday, December 10, 2008

Google Code Hosting -- Painless Open Source Management

Google Code Hosting really makes it simple to host open sourced projects. Especially if you like Subversion. In my few days with it I have tried just about all of the basic features and have found them easy to use and manage. Initial setup was very painless. The only desirable thing that is missing would be some method of adding to an rss/atom feed. Wait, thats what my blog and twitter are for.

The Delphi Wizard Framework - Design Decisions

The Delphi Wizard Framework, as I introduced in the previous post, was originally designed to replace a complex configuration system which was put together using a TNotebook component (yes, from the Delphi 1 days) on a single form. The first problem this faced was adding pages was more complex than it needed to be. The second problem was re-using entire pages in another project became a copy and paste fest, with plenty of room for missing a critical event.

My first goal was to take each page out of the single form, and create a form of its own that contains all of the logic just for that page. This worked very well, but I still had the problem where each form had to be added to the uses clause, and a circular reference back to the main containing form didn't feel right. Taking my research into using interfaces outside of COM, I developed a simple interface for the "FormManager" and another for the "FormPage", named IWizardManager and IWizardPage respectfully. When each page is displayed, the formmanager would pass forward its reference and the page would record this for later use.

With that out of the way, I then turned to how to let the system know about each form. I decided that the best way to address that problem would be to use the class registry system already existing in Delphi and call RegisterClass(classname) for each form that will be used. This cuts back on the need to add each unit to the uses clause and makes reuse almost as simple as adding the form to the project. I say almost, as the default behavior of Delphi when a form is added to the project is to auto-create it...this is not necessary with the framework as the framework will be responsible for the creation and deletion of each form.

In my next post, I will discuss form navigation.

Sunday, December 07, 2008

Introducing the Delphi Wizard Framework

I just posted my latest version of my wizard framework to http://code.google.com/p/delphiwizardframework/.  

This is some general purpose code that I have found myself using in many of my projects, as most of them at some point involve the need to step a user through many different "wizard" screens.  The concept behind it is quite simple, rather than code the button clicks on each form, instead use a container to hold the form which contains the buttons.  Each "wizard page" is a separate form, and can be invoked by the classname rather than a specific class.  This allows for the wizard to be data driven, and the loose binding into the project allows for easy reuse of wizard pages in other wizards.

For those who have used my tFrameManager component in Delphi 5, will see a few simularities.

Over the next few weeks, I'll be posting further instructions on how to put the system into action, along with some advanced tricks which are not currently evident in the sample project.

Wednesday, October 08, 2008

Fun with Generics.collections

I guess the best way to learn about new language features are to put them in practice, and with that I jumped into using the TDictionary to keep track of some xml nodes I was editing.  It was very easy to implement, but what got me stumped was then how to iterate thru the entire list and apply changes to all of the nodes at once.

Thats when I recalled the new for ... in ... syntax.  Using it was dirt simple.  Since my collection was created as tDictionary all I had to do was create a new variable of tPair and then use the for..in.. syntax to invoke a body of code against every IXmlNode in my tDictionary.


var
aPair : tPair<string,ixmlnode>
begin
for aPair in fDictionary do
aPair.Value.Attributes['dirty'] := '-1';
end;

In my option, this generates code which is much more readable and feels more natural.  Now, on to the next challenge.... finding a place in my project where I can put annoymous methods to practical use.

(EDIT: Updated syntax on variable declaration, as it was incorrect...seems the problem with generics is that they HIDE when copied to HTML.)

Tuesday, September 02, 2008

Google Chrome now available

Download and play with it now. http://tools.google.com/chrome/?hl=en-US

Very small footprint, very fast browser.

First look, browser has much more room compared to IE/Firefox out of the box....although my webmail provider (not Gmail of course) doesn't recognize the browser yet so it doesn't give me the rich experience I'm used too.

Sunday, October 21, 2007

Sychronizing source code directories

One of the big problems I have faced by using Vista Ultimate on my primary development machines as a host OS for virtual PC development environments has been the fact that Vista Ultimate (and I am assuming other versions of Vista as well) have problems copying extremely large files. It was part of this frustration that led us to develop AngeliaSync, a folder synchronization utility which does an excellent job of maintaining synchronized folders.

If you are looking for an inexpensive and easy to use backup utility, why not give AngeliaSync a try?

http://www.kamradtandhill.com/angeliasync.asp

Tuesday, August 22, 2006

Avoiding circular refrences

Sometimes its the simple things that make it all worth while. As I once again took out my fork and began to separate out a huge pile of spaghetti code that was left for me, I needed to come up with a better method to avoid the circular reference trap. I had several units which contained classes which were directly referencing the main form. The circular reference here was troubling me as if I needed to pull one of the units out for another project, the entire application would go along with it.

My solution turned out to be quite simple. I created a new interface unit which contained nothing more than a set of interfaces:

unit MyProgram_Intf;
interface
// ---------------------------
type
iMainGui = interface
['{3D8EC075-0A0D-438E-9BCD-9BDDE10112E8}']
procedure SetStatus(sStatusMsg:String;iProgress:Integer);
end;

iMyModule = interface
['{A6A09A36-C4F2-4E2E-B231-B51A948FE4D4}']
procedure SetMainGui(pMainGui:iMainGui);
function PerformTask : boolean;
end;
//----------------------------
implementation
end.

After saving this unit and adding it to my main form and my child forms, I then changed each child form unit to something like:

tModuleOne = class(tForm,iMyModule)
private
fMainGui : iMainGui;
procedure SetMainGui(pMainGui:iMainGui);
function PerformTask:boolean;
end;

The implementation of SetMainGui is very simple:

procedure tModuleOne.SetMainGui(pMainGui:iMainGui);
begin
fMainGui := pMainGui;
end;

After adding the implmentation for each of these two methods, I added the following code to the initialization section of the unit (replacing tModuleOne with the name of the form class for this unit):

initialization
register(tModuleOne);
end.

Next I removed each one of the units from the main form to force myself to only use the interface. I implemented the SetStatus routine in the main form. The only thing left was the method to invoke each item. I ended up with the following:

function tMainForm.InvokeTask(sTaskname:String):boolean;
var
fTaskClass : TCustomFormClass;
fTask : tCustomForm;
fModule : iMyModule;
begin
Result := false;
try
fTaskClass := tCustomFormClass(FindClass(sTaskname));
except
// an exception here signals the class was not found
exit;
end;
fTask := fTaskClass.Create(nil);
try
if not Supports(fTask,iMyModule,fModule) then
begin
// if we get here then the module
//doesn't support the correct interface
exit;
end;
fModule.SetMainGui(Self);
result := fModule.PerformTask;
finally
fModule := nil;
fTask.Free;
end;
end;


Then, when I needed to call one of the tasks, I just called the InvokeTask method passing it the name of the class I needed to use. No more direct circular refrences, and each unit could easily be picked up and dropped into another project only requiring the unit with the interfaces is brought along also.

Windows Live Writer

This is interesting, the new Windows Live Writer can write to my blogger blog.  It supports multiple blog accounts, and has the ability to upload images. It is still in beta, but definately worth a look.

Good to grant!

Sometimes it helps to have knowledge of life before Google. When attempting to navigate to the Managed VCL pages at http://www.managedvcl.com, I discovered that they were not working properly and I was immediately prompted by some sort of error message in obvious Russian. Not being fluent in that language, I thought I would run it thru the translator at Google... but they don't have a translation option for Russian. Then I remembered my "before Google" days with altavista. So after navigating to http://babelfish.altavista.com I was able to enter the url, locate the appropriate translation option and pressed the go button.

I guess not everything translates well. What I received was the following message:

Good to grant!

The site of the client of hosting- provider HostZilla.ru is temporarily blocked.

Obviously the site is being blocked...the question is for how long and for why? And why is that Google doesn't have a Russian language translator?

Thursday, December 08, 2005

Delphi Co-existence in a .Net 2.0 world

It wasn't very long after the release of the latest Microsoft .net 2.0 framework that applications were getting written to it, and the applications which we deployed using Delphi (and the .net 1.x frameworks) abruptly ceased to function.

The funny thing is that the portion that I had written for .net was a mutant dll file which allowed me to bridge from our legacy win32 application into the ACT! 2005/2006 SDK. Trying to figure out how (using Delphi 8) to limit what version of the framework to use was painful. Since not all of our customers would require the bridge, I needed to find a solution that would work without requiring the presence of any .net framework.

The solution turned out to be very simple. the ".config" file has the ability to limit what version of the framework should be loaded for a specific application. What didn't make sense at first was that I had to name the config file after my primary executable, not the dll file (as I first suspected).

So, with the following scenerio:

  • Project1.exe = delphi 7 application
  • bridge.dll = delphi 8 application

  • I needed to name my .config file project1.exe.config

    The contents of which are below:


    <?xml version="1.0"?>
    <configuration>
     <startup>
      <supportedRuntime version="v1.1.4322"/>
      <supportedRuntime version="v1.0.3705"/>
      <requiredRuntime version="v1.1.4322"/>
     </startup>
    </configuration>


    I have even tested this with other applications which have also failed, and have found it to be a fairly simple solution. Unfortunately it did add another file to manage on my clients computers.