Quantcast
Channel: Planet Object Pascal
Viewing all 1725 articles
Browse latest View live

Delphi Code Monkey: Why Delphi developers should learn Objective-C and XCode

$
0
0
This is an opinion piece with technical sprinkles on top.  I believe strongly that when a developer only knows one language, they tend to see the software development world through blinders. Ask yourself if this sounds like you:

1. If you had to work in an environnment where creating a new visible control on the screen wasn't a TControl, or where you had to add a new window and it wasn't possible to make that window and double click on an event on a component in that window, and then write your code inside there without ever writing a single line of boilerplate code, could you even work? Are you a RAD junkie?

2. Imagine that you had to learn a new set of libraries or frameworks. You've spent a lot of time learning the VCL. Have you ever tried to learn a new framework, whether it's the .NET framework used with the C# language, or the Boost libraries, or QT framework commonly used in cross-platform-C++, or others, like the UIKit which is the flavor of the Cocoa framework that you use to build native iPhone apps.

What happens to your brain when you learn a new framework, library, or language?  New ideas come in. And even if you then go back to doing the usual delphi thing, you might find a little fresh air has come in and disturbed the dusty recesses of your mind, where old, unchallenged ideas await, needing questioning, improvement, and calling for some general review.

Here are some reasons why Objective-C, and XCode 4.5, are worthy of your time:

1.  XCode 4.5 is an extremely nice, extremely powerful IDE with a lot of really good ideas in it, including "Assistant editor panes",  and a really powerful integrated visual GUI building tool which is not just slightly different from what you're used to when you do "RAD" style development in C# or Delphi, it's radically different.   Try to learn what a "first responder" is, and why "delegates", "categories", and "events" are not exactly something you can correlate 1:1 to an existing class, terminology, or practice you already know in Delphi,  because, actually, it really is quite different.   XCode as an IDE is stellar.  new user forgets to put in semicolon? XCode, help that user out! Done.    You forgot the @ sign that goes in front of an NSString literal, making your string literal a classic C string literal?  XCode notices, and warns you.  You have to try this compiler to really understand how awesome it is.

2.  Objective-C now has an amazing compiler and new set of language features collectively called "ARC", Automatic Reference Counting.  It's like the smart pointers of C++ have been moved quietly into the language itself.   This reduces the amount of boilerplate code needed to make the underlying reference-counting nature of Objective-C objects easy for users to handle in most cases. There are only a few areas where this approach requires manual intervention, including the fact that unlike a Garbage Collector, there is no cycle detection system, you must manually unhook cyclical links, for the collector to work.    So far I think the system is just about the most brilliant thing ever.  A secondary and surprising benefit of ARC is that it has taken a lot of weak-typed pitfalls that Objective-C had inherited from ANSI C and papered over them with warning labels (compiler warnings), or better yet, filled them with cement (compiler errors, that stop you from doing something bad).   Did you ever learn to thank a compiler for stopping now with an error or at least flagging with a warning or a hint, something that would have taken you a long time to find at runtime?  The latest CLANG/LLVM compiler (version 4.1) that compiles all the C-family languages (C, C++, and Objective-C) in XCode is a beautiful compiler, with beautiful error messages, and warnings.

3.  The frameworks (UIKit, which is Cocoa for iPhone) are amazing.   Lately I have come to wonder just how is Embarcadero going to handle things like screen rotation in their framework.  I hope they'll do an excellent job. How do you think the smart people at Embarcadero are going to design Firemonkey FM2 Mobile, or whatever it's called when they release it? You got it, Pontiac. They're going to study this working example of a mobile application framework, because it works, and there are millions of appStore apps out there that prove it's a solid design.

One caveat; You have to have a Mac in order to run XCode, and so, if what I've said makes you want to play with XCode, but you don't have a Mac, I suggest you get one. Go find a used Mac Mini on eBay, and try it out.  You'll be amazed.   You'll be frustrated sometimes. You'll want to yell at whoever decided to make something so alien and foreign to your delphi-loving brain.  But once your brain has seen other things, things it was not expecting, you will find that certain blind spots you had (and even cherished) begin to go away, leaving you to see Delphi in a clear, sober light.   Thus sobered you will not love Delphi less, but you will be more aware of where it is weak, and be able to help it along when it needs some care.

That might be a good blog post;  Areas where Delphi developers have blind spots.  One of them, just for starters is the tendency to create giant slimy muddles of code, with 10K lines of code in a single unit, and class. How dare anyone call a 20K line .pas unit with a single class in it a class. It's a compilation unit that is less object oriented than a stack of FORTRAN punchcards from 1957.  Sorry, it's not OOP. It's just a nasty mess, that doesn't even deserve the term "structured programming", which is the pre-OOP term for the desire for developers to stop making a mess, and to work in an elegant orderly, and understandable manner while building software.

There's no better way to learn to be a better developer than to force yourself to start over.  Beginner's mind. It's Zen, baby.  Look it up.

Update:  If you want to see the kind of learning curve you'd be facing, look at this question I posed today on StackOverflow.

Update2:  After a bit of a tussle with provisioning profiles and Wildcard AppIds, I'm now able to run apps on my device.




Behind the connection: Using ADO to display database schema

