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

jed-software.com: FireMonkey: Extending TFloatAnimation to support maximum loops

$
0
0

Background

In response to a QC report I wrote early last year I decided to implement a LoopCount property on the TFloatAnimation component.

Report No: 105140 Status: Open
Add a LoopCount property to the TAnimation class
http://qc.embarcadero.com/wc/qcmain.aspx?d=105140

Class Definition

  TJSCustomLoopCountFloatAnimation = class(TFloatAnimation)
  public
    type
      TAnimationLoopEvent = reference to procedure (Sender: TObject; const LoopNumber: Integer; var Cancel: Boolean);
  private
    FLoopCount: Integer;
    FCheckingLooping: Boolean;
    FOnLoop: TAnimationLoopEvent;
  protected
    FLoopsComplete: Integer;
    procedure FirstFrame; override;
    procedure DoLoop(var ACancel: Boolean); virtual;
    procedure ProcessAnimation; override;
  public
    constructor Create(AOwner: TComponent); override;
    property LoopCount: Integer read FLoopCount write FLoopCount default 3;
    property OnLoop: TAnimationLoopEvent read FOnLoop write FOnLoop;
  end;

Nothing that interesting in the new descendant. New property called LoopCount to control the number of loops and a new event that gets triggered each time a loop completes.

The published component publishes the new property and event but also changes the default values for two existing properties. It makes sense to set Loop to true when the new class is for enhancing the looping ability and if you’re looping, generally AutoReverse will be set to true.

  TJSLoopCountFloatAnimation = class(TJSCustomLoopCountFloatAnimation)
  published
    property AutoReverse default True;
    property Loop default True;
    property LoopCount;
    property OnLoop;
  end;

Implementation

I won’t post all of the code here because you can download from the link provided below, just a couple of snippets.

We need to override the FirstFrame method to initialise a couple of variables we use.

  • Checking to see if the LoopCount property is valid (raise an exception if it isn’t)
  • Initialise the variable to zero that counts the interactions
  • Make sure we are going to be checking the animation process for loops

Most of the work occurs in the overridden ProcessAnimation method.

procedure TJSCustomLoopCountFloatAnimation.ProcessAnimation;
var
  LCtx: TRttiContext;
  LType: TRttiType;
  LField: TRttiField;
  LCancel: Boolean;
begin
  inherited;
  if FCheckingLooping then
  begin
    LType := LCtx.GetType(Self.ClassInfo);
    if Assigned(LType) then
    begin
      LField := LType.GetField('FTime');
      if LField <> nil then
      begin
        if LField.GetValue(Self).AsExtended = 0 then
        begin
          Inc(FLoopsComplete);
          LCancel := False;
          if FLoopsComplete > 1 then
            DoLoop(LCancel);
          // The first time through, FTime is 0 so we need to offset this by
          // adding 1 when checking for completion
          if LCancel or (FLoopsComplete = LoopCount + 1) then
          begin
            LField := LType.GetField('FRunning');
            if LField <> nil then
              LField.SetValue(Self, False);
          end;
        end;
      end;
    end;
  end;
end;

Thanks to extended RTTI we can access a couple of private fields that we need to determine if a loop has been completed. This occurs when the FTime variable is zero. There is one issue with using this value and that is that the first “Loop” should be ignored since the first time ProcessAnimation is called FTime is zero so by the logic used, a loop has completed. This is why the DoLoop method is only called if the FLoopsComplete variable is greater than one.

Naturally it is possible to handle this one-off situation differently using a “First Time Through” variable but under the circumstances, I decided to go with the solution in place.

Once the LoopsComplete value is one greater than the LoopCount (refer to the above two paragraphs if you’ve already forgotten about why) the private field FRunning is set to False. Setting FRunning to false, stops the animation immediately.

Why not just call the public Stop method instead of going to the trouble of setting a private field? The answer to that is found in the ProcessTick method of the animation control (incidently, why isn’t this method virtual?).

  ...
  ProcessAnimation; // <==== We set FRunning to false here
  DoProcess;

  if not FRunning then
  begin
    if Assigned(AniThread) then
      TAniThread(AniThread).FAniList.Remove(Self);
    DoFinish;
  end;
  ...

By setting FRunning to false within our ProcessAnimation override, we are avoiding another frame being processed before the animation is stopped. This is because the Stop method calls ProcessAnimation and DoProcess as well.

Download

You can download the component and a cheesy demo application from the link provided. There is no package for the component to install it into your IDE, this is left as an exercise for the reader :-) .

Loop Animation Demo (short video – 39KB)

Download LoopCount Component and Demo

NOTE: Before downloading the source code you must agree to the license displayed below.

License Start




This space intentionally left blank…



License End


jed-software.com: Fixing FireMonkey: TMemo/TEdit OnExit

$
0
0

Currently in the Delphi XE3 release there is a bug in the OnExit processing of TMemo and TEdit (possibly others) controls.

Issue

If you make a change in a TEdit or TMemo control and then exit the control, after the OnExit event is called, another OnChange event is called. This shouldn’t happen.

This doesn’t occur in the VCL framework and shouldn’t happen in FireMonkey.

Solution

TEdit

The fix for the TEdit cause is pretty simple. Since the FNeedChange field in TCustomEdit is protected we can use a class cracker to fix it. You could put the fix into either a new control or in either an OnExit or OnChange handler in your application.