$
0
0
In this article, I will show how to get the database schema and display it in a tree view using the ADO components and Delphi (This applies to other languages as well). ADO stands for ActiveX Data Object and is a software layer that allows programmers a uniform and comprehensive way of developing applications that can access almost any datastore. ADO is actually using MDAC, Microsoft Data

Behind the connection: Automate Microsoft Office from Delphi

$
0
0
Microsoft Office (Word, Excel and others) are applications which can be fully automated from another application. Everything you can do by hand can also be done programmatically from another application and of course from your Delphi application. Office API and Delphi components Microsoft Office exposes his features thru a bunch of interfaces which are made accessible thru Windows COM API.

DelphiTools.info: Introducing dwsDatabase

$
0
0

dbDWScript now has database support classes built-in, these are based on a thin, interface-based layer, and can be used Delphi-side as well to get automatic memory management for simple DB access.

It currently supports mORMot SynDB and Universal InterBase, meaning it gets high performance native connectivity to SQLite, FireBird, Oracle, ODBC and OleDB (MySQL, MS SQLServer, MS Jet, AS400…).

Usage

Usage is very simple, for instance to connect to a local SQLite database and print two fields for a table:

var db := DataBase.Create('SQLite', ['d:\db\base.sql3']);
var query := db.Query('select fld1, fld2 from mytable where fld3=?', ['filter']);

while query.Step do
   PrintLn(query.AsString(0)+', '+query.AsString(1));
query.Close; // optional, only required if you need it closed ASAP

and to perform several queries in a transaction

db.BeginTransaction;
db.Exec('delete from mytable');
db.Exec('insert into mytable (fld1, fld3) values (?, ?)', ['hello', 'world']);
db.Commit;

The DataSet class supports classic EOF/Next iteration as well as the simpler Step iteration as in the previous example.

There are also JSON generation helpers, you can get a whole data set or a single record as JSON. This makes building ajax requests or even database “middle-ware” services simple.

Supporting other DB connectivity layers is quite simple, as you’ll see if you look in the source. SynDB & UIB were picked initially because together they offer high coverage of the usual suspects, and bring what are among, and maybe “the”, best in class performance and stability for Delphi DB connectivity these days.

Exemple: minimal web service

Those classes will be (are) used in leveraging the new “DWScript-returns-to-its-web-roots” Web Server (based on Synopse server). For instance in the DWS WebServer demo, you can make a minimal database “middle-ware” service with Windows domain authentication with just the following code:

case WebRequest.Authentication of
   WebAuthentication.None : 
      WebResponse.RequestAuthentication(WebAuthentication.Negotiate);
   WebAuthentication.NTLM .. WebAuthentication.Kerberos : 
      Print(DataBase.Create('UIB', ['dbServer:d:\db.fdb', 'login', 'password'])
                    .Query(WebRequest.QueryString)
                    .StringifyAll);
else
   WebResponse.StatusCode := 401;
end;

The above code will expect http requests with the sql as query string (ie. after the ‘?’ in the url). If the connection isn’t authenticated, it’ll ask for authentication. Note that Windows domain Single Sign On is supported by Chrome, Internet Explorer and FireFox (if you enabled it).

The query is run against a FireBird database hosted on another server, and the result returned as JSON. If the query fails for a reason or another, the client will get automatically get a 500 error code with the exception or error message. Oh, and the reply is compressed automatically if it’s larger than a couple hundred bytes.

And if you want to only serve on a secure connection, just add a check for WebRequest.Security, and you can then safely use extra or alternative authorization tokens or credentials.

Delphi Haven: Fixing a FireMonkey TCheckBox/TAction bug

$
0
0

Try this:

  • Create a new FireMonkey HD application, before adding a check box and an action list to the form.
  • Double click the action list and add an action to it; set the action’s AutoCheck property to True.
  • Assign the action just created to the check box’s Action property.
  • Double click the form to create a handler for its OnCreate event. In the handler, set the action’s DisableIfNoHandler property to False:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Action1.DisableIfNoHandler := False;
end;
  • Run the application; once showing, click the check box. Expected: its checked state is toggled. Actual: nothing happens
  • In fact, toggling the check box does work, however you need to double click the control for this to work. This is patently a bug caused by the IsChecked property setter getting called twice in the course of a single mouse click

To fix the problem, you can at a pinch create a suitable interposer class. Doing that won’t be very ‘clean’ however because the IsChecked property setter isn’t virtual, so do this instead:

  • Take a copy of FMX.Controls.pas, add it to your project, and open it up.
  • Find your way to the implementation of TCheckBox.MouseUp.
  • Ignoring the reams of ‘Live’Bindings support code, add a check for IsCheckedStored in front of IsChecked being toggled:

if IsCheckedStored then IsChecked := not IsChecked;

Rebuild the application, and the bug should be fixed.

Behind the connection: Enabling floating form designer in Delphi XE3

$
0
0
Delphi XE3 has an interesting feature removed from previous versions: the floating VCL form designer. You can enable it again easily, at your own risk. While the IDE is not running, launch the registry editor, locate the key  HKEY_CURRENT_USER\Software\Embarcadero\BDS\10.0\Form Design and set the "Embedded Designer" to FALSE. Note: Don't do that if you use FireMonkey. It's form designer

Dr.Bob's Delphi Notes: Delphi Developer Days 2013 - cities and dates announced

$
0
0
The Delphi Developer Days 2013 tour will be in Chicago (May 6-7), Frankfurt (May 30-31) and Amsterdam (June 3-4), as announced by my co-presenter Cary Jensen.

Andreano Lanusse | Technology and Software Development: Update 2 for Delphi XE3 and C++Builder XE3

$
0
0

Update 2 for Delphi XE3 and C++Builder XE3 is available, the majority of bugs fixed on this update are related with C++ 64-bit compiler, the Update 2 bug fix list is available here.

If you have a previous version of XE3 installed, you must uninstall it. In case you installed Platform Assistant before, you also need to uninstall it.

Update 2 is available for download on the registered user page, visit the following links:

Andreano Lanusse | Technology and Software Development
Follow me on Twitter: @andreanolanusse


Castle Game Engine news: Castle Game Engine 4.0.0 release! And view3dscene 3.12.0, and castle 1.0.0, and more

$
0
0
FPS game screen
FPS game screen
Lazarus form with 2 castle controls sharing textures
resource_animations: Knight default idle animation
Missile (arrow) stuck in a wall
Testing dropping items on level
German Pavillion in the Universal Expo of Barcelona of 1929 (by Victor Amat)
Room Arranger with SSAO demo, shown by view3dscene
Final stages of RoomArranger viewer using our engine, with more controls and SSAO
Lights Editor playing with shadow maps
Lights Editor in view3dscene - fountain, shadow volumes settings

We proudly present the Castle Game Engine 4.0.0 release! This is the greatest release of our engine ever for ObjectPascal developers interested in making their own games:

  1. We introduce a high-level game API, to construct a fully-working 3D game really easy. This includes integrated units to manage levels, creatures (with smart AI), items, player, with inventory, management of 3D resources, easy 3D sound, flexible game data layout (you can use XML files to define a lot of things without touching game code), and so on.

    Of course, we use VRML/X3D for all the 3D models, so everything can be animated and interactive, and may use features like shadows, mirrors, shaders and such. See our demo 3D models (in particular, check new water/caustics/ demo inside, by Victor Amat, movie showing it is here).

    There are a couple new examples in engine sources. First of all, examples/fps_game/ is a must-see: it shows a complete working FPS game, with a lot of comments in the source code and data files.

    The engine is very flexible, you can derive new classes and override a lot of methods to customize behavior of everything in ObjectPascal. You can define new level logic, new creatures, new items, and finally you can also use basic 3D classes to easily create any 3D entities suitable for your game. You can also easily create your own viewports, scene managers, 2D controls, use 3D sound and much more. Everything is explained in the new tutorial.

  2. We have a lot of new documentation to show you how to use the engine:

  3. The full list of changes is definitely too large to fit into a normal news item. In the past I usually tried to list all the important changes in a release announcement, but there's just too many things this time :) New engine units include CastleCreatures, CastleItems, CastleLevels, CastlePlayer, CastleMaterialProperties, CastleResources. There are also countless changes in the rest of the engine to make it better and more integrated. See the news from the whole 2012 year for a complete list of details.

    For developers upgrading from engine 3 version: all of our unit names are now prefixed with CastleXxx, see doc/naming_engine_4.0.txt document. So you will almost definitely need to fix your "uses" clauses. Aside from that, the engine is quite compatible with previous version. Of course please ask of the forum if you have any questions about upgrading code from engine 3 to 4 (or about anything else, for that matter :)

We also release a new 3.12.0 version of view3dscene, our VRML/X3D browser and viewer for other 3D model formats. The most important improvements are listed below. Note that improvements 1-8 are actually in the engine, instantly available for all the games/applications using our engine. But most users will probably observe them in view3dscene for the 1st time.

  1. Navigating in Walk / Fly modes by mouse dragging.
  2. Using 3D mouse devices.
  3. Screen-space ambient occlusion (see menu "View -> Screen Effects" menu item, developers: try the ultra-simple TCastleAbstractViewport.ScreenSpaceAmbientOcclusion boolean property).
  4. All screen effects cooperate now with multi-sampling (anti-aliasing).
  5. UNIT statement from X3D 3.3 is implemented.
  6. VisibilitySensor node is supported.
  7. Many fixes to triangulating concave polygons.
  8. X3D extension to force Phong shading.
  9. New "Edit -> Lights Editor" feature.

Many thanks go to Jan Adamec for implementing the 1-3 features above (and more)! Our engine is used as VRML viewer for shareware Room Arranger.

All the other programs and data on our pages were updated to use/show new engine 4.0.0 version: The Castle 1.0.0 (finally!), malfunction 1.2.8, kambi_lines 1.1.7, view3dscene 3.12.0, rayhunter 1.3.4, glViewImage 1.4.1, glplotter 1.2.5, bezier_curves 1.1.9, glinformation 1.2.2, gen_function 1.0.5, demo models 3.2.0.

Smart Mobile StudioSmart Mobile Studio: Smart Graphics

$
0
0
In this first installment we have taken a quick look at related concepts that you are bound to meet when programming graphics. Concepts like double buffering, sprites, alpha blending are universal and are deployed on all platforms regardless of language. So it's handy to get to know these concepts straight away. We have also introduced how the HTML5 canvas works, that it uses paths rather than ad-hoc, brute force like good old TCanvas.

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Delphi Haven: How to survive without image lists in a FireMonkey project