type
  TEditClass = class(TEdit);
...
procedure Form1.OnExit(Sender: TObject);
begin
  TEditClass(Edit1).FNeedChange := False;
end;

It’s interesting to note for TEdit, FNeedChange is protected. This is because in the TCustomEditBox descendant (used by TSpinBox and TNumberBox controls), the FNeedChange field is set to False after the overriden Change method is called. Perhaps this should have triggered the developer making that change, to actually fix the issue in the ancester class.

TMemo

The fix for TMemo is more interesting because unlike the TCustomEdit class, FNeedChange is private. Thankfully extended RTTI comes into play.

I put this code where the memo content was saved to disk, you could put the code in the same spot in your applications (if applicable), or place it in either OnChange or OnExit events.

var
  LCtx: TRTTIContext;
  LField: TRttiField;
  LInst: TRttiInstanceType;
begin
  // save your memo contents
  LInst := LCtx.GetType(Memo1.ClassType).AsInstance;
  LField := LInst.GetField('FNeedChange');
  if LField <> nil then
    LField.SetValue(Memo1, False);
end;

If your save is triggered by the user selecting a control that takes focus from the memo, the OnExit event will trigger before executing the fix above. Under these circumstances, moving the fix to the OnExit event of the memo is advised.

Another TMemo Issue

The OnChange event is only triggered after typing two characters in a TMemo, the first character typed into the memo doesn’t trigger the OnChange event.

jed-software.com: FireMonkey Style – TStyleTag (Part 2)

$
0
0

Part 1 – http://jed-software.com/blog/?p=699

Along with the missing registration of TStyleTag, the following components cannot be used in styles without hand editing FMX or Style files.

  1. TFontObject
  2. TBrushObject

I’ve updated the package to now register these missing style components so you can use them in custom styles.

Download Package

The change is straight forward if you have already downloaded and installed the previous package.

The register procedure should now look something like this:

procedure Register;
begin
  RegisterComponents('Shapes', [TStyleTag, TFontObject, TBrushObject]);
end;

NOTE: You may want to register them to a different palette location.

 

jed-software.com: Embarcadero: Dont hide behind bad design

$
0
0

Recently I created an QC report to try and get the default wizard behaviour changed to be user friendly.

The issue is that the description text for the wizard item only shows when the mouse is hovered over the item. This means that keyboard navigation will never show the description nor will just opening the dialog initially, unless you magically have your mouse in the wrong spot.

Apparently, this is the way the wizard has been designed.

Report No: 115353 (RAID: 38977) Status: Closed
The mobile wizard doesn’t show a description using you hover over the item

http://qc.embarcadero.com/wc/qcmain.aspx?d=115353

Mobile Wizard comparison screen captures

Another item that is also “As Designed” is the text used to describe the blank application item in the wizard. This text states:

“The Blank Application Template is a jumping off point for creating a completely custom mobile application.”

Now I acknowledge that English was the subject I liked the least at school but that sentence could be improved.

Here are a couple of alternatives that I’ve thought about in the past ten seconds.

  1. “The Blank Application Template is the starting point for creating a custom mobile application.”
  2. “Use the Blank Application Template to create a custom mobile application.”

Perhaps you can add your own.

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

This is more elaborate English version of a short Dutch message I recently sent to explain the differences between VCL and FMX:

Do not regard FMX as a replacement for VCL: they are different kinds of frameworks.

VCL is a wrapper around Windows Controls. In itself, it has not much functionality: it exposes the underlying Windows functionality. The exception are data aware controls that provide basic functionality for writing data aware applications. There is a huge 3rd party market for extending VCL support, for instance providing extra Windows functionality, enriching data aware behaviour (look at all those fancy data aware grids), and many more.

FMX  is the FireMonkey X-platform framework. Major functionalities are vector based 2D, 3D drawing and controls, and support for styles and composition.

When introducing FMX in Delphi XE2, Embarcadero also introduced a new way of data binding that is shared with FMX and VCL. FMX extends this a bit to some basic data aware controls.

Gone are most of the platform specific features like drag & drop, full blown Windows Shell ListViews, etc. There are some controls that manifests themselves differently on each supported platform (like Pickers), but most of that is currently left to the 3rd party FMX component market.

So if you want FMX to replace VCL, then be prepared for quite some shopping in the 3rd party market.

CLX tried to be a full blown cross platform VCL replacement, but that didn’t work very well.

–jeroen


Filed under: Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, FireMonkey, OS X FMX, Software Development Tagged: component market, data binding, fmx, software, technology, vcl, windows controls

Te Waka o Pascal: It’s a Good Time for NZ Delphi Users to Cross-Grade

$
0
0
Having lost our Delphi reseller in NZ last year, and with the Kiwi dollar riding high against the US dollar, now is a good time to make purchases from online stores operating in US currency. RemObjects has such a store and they also have a cross-grade offer for Delphi customers wishing to move over to [...]

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Te Waka o Pascal: Changing Your Delphi License Serial Number

$
0
0
Having installed and activated Delphi XE4 using the license available to me from my employer I decided that, despite the very nasty taste left in my mouth, I would pay the $49 required for the XE4 “hot-fix” release, albeit only in order to remain with the valid update window now imposed by Embarcadero, on the [...]