$
0
0

In the VCL, toolbar icons (glyphs) are set up using the TImageList component. In FireMonkey however, TImageList does not exist, and even TToolBar itself is half the component it is in the VCL – rather than manage its own buttons, it’s just a simple container control like TPanel. To add buttons to a FMX TToolBar, you therefore drop TSpeedButtons onto it; and to add glyphs to the buttons, you add a TImage control to each one. On the face of it this leads to a simpler situation that had with the VCL; on the other though, it causes maintenance hassles in non-trivial applications if the same glyph is supposed to be used by different buttons, or if you come to want to change the icon set to a different one, given each image must be changed separately.

Being bothered about this issue, I’ve found relief is at hand from the FireMonkey styling system though. Let’s see it in action:

  • Create a new FireMonkey HD application.
  • Drop a TSpeedButton onto the form, and clear its Text property. Next, add a TPanel (sic.) to the button. Since TSpeedButton won’t let you do this directly, reparent the panel by dragging its node onto the button’s node in the Structure pane (top left).
  • Set the panel’s HitTest property to False, and its Align property to alClient. If you want to be able to drag the button around at designtime, set either the panel’s Padding property to (2, 2, 2, 2) or the button’s Margins property to (2, 2, 2, 2). Note the meaning of Padding and Margins is (weirdly) flipped round compared to the VCL – this is something I still haven’t got used to myself!
  • Add a TLayout to the form, and set its Visible property to False.
  • Add a TImage to the layout, load a suitable ‘Open File’ glyph into its Bitmap property, and set its StyleName to ‘FileOpenGlyph’. For ease of identification in the designer, set its Name property to ‘FileOpenGlyph’ too.
  • Set the panel’s StyleLookup property to ‘FileNewGlyph’. Note you’ll have to type it, as the name won’t be in the drop-down list.

At the end of all that, you should have something like this:

GlyphStyleDemo

How this works is that TPanel, as a styled control (TStyledControl descendant), gets its visual appearance from another control, or more exactly, a copy of another control – the ‘style’. This other control can be anything – all that is crucial is that its StyleName property is set to a value matched by the value of the StyleLookup property of the intended style subject(s).

Normally, custom styles are set up via a TStyleBook component. Using a style book means using the IDE’s FireMonkey style designer though, which is something only a programming masochist can enjoy. What isn’t so obvious is that you don’t actually need to use TStyleBook in the first place however – any control that has its StyleName property assigned will be available as a custom style. So, doing just that is what we did in the demo.

Now, we placed the source TImage on a hidden TLayout given we didn’t want it to be shown at runtime – setting its own Visible property to False wasn’t an alternative, since that would have caused the control it styled to be invisible at runtime too! However, it may be the case that you would prefer not to clutter a form with the source glyphs at all. In a VCL scenario, this would mean putting the application’s image lists onto a data module, but given TImage instances are controls, we can’t do that here. Instead, we need to put the glyph images onto a dummy form, auto-created but not ever visible. In my own case I had a further requirement: the ability to switch at runtime to a different glyph set. This was necessary because I’m looking to support both dark and light UI styles, and currently working with monochrome icons. While that may change later, there was no harm in ensuring everything would work if it didn’t.

So, continuing with the demo, add another form to the project, name it ‘StdGlyphsForm’, and save its unit as App.Glyphs.Std.pas. Then, go back to the first form, cut the TImage to the clipboard, then paste it onto StdGlyphsForm. Because we do not want the new form to become the application’s ‘main’ form in the VCL/FMX sense, do not have it auto-created in the normal fashion (Project|Options, Forms). Instead, it needs to be created explicitly when the application starts up, and directly (i.e., using TGlyphsForm.Create not Application.CreateForm).

Before we get to that though, let’s set up an alternative icon set to test with. To do that, save everything, then duplicate App.Glyphs.Std.pas via File|Save As…; save it as App.Glyphs.Alt.pas, then rename the form to AltGlyphsForm. After that, change the contents of the image, then add the original version of the unit (App.Glyphs.Std.pas) back to the project as well. In principle, we can now choose which icon set to use at runtime by instantiating the appropriate form class (StdGlyphsForm or AltGlyphsForm); if we wanted to then switch sets at runtime, we can just free the first glyphs form, instantiate the second, and ask all ‘normal’ forms to update their styling.

When targting OS X pursuing such a plan works fine, but when targeting Windows there’s a problem: specifically, at one point in FMX.Platform.Win.pas, Screen.Forms[0] is used in lieu of Application.MainForm when the latter cannot be guaranteed to be initialised yet. Because of this, the first form that gets created – regardless of how – becomes the ‘owner window’ for subsequent forms at the Windows API level. If the first form created were to be one of our glyph container forms, bad things will then result.

One way to get around this is to ensure the real ‘main form’ creates the glyph container. However, this assumes you have a ‘main’ form in the first place, which when targeting OS X especially isn’t necessarily the case. After fiddling about the problem, my preferred solution at present is to create the glyph container, move its contents to something else that isn’t a form too (just a bare TComponent instance will do), then immediately free it. So, let’s do that with the demo, wrapping the necessary code in a simple singleton type.

For this, add a new unit to the project, and call it App.Glyphs.pas. Then, copy the following code into its interface section:

uses
  System.Classes;

type
  TGlyphsStyle = (gsStandard, gsAlternative);

  GlyphsManager = record
  strict private class var
    FGlyphsOwner: TComponent;
    FGlyphsStyle: TGlyphsStyle;
    class constructor Initialize;
    class destructor Finalize;
    class procedure SetGlyphsStyle(Value: TGlyphsStyle); static;
  public
    class property GlyphsStyle: TGlyphsStyle read FGlyphsStyle write SetGlyphsStyle;
  end;

Next, make its implementation section look like this:

uses
  FMX.Types, FMX.Forms, FMX.Styles, App.Glyphs.Std, App.Glyphs.Alt;

class constructor GlyphsManager.Initialize;
begin
  FGlyphsOwner := TComponent.Create(nil);
  FGlyphsStyle := gsAlternative;
  SetGlyphsStyle(gsStandard);
end;

class destructor GlyphsManager.Finalize;
begin
  FGlyphsOwner.Free;
end;

class procedure GlyphsManager.SetGlyphsStyle(Value: TGlyphsStyle);
var
  Comp: TComponent;
  I: Integer;
  SourceClass: TComponentClass;
  Source: TComponent;
begin
  if Value = FGlyphsStyle then Exit;
  case Value of
    gsStandard: SourceClass := TStdGlyphsForm;
    gsAlternative: SourceClass := TAltGlyphsForm;
  else
    Assert(False);
    SourceClass := nil; //avoid compiler warning
  end;
  FGlyphsOwner.DestroyComponents;
  Source := SourceClass.Create(nil);
  try
    for I := Source.ComponentCount - 1 downto 0 do
    begin
      Comp := Source.Components[I];
      FGlyphsOwner.InsertComponent(Comp);
      if Comp is TFmxObject then
      begin
        TFmxObject(Comp).Parent := nil;
        if Comp is TControl then
          TControl(Comp).SetNewScene(nil); //see below
      end;
    end;
  finally
    Source.Free;
  end;
  FGlyphsStyle := Value;
  { next lines only necessary because we aren't updating
    the style as such as well }
  for I := Screen.FormCount - 1 downto 0 do
    Screen.Forms[I].UpdateStyle;
end;

The code here should be pretty straightforward – when the glyph set is to be changed, the old glyphs are first destroyed, the new ones loaded, and the application’s forms asked to refresh their and their controls’ styling. The only slightly tricky thing is how we change an existing component’s owner – since the Owner property is read-only, we need to call InsertComponent on the new owner instead, the implementation of which first deassigns any existing owner. Further, since a FireMonkey control, like a VCL one, has both a parent and an owner, and both will destroy the control when the parent or owner is itself destroyed, we need to clear the parent too. Lastly, due to an oversight in the FireMonkey source, a further reference – to the ‘scene’ – needs to be manually cleared as well. If you check out FMX.Forms.pas, you’ll find TCustomForm calls SetNewScene(Self) in DoAddObject, but not SetNewScene(nil) in DoRemoveObject. The resulting dangling reference then causes access violations if not cleared.

To put the new unit in action, head back to the main form of the demo (i.e., the one with the button on it), remove the now empty TLayout, and add a couple of radio boxes called rdoStandard and rdoAlternative. Set the first’s IsChecked property to True in the Object Inspector, then handle its OnChange event as thus:

procedure TForm1.rdoStandardChange(Sender: TObject);
begin
  if rdoStandard.IsChecked then
    GlyphsManager.GlyphsStyle := gsStandard;
end;

Similarly, handle rdoAlternative’s OnChange event like this:

procedure TForm1.rdoStandardChange(Sender: TObject);
begin
  if rdoAlternative.IsChecked then
    GlyphsManager.GlyphsStyle := gsAlternative;
end;

Finally, add App.Glyphs to the form’s implementation section uses clause (Alt+F11) and run the application. If all goes well, clicking on the radio boxes should toggle the button glyph:

GlyphStyleDemo - standard
GlyphStyleDemo - alternative

One thing to watch out for is that if you save everything, close and then reopen the project and have the form open in the IDE without either StdGlyphsForm or AltGlyphsForm too, the button’s styling will revert to a normal TPanel. This is nothing to worry about – close the form, open one of the glyph forms, then reopen the form, and the image will be back.

At the end of the day, I’m pretty happy with all this. While there was the odd irritating oversight in the FireMonkey source to work around, overall I find the style system here producing a more convenient approach that the VCL – in particular, it’s much nicer to be able to refer to a glyph by name rather than a meaningless numerical index. Moreover, the cosmetic issue of the custom style apparently being ‘lost’ when the main form is open without one of the glyph forms alongside is just that – cosmetic. In contrast, if the form were a VCL one with a TToolBar referencing a TImageList on a data module, the IDE would silently clear the actual reference!

Postscript – using TSubImage

As a final note, there is one variant of my approach that you might wish to consider. This is to replace the individual TImage instances with individual TSubImage ones, which then reference a single big TImage (TSubImage isn’t automatically registered, annoyingly enough, so you’ll need to do what Jeremy North did for TStyleTag here first). The reason is that when a control is used as a style, a copy of it is taken – and one aspect of the copy in a TImage case will be the contents of its Bitmap property.