Behind the connection: OpenSource GDI+ Library

$
0
0
Sometimes ago, I discovered an open source GDI+ Library built by Erik Van Bilsen. I now use that Library extensively with excellent result. I used it to build an image processing system and other similar things. The Library is intended for Delphi 2009 and above. I currently use it with Delphi XE4 with no problem. It comes with a nice sample application that demonstrate the usage of GDI+

DelphiTools.info: Smart Contest 2013 – Round #2

$
0
0

wartrailThe second Smart Context 2013 has been announced! As with the previous round, first prize is a tablet device of your own choice (up to USD 750). This time the theme is “Game Development”

The rules are as follows:

  • Registration before the 13th of May (registration at contest@smartmobilestudio.com)
  • Deliver your contribution before 3rd of June
  • The source code will be shared in our show case area
  • Preferable that it can run in the integrated IDE browser (but not mandatory)
  • No restrictions w.r.t game genre
  • No restrictions w.r.t project type (canvas, sprite, console, VCL)
  • You can use the trial version to make your entry

The registration date limit is not intended to be binding, but more like an “Hey I’m in”, and for the previous contest latecomers were accepted as well.

For this round I’ll be one of the judges alongside Jon Lennart Aasenden, who recently posted two articles about game development, see part1 and part2.

For more details, head to the announcement page.

DelphiTools.info: DWScript news roundup for May 2013

$
0
0

dws-mirrorLanguage and Script Engine

  • Delphi XE4 is now supported, compiler hints for XE3 have been taken care of as well
  • compiler now supports “in” operator across strings, for for instance “if subString in myString then” is equivalent to “if myString.Contains(subString) then
  • added standard “helpers” for most built-in functions operating on String, Integer, Float and Boolean. These roughly follow the Delphi & .Net conventions, though standard Maths functions are accessible directly (f.i. you can do “angle.Cos” directly, rather than have to go through “Math.Cos(angle)“)
  • added some more string functions (DeleteLeft, DeleteRight, etc.)
  • added support for EmptyParam for the COM connector
  • added DivMod to the standard functions
  • improved performance of DecodeDate/Time functions
  • improvements and fixes for the JSON connector (now supports manipulating an existing JSON structure, creating, moving and deleting nodes)
  • misc. fixes and improvements

Note that there aren’t specifics DPKs for XE4, you can just copy/rename the XE2 or XE DPKs.

Changes for SmartMobileStudio / JavaScript Codegen

In addition to the  previous changes, the following will apply to the next version of SmartMS:

  • support “for str in variant” which allows enumerating members of a raw JavaScript object (compiles to “for (str in v)”)
  • improved code generation for functions with an “exit” statement
  • added specific optimizations for string copies and testing (startswidth/endwidth)
  • slightly faster code generation

 

Delphi Bistro: Cross-platform development the FireMonkey way

$
0
0

Para leer este articulo en espanol haz click aqui.

What is FireMonkey?

FireMonkey is cross-platform Framework developed by Embarcadero. FireMonkey was originally designed by Eugene Kryukov in the company “KSDev” as VGScene.

In 2011 Embarcadero acquired the rights to the software and renamed it to FireMonkey.

FireMonkey is included, along with the traditional Visual Component Library (VCL) in Delphi and C++ Builder.

FireMonkey was introduced in XE2. It’s goal is to allow developers to design cross-platform applications and interfaces that take advantage of the acceleration features available in Direct2D on Windows Vista and Windows 7, OpenGL on Mac OS X, OpenGL ES on iOS, and GDI+ on Windows platforms where Direct2D is not available

Applications and interfaces developed with FireMonkey are separated into two categories HD and 3D. HD and 3D elements can be mixed by utilizing built-in components that are included in the IDE.

HD applications are 2D applications with flat interfaces similar to software that is developed using VCL.  3D applications are 3D applications and feature an three dimensional  XYZ interface.

Firemonkey is a full software development framework, and retains many features available with VCL. The major differences are:

  • Cross-platform compatibility
  • Vector drawn interface elements
  • Any visual component can be a child of any other visual component allowing for creation of hybrid components
  • Built-in styling support
  • Support for visual effects (such as Glow, Inner Glow, Blur for example) and animation of visual components

Due to the framework being cross-platform compatible, the same source code can be used to deploy to the various platforms it supports. Originally, FireMonkey natively supported 32-bit and 64-bit executables on Windows and 32-bit executables on Mac OS X and iOS.

As of the release of XE3, iOS support has been dropped, but it is still possible to develop iOS applications using XE2 editions of the same products. FireMonkey 2 or FM² is the name of the framework in XE3, and though it provides similar features to what was shipped with XE2, there have been numerous improvements in many areas of the framework.

As of this writing (December 2012) the Embarcadero R&D team is working on iOS and Android support.

Windows 8 ARM and Linux server are targeted for the second half of 2013.

Are there alternatives to FireMonkey?