If this were the VCL that wouldn’t be an issue due to the fact TBitmap there implements a reference counting system internally. In other words, when you do DestBitmap.Assign(SourceBitmap) in a VCL application, no ‘deep copy’ of the source bitmap is made, similar to how DelphiString2 := DelphiString1 doesn’t cause character data to be duplicated ‘there and then’ – rather, copying only happens when one of the two bitmaps or strings is modified later (the jargon for this is ‘copy on write semantics’). Unfortunately, the FMX TBitmap does not implement this behaviour though, and because of that, doing DestBitmap.Assign(SourceBitmap) causes an immediate ‘deep copy’ of the source, duplicating the bitmap bits in memory. For a small application with a small number of glyphs that won’t matter, and perhaps it won’t matter much either in a bigger program. As an application grows you might want to at least consider swapping out the individual TImage controls for TSubImage ones though. Thanks to the flexibility of the styling system, the task shouldn’t be too hard – all existing style associations can be kept intact.


Free Pascal Answers: New language additions in Free Pascal

$
0
0

These are many new improvements of Object Pascal programming language in Free Pascal compiler. I don’t know how much new are they, but at least they are new since Delphi 7 language. I haven’t used any of these features before (until now) because I wasn’t know about them.

1. For .. in loop:

This can be used to loop in string characters:


procedure ForInLoop(aStr: string);
var
  ch: Char;
begin
  for ch in aStr do
    WriteLn(ch);
end;

or through set items:


procedure ForInSetLoop;
var
  s: set of 1 .. 100;
  i: Integer;
begin
  s:= [1, 3, 7];
  for i in s do
    Writeln(i);
end;

2. += operator

This new operator can be used to concatenate strings and add values to numbers:


var
  aName: string;
begin
  aName:= 'Free';
  aName += ' Pascal';
  Writeln(aName); // Free Pascal
end;

For numbers:


x:= 10;
x+= 15;
Writeln(x); // 25

3. Properties without OOP

Now you can define a property in a structured code:


var
  x: Integer;

procedure SetX(aX: Integer);
begin
  x:= ax;
end;

function GetX: Integer;
begin
  Result:= x;
end;

property MyX: Integer read GetX write SetX;

// Main program
begin
  MyX:= 170;
  Writeln(MyX);

end.

4. Bit packed record

You can define a record of bits, and display it as byte:

type
  tbit = 0..1;

  tBitsByte = bitpacked record
    bit0   : tbit;
    bit1   : tbit;
    bit2   : tbit;
    bit3   : tbit;
    bit4   : tbit;
    bit5   : tbit;
    bit6   : tbit;
    bit7   : tbit;
  end;

var
  aByte: tBitsByte;
begin
  aByte.bit0:= 1;
  aByte.bit1:= 0;
  aByte.bit2:= 1;
  Writeln(Byte(aByte)); // 5

5. Sealed class

You can prevent inheriting from a class by adding the keyword sealed:

TMyClass = class sealed
  private
    fValue: Integer;
  public
    constructor Create(aValue: Integer);
    destructor destroy; override;
    function GetValue: Integer;
end;

I couldn’t find a good example right now to explain why we need to do this, but in the future I may get one.

6. Class methods and variables

You can declare methods and variables that can be used by class name before object instantiation the same like Java static methods as in this example:


TMyClass = class sealed
  private
    class var fValue: Integer;
  public
    constructor Create(aValue: Integer);
    class function GetValue: Integer;
    class procedure SetValue(aValue: Integer);
end;

constructor TMyClass.Create(aValue: Integer);
begin
  inherited Create;
  fValue:= aValue;
end;

class function TMyClass.GetValue: Integer;
begin
  Result:= fValue;
end;

class procedure TMyClass.SetValue(aValue: Integer);
begin
  fValue:= aValue;
end;

// Main code

begin
  TMyClass.SetValue(900);
  Writeln(TMyClass.GetValue);
end.

7. case of String


case aName of
'Free Pascal': Writeln('Lazarus IDE');
'C++': Writeln('CodeBlocks IDE');
end;

 

If you know any new useful additions please let me now to write it here.

References:

http://lazarus.freepascal.org/index.php/topic,19107.0.html

http://www.freepascal.org/docs-html/ref/refse24.html#x56-630004.6

http://edn.embarcadero.com/article/34324


The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Just in case you wonder about Property using Generics in Delphi, they are not possible.

Thanks David for mentioning it, Hallvard for mentioning it even earlier and Rudy for confirming it.

These are supported with Generics in Delphi:

All of the supported aspects are linked to articles from excellent authors. There is far more on the internet about Delphi and Generics, but those are a good start.

Thanks Malcolm, Phil, Barry, Hallvard, Jolyon and many others for posting all those articles!

Note that this is not possible in C# either, Julian Bucknall organized a chat and explains why, but there is a workaround which I might try to port to Delphi in the future.

–jeroen

via: Property using Generics in Delphi – Stack Overflow.


Filed under: .NET, .NET 2.0, .NET 3.0, .NET 3.5, .NET 4.0, .NET 4.5, C#, C# 2.0, C# 3.0, C# 4.0, C# 5.0, Delphi, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Development, Software Development

The Wiert Corner - irregular stream of stuff: jpluimers


TPersistent: When a Date Drives you Nuts

$
0
0