Yes! Certainly. There are even Pascal based alternatives. FPC and Lazarus are cross platform options as well as Qt (C++) wxWidgets(C++).

  • FPC/Lazarus
    • Free Pascal (aka FPK Pascal) is a 32 and 64 bit professional Pascal compiler. It can target multiple processor architectures: Intel x86, AMD64/x86-64, PowerPC, PowerPC64, SPARC, and ARM. Supported operating systems include Linux, FreeBSD, Haiku, Mac OS X/iOS/Darwin, DOS, Win32, Win64, WinCE, OS/2, MorphOS, Nintendo GBA, Nintendo DS, and Nintendo Wii. Additionally, JVM, MIPS (big and little endian variants) and Motorola 68k architecture targets are available in the development versions.
  • Qt
    • Qt is a cross-platform application and UI framework for developers using C++ or QML, a CSS & JavaScript like language. Qt Creator is the supporting Qt IDE.”
  • Mono
    • “Mono is a software platform designed to allow developers to easily create cross platform applications. Sponsored by Xamarin, Mono is an open source implementation of Microsoft’s .NET Framework based on the ECMA standards for C# and the Common Language Runtime.”
  • wxWidgets
    • “wxWidgets is a C++ library that lets developers create applications for Windows, OS X, Linux and UNIX on 32-bit and 64-bit architectures as well as several mobile platforms including Windows Mobile, iPhone SDK and embedded GTK+. It has popular language bindings for Python, Perl, Ruby and many other languages. Unlike other cross-platform toolkits, wxWidgets gives its applications a truly native look and feel because it uses the platform’s native API rather than emulating the GUI. It’s also extensive, free, open-source and mature.”

Why FireMonkey?

From a Delphi developer perspective FireMonkey is an interesting alternative to developing cross-platform solutions because it allows for leveraging on existing knowledge and concepts from the VCL and the language.

Another less often mentioned reason is the fact that Embarcadero is a software  development company and as such is hardware and platform neutral.

To better understand the previous statement let’s take a look at what happened to Qt. Qt development was started in 1994 by Trolltech, a Norwegian software company, as a way to developing cross-platform applications, including mobile platforms. In mid 2008 Nokia acquired Trolltech and imposed a new development strategy focusing mostly on it’s own hardware and Symbian mobile OS. Lots of progress were done in the mobile environment. This was done in detriment of all other platforms. Then in early 2011 Nokia announced it was dropping the Symbian OS and as a side causality the Qt Framework. Qt was sold off to Digia. As a result of that Qt is lagging on several areas of the mobile segment.

FireMonkey versions

FireMonkey was introduced in Delphi XE2. In 2012 a new version, FireMonkey 2 or FM2, was shipped with Delphi XE3. From this point onwards we are going to concentrate on what is new in FM2.

VCL vs. FMX - a quick introduction to FMX for a VCL connoisseur

Visual Component Library or VCL is a Windows only framework and can not be used in FireMonkey. FireMonkey has introduced it’s on visual library named FMX.

FMX is compatible with Windows, Mac and soon IOS, Android, Linux and Windows ARM.

FMX and VCL share some common ancestry. Both object models start with a TObject that descends to a TPersistent and then to a TComponent. After TComponent the libraries diverge. FMX goes to TFMXObject, TControl and then to TStyleControl or TShape.

FMX and VCL Object tree

TStyledControl is used as a basis for all the visual components and is the base class for customizable and user-interaction controls.

TShape is the base class for 2D primitives. TShape defines the common behavior–methods and properties–for 2D graphic primitives and it cannot be used as stand alone component.

The event model remains the same between VCL and FMX. So, when it comes to events anything that applies to the VCL will apply to FMX. The same can be said about object persistence. FMX and VCL share TPersistent. As you already may know TPersistent is the ancestor for all objects that have assignment and streaming capabilities.

In a VCL application your component can broadcast messages to all the controls in a form, send messages to a particular control (or to the application itself), or even send messages to itself.  FMX does not support component messages in the same way  the VCL does.

The coordinate system is different in FM2. While the VCL uses left and top FMX uses X, Y and Z. Left and Top are integers and X,Y and Z are floating point. This change was brought into FMX out of the need to address 3D positioning on the form.

And speaking of properties, we need to be aware some properties have changed. For example: Caption is now Text, Left and Top are now Position.X, Position.Y and Position.Z

Object Ownership mechanism remains the same across the two libraries and Object parenting is similar. The difference is that FMX does not restrict parenting to container like controls like the VCL and Child Objects share attributes from it’s parents.

In FMX TCanvas is not a direct device wrapper as it is in VCL

As in the VCL the FMX.TControl is the base class for on-screen components. However, in FMX subclasses are divided into primitive shapes (TShape) and styleable controls (TStyledControl).  FMX.TControl extends TFmxObject to present objects that are seen, by adding properties and methods for size, position, margins, alignment, visibility, mouse and keyboard interaction, focus, animations, effects and painting.

What is new in FM2

While some changes were brought in to improve performance other changes were clearly targeting enhanced crossed platform including mobile devices. One can clearly see this pattern in the new items introduced and to some extent on the changes made to the framework.

FM2 brings framework refinements, a new Multimedia components, a new Layout components, a new Platform Services class, Styled Non-Client areas, Actions, Anchors, Sensors, Touch and Gestures. It also has enhanced Styles, 3D

Unneeded properties where prevented from being surfaced everywhere. That speeds up loading and saving form info at design time and loading forms at run time

Bitmap performance enhancements where brought in FM2. FM2 switches to native bitmap as soon as possible. That means that bitmaps are moved into the GPU’s memory. This brings the side effect of not allowing direct access to bitmaps. It is possible to map pixel data to a buffer and push changes to the GPU.

FM2 now offers support to capturing data from any capture devices. For that you can use TCaptureDevice and TCaptureDeviceManager. A new Multimedia wrapper was introduced to allow playing of media files. The TMedia, TMediaPalyer and TMediaPlayer control wrap around the host OS native multimedia system.

With cross-platform development come some unique challenges. Specially if you throw into the mix some smaller devices such as phones and tablets. So, some changes were introduced to allow for better screen layout management.

Every VCL programmer knows the worth of components Anchors. Anchors were missing from the first installment of FireMonkey. But never fear, Anchors were introduced on FM2 along with some welcome layout managers; TFlowLayout and TGridLayout.

Anchors were introduced to work together with Layout Managers

TFlowLayout arranges components as if they were words in a paragraph. It allows the developer to select spacing between components, component alignment and even forced breaks using a TFlowLayoutBreak.

TGridLayout allows controls to be arranged in a grid of equally sized cells. This layout manager rearranges objects in it’s grid every time the layout changes. The components inside the a TGridLayout are resized to fit the sizes of the cells. Controls can be arranged in vertical or horizontal cells.

FM2 obsoleted TPlatform as a means to find information about supported features on a host OS because it was too rigid, desktop centered and did not adapt well to targeting diverse software and hardware platforms with different/disparate services.

In it’s place TPlatformServices (FMX.Platform) was introduced.TPlatformServices can be used to to dynamically figure out what is available. This is a registry class that can be queried and uses Supports syntax. It also allows the programmer to easily implement custom devices and services.

FM2 introduced Touch and Gestures. This feature is modeled after the VCL Gesture engine. The are a few differences between the VCL implementation and the FMX implementation.

FireMonkey does not support fewer interactive gestures on Mac OS X than the number of supported gestures on a Windows PC. In the Mac only igZoom, igPan and igRotate are supported. FireMonkey does not support custom Gestures. Mouse gestures only work on Windows 7 and Windows 8.  And on Windows interactive gestures and standard gestures cannot be used at the same time. Also FireMonkey adds TouchTargetExpansion which allows for expanded touch target around a control by adding a specified zone to be behave as if the user had touched the control itself.