It’s been several years since I used datasets for anything other than quickly displaying the results of a SQL Query or Proc.  Recently I have been reminded why I dislike the TDataSet based RAD development approach so much.

If you’ve ever done a DBX conversion you would know that DBX maps datetime database columns to TSQLTimeStampFields instead of TDateTimeFields.  If your datasets use persistent TFields, which is typically the case so developers can make use of TField events to provide formatting, and validation, then you’re in for a treat!  All the persistent TFields have to be removed so new ones can be generated at design-time using DBX to ensure the right field types are used.  Of course you don’t want to remove any additional TField descendants created at design-time that are not in the dataset, so it might be necessary to go through each one to determine if the TField originates from the underlying dataset (using FieldKind may not be enough).

Once you’ve finished re-mapping all the TFields, you have to re-connect all the event handlers.  Hopefully, the original developers actually centralized all the database related code into datamodules, or you will be going through every form in the entire project.  Even re-connecting all the dataset TField handlers in the datamodules may be a treat if handlers were not shared across TFields of the same type.  For instance, if you use the OnSetText, OnGetText events to provide standard date formatting for TDateTimeFields using edit masks for input with a different format for displaying the date, you have to reconnect numerous handlers to each persistent TField event and the only way to tell if you have it right is GUI testing.  If you don’t get it right you will see errors from TField.SetAsString() with no idea what field is causing the exception.  The easiest way to actually find out is to put a breakpoint on the method, enable Debug DCUs, and generate the error through the UI.

In an application using domain objects with the MGM pattern for presentation, all the TField handlers would be replaced with mediators that perform the translation between the UI presentation layer and the database layer.  If you need to enhance the application to work with a variety of date formats, for instance, instead of locking it down to the corporate standard format which I see most often when using TField events, the enhancement would only involve a change in one place (the mediator).  It’s a much DRYer approach.  While using TField events doesn’t necessitate multiple handlers for the same purpose (one per TField type instance), not many developers think about consolidating such code across the application, and the result is a maintenance nightmare, especially if you ever think about changing the database layer.

Avoid vendor lock-in, even if you’re not thinking about changing your database, consider using an ORM, or even database application layer interfaces such as hcOPF’s IhcQuery and IhcStoredProc so changing your database layer doesn’t result in sleepless nights.  One “proposed” EULA change could have you swapping a database layer in a hurry ;-)

TPersistent: Delphi 2012 Redux

$
0
0

I delayed publishing this post as I contemplated the wisdom of doing so, but 2012 has been a big year for Delphi, so I thought I would review the events of the year and make my predictions for 2013 even if it’s the last day of January rather than the first.

Corporate

One of the biggest news items was of course Marco Cantu joining EMBT as a Delphi Product Manager. Sadly, this was not the only staff change at EMBT. Barry Kelly among others, decided to leave EMBT, and there were anonymous reports of lay-offs, and a large degree of employee dissatisfaction including no raises for employees since EMBT acquired CodeGear, as well as hiring of junior engineers in economically advantageous areas of the globe.

The new EULA agreement for XE2 included changes prohibiting the use of DBX drivers (EMBT’s and third party) for accessing remote databases in the Pro version of Delphi. These “proposed” changes were leaked to the community, and the agreement was subsequently changed to exclude the new restrictions.

With the release of FireMonkey (FMX) on Sept. 1, 2011 it’s been over a year that FireMonkey has been out in the wild. The introduction of FireMonkey heralded the deprecation of the VCL despite numerous enhancements, it’s clear that EMBT is betting the future expansion of the Delphi/BCB market on FMX.

Desktop

Since FMX was released, there have been two major component vendors providing support for FMX; TMS and FastReports. Delphi XE3 has also been released with an updated version of FireMonkey (FM^2). With third party advanced grid and reporting capabilities, FMX now has a sufficient tool set to author cross platform desktop applications for LOB (Line Of Business) applications.

Many of the technical blog articles on FMX have been quite critical of its implementation and lack of completeness in the version 1.0 release even in the desktop space.  Some of these deficiencies have been addressed in version 2, but the framework is still maturing, and the latest feedback on FM^2 by those deep diving the technology is not extremely positive.

Mobile

In the mobile space, several applications were authored and accepted into the Apple App Store using XE2 with FMX before FMX support for iOS was removed in the subsequent release (XE3). Users who bought XE2 for iOS were left with a discontinued version of the framework and development tool, with no clear indication what the future held for them. These early adopters were then required to pay to upgrade to XE3 for the privilege of beta testing the up-coming Mobile Studio, in order to ascertain what their migration path would look like, and whether they should continue to support EMBT’s efforts in the mobile space.

The Future?

With the layoffs/departures from EMBT, as well as delayed compiler releases it appears the decision to bet the farm on FireMonkey is not paying off yet, and even EMBT employees may no longer believe in the strategy. This is further validated by the attempted EULA change which would have required Pro users to buy a higher priced SKU, and the 10% price hike in the new year.

I think EMBT has bitten off more than they can chew. Trying to implement a cross platform UI framework is a major endeavor with minimal payback (development tool licenses only), and lots of competition. There are free frameworks out there, and ones that have been around for a long time. Creating a framework specific to the Delphi/BCB tool set immediately limits its market, and dramatically increases the code base that EMBT has to maintain. From what I can see, they are already challenged in that respect (just look at the number and age of QC reports). It’s been over a year since FireMonkey was released, and the adoption rate appears to be minimal if you look at the available components and applications based on FMX.

IMHO, the writing is on the wall.  Expect to pay more for Delphi/BCB licenses while EMBT pours their revenue into FMX to develop the market.   Expect to wait longer for bug fixes and suffer from longer startup times due to increased anti-piracy efforts. I would also expect that the Android and Linux support will be even later than indicated as EMBT focuses on the Mac/iOS platforms trying to get traction in one of the most appealing market segments for Delphi developers.

As unfortunate as it may be, I believe that FMX will continue to flounder and that’s why you don’t see vendors like Developer Express, or Raize porting their VCL products, and even after over a year the monkey is hardly on fire.  FMX will likely become a niche framework, used by some developers for XPlatform support and 3D development, while the number of developers moving to different languages and tools for new development continues to escalate.  Certainly the release of mobile studio will be a pivotal event for the future of FMX, and therefore Delphi.

Behind the connection: Internet Explorer Automation Part 1

$
0
0
Internet Explorer can be automated just like Word or Excel. Most automation is done using IWebBrowser2 interface. Getting hand on a IWebBrowser interface is easy. It is enough to call CreateComObject, passing the Internet Explorer ID. This will create a new instance of Internet Explorer: FWebBrowser := CreateComObject(CLASS_InternetExplorer) as IWebBrowser2; Once the instance is created (A new

See Different: Split Lazarus v0.0.1 build 2

$
0
0

לפני חודש בערך, הזכרתיכי אני כותב תוסף ללזרוס.

split_lazarus_v001  b2

התוסף מאפשר לעשות split view עבור העורך של לזרוס, ובכך לאפשר לבצע עריכה ו/או צפיה בקוד תחת 2 view ports על אותו טאב בעצם.

להגיע לנקודה הזו היה מאוד לא פשוט בגלל מספר סיבות:

  • פעם ראשונה שאני עושה דבר כזה
  • לדבג קוד למערכת הזו אינו פשוט – צריך לדבג את ה IDE בעצם מתוך ה IDE‏
  • מצאתי באגבספריות של FPC אשר דורש התייחסות
  • יש המון דברים שחשבתי עליהם בגישה איקס ומסתבר שהם ממומשים אחרת בפועל
  • מה שאומר ששכתבתי קוד יותר מפעם או פעמים להגיע לגישה הנכונה

הגרסה הנוכחיתיודעת רק להעתיק את צביעת הטקסט, תכונות הגופן ולהציג עצמה כמובן על המסך.
היא לא אמורה לעשות שום דבר מעבר לכך, ואם היא עושה, אז לא במכוון :)
התוסף מתקין עצמו בתפריט הימני של הלשוניות אשר מחזיקות בעורכי הטקסט, וגם מאפשרת לרשום עבור הפעולות קיצורי מקשים, אך בברירת המחדל, אינה מקצה כאלו.

גרסה זו נועדה יותר לבדיקות וחוו"ד מאשר שימוש אמיתי בה, ואשמח לשמוע ממכם בנושא

הוראות התקנה

פתחו בלזרוס את התפריט package ושם בחרו באפשרות open package file (.lpk)‎.
בספריית התוסף, בחרו את תת הספרייה בשם package ושם את הקובץ lazsplitview.lpk .
לאחר שנפתח לכם חלון של החבילה, לחצו קודם על כפתור compile לבדוק כי אין בעיות בבניית התוסף, וכשזה מסתיים, בחרו ב install.
לאחר אתחול מחדש של לזרוס, התוסף כבר מותקן אצלכם.


Filed under: FPC, Lazarus, Object Pascal, טכנולוגיה, פיתוח, קוד פתוח, תוכנה, תכנות Tagged: lazarus, split view

See Different: My First Lazarus plugins split lazarus

$
0
0
I have released today v0.0.1 b2 of my first ever Lazarus plugins – Split Lazarus.
This plugins allow users to split view source code using the Lazarus IDE.

split_lazarus_v001 b2

The following release is just to provide a look and feel, and request for help with testers etc… and by no mean should be used otherwise.
I must say that it was not so simple to arrive to this version due to few factors:
  • First time of writing such thing
  • For debugging my own code, I need to debug the IDE, because I'm executed from within
  • Found a bug with FPC class
  • There are things that I thought that works in one way, but actually in much different way
  • So I needed to rewrite code in that level as well …
The following release contains only few features, such as syntax color, and fonts that are copied from the original editor.
It also provide a splitter between the original editor and the new one, and should not support anything else. So if you find that it does something else, it was by mistake :)

The plugins install itself into the Editor tab menu, and also allow you to register a shortcut for it's actions that by default are empty.

Installation:

  • Open the package menu
  • Choose the option of open package file (.lpk)
  • Open the file under the package directory named lazsplitview.lpk
  • At the new opened window, press on compile to make sure that the source can be build. Then choose "Install".
  • You'll be prompt for a question if you wish to build it now, answer "yes"
  • Lazarus will be booted up and enjoy :)

Filed under: FPC, Lazarus, Object Pascal, טכנולוגיה, פיתוח, קוד פתוח, תוכנה, תכנות Tagged: lazarus
Viewing all 1725 articles
Browse latest View live