FMX has introduced non-visual components that implements location and motion sensors. A great way of looking at what is coming in the sensors framework is to examine the unit System.Sensors.  (One way to test location in Windows without a location device attached to your computer is to use Geosense for Windows (http://geosenseforwindows.com). Geosense is a free software driven location sensor for Windows.)

Speaking of units, any unit that starts with “FMX.” is a FMX unit only. However, units such as System.Sensors are framework agnostic. So, based on this statement, sensors components can be used in both VCL and FMX applications

Cross-platform programming

Last but not least, we need to talk about some best practices in cross-platform programming.

Always think cross-platform. Up to now our deployment OS was Windows and our way of thinking was base of the Windows programming model. Depending on your target(s) certain services may not available. For example, a desktop will certainly have a mouse, however a phone/tablet will be just the opposite.

Same recommendation goes for resources such as storage, connectivity, CPU power,  battery, screen size, and so on. While on the desktop environment such resources are virtually endless in a mobile scenario most resources are limited and at times not available at all.

And while a desktop computer is a generic device a smartphone is a specialized device and as such it has one primary function that overrides any other function – the ability to receive and place calls at will. So programs need to be able to deal with such interruptions in a graceful manner.

One must program accordingly to such limitations and specific functions. And in some cases program to the lowest common denominator.

Unless you have a very good reason, prefer a feature that is implemented thru the framework as opposed to natively. Most often there is no valid reason to do the opposite. Let the framework do it’s job and abstract you from the OS. That will buy you compatibility with newer platforms that come in to the framework.

If you must use a platform specific functionality make sure you document why yu are doing so and provide implementations to all platforms that your project is targeting. Also, provide an easy way to warn others that that specific feature was not supported by your implementation either at compile time or at run-time on any other platform.

A good way to implement this is to surround the implementation with a set of conditional pre-compiler directives as demonstrated in the code snippet below:

{$IFDEF MSWINDOWS}
  uses Winapi.Windows;
{$ELSE IFDEF MACOS}
  uses Macapi.Mach;
{$ELSE}
  {$MESSAGE FATAL &#039;Feature not implemented!&#039;}
{$ENDIF}

Final thoughts

FireMonkey is a serious contender for the seasoned Delphi/VCL developer. It has significantly improved on it’s second version. Furthermore, Embarcadero’s product development strategy is pushing the product into a very desirable position. That position is the ability to develop once and deploy across many platforms including the two leading mobile platforms. Thus making the platform irrelevant and allowing developers to focus on the delivery of a solution.

The iOS version of FM2 is imminent, followed soon by the Android version, and later by the Windows ARM and Linux version. From where I stand I can see an exciting future ahead. Call me an incorrigible optimist if you will. I’ll take that!

The Wiert Corner - irregular stream of stuff: CcKkOoSsUuVvWwXxZz are much alike.

$
0
0
Lucida Console Sample (thanks Wikimedia!)

Lucida Console Sample (thanks Wikimedia!)

I’m in search to see if there is a better programmers font than the monospaced Lucida Console mainly to be used in Visual Studio, Delphi, the Windows console, Xcode and Eclipse.

What I love about Lucida Console design is the relatively large x-height combined with a small leading (often called “line height”).

This combines very readable text, and a lot of code lines in view.

Lucida has two small drawbacks, see the second image at the right:

  • The captial O and digit 0 (zero) are very similar.
  • Some uppercase/lowercase character pairs are alike (because of the large x-height)

But, since the font hasn’t been updated for a very long time, lots of Unicode code points that are now in current fonts, are missing from Lucida Console (unless you buy the most recent version that has 666 characters from Fonts.com)

Well, there are dozens of monospaced fonts around, so I wonder: which ones do you like?

In the mean while, I’m going to do some experimenting with fonts mentioned in these lists:CcKkOoSsUuVvWwXxZz are much alike.

A few fonts I’m considering (I only want scalable fonts, so .fon files are out):

  • Anonymous Pro
  • Crystal
  • Envy Code R preview #7 (scalable coding font)
  • Hyperfont
  • Inconsolata-dz
  • ProFontWindows

–jeroen


Filed under: .NET, Apple, Delphi, Delphi 2007, Delphi XE3, Development, Font, Mac, OS X, Power User, Programmers Font, Software Development, Typography, Visual Studio 11, Visual Studio 2005, Visual Studio 2008, Visual Studio 2010, Visual Studio and tools, Windows, Windows 7, Windows 8, Windows Server 2008 R2, Windows XP, xCode/Mac/iPad/iPhone/iOS/cocoa

Delphi Code Monkey: My app is in the App Store.

$
0
0
This app is pure Objective-C, using the remObjects Data Abstract + RemObjects SDK to  build the Delphi middle-tier server service.

RentalPointToGo uses a Made-for-iPhone (MFi) accessory called the Linea Pro from Infinite Peripherals, which is the same barcode-scanning hardware used with iphones, in the Apple retail stores.




The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Behind the connection: OpenSource GDI+ Library - Part 2

$
0
0
In a previous article, I talked about OpenSource GDI+ Library for Delphi. In this article I will present a small application which is the basic of an image processing or image drawing application. A form to display an image The application is divided into two forms. One main form and one image display form. The main form creates two instances of the image display form to show two images

Žarko Gajić: Replacing SHFileOperation With IFileOperation To Process Multiple File Operations In One Call (Delphi Code)

$
0
0

delphi-ifileoperation
Starting with Windows Vista (and Windows Server 2008) the Windows API arsenal has a new and more powerful way of performing file operations like copy, move, delete and similar file and folder shell actions. The old (but still valid) SHFileOperation function is now replaced by the IFileOperation interface.
The IFileOperation exposes methods to copy, move, rename, create, and delete Shell items as well as methods to provide progress and error dialogs.

If you’ve used to working with SHFileOperation, and have been hit (for example) by the MAX_PATH problem, a solution can be found in IFileOperation. Here’s how to use IFileOperation in Delphi and ensure non existing folders are created in a copy operation.

The IFileOperation has many advantages over the SHFileOperation function, like being able to perform different operations in one call. You can delete a few files, copy some more, rename a folder, apply properties to a file – all in one operation. SHFileOperation can only do one operation at a time: copy, move, rename, or delete.

In this post I’ll concentrate on copying files. To make it simple the copy operation will copy a single file from its location to a destination folder and have the file name changed at the destination.

SHFileOperation

While you can locate lots of examples on how to use the SHFileOperation in Delphi, and the Jedi library also has it nicely wrapped in a component, here’s a short code to show you how to copy a file:

uses ShellApi;

function CopyFileSHFileOperation(const srcFile, destFile : string) : boolean;
var
  shFOS : TShFileOpStruct;
begin
  ZeroMemory(@shFOS, SizeOf(TShFileOpStruct));

  shFOS.Wnd := Application.MainForm.Handle;

  shFOS.wFunc := FO_COPY;

  shFOS.pFrom := PChar(srcFile + #0);
  shFOS.pTo := PChar(destFile + #0);

  //Do not ask the user to confirm the creation of a
  //new directory if the operation requires one to be created.
  shFOS.fFlags := FOF_NOCONFIRMMKDIR;

  result := SHFileOperation(shFOS) = 0;
end;

There’s one nice feature of the SHFileOperation: if the destination folder does not exist the function will create it! The FOF_NOCONFIRMMKDIR flag ensures no dialogs are presented to the user by Windows asking if the destination folder should be created.

IFileOperation

Here’s how you can copy a file using the IFileOperation interface

uses ActiveX, ComObj, ShlObj;;

function CopyFileIFileOperation(const srcFile, destFile : string) : boolean;
//works on Windows >= Vista and 2008 server
var
  r : HRESULT;
  fileOp: IFileOperation;
  siSrcFile: IShellItem;
  siDestFolder: IShellItem;
  destFileFolder, destFileName : string;
begin
  result := false;

  destFileFolder := ExtractFileDir(destFile);
  destFileName := ExtractFileName(destFile);

  //init com
  r := CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
  if Succeeded(r) then
  begin
    //create IFileOperation interface
    r := CoCreateInstance(CLSID_FileOperation, nil, CLSCTX_ALL, IFileOperation, fileOp);
    if Succeeded(r) then
    begin
      //set operations flags
      r := fileOp.SetOperationFlags(FOF_NOCONFIRMATION OR FOFX_NOMINIMIZEBOX);
      if Succeeded(r) then
      begin
        //get source shell item
        r := SHCreateItemFromParsingName(PChar(srcFile), nil, IShellItem, siSrcFile);
        if Succeeded(r) then
        begin
          //get destination folder shell item
          r := SHCreateItemFromParsingName(PChar(destFileFolder), nil, IShellItem, siDestFolder);

          //add copy operation
          if Succeeded(r) then r := fileOp.CopyItem(siSrcFile, siDestFolder, PChar(destFileName), nil);
        end;

        //execute
        if Succeeded(r) then r := fileOp.PerformOperations;

        result := Succeeded(r);

        OleCheck(r);
      end;
    end;

    CoUninitialize;
  end;
end;

Note that the PerformActions method executes actions added by calling individual methods like CopyItem(s), DeleteItem(s) and alike.

However, there’s one BIG problem in using IFIleOperation: in a copy action, if the destination folder does not exists the action will fail!

This is true even if FOF_NOCONFIRMMKDIR is set using the SetOperationFlags method.

Note the line where SHCreateItemFromParsingName is used for the second time:

//get destination folder shell item
r := SHCreateItemFromParsingName(PChar(destFileFolder), nil, IShellItem, siDestFolder);

It creates and initializes the shell item for the destination folder, and if this folder does not exist the call would fail.

IFileOperation.CopyItem + Force Destination Directory

The solution is to be found in the second parameter: const pbc: IBindCtx; This is a pointer to a bind context used to pass parameters to the parsing function (in this case SHCreateItemFromParsingName). We can use the binding context to force SHCreateItemFromParsingName not to query the file system – rather to just use what we provide. And what we will provide is a complex mixture of WIN32_FIND_DATA structure (specifying FILE_ATTRIBUTE_DIRECTORY), and instance of an object implementing IFileSystemBindData interface.

Here’s the full code, and the implementation of the required interface.

uses ActiveX, ComObj, ShlObj;

function CopyFileIFileOperationForceDirectories(const srcFile, destFile : string) : boolean;
//works on Windows >= Vista and 2008 server
var
  r : HRESULT;
  fileOp: IFileOperation;
  siSrcFile: IShellItem;
  siDestFolder: IShellItem;
  destFileFolder, destFileName : string;
  pbc : IBindCtx;
  w32fd : TWin32FindData;
  ifs : TFileSystemBindData;
begin
  result := false;

  destFileFolder := ExtractFileDir(destFile);
  destFileName := ExtractFileName(destFile);

  //init com
  r := CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
  if Succeeded(r) then
  begin
    //create IFileOperation interface
    r := CoCreateInstance(CLSID_FileOperation, nil, CLSCTX_ALL, IFileOperation, fileOp);
    if Succeeded(r) then
    begin
      //set operations flags
      r := fileOp.SetOperationFlags(FOF_NOCONFIRMATION OR FOFX_NOMINIMIZEBOX);
      if Succeeded(r) then
      begin
        //get source shell item
        r := SHCreateItemFromParsingName(PChar(srcFile), nil, IShellItem, siSrcFile);
        if Succeeded(r) then
        begin
          //create binding context to pretend there is a folder there
          if NOT DirectoryExists(destFileFolder) then
          begin
            ZeroMemory(@w32fd, Sizeof(TWin32FindData));
            w32fd.dwFileAttributes := FILE_ATTRIBUTE_DIRECTORY;
            ifs := TFileSystemBindData.Create;
            ifs.SetFindData(w32fd);
            r := CreateBindCtx(0, pbc);
            r := pbc.RegisterObjectParam(STR_FILE_SYS_BIND_DATA, ifs);
          end
          else
            pbc := nil;

          //get destination folder shell item
          r := SHCreateItemFromParsingName(PChar(destFileFolder), pbc, IShellItem, siDestFolder);

          //add copy operation
          if Succeeded(r) then r := fileOp.CopyItem(siSrcFile, siDestFolder, PChar(destFileName), nil);
        end;

        //execute
        if Succeeded(r) then r := fileOp.PerformOperations;

        result := Succeeded(r);

        OleCheck(r);
      end;
    end;

    CoUninitialize;
  end;
end;

Here’s the TFileSystemBindData, IFileSystemBindData interface implementation:

type
  TFileSystemBindData = class (TInterfacedObject, IFileSystemBindData)
    fw32fd: TWin32FindData;

    function SetFindData(var w32fd: TWin32FindData): HRESULT; stdcall;
    function GetFindData(var w32fd: TWin32FindData): HRESULT; stdcall;
  end;
...
function TFileSystemBindData.GetFindData(var w32fd: TWin32FindData): HRESULT;
begin
  w32fd:= fw32fd;
  Result := S_OK;
end;

function TFileSystemBindData.SetFindData(var w32fd: TWin32FindData): HRESULT;
begin
  fw32fd := w32fd;
  Result := S_OK;
end;

Finally, the usage goes like:

//works even if "d:\f1\f2\f3\" does not exist!
CopyFileIFileOperationForceDirectories('c:\somefile.png', 'd:\f1\f2\f3\copiedfile.png');

That’s it, now you can use IFIleOperation instead of SHFileOperation. Of course, you need to make sure your code runs on at least Windows Vista or Windows Server 2008. You can use the TOSVersion to check the operating system your code runs on.

Delphi Haven: Arnaud Bouchez on the nextgen compiler

$
0
0

Arnaud Bouchez of Synopse open source fame (mORmot etc.) has written an interesting piece on the ‘nextgen’ compiler that debuted with XE4′s iOS support – check it out.


Firebird News: Jaybird 2.2.3 (Firebird JDBC) released

$
0
0
The Firebird JDBC team is happy to announce the release of Jaybird 2.2.3. See http://www.firebirdsql.org/en/jdbc-driver/ for the downloadlinks. The release is also available on maven: <groupId>org.firebirdsql.jdbc</groupId> <artifactId>jaybird-jdkXX</artifactId> <version>2.2.3</version> The artifactId depends on your target Java version: jaybird-jdk15, jaybird-jdk16 or jaybird-jdk17. The following has been changed or fixed in Jaybird 2.2.3: Fixed incorrect synchronization in native [...]

Castle Game Engine news: Development: transitionComplete, Debian packages, network tutorial, data URI, MultiTexture tests, more

$
0
0
Caffeine model from http://www.web3d.org/x3d/content/examples/Basic/ChemicalMarkupLanguage/index.html
data URI demo. All the textures, movies, sounds, scripts, linked 3D models here are embedded using data URI.
MultiTexture.function test
MultiTexture.mode and source test
MultiTexture blending modes test
Fireplace model, with fire rendered as animated image sequence

Various new features developed for next Castle Game Engine and view3dscene:

  1. NavigationInfo.transitionComplete support. Demo model transition_multiple_viewpoints.x3dv shows how to use it to make an animated transition between a couple of viewpoints.

  2. Thanks to Abou Al Montacir we will have packages with Castle Game Engine and view3dscene in Debian! Most of this software was developed by Michalis using Debian, so having my software in the Debian repository would feel really great for me :) See here for our forum thread, and here is the Debian bug marking ITP (Intent To Package) for engine: #706408 and for view3dscene: #707932.

  3. For developers, new chapter of our tutorial describing network support is available.

  4. Engine examples contain a simple tool examples/tools/to_data_uri.lpr that can generate data URI (to embed your texture, audio, model, etc. inside a VRML/X3D model, or a webpage, or other documents) from any file. It gets the file and guesses MIME type using our existing CastleDownload unit, so it supports local files as well as http links, and MIME type is retrieved from server or guessed based on file extension.

    There is a demo data_uri.x3dv showing how you can use data URI to embed all kinds of things inside X3D file: textures, sounds, other 3D models (to Inline or Anchor to them), scripts etc.

  5. MultiTexture.function support (forces shader pipeline rendering for given shape; there's no way to reasonably implement this using fixed-function pipeline). Demo in functions.x3dv.

  6. A set of X3D multi-texturing tests is available, testing support of view3dscene and other VRML / X3D browsers for multi-texture features. This is part of my ongoing effort to improve X3D MultiTexturing specification.

  7. There is a progress bar showing the process the downloading. The download is still blocking, but at least now you see what's going on :)

  8. If you load or save image sequences using the syntax image%d.png, for example inside our extension Movies for MovieTexture can be loaded from images sequence: the new syntax to indicate counter inside the URL will be @counter(4), where 4 is the padding. For example image%d.png has to be changed to image@counter(1).png and image%4d.png has to be changed to image@counter(4).png.

    For loading, you will have to use new syntax with @counter(<padding>) with new view3dscene / Castle Game Engine versions. You will have to update your VRML/X3D models, old syntax will unfortunately not work anymore (reasons below). For saving, the old syntax %d will continue to work for some time (along the new @counter(<padding>) syntax, and you're encouraged to upgrade to new syntax).

    The reason for this is that MovieTexture.url is now correctly treated as an URL, and this means that percent character % needs to be escaped to %25. Inside URL the sequence %4d has to mean letter M (ASCII code 77, which is 4d in hexadecimal). So there is unfortunately no way to avoid breaking compatibility — we want to correctly support URLs, which implies that %4d must be interpreted as letter "M", not as a magic counter.

    Looking back, it was an unfortunate choice to use percent character to indicate images sequence, since percent is special inside URIs. It was done for consistency with ffmpeg, that supports things like image%4d.png on the command-line (but not when using URLs; for example, ffplay /home/image%4d.png works, but ffplay file:///home/image%4d.png does not work, neither does ffplay file:///home/image%254d.png). So, one can say that it was ffmpeg that made a bad choice, but then ffmpeg did it for consistency with common string formatting functions (C sprintf, ObjectPascal Format)...

    Comments about this change are of course welcome, through forum or any other means. Right now, I just don't see a way to avoid breaking compatibility. We made a bad decision to use %d to indicate image sequence, and it has to change in order to correctly support URL encoding in new versions.

  9. A couple of bugfixes. Including bugfix to a quite horrible mistake in ShaderPart node, in some circumstances the shader code would be reloaded from file at every frame, causing a horrible slowdown. It's fixed now of course.

Viewing all 1725 articles
Browse latest View live