Planet Object Pascal

October 01, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

I’ve been experimenting with the Delphi hinting directives lately to make it easier to migrate some libraries to newer versions of Delphi and newer platforms.

Hinting directives (deprecated, experimental, library and platform) were – like the $MESSAGE directive – added to Delphi 6.

Up to Delphi 5 you didn’t have any means to declare code obsolete. You had to find clever ways around it.

Warnings for hinting directives

When referring to identifiers marked with a hinting directive, you can get various warning messages that depend on the kind of identifier: unit, or other symbol.

Note the warning numbering is not in the alphabetic order of the hinting directive.

Unit identifiers can get these warnings:

  • W1006 Unit ‘HintingDirectivesUnit’ is deprecated
    //unit HintingDirectivesUnit deprecated;
  • W1007 Unit ‘HintingDirectivesUnit’ is experimental
    //unit HintingDirectivesUnit experimental;
  • W1004 Unit ‘HintingDirectivesUnit’ is specific to a library
    //unit HintingDirectivesUnit library;
  • W1005 Unit ‘HintingDirectivesUnit’ is specific to a platform
    //unit HintingDirectivesUnit platform;

Non-unit symbols can get these warnings:

  •  W1000 Symbol ‘FieldDepracated’ is deprecated
    //Default.FieldDepracated := 1;
  •  W1003 Symbol ‘FieldExperimental’ is experimental
    //Default.FieldExperimental := 1;
  •  W1001 Symbol ‘FieldLibrary’ is specific to a library
    //Default.FieldLibrary := 1;
  •  W1002 Symbol ‘FieldPlatform’ is specific to a platform
    //Default.FieldPlatform := 1;

Hinting directives: deprecated differs from the others

Of the hinting directives, deprecated is more versatile than experimental, library and platform as it allows two forms: with and without a ‘comment’.

I wasn’t aware of this part of the deprecated syntax until recently. The syntax part was introduced in Delphi 12.0 (aka Delphi 2009). You can for instance see it in the RTLConsts unit:

SInvalidDate = '''''%s'''' is not a valid date' deprecated 'Use SysConsts.SInvalidDate';
SInvalidDateTime = '''''%s'''' is not a valid date and time' deprecated 'Use SysConsts.SInvalidDateTime';
SInvalidInteger = '''''%s'''' is not a valid integer value' deprecated 'Use SysConsts.SInvalidInteger';
SInvalidTime = '''''%s'''' is not a valid time' deprecated 'Use SysConsts.SInvalidTime';
STimeEncodeError = 'Invalid argument to time encode' deprecated 'Use SysConsts.STimeEncodeError';

ModelMaker Code Explorer does not support this syntax yet, but they are aware of this.

But depending on the kind of identifier you use it on, the compiler warnings can be different.

When used on a unit, you can use both forms, but when using the unit, you get one kind of compiler warning:

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1006 Unit 'HintingDirectivesUnit' is deprecated
//unit HintingDirectivesUnit deprecated;

No warning about the ‘comment':

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1006 Unit 'HintingDirectivesUnit' is deprecated
//unit HintingDirectivesUnit deprecated 'use a different one';

But when using it on a variable,

var
I: Integer deprecated 'do not use global variables';
J: Integer deprecated;
K: Integer deprecated platform library experimental;

the forms result in different compiler warnings:

// W1000 Symbol 'I' is deprecated: 'do not use global variables'
I := 1;

// W1000 Symbol 'J' is deprecated
J := 2;

// W1000 Symbol 'K' is deprecated
// W1001 Symbol 'K' is specific to a library
// W1002 Symbol 'K' is specific to a platform
// W1003 Symbol 'K' is experimental
K := 3;

The effects of a unit hinting directive

The hinting directive documentation states that hinting directives on units apply on references to all the symbols on the unit:

When a hint directive appears in a unit declaration, it means that the hint applies to everything in the unit. For example, the Windows 3.1 style OleAuto.pas unit on Windows is completely deprecated. Any reference to that unit or any symbol in that unit produces a deprecation message.

But this also has a twist on all the unit symbols referenced from within the unit: when a symbol is marked with the same hinting directive as the unit, you will not get a warning referencing that symbol in the unit itself.

So a symbol marked deprecated, will not show a warning when referenced from inside the unit if the unit is also marked deprecated. The same holds for the other hinting directives.

Hinting directives on properties are still a no-go

Despite QC96350 (Cannot apply ‘deprecated’ keyword to property declarations) being open for 2 years, and the StackOverflow question How can I mark a property as deprecated in delphi? you can’t use hinting directives on properties.

So far for consistency (I will blog more on that later).

You cannot do either of these:

type
  TTest = class
  protected
    FValue: Integer;
  public
    property Value: Integer read FValue write FValue; deprecated; // E2169 Field definition not allowed after methods or properties
    property Value2: Integer read FValue write FValue deprecated; // E2029 ';' expected but identifier 'deprecated' found
  end;

Applying and combining hinting directives

A few rules for using hinting directives

  • The semicolon between the hinting directive and the symbol declaration usually has to be left out, except for methods where it has to be there.
  • There is no semicolon between combined hinting directives.
  • The abstract directive comes after the last hinting directive and does get separated by a semicolon.

So you get code like this:

THinted = class
end deprecated platform library experimental;

FieldDepracated: Integer deprecated;
FieldAll: Integer deprecated platform library experimental;

function Func: Integer; virtual; abstract;
function FuncDeprecated: Integer; virtual; deprecated; abstract;

procedure Proc; virtual; abstract;
procedure ProcDeprecated virtual; deprecated; abstract;

Full sample code

The full sample code is a BeSharp SVN change-set; the main unit is below.

Have fun with it!

–jeroen

unit HintingDirectivesUnit;

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1006 Unit 'HintingDirectivesUnit' is deprecated
//unit HintingDirectivesUnit deprecated;

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1007 Unit 'HintingDirectivesUnit' is experimental
//unit HintingDirectivesUnit experimental;

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1004 Unit 'HintingDirectivesUnit' is specific to a library
//unit HintingDirectivesUnit library;

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1005 Unit 'HintingDirectivesUnit' is specific to a platform
//unit HintingDirectivesUnit platform;

//[DCC Warning] HintingDirectivesConsoleProject.dpr(9): W1006 Unit 'HintingDirectivesUnit' is deprecated
//unit HintingDirectivesUnit deprecated 'use a different one';

interface

var
  I: Integer deprecated 'do not use global variables';
  J: Integer deprecated;
  K: Integer deprecated platform library experimental;

type
  THinted = class
  end deprecated platform library experimental;

// W1000 Symbol 'THinted' is deprecated
// W1001 Symbol 'THinted' is specific to a library
// W1002 Symbol 'THinted' is specific to a platform
// W1003 Symbol 'THinted' is experimental
// W1000 Symbol 'THinted' is deprecated
  THintedClass = class of THinted;

  TDefault = class(TObject)
  strict private
    FMember: Integer;
  public
    Field: Integer;
    FieldDepracated: Integer deprecated;
    FieldExperimental: Integer experimental;
    FieldLibrary: Integer library;
    FieldPlatform: Integer platform;
    FieldAll: Integer deprecated platform library experimental;
    function Func: Integer; virtual; abstract;
    function FuncDeprecated: Integer; virtual; deprecated; abstract;
    function FuncExperimental: Integer; virtual; experimental; abstract;
    function FuncLibrary: Integer; virtual; library; abstract;
    function FuncPlatform: Integer; virtual; platform; abstract;
    procedure Proc; virtual; abstract;
    procedure ProcDeprecated; virtual; deprecated; abstract;
    procedure ProcExperimental; virtual; experimental; abstract;
    procedure ProcLibrary; virtual; library; abstract;
    procedure ProcPlatform; virtual; platform; abstract;
    property Member: Integer read FMember write FMember;
  strict protected
    procedure ProcDeprecatedComment; virtual; deprecated 'use some other Proc in stead'; abstract;
  strict private
    // E2169 Field definition not allowed after Procs or properties
    // procedure ProcAbstractDeprecated; virtual;  abstract; deprecated;

    // E2029 ';' expected but string constant found
    // procedure ProcExperimentalComment; virtual; experimental 'Experimental Proc'; abstract;

    // E2029 ';' expected but string constant found
    // procedure ProcLibraryComment; virtual; library 'Library Proc'; abstract;

    // E2029 ';' expected but string constant found
    // procedure ProcPlatformComment; virtual; platform 'Platform Proc'; abstract;

    // E2169 Field definition not allowed after Procs or properties
    // property MemberDeprecated: Integer read FMember write FMember; deprecated;
  end;

// W1001 Symbol 'THinted' is specific to a library
// W1002 Symbol 'THinted' is specific to a platform
// W1003 Symbol 'THinted' is experimental
implementation

procedure UseDefault;
var
  Default: TDefault;
begin
// W1000 Symbol 'I' is deprecated: 'do not use global variables'
  I := 1;
// W1000 Symbol 'J' is deprecated
  J := 2;
// W1000 Symbol 'K' is deprecated
// W1001 Symbol 'K' is specific to a library
// W1002 Symbol 'K' is specific to a platform
// W1003 Symbol 'K' is experimental
  K := 3;
// W1000 Symbol 'FuncDeprecated' is deprecated
// W1003 Symbol 'FuncExperimental' is experimental
// W1001 Symbol 'FuncLibrary' is specific to a library
// W1002 Symbol 'FuncPlatform' is specific to a platform

// W1000 Symbol 'ProcDeprecated' is deprecated
// W1003 Symbol 'ProcExperimental' is experimental
// W1001 Symbol 'ProcLibrary' is specific to a library
// W1002 Symbol 'ProcPlatform' is specific to a platform

// W1000 Symbol 'ProcDeprecatedComment' is deprecated: 'use some other Proc in stead'
  Default := TDefault.Create();
  try
    Default.Field := 1;
// W1000 Symbol 'FieldDepracated' is deprecated
    Default.FieldDepracated := 1;
// W1003 Symbol 'FieldExperimental' is experimental
    Default.FieldExperimental := 1;
// W1001 Symbol 'FieldLibrary' is specific to a library
    Default.FieldLibrary := 1;
// W1002 Symbol 'FieldPlatform' is specific to a platform
    Default.FieldPlatform := 1;
  finally
    Default.Free;
  end;
end;

end.

Filed under: Apple Pascal, Borland Pascal, DEC Pascal, Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 6, Delphi 7, Delphi 8, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Encoding, FreePascal, ISO-8859, ISO8859, Java, Lazarus, MQ Message Queueing/Queuing, Reflection, Software Development, Sybase, Unicode, UTF-8, UTF8

by Jeroen Pluimers at October 01, 2014 05:00 AM

September 30, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

I recently bumped into the NTCore website by Daniel Pisti.

At a client without my own VMs, I wanted to create a DebugBreak like function in Delphi, which I remembered from my Turbo Pascal days to be something like Inline($CC). So searching for both Delphi and INT 3, I found an EXE injection page at NTCore.

In Delphi, you can do this with a procedure like this, which cannot be inlined because it has an asm block:

procedure DebugBreak();
asm
  int 3
end;

(Reminder to self: sort out what to do here to break on an iOS device; Xcode has an alternative)

The site has information about system internals and software security posted as articles until 2009,  when he switched to blog posts. Besides that, he has written a bunch of interesting articles at CodeProject.

An important product on his site is the Explorer Suite:

A freeware suite of tools including a PE editor called CFF Explorer and a process viewer. The PE editor has full support for PE32/64. Special fields description and modification (.NET supported), utilities, rebuilder, hex editor, import adder, signature scanner, signature manager, extension support, scripting, disassembler, dependency walker etc. First PE editor with support for .NET internal structures. Resource Editor (Windows Vista icons supported) capable of handling .NET manifest resources. The suite is available for x86 and x64.

It is a great tool aimed at the Windows PE format, and a prelude to the commercial Cerbero profiler at iCerbero.com which covers many more file formats and tools that can aid for instance in analyzing malware. Daniel has moved to Frankfurt, Germany and now is a security expert doing great work.

Daniel also as a great twitter feed where he refers to posts from others.

For instance, malware usually runs in the user context, which is one of the reasons you should be really careful storing passwords locally. So I was glad that Daniel pointed to all of your browser password stores are straightforward to decrypt.

–jeroen

Further reading:


Filed under: Delphi, Development, Pascal, Power User, Software Development, Turbo Pascal, Windows, xCode/Mac/iPad/iPhone/iOS/cocoa

by Jeroen Pluimers at September 30, 2014 05:00 AM

September 29, 2014

Firebird News

Interview with the author of Sqitch (database change management application)

As you might now Ștefan Suciu created a Firebird port for Sqitch Bellow is a interview with the author of Sqitch : David Wheeler with a few Firebird mentions ps: There is a GUI for Sqitch – Simple SQL change management created by Stefan https://github.com/stefansbv/sqitch-gui

by mariuz at September 29, 2014 03:49 PM

Mini-interview with Paul Reeves

We started a series or mini-interviews with speakers of Firebird International Conference 2014. The second guest is Paul Reeves

by mariuz at September 29, 2014 03:39 PM

Castle Game Engine news

September 26, 2014

while true do;

My “Delphi Cookbook” has been published

Almost an year ago I started to write a book about Delphi for Packt Publishing. Today that book has been published. This book is a cookbook! That’s it, in 328 pages you will find useful (I hope) “recipes” for your day-by-day Delphi job. Topics of the book Create visually stunning applications using FireMonkey Effectively use LiveBindings with the right OOP approach Create [...]

by Daniele Teti at September 26, 2014 03:34 PM

Firebird News

Mini-interview with Ann W. Harrison

We are starting series or mini-interviews with speakers of Firebird International Conference 2014. The first guest is Ann W. Harrison

by mariuz at September 26, 2014 11:29 AM

September 25, 2014

Castle Game Engine news

The Wiert Corner - irregular stream of stuff

jpluimers

If you are going to do test driven development and unit testing, you should watch these videos and slide decks, most of them by Miško Hevery:

  1. Not a video, but a good starter: Guide: Writing Testable Code (or read the PDF version).
  2. 0:32:07 ▶ “The Clean Code Talks — Unit Testing” – YouTube.
  3. 0:37:56 ▶ The Clean Code Talks – Don’t Look For Things! – YouTube.
  4. 0:54:08 ▶ The Clean Code Talks – “Global State and Singletons” – YouTube.
    • slides:     Clean Code Talks – Global State and Singletons. (slide 57; “global state is the root of all test problems”)
    • global state consequences for unit tests:
      • flakiness
      • order of test matters
      • tests cannot be run in parallel
    • red flags:
      • getting current time or date
      • getting a random number
    • be careful:
      • new operators are dangerous;
      • ask for what you need;
      • global state is nightmare;
      • constructor work is dangerous
  5. 0:38:24 ▶ “The Clean Code Talks — Inheritance, Polymorphism, & Testing” – YouTube.
  6. 0:56:02 ▶ Design Tech Talk Series Presents: OO Design for Testability – YouTube.
    • slides:     Design For Testablity (eye opener: slide 3; “No tests”: unit testing Common misconceptions/Invalid excuses)
  7. 1:18:41 ▶ How to Write Clean, Testable Code – YouTube.

The colon separated numbers in front of each video are the duration in H:MM:SS (yes, the final one is over an hour, but very interesting).

Each item consists of a video from the …. followed by the slide decks I find on …. site:

Thanks Stu Sherwin for pointing at this playist: Google Tech Talks – Misko Hevery – YouTube  by rtvdoorn (I found the playlist after bumping into the second talk).

There is also a list of videos at Info on OOP | westworld of which the non-overlapping ones are more aimed specifically at Java development (but for non-Java programmers, it is good to know about things like GUICE, JMock and EasyMock).

I still need to review the rest of the talks listed at About Miško Hevery.

–jeroen


Filed under: .NET, Agile, C#, Delphi, Development, Java, JavaScript, JavaScript/ECMAScript, Pascal, Software Development, Unit Testing, VB.NET

by Jeroen Pluimers at September 25, 2014 11:00 AM

September 24, 2014

while true do;

Using dynamic arrays and Parallel Programming Library (Part 1)

The Parallel Programming Library introduced in XE7 is one of the  most awaited built-in library for the Delphi and C++Builder RTL, at least for me. I’ve still a nice list waiting for the next versions, but this is another story Marco Cantù wrote about dynamic arrays some days ago, another nice feature introduced in [...]

by Daniele Teti at September 24, 2014 08:48 PM

Firebird News

Firebird 3.0 beta 1 is almost ready

Dmitry Yemanov recently announced (in fb-devel discussion list) that Beta 1 of Firebird 3 is expected to be released in the next week. Please take some time when Beta1 is out and do as much tests as you can, and report the problems back in fb-devel or Firebird tracker, helping the core developers to address the issues […]

by Cantu at September 24, 2014 04:42 PM

The Wiert Corner - irregular stream of stuff

jpluimers

A while ago, I had a client with an exception on a workstation.

There was no permission to run a debugger on their system, or use something like MadExcept or Exceptional Magic in their code base.

The exception looked like this:

---------------------------
Application Error
---------------------------
Exception EInOutError in module MyApplication.exe at 001656B1.File access denied.
---------------------------
OK
---------------------------

These are the steps to get at the source line in an x86 Delphi program (I still have to try the x64, but presume it works similarly):

  1. Go to the Project Options dialog
  2. Browse to Delphi Compiler; Linking
  3. Note the value of the Image Base setting (in this case $400000
  4. Add that to the value from the error dialog ($001656B1 + $400000 = $005656B1)
  5. Use F7 to step into your executable
  6. In the menu goto View; Debug Windows; CPU Windows; Entire CPU
  7. Press Ctrl-G then enter $005656B1
  8. Press Ctrl-V to go to the source code line

Convoluted, but it works (:

 

–jeroen


Filed under: Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development

by Jeroen Pluimers at September 24, 2014 05:00 AM

September 23, 2014

Firebird News

NHibernate 4.0.1.GA released with Firebird fixes

NHibernate 4.0.1 General Availability is now available for download from Sourceforge and Nuget. http://sourceforge.net/projects/nhibernate/?source=directory This includes fixes for regressions in NH 4.0.0, and some fixes for mapping-by-code and Firebird issues. Please see the full release notes for more information: https://github.com/nhibernate/nhibernate-core/blob/4.0.1.GA/releasenotes.txt

by mariuz at September 23, 2014 11:45 AM

September 21, 2014

Firebird News

Database .NET 13.0 released

Database .NET is an innovative, powerful and intuitive multiple database management tool, With it you can Browse objects, Design tables, Edit rows, Export data and Run queries with a consistent interface. New features and improvements from 12.4 to 13.0 (2014/09/22) Updated to FirebirdSql.Data.FirebirdClient.dll 4.5.1 Added [ADV] Advanced Browsing Options Added [ADV] Advanced Edit Options Added […]

by fishcodelib at September 21, 2014 04:23 PM

September 20, 2014

twm’s blog

Some changes to CustomContainerPack

Today I made some small changes to the CustomContainerPack.

If you don’t know about the Custom Container Pack, see my previous blog post.

Apart from removing two with statements I changed the place where the wizard shows up in the File -> New -> Other dialog. Up to Delphi 7 it is still in the “New” category.

ccpack_delphi7

For newer Delphi versions, it now shows up in the “Delphi Files” category:

ccpack_delphi2005

It took me quite a while to figure out how to do it. Just returning “Delphi Files” from the IOTARepositoryWizard.GetPage function doesn’t work. The trick is to use the IOTARepositoryWizard80 interface that was introduced with Delphi 2005 (or, judging from the name, probably with Delphi 8). It added two new functions to IOTARepositoryWizard:

    function GetPersonality: string;
    function GetGalleryCategory: IOTAGalleryCategory;

GetPersonality is easy, you just return one of the pre-defined string constants sXxxxPersonality, in this case: sDelphiPersonality

function TCCWizard.GetPersonality: string;
begin
  Result := sDelphiPersonality;
end;

(If anybody wants to check if CustomContainerCack can be used with the C++Builder personality, please contact me through my Google+ page.)

GetGalleryCategory is a bit more tricky. I found the solution in Steve’s Blog:

function TCCWizard.GetGalleryCategory: IOTAGalleryCategory;
var
  cat: IOTAGalleryCategory;
  catMgr: IOTAGalleryCategoryManager;
begin
  catMgr := (BorlandIDEServices as IOTAGalleryCategoryManager);
  Assert(Assigned(catMgr));
  cat := catMgr.FindCategory(sCategoryDelphiNewFiles);
  Assert(Assigned(cat));
  Result := cat;
end;

by dummzeuch at September 20, 2014 04:02 PM

The Wiert Corner - irregular stream of stuff

Firebird News

Avoding blind sql injections in #php

Common steps in avoiding sql injections 1.First step is to sanitize the inputs and never trust what comes from POST/GET : 2.Another tip is to Always use prepared statements (in ibase) or PDO that is more safe (query stays unchaged while executing the php script) and the parameters will be the only changes in the queries (feed them from […]

by mariuz at September 20, 2014 10:40 AM

September 19, 2014

The Podcast at Delphi.org

Hello Moto 360 from Delphi XE7

Moto 360I really like my Moto 360 watch. It looks fabulous, and does great as an extension of my Android phone, but of course the most important question is how to make an app for it. Turns out it just works with RAD Studio X7, Delphi or C++. Thanks to the new FireUI Multi-Device designer I can actually create a custom view in the UI to make designing the perfect user interface a breeze. Here are some of the details of what I discovered along the way, followed by a download of my sample and the custom view.

The bottom line is it just works, which really isn’t a surprise. Most new Android devices use ARMv7 and the NEON instruction set. (NEON is kind of like the MMX standard on the Intel platform. At first not everyone used those instructions, but once they caught on, everyone did.) So it is no surprise that the Moto 360 does too. Unlike some of the other watches, the Moto 360 does not have a micro USB port. So you have to use ADB over BlueTooth. This requires a few extra steps to setup, and is really slow to deploy over. So slow I canceled the first two deployments because I thought I set something up wrong.

First of all, the Moto 360 display is not perfectly round. It has a flat area on the bottom. If you look closely you can see the light sensor there. Not sure if that was why it wasn’t round, or if there was another design reason. In any case, the screen resolution is 320 x 290 pixels at 213 Pixels Per Inch. This means at design time you have a usable area of 240 x 218 pixels. This is the information we need to create a custom view. Just put the following code in a package.

  TDeviceinfo.AddDevice(TDeviceinfo.TDeviceClass.Tablet, ViewName,
    // The Moto360 is 320x290 phyiscal and 240x218 logical with 213 PPI
    TSize.Create(320, 290), TSize.Create(240, 218),
    TOSVersion.TPlatform.pfAndroid, 213,
    True); // Exclusive

The Device class enumeration actually has a Watch class, but looking in the code that detects the class at runtime and it doesn’t know how to detect a watch yet. So it defaults to Tablet. It makes sense if you think about the fact that XE7 was released before the Moto 360. I imagine an update will address this.

The requirement to get the custom view to show up in the IDE is you need to update the XML file found at %AppData%\Roaming\Embarcadero\BDS\15.0\MobileDevices.xml to reference the new view. Inside the MobileDevices element, add the following:

  <MobileDevice>
    <Displayname>Moto360</Displayname>
    <Name>Moto360</Name>
    <DevicePlatform>3</DevicePlatform>
    <FormFactor>2</FormFactor>
    <Portrait Enabled="True" Width="240" Height="218" Top="102" Left="29" StatusbarHeight="0" StatusBarPos="0" Artwork="C:\Users\jim\Documents\Embarcadero\Studio\Projects\HelloMoto360\Moto360.png" />
    <UpsideDown Enabled="False" Width="240" Height="218" Top="0" Left="0" StatusbarHeight="0" StatusBarPos="0" Artwork="" />
    <LandscapeLeft Enabled="False" Width="240" Height="218" Top="0" Left="0" StatusbarHeight="0" StatusBarPos="0" Artwork="" />
    <LandscapeRight Enabled="False" Width="240" Height="218" Top="0" Left="0" StatusbarHeight="0" StatusBarPos="0" Artwork="" />
  </MobileDevice>

You’ll need to update the path to that Artwork to point to the correct location of the PNG on your system. Or you can just leave it blank. Here is what it all looks like when setup in the IDE.

Hello Moto 360 in the XE7 IDE

You’ll notice a red circle on the design surface. I added this to see where the corners are (since the display is round). At runtime you can just barely see the red if you hold the watch right. In production I’d hide this at runtime. I placed the TCircle at -1, -1 and set the size to 242 x 242. This way the circle follows the bezel and not the display area of the screen. I suppose if I bumped it out another pixel it would disappear completely at runtime.

To get the Moto 360 to show up as a target device you first need to enable Bluetooth debugging.

  1. Hold the side button in until Settings appears
  2. Swipe down to About and tap it.
  3. Tap on build number until it tells you that you are a developer.
  4. Swipe back to settings and then tap on Developer options.
  5. Tap on ADB Debugging until it says Enabled.
  6. Tap on Debug over Bluetooth until it says Enabled.
  7. On your paired phone, go into Android Wear settings (gears in the upper right)
  8. Enable Debugging over Bluetooth.
    1. It should show
      • Host: disconnected
      • Target: connected
    2. Target is the watch, Host is your computer.

Then you connect your phone that is connected to the Moto 360 via USB and run the following commands (assuming ADB is on your system path) to connect via Bluetooth. I made a batch file.

[dos]
@echo off
REM optional cleaning up
adb disconnect localhost:4444
adb -d forward –remove-all
REM this is the connection
adb -d forward tcp:4444 localabstract:/adb-hub
adb -d connect localhost:4444
REM these lines are to see if it worked
echo Here is the forwarded ports . . . .
adb forward –list
echo.
echo Wait a second for it to connect . . . .
pause
adb devices
[/dos]

The ADB Devices list should show something like

List of devices attached 
123456abcd device 
localhost:4444 device

Now the Android Wear app on your phone should show

  • Host: connected
  • Target: connected

Be sure that your Moto 360 app uses the unit that defines the Moto 360 device (from your package). This way your app can select it at runtime. If you do all that, you’ll see something similar to this with it running on the Moto 360:

Hello Moto 360 from Delphi XE7

My camera had a hard time focusing on it, but rest assured it looks fabulous! I tried C++ too, and no surprises, it works as well. More experimenting to do, but it is nice to know I have a tool that will take me everywhere I want to go.

If you don’t have a Moto 360, you can setup an Android emulator (AVD) instead. I did that before mine showed up. You need to download the Android 4.4W (API20) SDK Platform and ARM System image.

Android Wear SDK Download

Then create an AVD with the new Emulator.

Android Wear AVD Settings

It actually gives you the rectangle screen with a round bezel. Also it is 320 x 320 (so completely round) and 240 PPI. This means the view I created (since it was exclusive) won’t work on the emulator. You’ll need to create a new custom view for the emulator, but I’ll leave that up to to.

you can download all of my code for the custom view, Bluetooth ADB batch file, and sample apps from Github. BTW, XE7 adds local Git support, which is another great new feature. Download the trial and check it out.

by Jim McKeeth at September 19, 2014 06:40 PM

September 18, 2014

The Wiert Corner - irregular stream of stuff

Click on the shield icon, followed by

If you run Continua CI 1.5.x.y and use Git then make sure you upgrade to at least Continua CI 1.5.0.295 (get it from the Continua CI download page).

Click on the shield icon, followed by

Click on the shield icon, followed by “CI Server”

After that, reset all your Git repositories in ContinuaCI.

To view all the repositories on the server, follow either of these steps:

  • A:
    1. Logon as an administrator with the rights to view all repositories on the Continua CI server.
    2. Click on the shield icon in the top bar.
    3. Then click on “CI Server”.
    4. In the list on the left, scroll down and click “Repositories”.
  • B:
    1. Logon as an administrator with the rights to view all repositories on the Continua CI server.
    2. Note the URL in the address bar of your browser (for instance http://localhost:8080/ci).
    3. Replace the /ci part of your URL with /administration/ci/repositories (so you end up at something like http://localhost:8080/administration/ci/repositories).
    4. Go to that URL.

Now you are in the repositories section, where you see all the repositories configured on the Continua CI. Each repository has a [Reset] link in the right most column.

Then follow these steps:

  1. For all Git repositories,
    1. Click on the [Reset] link.
    2. Confirm the “Are you sure you want to reset this repository?” question by clicking “Yes”.
  2. Wait for all Git repositories to be marked “Ready” and have a green checkmark icon.

The Git repositories will go through these states to become “Ready”:

  1. Initialising
  2. Updating cache
  3. Getting changessets
  4. Ready

–jeroen

via Continua CI – v1.5.0.295 Released. Critical bug fix for Git.

A new version of Continua CI has been uploaded and is available from Continua CI Downloads. The latest version of Continua CI is now 1.5.0.295.

Critical fix notification for users running v1.5 or greater: All users with Git repositories should install this update. After installing please perform a repository reset of all Git repositories which contain the “fetch other refs” option. This can be done from the Administration -> Repository area

v1.5.0.295 Changes

  • Fix: Critical issue with Git repositories which contain the “fetch other refs” option causing large repository cache size and lost of performance. Please reset all Git repositories which contain “fetch other refs” options.
  • Fix: Vault repositories now allow a blank empty password to be entered
  • Fix: Copying Subversion branches which contain externals would result in externals from the destination branch to be ignored.
  • Fix: Issue where empty Subversion changesets would prevent a build from starting.Note : You will need to update your agents after installing this build.

View full version history for Continua CI 1.5.

Note : You will need to update your agents after upgrading to this build.


Filed under: .NET, Continua CI, Continuous Integration, Delphi, Development, Software Development

by Jeroen Pluimers at September 18, 2014 10:22 AM

September 17, 2014

The road to Delphi

The Podcast at Delphi.org

The FireUI: Multi-Device Designer in RAD Studio XE7

Here is the video replay, slides and resources from my Developer Skill Sprint on the new Multi-Device Designer in RAD Studio XE7. This is one part of the new FireUI, the evolution of FireMonkey.

The Multi-Device Designer is a new feature in Appmethod, RAD Studio, Delphi and C++Builder XE7 that makes it easy to maximize the reuse of your visually designed forms across devices, while also getting the most flexibility and customization as possible.

Design your UI once for Windows, OS X, iOS and Android, then customize it for different screen sizes: iPad, iPhone, Tablet, Google Glass, Surface Pro, etc.

You can view the slides on Google Docs.

Check out the Guided Tour on the Welcome Page and the following DocWiki pages:

Check out the other skill sprints too. . .

by Jim McKeeth at September 17, 2014 08:03 PM

September 16, 2014

Firebird News

Firebird Manual Pages Reorganisation and cleanup

Paul Vinkenoog cleaned up that page and wrote on Firebird-docs: – On top are the most important version-specific docs for the currently supported versions, i.e. 2.5 and 2.1 Quick Start Guides and LangRef Updates. – After that, the Command Line Utilities manuals, followed by other user manuals, reference material and the Firebird licenses. – Then come the […]

by mariuz at September 16, 2014 12:39 PM

Firebird Conference 2014: only 1 month left

Firebird International Conference 2014 will take place on October 24-25, in Prague. 2 days of the intensive talks from Firebird core and drivers developers, vendors of leading Firebird tools and even legends of the database world: Ann Harrison and Jim Starkey. Take a look at detailed talks descriptions. Don’t miss the biggest event of the year, […]

by mariuz at September 16, 2014 09:14 AM

September 15, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Simon Stuart yesterday posted a very interesting post on G+ that explains on this (edited) topic:

#Rendering   I was having a conversation last night … with +David Berneda regarding rendering performance improvements for FireMonkey applications.
Specifically, custom drawing/rendering on a FireMonkey Canvas.

I just want to summarize the points I raised, and some of the conclusions I’ve come to having been working with rendering in FireMonkey since the end of June this year.

–jeroen

via: Simon Stuart rendering performance improvements for FireMonkey applications. Specifically, custom drawing/rendering on a FireMonkey Canvas.


Filed under: Delphi, Delphi XE5, Delphi XE6, Delphi XE7, Development, FireMonkey, OS X FMX, Software Development

by Jeroen Pluimers at September 15, 2014 05:30 AM

September 14, 2014

Lazarus Team Anouncements

Bug Busters

Hello

We are slowly moving towards the next Lazarus 1.4 release. (No fixed date yet.)
The list of open issues targeted for 1.4 is partly cleaned. There were ~400 of them (for historical reasons), now they are down to ~140.

Maybe due to increased popula...

September 14, 2014 04:04 PM

twm’s blog

Custom Container Pack for Delphi XE2 to XE7

I just updated the Custom Container Pack sources to support Delphi XE2 to XE7. It was mostly a matter of creating the packages for the newer versions. I also had to adapt the registration code to changes in Delphi XE2.

It now compiles and installs. I have not tested it extensively. We use it at work with Delphi 2007 and I know of no bugs with it.

Custom Containers Pack (CCPack) is an integrated tool and component mini-library to produce and maintain composite controls (or simply “composites”) and other containers (forms, data modules and frames). The process of building composite components looks like ActiveForm and Frame creating, but the result is the native VCL component. You can create new composites just as usual forms.

Here is the original documentation in RTF format.

It was originally developed by Sergey Orlik who posted the source code to code central

by dummzeuch at September 14, 2014 12:37 PM

September 13, 2014

Te Waka o Pascal

Zombie Apps (not) in the Apple App Store

In the run up to the announcement of the new iPhone 6 and the Apple Watch, Apple also revamped iTunes Connect, the portal through which apps are submitted to the App Store. Unfortunately the new interface has a number of problems which I spent wasted hours dealing with yesterday. Beginning at the Beginning The problems […]

by Jolyon Direnko-Smith at September 13, 2014 10:12 PM

twm’s blog

dzlib compiles with all Delphi versions from 2007 to XE6

Today I spent some time to make dzlib compile with all Delphi versions from 2007 to XE6 (XE7 to come later). It didn’t take too long since it already supported 2007, XE2 and XE6.

It’s interesting to see, how the RTL evolved between these versions. Some examples:

  • The IsWhitespace function started out as a class method of TCharacter, then moved to TCharHelper and finally ended up as a method of the Char type itself (probably added through a class helper, I didn’t check).
  • The global DecimalSeparator variable was marked deprecated for a long time (replaced by a property of the global FormatSettings class) and has finally been removed from the RTL.

There is also a breaking change in the Delphi XE6 RTL:
You can no longer create a TThread suspended and then call Resume/Start from within its constructor. If you do that, you will get an exception. But since the thread no longer gets started until the constructor has run that is no longer necessary.

by dummzeuch at September 13, 2014 06:51 PM

[German only] Fahrradbeleuchtung

Es wird wieder dunkel, und so allmählich braucht man auch zu normalen Radfahrzeiten wieder Licht. Seit einiger Zeit sind laut STVZO batteriebetriebene Lampen auch für normale Fahrräder zugelassen, sofern sie einige Bedingungen erfüllen. Passend dazu hatte Aldi Nord am 11.8.2014 die Pedaluxx LED Fahrradbeleuchtung im Angebot. Ich habe zugegriffen, weil ich dachte, dass man für 9,99 Euro nicht allzuviel verliert, wenn sie nichts taugt.

Die Lampen an sich sind ganz OK, auch wenn es ziemlich verwirrend ist, dass die Lade-Kontrolleuchte der Frontlampe an geht, wenn die Batterien gewechselt werden sollen, die des Rücklichts hingegen geht dann aus.

Die Halter allerdings sind ziemlich wacklig. Ich bin mir sicher, dass sie nicht lange halten werden. Schon bei der Montage der Halterung für die Frontlampe habe ich bemerkt, dass sich das dünne Plastik, in dem die Schraube halten soll, nach außen verbiegt.

Ich hatte vorher (bevor mir das Fahrrad komplett geklaut wurde) eine andere (aber auch deutlich teurere) Frontlampe, damals noch ohne STVZO-Zulassung, deren Halter bombenfest sass. Leider gibt es die nicht mehr zu kaufen.

Batterien (8x AAA) waren dabei, aber ich werde sie, sobald sie leer sind, durch Akkus ersetzen.

Man sollte vielleicht erwähnen, dass die neue Fassung der STVZO zwar batteriebetriebene Lampen erlaubt, man diese allerdings nach STVO bei der Benutzung des Fahrrads (also auch tagsüber) montiert haben muss. Mitführen alleine reicht nicht. Genaugenommen ist es sogar noch schlimmer: Die Leuchten müssen “fest” am Rad montiert sein, danach wären Ansteckleuchten gar nicht zulässig. Ob das so ist, ist noch nicht endgültig geklärt.

Mir persönlich ist es ziemlich egal, was diese Vorschriften zur Fahrradbeleuchtung sagen. Mir ist wichtig, dass ich im Straßenverkehr gesehen werden, denn ich möchte gerne noch ein paar Jährchen leben und ich weiß, wie schlecht Radfahrer ohne Licht in der Dämmerung zu sehen sind. Deshalb werde ich diese Beleuchtung testen und verwenden, wenn sie ihren Zweck erfüllt. Wenn nicht, muss eine andere her, Zulassung oder nicht.

Vielleicht noch ein Hinweis: Anders als früher sind Fahrradlampen heute so hell, dass sie entgegenkommende Verkehrsteilnehmer blenden, wenn sie falsch eingestellt sind. Die Frontlampe muss so eingestellt sein, dass ihr Leuchtkegel die Straße max. 15 m vor dem Fahrrad beleuchtet. Mir kommen in letzter Zeit leider immer wieder andere Radfahrer entgegen, deren Licht viel zu hoch gestellt ist.

(STVO = Straßenverkehrsordnung, STVZO = Straßenverkehrs-Zulassungs-Ordnung)

by dummzeuch at September 13, 2014 06:39 PM

September 12, 2014

Andy's Blog and Tools

EditorLineEnds.ttr – IDEFixPack users are not affected

With the latest Windows updates (KB2982791, KB2970228) Delphi 8-2010 can’t be started twice without a reboot because the IDE wants to create the file %TEMP%\EditorLineEnds.ttr that is now locked by the system.

The IDE extracts a FONT-resource to %TEMP%\EditorLineEnds.ttr and then loads it with AddFontResource(). The IDE’s finalization code unloads the font. But with the newest Windows Updates, Microsoft prevents the RemoveFontResource() function from unlocking the file (for security reasons). If you start a second IDE the resource-extraction fails and throws an exception causing the IDE to terminate.

If you have IDEFixPack newer than 2.7 already installed, you are not affected because IDEFixPack prevents the IDE from calling AddFontResource (this was a patch to work around a performance nightmare with an installed Adobe Type Manager). Thus the file is never locked.

If you are a new user to IDEFixPack, you may need to reboot after installing IDEFixPack if the font file is already locked.

IDEFixPack for 2009 or newer

IDEFixPack for 2007 (if you have Windows 8 you need to use version 4.3 instead of 4.4)

by Andreas Hausladen at September 12, 2014 03:05 PM

Firebird News

The Perfect Database Server: Firebird 2.5.3 And FreeBSD 10

Here is the guide on installing Firebird 2.5.3 from FreeBSD 10 Ports and creating your first test database; also we show you how to install Flamerobin GUI (administration tool) and the PHP driver for it. This was tested on fresh FreeBSD 10 on a kvm-linux virtual machine. Download a compressed snapshot of the Ports Collection into /var/db/portsnap. […]

by mariuz at September 12, 2014 02:35 PM

September 11, 2014

Daniel Magin's Logfile

NFC Android Application with Delphi XE6 and XE7

NFC Android Application with Delphi XE6 and XE7

DelphiXE6

Download Delphi XE6 Example Source Code

For the German Delphi Days last Weekend in Bonn i prepared a Workshop and a Session how to develop with Delphi a Android Application to read and write NFC tags. So i worked out a Delphi Example to do this. Delphi brings no ready components to do this out of the box. So i tried my first steps and i found it is not only necessary to add in classes.dex the NFC SDK Jar Files, no it was also necessary to change the NativeActivity in the AndroidManfifest.template (see later more in detail). I remember that my friend Brian Long, also a Embarcadero MVP have done this with XE5 and XE6 on his blog (LINK). So i called him and we suprise, he was also to test out NFC with Delphi for Android at the same time. So we decided everybody was work for 1 week seperate and then we merge our knowledge. It was really funny later he did found out what i am missing and i found out stuff he missed.

Brian Long also published his result here: LINK

Requirements

1. to run such Android Applications you need a Android Device WITH NFC ! So please check your device. I found also a nice webpage with a collection of NFC Android Devices on LINK/

2. Ready installed Delphi XE6 or XE7

3. Read AND understand (!) the Article published from Google in the Developer Network. Minimum read and understand the following parts in Chapter NFC Basics:

LINK

NFC Basics

  • The Tag Dispatch System
  • Requesting NFC Access in the Android Manifest
  • Filtering for NFC Intents
  • Creating Common Types of NDEF Records

4. Read dokwiki what is classes.dex in Delphi and how to patch this:

- XE6 Users: LINK

- XE7 Users: LINK

XE6 Users: A big new function in XE7 IDE is to drag and drop a jar file in your porject, and Delphi create on compile the classes.dex file for you automatic. So ist is extreme much easier to add your custom or 3rd Party JARS from other Hardware for your device into your Delphi Project

RadStudioXE7

Ok let's rock Delphi to work with NFC on Android Devices

Before we create the Delphi Project, we need to pack all the NFC SDK stuff in a JAR file and create the Pascal files to use it.

The minimum version requirements, the NFC is to Android2.3 (Level 10) began to support the minimum version requirements must be specified as 10. Introduced in Android 4.0 (API level 14) we can all we need to read and write NFC and much more. This should also you minimum SDK on your Computer. So if you have not this SDK on your machine, please update your sdk folder with local "SDK Manager.exe" in your Android SDK folder Path.

RadStudioXE7

Let's tals also for nun Java Friends how to generate a .java text file to a .jar file. It is very simple. For Delphi XE6 you need minimum java 1.6 and XE7 java 1.7 on your machine. Open a Command box and type "java -version". If java is installed correct you should a result like this:

RadStudioXE7

crash session how to compile a jar file from a .java text file

  1. javac ABC.java <-- create a ABC.class from .java file
  2. jar cfv ABC.jar ABC.class <-- this create a .jar file from .class file

so wee need all NFC .java files in your

PATH_TO YOUR SDK FOLDER ..Android\sdk\sources\android-20\android\nfc\

After this two simple commands we have a ready jar file to generate the pascal file.

This inteface pascal file for this new Java classes. This is not so simple for XE6 Users. You can write it by hand but this will end in a horror never ending time. There are some 3rd party tools like Java2Pas and other, but this produce for each created .jar file a seperate .pas file. But mostly each file uses each other. So you have circular uses wich delphi can not compile this, so you must copy paste all .pas files in one file per hand. XE7 Users get a free tool Java2OP.exe (it should be possible to download in a few days). This tool handles all for you perfect - LINK TO JAVA2OP .

I think the generated files can be used also in XE6, but i have not tested out, cause the Embarcadero Java2OP.exe is not available now during the time i was writing this article. Also the Embarcadero Java2OP.exe should generate the Pascal files direct form the .java files, so compiling to jar is not necessary anymore, as the documentation is talk about it. but it was not possible to test.

Don't go in panic in my example download, the .pas file is ready to use. i have generated it with my own converter.

Ok what also we need and this we add in the classes.dex file:

to catch the event if a user is bring a NFC Card to the Phone i found out the application get a onNewIntent fired. But this Events we did not find translated to the firemonkey framework. but this is very simple to solve. we write a very small java class and add this class to our classes.dex.

This java class handles everything for us like onNewIntent, NFC enable/disable on pause, resume,...

With the line public native void onNewIntentNative(Intent NewIntent); we introduce a new method wich will be fired on the original onNewIntent method. Thanks to Brian Long to figure this out :-)

  1. package net.developerexperts.nfc;
  2.  
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.content.Intent;
  6.  
  7. import android.nfc.NfcAdapter;
  8. import android.content.Intent;
  9. import android.app.PendingIntent;
  10.  
  11. import android.app.AlertDialog;
  12. import android.content.DialogInterface;
  13. import android.content.DialogInterface.OnClickListener;
  14.  
  15. public class NativeActivitySubclass extends com.embarcadero.firemonkey.FMXNativeActivity {
  16.  
  17. static final String TAG = "NativeActivitySubclass";
  18.  
  19. private NfcAdapter nfcAdapter;
  20. private PendingIntent pendingIntent;
  21.  
  22. @Override
  23. protected void onCreate(Bundle savedInstanceState) {
  24. super.onCreate(savedInstanceState);
  25. //Custom initialization
  26. nfcAdapter = NfcAdapter.getDefaultAdapter(this);
  27.         Intent intent = new Intent(this, getClass());
  28.         pendingIntent = PendingIntent.getActivity(this, 0,
  29.             intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
  30. }
  31.  
  32. public native void onNewIntentNative(Intent NewIntent);
  33.  
  34. @Override
  35. protected void onNewIntent(Intent intent)
  36.     {
  37. super.onNewIntent(intent);
  38. onNewIntentNative(intent);
  39. }
  40.  
  41. @Override
  42.     public void onPause()
  43.     {
  44.         super.onPause();
  45. disableForegroundDispatch();
  46.     }
  47.  
  48. @Override
  49.     public void onResume()
  50.     {
  51.         super.onResume();
  52. enableForegroundDispatch(pendingIntent);
  53.     }
  54.  
  55. public void enableForegroundDispatch(PendingIntent pendingIntent)
  56. {
  57. nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
  58. }
  59.  
  60. public void disableForegroundDispatch()
  61. {
  62. nfcAdapter.disableForegroundDispatch(this);
  63. }
  64.  
  65. public void showDialog(final String title, final String msg)
  66. {
  67. Log.d(TAG, "Displaying dialog");
  68. runOnUiThread(new Runnable() {
  69. public void run() {
  70. AlertDialog.Builder builder = new AlertDialog.Builder(NativeActivitySubclass.this);
  71. builder.setMessage(msg).
  72.                         setTitle(title).
  73.                         setCancelable(true).
  74.                         setPositiveButton("OK", new OnClickListener(){
  75. public void onClick(DialogInterface dialog, int which)
  76. {
  77. dialog.dismiss();
  78. }
  79.        }).show();
  80. }
  81. });
  82. }
  83. }

for this small new onNewIntentNative we add later a method in our mainform:

  1. procedure OnNewIntentNative(PEnv: PJNIEnv; This: JNIObject; NewIntent: JNIObject); cdecl;
  2. begin
  3.   Log.d('Queuing native routine to run synchronized');
  4.   TThread.Queue(nil,
  5.     procedure
  6.     begin
  7.       frmMain.OnNewIntent(TJIntent.Wrap(NewIntent)); //CALL the next procedure
  8.     end);
  9. end;
  10.  
  11.  
  12. procedure TfrmMain.OnNewIntent(Intent: JIntent);
  13. begin
  14.   //here we add later code what ever we like to do if a NFC Card is found
  15. end;

to register the native event we this code in delphi

  1. procedure TfrmMain.RegisterDelphiNativeMethods;
  2. var
  3.   PEnv: PJNIEnv;
  4.   ActivityClass: JNIClass;
  5.   NativeMethod: JNINativeMethod;
  6. begin
  7.   Log.d('Starting the registration JNI stuff');
  8.  
  9.   PEnv := TJNIResolver.GetJNIEnv;
  10.  
  11.   Log.d('Registering interop method');
  12.  
  13.   NativeMethod.Name := 'onNewIntentNative';
  14.   NativeMethod.Signature := '(Landroid/content/Intent;)V';
  15.   NativeMethod.FnPtr := @OnNewIntentNative;
  16.  
  17.   ActivityClass := PEnv^.GetObjectClass(PEnv, PANativeActivity(System.DelphiActivity).clazz);
  18.  
  19.   PEnv^.RegisterNatives(PEnv, ActivityClass, @NativeMethod, 1);
  20.  
  21.   PEnv^.DeleteLocalRef(PEnv, ActivityClass);
  22. end;

Ok let's go back to add our small jar file into XE6

To generate in XE6 your custom classes.dex file Brian Long have written a wonderful batch file:

  1. @echo off
  2.  
  3. setlocal
  4.  
  5.  
  6. // CHANGE IN NEXT LINE YOUR SDK ROOT FOLDER
  7. if x%ANDROID% == x set ANDROID=c:\Android\sdk\
  8. set ANDROID_PLATFORM=%ANDROID%\platforms\android-19
  9. set DX_LIB=%ANDROID%\build-tools\android-4.4\lib
  10. set DX_BATCH=%ANDROID%\build-tools\android-4.4
  11.  
  12. set EMBO_DEX="C:\Program Files (x86)\Embarcadero\Studio\14.0\lib\android\debug\classes.dex"
  13. set PROJ_DIR="%CD%"
  14. set VERBOSE=0
  15.  
  16. echo.
  17. echo Compiling the Java activity source file
  18. echo.
  19. mkdir output 2> nul
  20. mkdir output\classes 2> nul
  21. if x%VERBOSE% == x1 SET VERBOSE_FLAG=-verbose
  22. javac %VERBOSE_FLAG% -source 1.6 -target 1.6 -Xlint:deprecation -cp %ANDROID_PLATFORM%\android.jar;classes.jar -d output\classes src\net\developerexperts\nfc\NativeActivitySubclass.java
  23.  
  24. echo.
  25. echo Creating jar containing the new classes
  26. echo.
  27. mkdir output\jar 2> nul
  28. if x%VERBOSE% == x1 SET VERBOSE_FLAG=v
  29. jar c%VERBOSE_FLAG%f output\jar\test_classes.jar -C output\classes net
  30.  
  31. echo.
  32. echo Converting from jar to dex...
  33. echo.
  34. mkdir output\dex 2> nul
  35. if x%VERBOSE% == x1 SET VERBOSE_FLAG=--verbose
  36. call %DX_BATCH%\dx --dex %VERBOSE_FLAG% --output=%PROJ_DIR%\output\dex\test_classes.dex --positions=lines %PROJ_DIR%\output\jar\test_classes.jar
  37.  
  38. echo.
  39. echo Merging dex files
  40. echo.
  41. java -cp %DX_LIB%\dx.jar com.android.dx.merge.DexMerger %PROJ_DIR%\output\dex\classes.dex %PROJ_DIR%\output\dex\test_classes.dex %EMBO_DEX%
  42.  
  43. echo Tidying up
  44. echo.
  45. del output\classes\net\developerexperts\nfc\NativeActivitySubclass*.class
  46. rmdir output\classes\net\developerexperts\nfc
  47. rmdir output\classes\net\developerexperts
  48. rmdir output\classes\net
  49. rmdir output\classes
  50. del output\dex\test_classes.dex
  51. del output\jar\test_classes.jar
  52. rmdir output\jar
  53.  
  54. echo.
  55. echo Now we have the end result, which is output\dex\classes.dex
  56.  
  57. :Exit
  58.  
  59. endlocal

Important: if you have installed on your machine Java 1.7 or higher you must compile for Delphi XE6 in java 1.6 this you do like in the batch file:

javac %VERBOSE_FLAG% -source 1.6 -target 1.6 -Xlint:deprecation......

This batch file is not needed for XE7 users cause as i have written you can easy drag and drop the jar files in your project under the project tree in android section.

WOW what a hard work, but if you understand this you are now a hero. now you can add every other jar file in your classes.dex and can easy call.

Now we can with Delphi and welcome back to pascal code ;-)

Generate a new Delphi FMX Project and change it to Android. Save and open the AndroidManifest.template.xml

there we found in the activity area and have to change:

  1.       <activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
  2.                 android:label="%activityLabel%"
  3.                 android:configChanges="orientation|keyboardHidden">

Replace with our new Added class to receive our onNewIntent

  1.      <activity android:name="net.developerexperts.nfc.NativeActivitySubclass"
  2.                 android:label="%activityLabel%"
  3.                 android:configChanges="orientation|keyboardHidden"
  4. android:launchMode="singleTop">

Also we add all NFC enhancements what we like to use in our Delphi Application, as you have readed in the Google Developer docs (see requirements on the top of this article). So your AndroidManifest.template.xml sould look like this:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- BEGIN_INCLUDE(manifest) -->
  3. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  4.         package="%package%"
  5.         android:versionCode="%versionCode%"
  6.         android:versionName="%versionName%">
  7.  
  8.     <!-- This is the platform API where NativeActivity was introduced. -->
  9.     <!--<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="%targetSdkVersion%" /> -->
  10.    <!--  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="11" /> -->
  11.      <uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
  12.  
  13. <%uses-permission%>
  14.     <application android:persistent="%persistent%"
  15.         android:restoreAnyVersion="%restoreAnyVersion%"
  16.         android:label="%label%"
  17.         android:installLocation="%installLocation%"
  18.         android:debuggable="%debuggable%"
  19.         android:largeHeap="%largeHeap%"
  20.         android:icon="%icon%"
  21.         android:theme="%theme%"
  22.         android:hardwareAccelerated="%hardwareAccelerated%">
  23.         <!-- Our activity is a subclass of the built-in NativeActivity framework class.
  24.              This will take care of integrating with our NDK code. -->
  25.         <activity android:name="net.developerexperts.nfc.NativeActivitySubclass"
  26.                 android:label="%activityLabel%"
  27.                 android:configChanges="orientation|keyboardHidden"
  28. android:launchMode="singleTop">
  29.             <!-- Tell NativeActivity the name of our .so -->
  30.             <meta-data android:name="android.app.lib_name"
  31.                 android:value="%libNameValue%" />
  32.  
  33.  
  34. <intent-filter>
  35.                 <action android:name="android.intent.action.MAIN" />
  36.                 <category android:name="android.intent.category.LAUNCHER" />
  37.             </intent-filter>
  38.  
  39.  
  40. <intent-filter>  
  41.          <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  42. <category android:name="android.intent.category.DEFAULT"/>
  43. <data android:mimeType="text/plain" />
  44.  
  45.             </intent-filter>
  46.  
  47. <intent-filter>
  48.      <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  49.      <category android:name="android.intent.category.DEFAULT"/>
  50.      <data android:scheme="http" />
  51. </intent-filter>
  52.  
  53. <intent-filter>
  54.      <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  55.      <category android:name="android.intent.category.DEFAULT"/>
  56.      <data android:scheme="dav" />
  57. </intent-filter>
  58.  
  59.  
  60. <intent-filter>
  61. <action android:name="android.nfc.action.TECH_DISCOVERED" />
  62. <category android:name="android.intent.category.DEFAULT" />
  63. </intent-filter>
  64. <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
  65. android:resource="@xml/nfc_tech_filter" />
  66.  
  67.  
  68.  
  69.  
  70. </activity>
  71.         <receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" />
  72.     </application>
  73. </manifest>  
  74. <!-- END_INCLUDE(manifest) -->

Also in in Deployment Options (Menu: Project - Deployment) it is important to disable (only XE6, XE7 do it four you automatic as you learned) the original classes.dex file and deploy your new generated classes.dex file.

DelphiXE6

Next important step is to enable in your Application under Menu Project - Options the NFC rights.

DelphiXE6

I think it is not necessary to discuss all the source lines, but lets try to explain all the new NFC new line. In my Project you find two units:

DeveloperExperts.Android.nfc.pas

this is the generated interface unit to the NFC Android imported SDK we like to use and call

DeveloperExperts.Android.nfc.Helper.pas

this unit handles the most important stuff to work with NFC and Delphi

  1. TDXNFCHelper = class
  2.   private
  3.   public
  4.     class function getNFCManager: JNfcManager;
  5.     class function checkNFC: boolean;
  6.     class function getNFCDefaultAdapter: JNfcAdapter;
  7.     class function NdefRecordsJavaBytesToString(jbytes: TJavaArray<Byte>; const MimeType: TDXMimeType): TDXStringRecord;
  8.     class function GetDXMimeTypeFromString(const sMimeType: string): TDXMimeType;
  9.     class function GetURIType(const _uriID: integer): TDXUriResult;
  10.     class function StringToJavaArrayOfBytes(sText: string): TJavaArray<System.Byte>; static;
  11.     class procedure JavaArrayByteCopy(src: TJavaArray<System.Byte>; srcPos: integer; dest: TJavaArray<System.Byte>; destPos: integer; _length: integer);
  12.     class procedure WriteTextRecordsToNfcCard(NdefRecordsText: TList<string>; IsoLangCode: string; _tag: JTag);
  13.  
  14.   end;
  15.   

this helper class with class methods (for delphi beginners: you do not need to create this class) gives you some methods:

class function checkNFC: boolean;

check is NFC is available an possible to access

class function getNFCManager: JNfcManager;

like described in the Google Developer NFC Guide you get back a NFCManager over this you can access for example the default Adapter to read and write the NFC Card stuff

class function getNFCDefaultAdapter: JNfcAdapter;

direct access to the NFC Default Adapter

class procedure WriteTextRecordsToNfcCard(NdefRecordsText: TList; IsoLangCode: string; _tag: JTag);

write all strings from the Input Parameter TList to text records to the NCF card

all other methods are helper to convert String to Java Array, getMimeTypes, URIType and much more...

Lets analyse the main form

You find a ListBox with 2 items:

checkNFC: call the HelperClass checkNFC to check is NFC available

writeNFC: set a local variable NextNFCTagScanWaitingDataToWrite:=true

so next NFC card touched to the device will be written. Every time a NFC card touched to the device OnNewIntent will be fired (you remember we introduced our java class to get this event)

  1. procedure TfrmMain.OnNewIntent(Intent: JIntent);
  2. begin
  3.   SharedActivity.setIntent(Intent);
  4.  
  5.   CurrentNFCTag := Intent.getParcelableExtra(TJNFCAdapter.JavaClass.EXTRA_TAG);
  6.  
  7.   if not NextNFCTagScanWaitingDataToWrite then
  8.     ReadAllInfomationsFromCurrentNFCIntent
  9.   else
  10.   begin
  11.     WriteWaitingDataToNfcTag;
  12.   end;
  13. end;

There you can found the local variable NextNFCTagScanWaitingDataToWrite check if we read or write the NFC Card.

Writing is very simple.

  1. procedure TfrmMain.WriteWaitingDataToNfcTag;
  2. var
  3.   _tag: JTag;
  4.   sRecords: TList<string>;
  5.  
  6. begin
  7.   NextNFCTagScanWaitingDataToWrite := false;
  8.   displayResult('start writing data', true);
  9.   _tag := TJTag.Wrap((CurrentNFCTag as ILocalObject).GetObjectID);
  10.   if Assigned(_tag) then
  11.   begin
  12.     sRecords:=TList<string>.Create;
  13.     sRecords.Add('This record is from Elmo');
  14.     sRecords.Add('This record is from Bert');
  15.     sRecords.Add('This record is from Cookiemonster');
  16.     TDXNFCHelper.WriteTextRecordsToNfcCard(sRecords,'en',_tag);
  17.     displayResult('finished writing data', true);
  18.   end
  19.   else
  20.   begin
  21.     displayResult('Tag instance not found');
  22.   end;
  23. end;

We generate a TList with all the string we write to the NFC Records. The Helper class make us easy to write:

TDXNFCHelper.WriteTextRecordsToNfcCard(sRecords,'en',_tag);

1. Parameter = the list of strings

2. given a Language Code of our text

3. the _tag (our NFC Card access)

Reading:

  1. procedure TfrmMain.ReadNFCRecords;
  2. var
  3.   Intent: JIntent;
  4.   jIntentName: JString;
  5.   IntentName: string;
  6.   rawMsgs: Androidapi.JNIBridge.TJavaArray<JParcelable>;
  7.   msg: JNdefMessage;
  8.   msgRecords: Androidapi.JNIBridge.TJavaObjectArray<JNdefRecord>;
  9.   i: Integer;
  10.   _NdefRecordRaw: JNIObject;
  11.   _NdefRecord: JNdefRecord;
  12.   recBytes: Androidapi.JNIBridge.TJavaArray<Byte>;
  13.   _currentRecord: TDXStringRecord;
  14. begin
  15.   Intent := SharedActivity.getIntent;
  16.   if Intent <> nil then
  17.   begin
  18.     jIntentName := Intent.getAction;
  19.     IntentName := JStringToString(jIntentName);
  20.     if (TJNFCAdapter.JavaClass.ACTION_NDEF_DISCOVERED.equals(Intent.getAction)) or (TJNFCAdapter.JavaClass.ACTION_TECH_DISCOVERED.equals(Intent.getAction)) then
  21.     begin
  22.       try
  23.         rawMsgs := Intent.getParcelableArrayExtra(TJNFCAdapter.JavaClass.EXTRA_NDEF_MESSAGES);
  24.         if rawMsgs <> nil then
  25.         begin
  26.           if rawMsgs.Length > 0 then
  27.           begin
  28.             msg := TJNdefMessage.Wrap((rawMsgs[0] as ILocalObject).GetObjectID);
  29.             msgRecords := msg.getRecords;
  30.             for i := 0 to msgRecords.Length - 1 do
  31.             begin
  32.               _NdefRecordRaw := msgRecords.GetRawItem(i);
  33.               _NdefRecord := TJNdefRecord.Wrap(_NdefRecordRaw);
  34.               recBytes := _NdefRecord.getPayload;
  35.               _currentRecord := TDXNfcHelper.NdefRecordsJavaBytesToString(recBytes, TDXNfcHelper.GetDXMimeTypeFromString(JStringToString(_NdefRecord.toMimeType)));
  36.               if not _currentRecord.UriResult.UriIsValid then
  37.               begin
  38.                 // mimetype text
  39.                 displayResult('Record ' + i.ToString);
  40.                 displayResult('MIME: ' + JStringToString(_NdefRecord.toMimeType));
  41.                 displayResult('ISO CODE: ' + _currentRecord.ISOCode);
  42.                 displayResult(_currentRecord.payload);
  43.               end
  44.               else
  45.               begin
  46.                 // mimetype URI
  47.                 displayResult('Record ' + i.ToString);
  48.                 displayResult('URI: ' + _currentRecord.UriResult.UriText + _currentRecord.payload);
  49.               end;
  50.             end;
  51.           end;
  52.         end;
  53.       except
  54.         on E: Exception do
  55.         begin
  56.           //Log however you like
  57.         end;
  58.       end;
  59.     end;
  60.   end;
  61. end;

First we check over the intent name if ACTION_NDEF_DISCOVERED (remmeber Google Article NFC Basics). If NFC Intent equals ACTION_NDEF_DISCOVERED so we know we have standard records. So we must read out the the message. The message contains none to many records. we loop over each record and read out the mime time and display the result. In my example i analyse only text and URI types, but you can easy extend to every valid type.

Now you know the most basic steps. You find much more in my example. So take your time to play and work with it.

Summary

You learned how to:

- import android sdk framework stuff

- convert your self written java to jar's

- add your jar's to classes.dex

- how to generate pascal interface files

- call from delphi such stuff

Download Delphi XE6 Example Source Code

What's coming next? Waiting to catch a iPhone 6 to use Delphi and NFC on iOS. This Article will be continued after i have this device in my hand :-)

regards

daniel magin

Embarcadero MVP

@ the end here the wrapped NFC Pascal file (also included in download)

  1. // File generated on 29.07.2014 12:05:01 by DeveloperExperts
  2.  
  3. unit DeveloperExperts.Android.nfc;
  4.  
  5. interface
  6.  
  7. uses
  8.   Androidapi.JNIBridge,
  9.   Androidapi.JNI.Analytics,
  10.   Androidapi.JNI.ApkExpansion,
  11.   Androidapi.JNI.App,
  12.   Androidapi.JNI.Dalvik,
  13.   Androidapi.JNI.Embarcadero,
  14.   Androidapi.JNI.GraphicsContentViewText,
  15.   Androidapi.JNI.Hardware,
  16.   Androidapi.JNI.InputMethodService,
  17.   Androidapi.JNI.JavaTypes,
  18.   Androidapi.JNI.Licensing,
  19.   Androidapi.JNI.Location,
  20.   Androidapi.JNI.Media,
  21.   Androidapi.JNI.Net,
  22.   Androidapi.JNI.OpenGL,
  23.   Androidapi.JNI.Os,
  24.   Androidapi.JNI.PlayServices,
  25.   Androidapi.JNI.Provider,
  26.   Androidapi.JNI.Support,
  27.   Androidapi.JNI.Telephony,
  28.   Androidapi.JNI.Util,
  29.   Androidapi.JNI.VideoView,
  30.   Androidapi.JNI.Webkit,
  31.   Androidapi.JNI.Widget;
  32.  
  33. type
  34.   { Class forward declarations }
  35.   JCardEmulation = interface; { android/nfc/cardemulation/CardEmulation }
  36.   JHostApduService = interface; { android/nfc/cardemulation/HostApduService }
  37.   JOffHostApduService = interface; { android/nfc/cardemulation/OffHostApduService }
  38.   JFormatException = interface; { android/nfc/FormatException }
  39.   JNdefMessage = interface; { android/nfc/NdefMessage }
  40.   JNdefRecord = interface; { android/nfc/NdefRecord }
  41.   JNfcAdapter_CreateBeamUrisCallback = interface; { android/nfc/NfcAdapter$CreateBeamUrisCallback }
  42.   JNfcAdapter_CreateNdefMessageCallback = interface; { android/nfc/NfcAdapter$CreateNdefMessageCallback }
  43.   JNfcAdapter_OnNdefPushCompleteCallback = interface; { android/nfc/NfcAdapter$OnNdefPushCompleteCallback }
  44.   JNfcAdapter_ReaderCallback = interface; { android/nfc/NfcAdapter$ReaderCallback }
  45.   JNfcAdapter = interface; { android/nfc/NfcAdapter }
  46.   JNfcEvent = interface; { android/nfc/NfcEvent }
  47.   JNfcManager = interface; { android/nfc/NfcManager }
  48.   JTag = interface; { android/nfc/Tag }
  49.   JTagLostException = interface; { android/nfc/TagLostException }
  50.   JBasicTagTechnology = interface; { android/nfc/tech/BasicTagTechnology }
  51.   JIsoDep = interface; { android/nfc/tech/IsoDep }
  52.   JMifareClassic = interface; { android/nfc/tech/MifareClassic }
  53.   JMifareUltralight = interface; { android/nfc/tech/MifareUltralight }
  54.   JNdef = interface; { android/nfc/tech/Ndef }
  55.   JNdefFormatable = interface; { android/nfc/tech/NdefFormatable }
  56.   JNfcA = interface; { android/nfc/tech/NfcA }
  57.   JNfcB = interface; { android/nfc/tech/NfcB }
  58.   JNfcBarcode = interface; { android/nfc/tech/NfcBarcode }
  59.   JNfcF = interface; { android/nfc/tech/NfcF }
  60.   JNfcV = interface; { android/nfc/tech/NfcV }
  61.   JTagTechnology = interface; { android/nfc/tech/TagTechnology }
  62.  
  63.   JCardEmulationClass = interface(JObjectClass)
  64.     ['{43DA51E2-EA67-4A69-A20F-1DD312214C2E}']
  65.     { Property methods }
  66.     function _GetACTION_CHANGE_DEFAULT: JString;
  67.     function _GetCATEGORY_OTHER: JString;
  68.     function _GetCATEGORY_PAYMENT: JString;
  69.     function _GetEXTRA_CATEGORY: JString;
  70.     function _GetEXTRA_SERVICE_COMPONENT: JString;
  71.     function _GetSELECTION_MODE_ALWAYS_ASK: Integer;
  72.     function _GetSELECTION_MODE_ASK_IF_CONFLICT: Integer;
  73.     function _GetSELECTION_MODE_PREFER_DEFAULT: Integer;
  74.     { Methods }
  75.     function getInstance(adapter: JNfcAdapter): JCardEmulation; cdecl;
  76.     { Properties }
  77.     property ACTION_CHANGE_DEFAULT: JString read _GetACTION_CHANGE_DEFAULT;
  78.     property CATEGORY_OTHER: JString read _GetCATEGORY_OTHER;
  79.     property CATEGORY_PAYMENT: JString read _GetCATEGORY_PAYMENT;
  80.     property EXTRA_CATEGORY: JString read _GetEXTRA_CATEGORY;
  81.     property EXTRA_SERVICE_COMPONENT: JString read _GetEXTRA_SERVICE_COMPONENT;
  82.     property SELECTION_MODE_ALWAYS_ASK: Integer read _GetSELECTION_MODE_ALWAYS_ASK;
  83.     property SELECTION_MODE_ASK_IF_CONFLICT: Integer read _GetSELECTION_MODE_ASK_IF_CONFLICT;
  84.     property SELECTION_MODE_PREFER_DEFAULT: Integer read _GetSELECTION_MODE_PREFER_DEFAULT;
  85.   end;
  86.  
  87.   [JavaSignature('android/nfc/cardemulation/CardEmulation')]
  88.   JCardEmulation = interface(JObject)
  89.     ['{79EFB1E2-A217-4FA3-BF59-5E79FE67A54B}']
  90.     { Methods }
  91.     function getSelectionModeForCategory(category: JString): Integer; cdecl;
  92.     function isDefaultServiceForAid(service: JComponentName; aid: JString): Boolean; cdecl;
  93.     function isDefaultServiceForCategory(service: JComponentName; category: JString): Boolean; cdecl;
  94.   end;
  95.  
  96.   TJCardEmulation = class(TJavaGenericImport<JCardEmulationClass, JCardEmulation>)
  97.   end;
  98.  
  99.   JHostApduServiceClass = interface(JObjectClass)
  100.     ['{D81BC39F-9EC2-4FF2-80C2-AA000344F762}']
  101.     { Property methods }
  102.     function _GetDEACTIVATION_DESELECTED: Integer;
  103.     function _GetDEACTIVATION_LINK_LOSS: Integer;
  104.     function _GetSERVICE_INTERFACE: JString;
  105.     function _GetSERVICE_META_DATA: JString;
  106.     { Methods }
  107.     function init: JHostApduService; cdecl;
  108.     { Properties }
  109.     property DEACTIVATION_DESELECTED: Integer read _GetDEACTIVATION_DESELECTED;
  110.     property DEACTIVATION_LINK_LOSS: Integer read _GetDEACTIVATION_LINK_LOSS;
  111.     property SERVICE_INTERFACE: JString read _GetSERVICE_INTERFACE;
  112.     property SERVICE_META_DATA: JString read _GetSERVICE_META_DATA;
  113.   end;
  114.  
  115.   [JavaSignature('android/nfc/cardemulation/HostApduService')]
  116.   JHostApduService = interface(JObject)
  117.     ['{C0BA2359-5768-4B3B-9404-2AFFD6F6541B}']
  118.     { Methods }
  119.     procedure notifyUnhandled; cdecl;
  120.     function onBind(intent: JIntent): JIBinder; cdecl;
  121.     procedure onDeactivated(Param0: Integer); cdecl;
  122.     function processCommandApdu(Param0: TJavaArray<Byte>; Param1: JBundle): TJavaArray<Byte>; cdecl;
  123.     procedure sendResponseApdu(responseApdu: TJavaArray<Byte>); cdecl;
  124.   end;
  125.  
  126.   TJHostApduService = class(TJavaGenericImport<JHostApduServiceClass, JHostApduService>)
  127.   end;
  128.  
  129.   JOffHostApduServiceClass = interface(JObjectClass)
  130.     ['{F4642B6A-DEFB-49D6-9A3A-D90BB03600AF}']
  131.     { Property methods }
  132.     function _GetSERVICE_INTERFACE: JString;
  133.     function _GetSERVICE_META_DATA: JString;
  134.     { Methods }
  135.     function init: JOffHostApduService; cdecl;
  136.     { Properties }
  137.     property SERVICE_INTERFACE: JString read _GetSERVICE_INTERFACE;
  138.     property SERVICE_META_DATA: JString read _GetSERVICE_META_DATA;
  139.   end;
  140.  
  141.   [JavaSignature('android/nfc/cardemulation/OffHostApduService')]
  142.   JOffHostApduService = interface(JObject)
  143.     ['{94CBB2DE-3E84-4557-B253-2747C82EBBBA}']
  144.     { Methods }
  145.     function onBind(Param0: JIntent): JIBinder; cdecl;
  146.   end;
  147.  
  148.   TJOffHostApduService = class(TJavaGenericImport<JOffHostApduServiceClass, JOffHostApduService>)
  149.   end;
  150.  
  151.   JFormatExceptionClass = interface(JObjectClass)
  152.     ['{558F4E4C-2DE0-4352-B626-2C9B0D482504}']
  153.     { Methods }
  154.     function init: JFormatException; cdecl; overload;
  155.     function init(&message: JString): JFormatException; cdecl; overload;
  156.     function init(&message: JString; e: JThrowable): JFormatException; cdecl; overload;
  157.   end;
  158.  
  159.   [JavaSignature('android/nfc/FormatException')]
  160.   JFormatException = interface(JObject)
  161.     ['{9F16ED2E-6826-4A40-959E-8858D07D7EF4}']
  162.   end;
  163.  
  164.   TJFormatException = class(TJavaGenericImport<JFormatExceptionClass, JFormatException>)
  165.   end;
  166.  
  167.   JNdefMessageClass = interface(JObjectClass)
  168.     ['{1FFA39B2-A5DB-47A9-9737-7C5821DD97ED}']
  169.     { Property methods }
  170.     function _GetCREATOR: JParcelable_Creator;
  171.     procedure _SetCREATOR(Value: JParcelable_Creator);
  172.     { Methods }
  173.     function init(data: TJavaArray<Byte>): JNdefMessage; cdecl; overload;
  174.     function init(&record: JNdefRecord; records: TJavaObjectArray<JNdefRecord>): JNdefMessage; cdecl; overload;
  175.     function init(records: TJavaObjectArray<JNdefRecord>): JNdefMessage; cdecl; overload;
  176.     { Properties }
  177.     property CREATOR: JParcelable_Creator read _GetCREATOR write _SetCREATOR;
  178.   end;
  179.  
  180.   [JavaSignature('android/nfc/NdefMessage')]
  181.   JNdefMessage = interface(JObject)
  182.     ['{6F6F2C4B-72AA-4F38-9253-A2EF427721C6}']
  183.     { Methods }
  184.     function describeContents: Integer; cdecl;
  185.     function equals(obj: JObject): Boolean; cdecl;
  186.     function getByteArrayLength: Integer; cdecl;
  187.     function getRecords: TJavaObjectArray<JNdefRecord>; cdecl;
  188. //    function getRecords: TJavaArray<JNdefRecord>; cdecl;
  189.     function hashCode: Integer; cdecl;
  190.     function toByteArray: TJavaArray<Byte>; cdecl;
  191.     function toString: JString; cdecl;
  192.     procedure writeToParcel(dest: JParcel; flags: Integer); cdecl;
  193.   end;
  194.  
  195.   TJNdefMessage = class(TJavaGenericImport<JNdefMessageClass, JNdefMessage>)
  196.   end;
  197.  
  198.   JNdefRecordClass = interface(JObjectClass)
  199.     ['{A378AA8C-A1F5-4846-9983-EA96BB1E87E4}']
  200.     { Property methods }
  201.     function _GetCREATOR: JParcelable_Creator;
  202.     procedure _SetCREATOR(Value: JParcelable_Creator);
  203.     function _GetRTD_ALTERNATIVE_CARRIER: TJavaArray<Byte>;
  204.     procedure _SetRTD_ALTERNATIVE_CARRIER(Value: TJavaArray<Byte>);
  205.     function _GetRTD_HANDOVER_CARRIER: TJavaArray<Byte>;
  206.     procedure _SetRTD_HANDOVER_CARRIER(Value: TJavaArray<Byte>);
  207.     function _GetRTD_HANDOVER_REQUEST: TJavaArray<Byte>;
  208.     procedure _SetRTD_HANDOVER_REQUEST(Value: TJavaArray<Byte>);
  209.     function _GetRTD_HANDOVER_SELECT: TJavaArray<Byte>;
  210.     procedure _SetRTD_HANDOVER_SELECT(Value: TJavaArray<Byte>);
  211.     function _GetRTD_SMART_POSTER: TJavaArray<Byte>;
  212.     procedure _SetRTD_SMART_POSTER(Value: TJavaArray<Byte>);
  213.     function _GetRTD_TEXT: TJavaArray<Byte>;
  214.     procedure _SetRTD_TEXT(Value: TJavaArray<Byte>);
  215.     function _GetRTD_URI: TJavaArray<Byte>;
  216.     procedure _SetRTD_URI(Value: TJavaArray<Byte>);
  217.     function _GetTNF_ABSOLUTE_URI: SmallInt;
  218.     function _GetTNF_EMPTY: SmallInt;
  219.     function _GetTNF_EXTERNAL_TYPE: SmallInt;
  220.     function _GetTNF_MIME_MEDIA: SmallInt;
  221.     function _GetTNF_UNCHANGED: SmallInt;
  222.     function _GetTNF_UNKNOWN: SmallInt;
  223.     function _GetTNF_WELL_KNOWN: SmallInt;
  224.     { Methods }
  225.     function init(tnf: SmallInt; &type: TJavaArray<Byte>; id: TJavaArray<Byte>; payload: TJavaArray<Byte>): JNdefRecord; cdecl; overload;
  226.     function init(data: TJavaArray<Byte>): JNdefRecord; cdecl; overload; deprecated;
  227.     function createApplicationRecord(packageName: JString): JNdefRecord; cdecl;
  228.     function createExternal(domain: JString; &type: JString; data: TJavaArray<Byte>): JNdefRecord; cdecl;
  229.     function createMime(mimeType: JString; mimeData: TJavaArray<Byte>): JNdefRecord; cdecl;
  230.     function createUri(uriString: JString): JNdefRecord; cdecl; overload;
  231.     function createUri(uri: Jnet_Uri): JNdefRecord; cdecl; overload;
  232.     { Properties }
  233.     property CREATOR: JParcelable_Creator read _GetCREATOR write _SetCREATOR;
  234.     property RTD_ALTERNATIVE_CARRIER: TJavaArray<Byte> read _GetRTD_ALTERNATIVE_CARRIER write _SetRTD_ALTERNATIVE_CARRIER;
  235.     property RTD_HANDOVER_CARRIER: TJavaArray<Byte> read _GetRTD_HANDOVER_CARRIER write _SetRTD_HANDOVER_CARRIER;
  236.     property RTD_HANDOVER_REQUEST: TJavaArray<Byte> read _GetRTD_HANDOVER_REQUEST write _SetRTD_HANDOVER_REQUEST;
  237.     property RTD_HANDOVER_SELECT: TJavaArray<Byte> read _GetRTD_HANDOVER_SELECT write _SetRTD_HANDOVER_SELECT;
  238.     property RTD_SMART_POSTER: TJavaArray<Byte> read _GetRTD_SMART_POSTER write _SetRTD_SMART_POSTER;
  239.     property RTD_TEXT: TJavaArray<Byte> read _GetRTD_TEXT write _SetRTD_TEXT;
  240.     property RTD_URI: TJavaArray<Byte> read _GetRTD_URI write _SetRTD_URI;
  241.     property TNF_ABSOLUTE_URI: SmallInt read _GetTNF_ABSOLUTE_URI;
  242.     property TNF_EMPTY: SmallInt read _GetTNF_EMPTY;
  243.     property TNF_EXTERNAL_TYPE: SmallInt read _GetTNF_EXTERNAL_TYPE;
  244.     property TNF_MIME_MEDIA: SmallInt read _GetTNF_MIME_MEDIA;
  245.     property TNF_UNCHANGED: SmallInt read _GetTNF_UNCHANGED;
  246.     property TNF_UNKNOWN: SmallInt read _GetTNF_UNKNOWN;
  247.     property TNF_WELL_KNOWN: SmallInt read _GetTNF_WELL_KNOWN;
  248.   end;
  249.  
  250.   [JavaSignature('android/nfc/NdefRecord')]
  251.   JNdefRecord = interface(JObject)
  252.     ['{0E552F6E-B67C-4A19-9BD0-82864906025B}']
  253.     { Methods }
  254.     function describeContents: Integer; cdecl;
  255.     function equals(obj: JObject): Boolean; cdecl;
  256.     function getId: TJavaArray<Byte>; cdecl;
  257.     function getPayload: TJavaArray<Byte>; cdecl;
  258.     function getTnf: SmallInt; cdecl;
  259.     function getType: TJavaArray<Byte>; cdecl;
  260.     function hashCode: Integer; cdecl;
  261.     function toByteArray: TJavaArray<Byte>; cdecl; deprecated;
  262.     function toMimeType: JString; cdecl;
  263.     function toString: JString; cdecl;
  264.     function toUri: Jnet_Uri; cdecl;
  265.     procedure writeToParcel(dest: JParcel; flags: Integer); cdecl;
  266.   end;
  267.  
  268.   TJNdefRecord = class(TJavaGenericImport<JNdefRecordClass, JNdefRecord>)
  269.   end;
  270.  
  271.   JNfcAdapter_CreateBeamUrisCallbackClass = interface(IJavaClass)
  272.     ['{BFE6DE18-1854-4C2C-A523-6425F39AE21C}']
  273.   end;
  274.  
  275.   [JavaSignature('android/nfc/NfcAdapter$CreateBeamUrisCallback')]
  276.   JNfcAdapter_CreateBeamUrisCallback = interface(IJavaInstance)
  277.     ['{609C5FF3-B699-4E05-AF60-567A0BBF0E01}']
  278.     { Methods }
  279.     function createBeamUris(Param0: JNfcEvent): TJavaObjectArray<Jnet_Uri>; cdecl;
  280.   end;
  281.  
  282.   TJNfcAdapter_CreateBeamUrisCallback = class(TJavaGenericImport<JNfcAdapter_CreateBeamUrisCallbackClass, JNfcAdapter_CreateBeamUrisCallback>)
  283.   end;
  284.  
  285.   JNfcAdapter_CreateNdefMessageCallbackClass = interface(IJavaClass)
  286.     ['{51DBF0BD-EF76-40F6-9570-4CA6C447E19A}']
  287.   end;
  288.  
  289.   [JavaSignature('android/nfc/NfcAdapter$CreateNdefMessageCallback')]
  290.   JNfcAdapter_CreateNdefMessageCallback = interface(IJavaInstance)
  291.     ['{A72FD9C9-8A67-499D-B3B0-10E8EC2D6139}']
  292.     { Methods }
  293.     function createNdefMessage(Param0: JNfcEvent): JNdefMessage; cdecl;
  294.   end;
  295.  
  296.   TJNfcAdapter_CreateNdefMessageCallback = class(TJavaGenericImport<JNfcAdapter_CreateNdefMessageCallbackClass, JNfcAdapter_CreateNdefMessageCallback>)
  297.   end;
  298.  
  299.   JNfcAdapter_OnNdefPushCompleteCallbackClass = interface(IJavaClass)
  300.     ['{D859E3F0-641A-410A-9876-DD609FA72DAD}']
  301.   end;
  302.  
  303.   [JavaSignature('android/nfc/NfcAdapter$OnNdefPushCompleteCallback')]
  304.   JNfcAdapter_OnNdefPushCompleteCallback = interface(IJavaInstance)
  305.     ['{01D93D7A-2E1E-4C87-ABE1-77EE7D98C77B}']
  306.     { Methods }
  307.     procedure onNdefPushComplete(Param0: JNfcEvent); cdecl;
  308.   end;
  309.  
  310.   TJNfcAdapter_OnNdefPushCompleteCallback = class(TJavaGenericImport<JNfcAdapter_OnNdefPushCompleteCallbackClass, JNfcAdapter_OnNdefPushCompleteCallback>)
  311.   end;
  312.  
  313.   JNfcAdapter_ReaderCallbackClass = interface(IJavaClass)
  314.     ['{823E7F01-FCE8-43A5-96D4-57B348EDCDF2}']
  315.   end;
  316.  
  317.   [JavaSignature('android/nfc/NfcAdapter$ReaderCallback')]
  318.   JNfcAdapter_ReaderCallback = interface(IJavaInstance)
  319.     ['{F7435248-FC54-4183-923D-BE74FF7E3D40}']
  320.     { Methods }
  321.     procedure onTagDiscovered(Param0: JTag); cdecl;
  322.   end;
  323.  
  324.   TJNfcAdapter_ReaderCallback = class(TJavaGenericImport<JNfcAdapter_ReaderCallbackClass, JNfcAdapter_ReaderCallback>)
  325.   end;
  326.  
  327.   JNfcAdapterClass = interface(JObjectClass)
  328.     ['{16C97862-EAB8-4A85-A481-2DBF26084379}']
  329.     { Property methods }
  330.     function _GetACTION_ADAPTER_STATE_CHANGED: JString;
  331.     function _GetACTION_NDEF_DISCOVERED: JString;
  332.     function _GetACTION_TAG_DISCOVERED: JString;
  333.     function _GetACTION_TECH_DISCOVERED: JString;
  334.     function _GetEXTRA_ADAPTER_STATE: JString;
  335.     function _GetEXTRA_ID: JString;
  336.     function _GetEXTRA_NDEF_MESSAGES: JString;
  337.     function _GetEXTRA_READER_PRESENCE_CHECK_DELAY: JString;
  338.     function _GetEXTRA_TAG: JString;
  339.     function _GetFLAG_READER_NFC_A: Integer;
  340.     function _GetFLAG_READER_NFC_B: Integer;
  341.     function _GetFLAG_READER_NFC_BARCODE: Integer;
  342.     function _GetFLAG_READER_NFC_F: Integer;
  343.     function _GetFLAG_READER_NFC_V: Integer;
  344.     function _GetFLAG_READER_NO_PLATFORM_SOUNDS: Integer;
  345.     function _GetFLAG_READER_SKIP_NDEF_CHECK: Integer;
  346.     function _GetSTATE_OFF: Integer;
  347.     function _GetSTATE_ON: Integer;
  348.     function _GetSTATE_TURNING_OFF: Integer;
  349.     function _GetSTATE_TURNING_ON: Integer;
  350.     { Methods }
  351.     function getDefaultAdapter(context: JContext): JNfcAdapter; cdecl;
  352.     { Properties }
  353.     property ACTION_ADAPTER_STATE_CHANGED: JString read _GetACTION_ADAPTER_STATE_CHANGED;
  354.     property ACTION_NDEF_DISCOVERED: JString read _GetACTION_NDEF_DISCOVERED;
  355.     property ACTION_TAG_DISCOVERED: JString read _GetACTION_TAG_DISCOVERED;
  356.     property ACTION_TECH_DISCOVERED: JString read _GetACTION_TECH_DISCOVERED;
  357.     property EXTRA_ADAPTER_STATE: JString read _GetEXTRA_ADAPTER_STATE;
  358.     property EXTRA_ID: JString read _GetEXTRA_ID;
  359.     property EXTRA_NDEF_MESSAGES: JString read _GetEXTRA_NDEF_MESSAGES;
  360.     property EXTRA_READER_PRESENCE_CHECK_DELAY: JString read _GetEXTRA_READER_PRESENCE_CHECK_DELAY;
  361.     property EXTRA_TAG: JString read _GetEXTRA_TAG;
  362.     property FLAG_READER_NFC_A: Integer read _GetFLAG_READER_NFC_A;
  363.     property FLAG_READER_NFC_B: Integer read _GetFLAG_READER_NFC_B;
  364.     property FLAG_READER_NFC_BARCODE: Integer read _GetFLAG_READER_NFC_BARCODE;
  365.     property FLAG_READER_NFC_F: Integer read _GetFLAG_READER_NFC_F;
  366.     property FLAG_READER_NFC_V: Integer read _GetFLAG_READER_NFC_V;
  367.     property FLAG_READER_NO_PLATFORM_SOUNDS: Integer read _GetFLAG_READER_NO_PLATFORM_SOUNDS;
  368.     property FLAG_READER_SKIP_NDEF_CHECK: Integer read _GetFLAG_READER_SKIP_NDEF_CHECK;
  369.     property STATE_OFF: Integer read _GetSTATE_OFF;
  370.     property STATE_ON: Integer read _GetSTATE_ON;
  371.     property STATE_TURNING_OFF: Integer read _GetSTATE_TURNING_OFF;
  372.     property STATE_TURNING_ON: Integer read _GetSTATE_TURNING_ON;
  373.   end;
  374.  
  375.   [JavaSignature('android/nfc/NfcAdapter')]
  376.   JNfcAdapter = interface(JObject)
  377.     ['{DADBBFEC-CED5-4E38-8BCD-A45F01CE3EFE}']
  378.     { Methods }
  379.     procedure disableForegroundDispatch(activity: JActivity); cdecl;
  380.     procedure disableForegroundNdefPush(activity: JActivity); cdecl; deprecated;
  381.     procedure disableReaderMode(activity: JActivity); cdecl;
  382.     procedure enableForegroundDispatch(activity: JActivity; intent: JPendingIntent; filters: TJavaObjectArray<JIntentFilter>; techLists: TJavaObjectArray<JString>); cdecl;
  383.     procedure enableForegroundNdefPush(activity: JActivity; &message: JNdefMessage); cdecl; deprecated;
  384.     procedure enableReaderMode(activity: JActivity; callback: JNfcAdapter_ReaderCallback; flags: Integer; extras: JBundle); cdecl;
  385.     function isEnabled: Boolean; cdecl;
  386.     function isNdefPushEnabled: Boolean; cdecl;
  387.     procedure setBeamPushUris(uris: TJavaObjectArray<Jnet_Uri>; activity: JActivity); cdecl;
  388.     procedure setBeamPushUrisCallback(callback: JNfcAdapter_CreateBeamUrisCallback; activity: JActivity); cdecl;
  389.     procedure setNdefPushMessage(&message: JNdefMessage; activity: JActivity; activities: TJavaObjectArray<JActivity>); cdecl;
  390.     procedure setNdefPushMessageCallback(callback: JNfcAdapter_CreateNdefMessageCallback; activity: JActivity; activities: TJavaObjectArray<JActivity>); cdecl;
  391.     procedure setOnNdefPushCompleteCallback(callback: JNfcAdapter_OnNdefPushCompleteCallback; activity: JActivity; activities: TJavaObjectArray<JActivity>); cdecl;
  392.   end;
  393.  
  394.   TJNfcAdapter = class(TJavaGenericImport<JNfcAdapterClass, JNfcAdapter>)
  395.   end;
  396.  
  397.   JNfcEventClass = interface(JObjectClass)
  398.     ['{83B91408-3117-4EC6-AC92-6D62F859ADCF}']
  399.   end;
  400.  
  401.   [JavaSignature('android/nfc/NfcEvent')]
  402.   JNfcEvent = interface(JObject)
  403.     ['{AB045C54-D04D-418B-921A-6D63C2F234A4}']
  404.     { Property methods }
  405.     function _GetnfcAdapter: JNfcAdapter;
  406.     procedure _SetnfcAdapter(Value: JNfcAdapter);
  407.     { Properties }
  408.     property nfcAdapter: JNfcAdapter read _GetnfcAdapter write _SetnfcAdapter;
  409.   end;
  410.  
  411.   TJNfcEvent = class(TJavaGenericImport<JNfcEventClass, JNfcEvent>)
  412.   end;
  413.  
  414.   JNfcManagerClass = interface(JObjectClass)
  415.     ['{7C17404C-DC8B-45BF-95F5-89BB7C8ACD7B}']
  416.   end;
  417.  
  418.   [JavaSignature('android/nfc/NfcManager')]
  419.   JNfcManager = interface(JObject)
  420.     ['{CC1C67F6-DB7C-422E-AEED-8BE978E38F82}']
  421.     { Methods }
  422.     function getDefaultAdapter: JNfcAdapter; cdecl;
  423.   end;
  424.  
  425.   TJNfcManager = class(TJavaGenericImport<JNfcManagerClass, JNfcManager>)
  426.   end;
  427.  
  428.   JTagClass = interface(JObjectClass)
  429.     ['{70D70482-9B7C-4FED-8F69-531F49E8F179}']
  430.     { Property methods }
  431.     function _GetCREATOR: JParcelable_Creator;
  432.     procedure _SetCREATOR(Value: JParcelable_Creator);
  433.     { Properties }
  434.     property CREATOR: JParcelable_Creator read _GetCREATOR write _SetCREATOR;
  435.   end;
  436.  
  437.   [JavaSignature('android/nfc/Tag')]
  438.   JTag = interface(JObject)
  439.     ['{F0137B87-18CA-4D88-A95B-0E02B5A8448C}']
  440.     { Methods }
  441.     function describeContents: Integer; cdecl;
  442.     function getId: TJavaArray<Byte>; cdecl;
  443.     function getTechList: TJavaObjectArray<JString>; cdecl;
  444.     function toString: JString; cdecl;
  445.     procedure writeToParcel(dest: JParcel; flags: Integer); cdecl;
  446.   end;
  447.  
  448.   TJTag = class(TJavaGenericImport<JTagClass, JTag>)
  449.   end;
  450.  
  451.   JTagLostExceptionClass = interface(JObjectClass)
  452.     ['{1FFE5C44-ABD4-487B-9755-0F5250B7C1F5}']
  453.     { Methods }
  454.     function init: JTagLostException; cdecl; overload;
  455.     function init(&message: JString): JTagLostException; cdecl; overload;
  456.   end;
  457.  
  458.   [JavaSignature('android/nfc/TagLostException')]
  459.   JTagLostException = interface(JObject)
  460.     ['{FD51EE40-3222-4B5F-96E5-E03C32DF270C}']
  461.   end;
  462.  
  463.   TJTagLostException = class(TJavaGenericImport<JTagLostExceptionClass, JTagLostException>)
  464.   end;
  465.  
  466.   JBasicTagTechnologyClass = interface(JObjectClass)
  467.     ['{EAB8AA93-40FD-4CD1-9D54-794094E3242E}']
  468.   end;
  469.  
  470.   [JavaSignature('android/nfc/tech/BasicTagTechnology')]
  471.   JBasicTagTechnology = interface(JObject)
  472.     ['{783BBD0E-6377-4C10-9D11-0D6F496F9180}']
  473.     { Methods }
  474.     procedure close; cdecl;
  475.     procedure connect; cdecl;
  476.     function getTag: JTag; cdecl;
  477.     function isConnected: Boolean; cdecl;
  478.   end;
  479.  
  480.   TJBasicTagTechnology = class(TJavaGenericImport<JBasicTagTechnologyClass, JBasicTagTechnology>)
  481.   end;
  482.  
  483.   JIsoDepClass = interface(JObjectClass)
  484.     ['{CFC924FE-2D4A-49A6-AB30-BAF82FEBD2A6}']
  485.     { Methods }
  486.     function get(tag: JTag): JIsoDep; cdecl;
  487.   end;
  488.  
  489.   [JavaSignature('android/nfc/tech/IsoDep')]
  490.   JIsoDep = interface(JObject)
  491.     ['{2DC3AA71-4565-4D17-99DA-9B82DB9FFD06}']
  492.     { Methods }
  493.     procedure close; cdecl;
  494.     procedure connect; cdecl;
  495.     function getHiLayerResponse: TJavaArray<Byte>; cdecl;
  496.     function getHistoricalBytes: TJavaArray<Byte>; cdecl;
  497.     function getMaxTransceiveLength: Integer; cdecl;
  498.     function getTag: JTag; cdecl;
  499.     function getTimeout: Integer; cdecl;
  500.     function isConnected: Boolean; cdecl;
  501.     function isExtendedLengthApduSupported: Boolean; cdecl;
  502.     procedure setTimeout(timeout: Integer); cdecl;
  503.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  504.   end;
  505.  
  506.   TJIsoDep = class(TJavaGenericImport<JIsoDepClass, JIsoDep>)
  507.   end;
  508.  
  509.   JMifareClassicClass = interface(JObjectClass)
  510.     ['{354CDE1A-A65C-43A7-A03F-11614913B0EB}']
  511.     { Property methods }
  512.     function _GetBLOCK_SIZE: Integer;
  513.     function _GetKEY_DEFAULT: TJavaArray<Byte>;
  514.     procedure _SetKEY_DEFAULT(Value: TJavaArray<Byte>);
  515.     function _GetKEY_MIFARE_APPLICATION_DIRECTORY: TJavaArray<Byte>;
  516.     procedure _SetKEY_MIFARE_APPLICATION_DIRECTORY(Value: TJavaArray<Byte>);
  517.     function _GetKEY_NFC_FORUM: TJavaArray<Byte>;
  518.     procedure _SetKEY_NFC_FORUM(Value: TJavaArray<Byte>);
  519.     function _GetSIZE_1K: Integer;
  520.     function _GetSIZE_2K: Integer;
  521.     function _GetSIZE_4K: Integer;
  522.     function _GetSIZE_MINI: Integer;
  523.     function _GetTYPE_CLASSIC: Integer;
  524.     function _GetTYPE_PLUS: Integer;
  525.     function _GetTYPE_PRO: Integer;
  526.     function _GetTYPE_UNKNOWN: Integer;
  527.     { Methods }
  528.     function get(tag: JTag): JMifareClassic; cdecl;
  529.     { Properties }
  530.     property BLOCK_SIZE: Integer read _GetBLOCK_SIZE;
  531.     property KEY_DEFAULT: TJavaArray<Byte> read _GetKEY_DEFAULT write _SetKEY_DEFAULT;
  532.     property KEY_MIFARE_APPLICATION_DIRECTORY: TJavaArray<Byte> read _GetKEY_MIFARE_APPLICATION_DIRECTORY write _SetKEY_MIFARE_APPLICATION_DIRECTORY;
  533.     property KEY_NFC_FORUM: TJavaArray<Byte> read _GetKEY_NFC_FORUM write _SetKEY_NFC_FORUM;
  534.     property SIZE_1K: Integer read _GetSIZE_1K;
  535.     property SIZE_2K: Integer read _GetSIZE_2K;
  536.     property SIZE_4K: Integer read _GetSIZE_4K;
  537.     property SIZE_MINI: Integer read _GetSIZE_MINI;
  538.     property TYPE_CLASSIC: Integer read _GetTYPE_CLASSIC;
  539.     property TYPE_PLUS: Integer read _GetTYPE_PLUS;
  540.     property TYPE_PRO: Integer read _GetTYPE_PRO;
  541.     property TYPE_UNKNOWN: Integer read _GetTYPE_UNKNOWN;
  542.   end;
  543.  
  544.   [JavaSignature('android/nfc/tech/MifareClassic')]
  545.   JMifareClassic = interface(JObject)
  546.     ['{AB88587E-A31A-4797-BF79-F178123160E3}']
  547.     { Methods }
  548.     function authenticateSectorWithKeyA(sectorIndex: Integer; key: TJavaArray<Byte>): Boolean; cdecl;
  549.     function authenticateSectorWithKeyB(sectorIndex: Integer; key: TJavaArray<Byte>): Boolean; cdecl;
  550.     function blockToSector(blockIndex: Integer): Integer; cdecl;
  551.     procedure close; cdecl;
  552.     procedure connect; cdecl;
  553.     procedure decrement(blockIndex: Integer; Value: Integer); cdecl;
  554.     function getBlockCount: Integer; cdecl;
  555.     function getBlockCountInSector(sectorIndex: Integer): Integer; cdecl;
  556.     function getMaxTransceiveLength: Integer; cdecl;
  557.     function getSectorCount: Integer; cdecl;
  558.     function getSize: Integer; cdecl;
  559.     function getTag: JTag; cdecl;
  560.     function getTimeout: Integer; cdecl;
  561.     function getType: Integer; cdecl;
  562.     procedure increment(blockIndex: Integer; Value: Integer); cdecl;
  563.     function isConnected: Boolean; cdecl;
  564.     function readBlock(blockIndex: Integer): TJavaArray<Byte>; cdecl;
  565.     procedure restore(blockIndex: Integer); cdecl;
  566.     function sectorToBlock(sectorIndex: Integer): Integer; cdecl;
  567.     procedure setTimeout(timeout: Integer); cdecl;
  568.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  569.     procedure transfer(blockIndex: Integer); cdecl;
  570.     procedure writeBlock(blockIndex: Integer; data: TJavaArray<Byte>); cdecl;
  571.   end;
  572.  
  573.   TJMifareClassic = class(TJavaGenericImport<JMifareClassicClass, JMifareClassic>)
  574.   end;
  575.  
  576.   JMifareUltralightClass = interface(JObjectClass)
  577.     ['{6677366A-EC35-4855-9D4A-29833A20930B}']
  578.     { Property methods }
  579.     function _GetPAGE_SIZE: Integer;
  580.     function _GetTYPE_ULTRALIGHT: Integer;
  581.     function _GetTYPE_ULTRALIGHT_C: Integer;
  582.     function _GetTYPE_UNKNOWN: Integer;
  583.     { Methods }
  584.     function get(tag: JTag): JMifareUltralight; cdecl;
  585.     { Properties }
  586.     property PAGE_SIZE: Integer read _GetPAGE_SIZE;
  587.     property TYPE_ULTRALIGHT: Integer read _GetTYPE_ULTRALIGHT;
  588.     property TYPE_ULTRALIGHT_C: Integer read _GetTYPE_ULTRALIGHT_C;
  589.     property TYPE_UNKNOWN: Integer read _GetTYPE_UNKNOWN;
  590.   end;
  591.  
  592.   [JavaSignature('android/nfc/tech/MifareUltralight')]
  593.   JMifareUltralight = interface(JObject)
  594.     ['{25C8EEF0-D566-4014-8DF8-6FF039A88DEB}']
  595.     { Methods }
  596.     procedure close; cdecl;
  597.     procedure connect; cdecl;
  598.     function getMaxTransceiveLength: Integer; cdecl;
  599.     function getTag: JTag; cdecl;
  600.     function getTimeout: Integer; cdecl;
  601.     function getType: Integer; cdecl;
  602.     function isConnected: Boolean; cdecl;
  603.     function readPages(pageOffset: Integer): TJavaArray<Byte>; cdecl;
  604.     procedure setTimeout(timeout: Integer); cdecl;
  605.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  606.     procedure writePage(pageOffset: Integer; data: TJavaArray<Byte>); cdecl;
  607.   end;
  608.  
  609.   TJMifareUltralight = class(TJavaGenericImport<JMifareUltralightClass, JMifareUltralight>)
  610.   end;
  611.  
  612.   JNdefClass = interface(JObjectClass)
  613.     ['{952E5F09-C924-419A-AEA0-802C8F4B018C}']
  614.     { Property methods }
  615.     function _GetMIFARE_CLASSIC: JString;
  616.     function _GetNFC_FORUM_TYPE_1: JString;
  617.     function _GetNFC_FORUM_TYPE_2: JString;
  618.     function _GetNFC_FORUM_TYPE_3: JString;
  619.     function _GetNFC_FORUM_TYPE_4: JString;
  620.     { Methods }
  621.     function get(tag: JTag): JNdef; cdecl;
  622.     { Properties }
  623.     property MIFARE_CLASSIC: JString read _GetMIFARE_CLASSIC;
  624.     property NFC_FORUM_TYPE_1: JString read _GetNFC_FORUM_TYPE_1;
  625.     property NFC_FORUM_TYPE_2: JString read _GetNFC_FORUM_TYPE_2;
  626.     property NFC_FORUM_TYPE_3: JString read _GetNFC_FORUM_TYPE_3;
  627.     property NFC_FORUM_TYPE_4: JString read _GetNFC_FORUM_TYPE_4;
  628.   end;
  629.  
  630.   [JavaSignature('android/nfc/tech/Ndef')]
  631.   JNdef = interface(JObject)
  632.     ['{07CB3172-9D1B-48BE-A9A6-01884C306109}']
  633.     { Methods }
  634.     function canMakeReadOnly: Boolean; cdecl;
  635.     procedure close; cdecl;
  636.     procedure connect; cdecl;
  637.     function getCachedNdefMessage: JNdefMessage; cdecl;
  638.     function getMaxSize: Integer; cdecl;
  639.     function getNdefMessage: JNdefMessage; cdecl;
  640.     function getTag: JTag; cdecl;
  641.     function getType: JString; cdecl;
  642.     function isConnected: Boolean; cdecl;
  643.     function isWritable: Boolean; cdecl;
  644.     function makeReadOnly: Boolean; cdecl;
  645.     procedure writeNdefMessage(msg: JNdefMessage); cdecl;
  646.   end;
  647.  
  648.   TJNdef = class(TJavaGenericImport<JNdefClass, JNdef>)
  649.   end;
  650.  
  651.   JNdefFormatableClass = interface(JObjectClass)
  652.     ['{FD2507AE-8201-4056-9603-01834A2E375D}']
  653.     { Methods }
  654.     function get(tag: JTag): JNdefFormatable; cdecl;
  655.   end;
  656.  
  657.   [JavaSignature('android/nfc/tech/NdefFormatable')]
  658.   JNdefFormatable = interface(JObject)
  659.     ['{08C293E6-9130-457A-BE7D-0EFCCB5AB8AF}']
  660.     { Methods }
  661.     procedure close; cdecl;
  662.     procedure connect; cdecl;
  663.     procedure format(firstMessage: JNdefMessage); cdecl;
  664.     procedure formatReadOnly(firstMessage: JNdefMessage); cdecl;
  665.     function getTag: JTag; cdecl;
  666.     function isConnected: Boolean; cdecl;
  667.   end;
  668.  
  669.   TJNdefFormatable = class(TJavaGenericImport<JNdefFormatableClass, JNdefFormatable>)
  670.   end;
  671.  
  672.   JNfcAClass = interface(JObjectClass)
  673.     ['{C7CC1347-7CCB-4ED5-9A2C-1D82FA20AD1B}']
  674.     { Methods }
  675.     function get(tag: JTag): JNfcA; cdecl;
  676.   end;
  677.  
  678.   [JavaSignature('android/nfc/tech/NfcA')]
  679.   JNfcA = interface(JObject)
  680.     ['{6EAD7DA0-95A6-4230-B33E-FDDF98D80ACD}']
  681.     { Methods }
  682.     procedure close; cdecl;
  683.     procedure connect; cdecl;
  684.     function getAtqa: TJavaArray<Byte>; cdecl;
  685.     function getMaxTransceiveLength: Integer; cdecl;
  686.     function getSak: SmallInt; cdecl;
  687.     function getTag: JTag; cdecl;
  688.     function getTimeout: Integer; cdecl;
  689.     function isConnected: Boolean; cdecl;
  690.     procedure setTimeout(timeout: Integer); cdecl;
  691.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  692.   end;
  693.  
  694.   TJNfcA = class(TJavaGenericImport<JNfcAClass, JNfcA>)
  695.   end;
  696.  
  697.   JNfcBClass = interface(JObjectClass)
  698.     ['{3AA0A259-27DC-4442-BA25-B5C44DE8FC1D}']
  699.     { Methods }
  700.     function get(tag: JTag): JNfcB; cdecl;
  701.   end;
  702.  
  703.   [JavaSignature('android/nfc/tech/NfcB')]
  704.   JNfcB = interface(JObject)
  705.     ['{ECEFD061-2CE5-4B51-AC25-C98A28C79FB5}']
  706.     { Methods }
  707.     procedure close; cdecl;
  708.     procedure connect; cdecl;
  709.     function getApplicationData: TJavaArray<Byte>; cdecl;
  710.     function getMaxTransceiveLength: Integer; cdecl;
  711.     function getProtocolInfo: TJavaArray<Byte>; cdecl;
  712.     function getTag: JTag; cdecl;
  713.     function isConnected: Boolean; cdecl;
  714.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  715.   end;
  716.  
  717.   TJNfcB = class(TJavaGenericImport<JNfcBClass, JNfcB>)
  718.   end;
  719.  
  720.   JNfcBarcodeClass = interface(JObjectClass)
  721.     ['{969DCC14-1526-486B-A41B-3E7DC426DB36}']
  722.     { Property methods }
  723.     function _GetTYPE_KOVIO: Integer;
  724.     function _GetTYPE_UNKNOWN: Integer;
  725.     { Methods }
  726.     function get(tag: JTag): JNfcBarcode; cdecl;
  727.     { Properties }
  728.     property TYPE_KOVIO: Integer read _GetTYPE_KOVIO;
  729.     property TYPE_UNKNOWN: Integer read _GetTYPE_UNKNOWN;
  730.   end;
  731.  
  732.   [JavaSignature('android/nfc/tech/NfcBarcode')]
  733.   JNfcBarcode = interface(JObject)
  734.     ['{0E0D7BC3-EE8B-4E84-A497-E42FEE88A6F4}']
  735.     { Methods }
  736.     procedure close; cdecl;
  737.     procedure connect; cdecl;
  738.     function getBarcode: TJavaArray<Byte>; cdecl;
  739.     function getTag: JTag; cdecl;
  740.     function getType: Integer; cdecl;
  741.     function isConnected: Boolean; cdecl;
  742.   end;
  743.  
  744.   TJNfcBarcode = class(TJavaGenericImport<JNfcBarcodeClass, JNfcBarcode>)
  745.   end;
  746.  
  747.   JNfcFClass = interface(JObjectClass)
  748.     ['{A61ADBBC-6687-442F-9005-48CFBAA1D3BF}']
  749.     { Methods }
  750.     function get(tag: JTag): JNfcF; cdecl;
  751.   end;
  752.  
  753.   [JavaSignature('android/nfc/tech/NfcF')]
  754.   JNfcF = interface(JObject)
  755.     ['{76433696-EF45-4D38-A3C2-15C5B9D6817D}']
  756.     { Methods }
  757.     procedure close; cdecl;
  758.     procedure connect; cdecl;
  759.     function getManufacturer: TJavaArray<Byte>; cdecl;
  760.     function getMaxTransceiveLength: Integer; cdecl;
  761.     function getSystemCode: TJavaArray<Byte>; cdecl;
  762.     function getTag: JTag; cdecl;
  763.     function getTimeout: Integer; cdecl;
  764.     function isConnected: Boolean; cdecl;
  765.     procedure setTimeout(timeout: Integer); cdecl;
  766.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  767.   end;
  768.  
  769.   TJNfcF = class(TJavaGenericImport<JNfcFClass, JNfcF>)
  770.   end;
  771.  
  772.   JNfcVClass = interface(JObjectClass)
  773.     ['{30E78EF3-BA54-43EA-A30B-E7DB2F13F635}']
  774.     { Methods }
  775.     function get(tag: JTag): JNfcV; cdecl;
  776.   end;
  777.  
  778.   [JavaSignature('android/nfc/tech/NfcV')]
  779.   JNfcV = interface(JObject)
  780.     ['{79448CB5-93BC-49D4-8424-B1CEE62FA71F}']
  781.     { Methods }
  782.     procedure close; cdecl;
  783.     procedure connect; cdecl;
  784.     function getDsfId: Byte; cdecl;
  785.     function getMaxTransceiveLength: Integer; cdecl;
  786.     function getResponseFlags: Byte; cdecl;
  787.     function getTag: JTag; cdecl;
  788.     function isConnected: Boolean; cdecl;
  789.     function transceive(data: TJavaArray<Byte>): TJavaArray<Byte>; cdecl;
  790.   end;
  791.  
  792.   TJNfcV = class(TJavaGenericImport<JNfcVClass, JNfcV>)
  793.   end;
  794.  
  795.   JTagTechnologyClass = interface(IJavaClass)
  796.     ['{3C1A028A-02C0-4AEC-9EAC-5CFA949C5ACF}']
  797.   end;
  798.  
  799.   [JavaSignature('android/nfc/tech/TagTechnology')]
  800.   JTagTechnology = interface(IJavaInstance)
  801.     ['{C191C90F-0D45-468B-8DFC-463313DFA51D}']
  802.     { Methods }
  803.     procedure close; cdecl;
  804.     procedure connect; cdecl;
  805.     function getTag: JTag; cdecl;
  806.     function isConnected: Boolean; cdecl;
  807.   end;
  808.  
  809.   TJTagTechnology = class(TJavaGenericImport<JTagTechnologyClass, JTagTechnology>)
  810.   end;
  811.  
  812. const
  813.   TJCardEmulation_ACTION_CHANGE_DEFAULT = 'android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT';
  814.   TJCardEmulation_CATEGORY_OTHER = 'other';
  815.   TJCardEmulation_CATEGORY_PAYMENT = 'payment';
  816.   TJCardEmulation_EXTRA_CATEGORY = 'category';
  817.   TJCardEmulation_EXTRA_SERVICE_COMPONENT = 'component';
  818.   TJCardEmulation_SELECTION_MODE_ALWAYS_ASK = 1;
  819.   TJCardEmulation_SELECTION_MODE_ASK_IF_CONFLICT = 2;
  820.   TJCardEmulation_SELECTION_MODE_PREFER_DEFAULT = 0;
  821.  
  822.   TJHostApduService_DEACTIVATION_DESELECTED = 1;
  823.   TJHostApduService_DEACTIVATION_LINK_LOSS = 0;
  824.   TJHostApduService_SERVICE_INTERFACE = 'android.nfc.cardemulation.action.HOST_APDU_SERVICE';
  825.   TJHostApduService_SERVICE_META_DATA = 'android.nfc.cardemulation.host_apdu_service';
  826.  
  827.   TJOffHostApduService_SERVICE_INTERFACE = 'android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE';
  828.   TJOffHostApduService_SERVICE_META_DATA = 'android.nfc.cardemulation.off_host_apdu_service';
  829.  
  830.   TJNdefRecord_TNF_ABSOLUTE_URI = 3;
  831.   TJNdefRecord_TNF_EMPTY = 0;
  832.   TJNdefRecord_TNF_EXTERNAL_TYPE = 4;
  833.   TJNdefRecord_TNF_MIME_MEDIA = 2;
  834.   TJNdefRecord_TNF_UNCHANGED = 6;
  835.   TJNdefRecord_TNF_UNKNOWN = 5;
  836.   TJNdefRecord_TNF_WELL_KNOWN = 1;
  837.  
  838.   TJNfcAdapter_ACTION_ADAPTER_STATE_CHANGED = 'android.nfc.action.ADAPTER_STATE_CHANGED';
  839.   TJNfcAdapter_ACTION_NDEF_DISCOVERED = 'android.nfc.action.NDEF_DISCOVERED';
  840.   TJNfcAdapter_ACTION_TAG_DISCOVERED = 'android.nfc.action.TAG_DISCOVERED';
  841.   TJNfcAdapter_ACTION_TECH_DISCOVERED = 'android.nfc.action.TECH_DISCOVERED';
  842.   TJNfcAdapter_EXTRA_ADAPTER_STATE = 'android.nfc.extra.ADAPTER_STATE';
  843.   TJNfcAdapter_EXTRA_ID = 'android.nfc.extra.ID';
  844.   TJNfcAdapter_EXTRA_NDEF_MESSAGES = 'android.nfc.extra.NDEF_MESSAGES';
  845.   TJNfcAdapter_EXTRA_READER_PRESENCE_CHECK_DELAY = 'presence';
  846.   TJNfcAdapter_EXTRA_TAG = 'android.nfc.extra.TAG';
  847.   TJNfcAdapter_FLAG_READER_NFC_A = 1;
  848.   TJNfcAdapter_FLAG_READER_NFC_B = 2;
  849.   TJNfcAdapter_FLAG_READER_NFC_BARCODE = 16;
  850.   TJNfcAdapter_FLAG_READER_NFC_F = 4;
  851.   TJNfcAdapter_FLAG_READER_NFC_V = 8;
  852.   TJNfcAdapter_FLAG_READER_NO_PLATFORM_SOUNDS = 256;
  853.   TJNfcAdapter_FLAG_READER_SKIP_NDEF_CHECK = 128;
  854.   TJNfcAdapter_STATE_OFF = 1;
  855.   TJNfcAdapter_STATE_ON = 3;
  856.   TJNfcAdapter_STATE_TURNING_OFF = 4;
  857.   TJNfcAdapter_STATE_TURNING_ON = 2;
  858.  
  859.   TJMifareClassic_BLOCK_SIZE = 16;
  860.   TJMifareClassic_SIZE_1K = 1024;
  861.   TJMifareClassic_SIZE_2K = 2048;
  862.   TJMifareClassic_SIZE_4K = 4096;
  863.   TJMifareClassic_SIZE_MINI = 320;
  864.   TJMifareClassic_TYPE_CLASSIC = 0;
  865.   TJMifareClassic_TYPE_PLUS = 1;
  866.   TJMifareClassic_TYPE_PRO = 2;
  867.   TJMifareClassic_TYPE_UNKNOWN = -1;
  868.  
  869.   TJMifareUltralight_PAGE_SIZE = 4;
  870.   TJMifareUltralight_TYPE_ULTRALIGHT = 1;
  871.   TJMifareUltralight_TYPE_ULTRALIGHT_C = 2;
  872.   TJMifareUltralight_TYPE_UNKNOWN = -1;
  873.  
  874.   TJNdef_MIFARE_CLASSIC = 'com.nxp.ndef.mifareclassic';
  875.   TJNdef_NFC_FORUM_TYPE_1 = 'org.nfcforum.ndef.type1';
  876.   TJNdef_NFC_FORUM_TYPE_2 = 'org.nfcforum.ndef.type2';
  877.   TJNdef_NFC_FORUM_TYPE_3 = 'org.nfcforum.ndef.type3';
  878.   TJNdef_NFC_FORUM_TYPE_4 = 'org.nfcforum.ndef.type4';
  879.  
  880.   TJNfcBarcode_TYPE_KOVIO = 1;
  881.   TJNfcBarcode_TYPE_UNKNOWN = -1;
  882.  
  883. implementation
  884.  
  885. end.

by admin at September 11, 2014 09:22 PM

Žarko Gajić

Fun: Refactoring a Complex Delphi Boolean Function

tfRefactoring your own code is, what I guess, something that you do frequently – at least I am. Maybe a better description of the process I went through would be rewriting, but let’s stick with refactoring. Either the routines get too complex, or there’s an extra parameter needed or there’s some new special case to be handled, never mind the reason, refactoring of your own code is what we all do and should do.

I will not go here into explaining various reasons (and solutions) why and how you would want to rewrite your own functions (maybe originally coded years ago). There are plenty of possible scenarios/solutions: extract some piece of code into a separate routine, optimize sections, replace records with objects (or the opposite), introduce new language constructs and so on.

A few days ago I’ve placed my hands over a Delphi application coded years ago. My task was to extend one function with some special processing. The actual function already had some 2000 (two thousand) lines of code. There were a couple of nested subroutines including more nested subroutines. There were some 20 (twenty) input parameters.

As you might imagine: a mess!

But, a task is a task and one has to finish what was started. After a few hours (read: days) I’ve successfully refactored the entire function (introduced function overloads, removed duplicated code, normal optimization stuff…)

However, and to be honest, my first reaction was “heck, I guess the fastest would be to rewrite the entire function in the following, much simpler manner (code below). After all, a boolean function would either return a false or a true value – only 2 possible outcomes of the 2000 lines of code!

And here’s what my first (virtual) solution was:

function Refactored(const someInputParameters : integer): boolean;
const
  returnValue : array [0..1] of boolean = (false, true);
begin
  result := returnValue[GetTickCount MOD 2];
end;

From the first look, the above implementation of a boolean function is as good as any. After all, it would return either true or false, there’s no 3rd option with booleans :)

You? Had a similar moment?

by zarkogajic at September 11, 2014 11:00 AM

The Wiert Corner - irregular stream of stuff

jpluimers

For a breaking issue, there has been an important bug fix to Coninua CI. From the downloads page:

From the change log:

v1.5.0.278

September 11th, 2014

  • Download Continua CI (64 bit)
  • Download Continua CI (32 bit)
  • Download Agent Installer (64 bit)
  • Download Agent Installer (32 bit)

Changes

  • Fix: A breaking issue with the repository cache in Git and possibly other branch-aware repositories was introduced the last build to fix issue with Subversion branches. This has now been fixed.
  • Update: Cancelling a stage promotion will now cause the build finish time to be set to the finish time of the last stage run.

–jeroen

via: Version 1.5 History | Continua CI.

PS: I also updated Continua CI Version 1.5 has been released build 1.5.0.268; smaller, faster, loads of new features; Spring4D XE7 builds automated with the new links.


Filed under: .NET, Continua CI, Continuous Integration, Delphi, Development, DVCS - Distributed Version Control, git, Mercurial/Hg, Software Development, Subversion/SVN

by Jeroen Pluimers at September 11, 2014 05:30 AM

jpluimers

Reminder to Self: write Eurekalog article about finding cause for hard to catch Access Violations in Delphi

–jeroen

via: web services – Access Violation (Delphi) – except the first run – Stack Overflow.


Filed under: Delphi, Development, Software Development

by Jeroen Pluimers at September 11, 2014 05:00 AM

September 10, 2014

Firebird News

A new theme for FirebirdNews?

I think it is time for updating the WordPress’s theme used in FirebirdNews. The actual theme is based in the Firefox theme (old and no more maintained) and doesn’t support well some of the new features available in the most recent versions of WordPress. WordPress has thousands of themes, and choosing the right one is a difficult task, […]

by Cantu at September 10, 2014 07:29 PM

It's a blong, blong, blong road...

Delphi and NFC on Android

NFC is a neat technology.

If you’ve got an NFC sensor on your phone or tablet then there is a reasonable chance you’ve played around with apps like Trigger, which perform various actions on your device when you wave it over NFC tags in stickers or on key fobs etc. after a bit of setup.

So, for example, you could have an NFC sticker by the front door that has been coded by Trigger to turn off Wi-Fi and Bluetooth. With a variety of of NFC tags around and about you can set up your phone how you need it when you need it by a simple wave, avoiding a whole lot of fiddling about in the device settings.

Anyway, that’s one application of NFC tags. There are, of course, plenty more.

Indeed there have been a good number of questions in various forums asking how to get programmable NFC support in Delphi. Of course NFC is not currently “wrapped up” by Delphi’s RTL so up until now it’s been in the hands of the “creative”.

NFC tag scanning support in Android falls into 2 areas:

  1. You install an app that advertises that it can respond to some NFC tag content. When the device is waved against such a tag the app can be automatically launched. If more than 1 app is registered Android will initially launch a chooser dialog to allow the user to pick the app they require.
    Actually this support is easy enough to do in Delphi so long as you can locate a suitable import unit or two containing the required Android APIs for NFC.
  2. You run an app that permits the user to scan NFC tags while it is in the foreground and it directly responds to any scanned tags.
    This seems to be more commonly required in commercial applications and alas is much more difficult to achieve with Delphi. It falls into the category of problem that requires some Java smarts and some command prompt hackery to achieve.
    Bummer.

Anyway, I was recently looking into writing some NFC support, given the frequency of questions being asked. Part way through my research I discovered that Daniel Magin was simultaneously trying to do the same thing, primarily for a talk at Delphi Tage.

I helped Daniel out with the Java callback and command-line building trickery – that seems to be an area where I can readily add value to Android low level chicanery – and he helped me out overcoming a nasty crash bug with Java arrays of NFC data records not being surfaced correctly by the Delphi RTL.

In the end we both had some sample apps that permit NFC scanning and also, just as an added bonus, NFC writing!

You can find my solutions written up in quite some detail here:

Daniel’s efforts will also be made available very soon.

Enjoy coding up your NFC apps, everyone!

by Brian Long (noreply@blogger.com) at September 10, 2014 01:36 PM

The Wiert Corner - irregular stream of stuff

jpluimers

I’m really happy that Continua CI Version 1.5 got released a few hours ago as per the Continua 1.5 released announcement.

It means that my Build Automation Session during the Dutch Delphi 2014 conference tomorrow can range from:

  • build using MSbuild from the command-line
  • build batch files
  • build using a custom front-end
  • build using Continuous Integration front-end

The session will explain lots of details about what various Delphi versions do, how to cope with dependencies, etc.

In the mean time, the preliminary Spring4D work on build automation is visible to guest users. Those include building for Delphi XE7 for the Win32, Win64 and OSX32 targets (in Debug and Release mode).

There is a huge list of Version 1.5 History @ Continua CI changes, which is partially quoted below.

For me these are the most important:

  • in-place upgrade without having to do any changes on my part
  • truckload of new features (including Delphi XE7, NuGet and Fake F# support)
  • smaller
  • faster

(as a side note: also FinalBuilder 7 was recently updated to support Delphi XE7)

In general, I like Continua CI a lot, most importantly because:

  • it is very stable
  • it has native support for a wide range of software development tools (including Delphi, Visual Studio and much more)
  • supports DVCS (like Git/Mercurial) just as you expect it to
  • if something breaks, you get a response and fix very very soon

You can download the new version through the Downloads @ Continua CI. These are the direct links:

For a breaking issue, there has been an important bug fix, so the new downloads are:

I created an RSS feed through Page2RSS to watch any new releases of Continua CI.

Parts of the changes in 1.5.0.268 1.5.0.278

The full list of changes are at Version 1.5 History @ Continua CI.

Be sure to also look at the official Continua 1.5 released announcement.

  • Reworked UI:
    • Now using bootstrap framework for styling
    • Redesigned Project detail view to show more information including graphs.
    • Added stages information to the Project tile and list views
    • Disabled configurations are now displayed as faded
  • Cloning:
    • Can now clone whole projects and clone configurations between projects.
  • Stage Conditions:
    • Auto Promote conditions – stages can now use conditions to control whether to auto-promote to the next stage.
    • Skip conditions – you can now provide conditions for skipping stages or disable a stage completely.
  • New Actions:
    • Fake (F#) build runner.
    • NuGet restore action.
    • Update GitHub Status Action is now deprecated (use event handler instead – see below).
  • Repository Tags: (Git, Mercurial and Subversion repositories only)
    • Continua CI can now detect and list repository tags.
    • Tags are now displayed in changeset tabs on configuration and build views.
    • Repository trigger can now be set to trigger on tag changes (new tags, edits and deletions) changes).
    • You can now run a build on a tagged changeset.
  • Build Event Handlers: allowing you execute various tasks on the server based on build status changes.
    • Octopus Deploy: Create/Deploy/Promote Octopus Deploy releases.
    • Tag Repository Changeset – Apply tags to a repository changeset (Git, Mercurial and Subversion repositories only)
    • Update GitHub Status – replaces the Update GitHub Status action.
  • Various other changes including:
    • Report ordering: you can choose which one is displayed first on the build view.
    • New expression functions: Utils.NewGuid() and Utils.RandomNumber() can be used for generation of temporary paths for example

Note : You will need to update your agents after upgrading the server to this build.<


Filed under: .NET, Continua CI, Continuous Integration, Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Development, Software Development, Spring4D

by Jeroen Pluimers at September 10, 2014 07:08 AM

Firebird News

ADO.NET provider 4.5.1.0 for Firebird is ready

More info here. You can get the bits from NuGet FirebirdSql.Data.FirebirdClient and EntityFramework.Firebird.

by Jiri Cincura at September 10, 2014 05:25 AM

September 09, 2014

Firebird News

Jaybird will switch to Java Native Access instead of JNI

Mark Rotteveel tweeted about his progress towards using JNA instead of JNI: Continuing my adventure with JNA for Firebird native client and embedded support in Jaybird 3.0, so I can remove existing JNI wrapper.

by mariuz at September 09, 2014 03:01 PM

September 08, 2014

The road to Delphi

Firebird News

Firebird 2.5.3 from EPEL 7 stable repository

EPEL 7 left the beta stage so you can install Firebird 2.5.3 packages for Centos/RHEL 7 from stable repository sudo yum install http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-1.noarch.rpm yum –enablerepo=epel install firebird-superclassic and since EPEL 7 use Systemd, you can use Systemd to enable the service and stop or start it read the README provided : http://pkgs.fedoraproject.org/cgit/firebird.git/tree/README.Fedora?h=epel7 you also have […]

by mariuz at September 08, 2014 08:58 AM

Delphi Code Monkey

Embarcadero's forums are down. Communities are the future.

Embarcadero's forums have been down for a while now, they are working on bringing them back up.

Update Aug 25, 3PM EST:  The forums appear to be back now!
Update Aug 26, 9PM EST: They're back down again.  ... and at 9:30 PM EST: Back again!

Update Aug 27: It seems that the new Community link is going to become the main forums sooner rather than later, as there is something that just keeps breaking, crashing, or corrupting itself, in the old forum site. I'm sure Embarcadero would love your feedback on any way that they could bring forward sub-forums that you really want to still see as separate sub-forums, it seems that the new site has much fewer sub-forums than the old ones.  I'm sure that this will need a bit of time to settle, and get re-organized.  The Development forum list seems pretty "generic" at this point. There is an installation help forum, and a few general forum areas, but I get the idea that one should really use "Tags" carefully in the new forums. Remember to tag your post as Delphi or C++ and then you can view all Delphi or C++ posts easily, using the Tags feature, across all the groups.


Update Sept 3: They are down again, and still down several days later.  (TV Medical drama voice on.) Ok folks, I am going to call this one.  Time of death: Sept 3, 2014, 5:01 AM. (TV Medical drama voice off.)   The forum software has some kind of bug that keeps corrupting the database that the forum data is stored in.   If it ever comes back online, I'm guessing it will be done in a read-only fashion so that the 10,000 web-URLs that link to conversations there can be kept around for reference.   The new Community site is really rough but I am sure that they'll get it fixed up and usable soon.

Update Sept 8:  They are back UP again, but for how long? Nick Hodges discusses the idea that we need to move on.

 

by Warren Postma (noreply@blogger.com) at September 08, 2014 08:33 AM

The Wiert Corner - irregular stream of stuff

jpluimers

I long time ago, I asked about Why doesn’t WINWORD.EXE quit after Closing the document from Delphi?.

It turns out that question is a lot harder in .NET than it is in Delphi. I already had a gut feeling of this when at clients I saw many more .NET applications leaking WINWORD.EXE stray processes than Delphi applications, even though both kinds were calling Quit on the Word application object.

Delphi has a deterministic way of coping with interfaces (hence you can do a One-liner RAII in Delphi, or make a memento): Interface references are released at the end of their scope.

.NET has non-deterministic finalization of the Common Language Runtime (CLR) and has Runtime Callable Wrappers (RCWs) around your COM references which are sometimes created “on the fly”.

The combination of non-deterministic finalization and RCWs can be very confusing, so lets start with the parts first.

Non-deterministic finalization

One of the biggest traps in C# (see Ten Traps in C# for C++ Programmers) is non-deterministic finalization is. It is explained very well by Non-Deterministic Destructors – What Are They?

There are quite a few non-deterministic parts in the whole finalization proces.

  1. It starts the point at which an object becomes eligible for finalization: you don’t know exactly when that will happen. The deterministic part is that an object has no root references. But the point in time that is determined is unknown. That point in time depends on when the garbage collector runs. You don’t know when the garbage collector starts to run: the garbage collector runs you. As the garbage collector runs in a separate thread, there are the basic multi-threading uncertainties. In addition, the garbage collecting thread however does not run continuously: so another uncertainty is when it will start to run. It will start when memory pressure gets high enough. But there are other factors like LatencyMode that the CLR takes into consideration. See the “further reading” for a few links on this.
  2. By now you should understand that garbage collection and final disposal are separated. When an object is eligible for finalization, the second non-deterministic part kicks in: during the garbage collection phase, all objects that are not reachable any more will have their finalizer called at some point in time. This is done in yet another thread: the finalization thread which finalizes objects from the finalization queue (which you should think of as a list, not a queue). In addition, you do not know in which order they are called. Since the execution order of fianlizers is unknown, any references between unreachable objects (private fields from one object to another object) are a no-go area in your finalizer code.

Mike Rosenblum wrote a great answer about finalizers on .net – Release Excel Object In My Destructor?

It is not wise to call the Garbage Collector yourself, as it manages 3 generations and does a balancing act to keep objects that are frequently used into the lowest two generations.

This is contrary to the popular belief of many posts. Just don’t follow that popular belief (:

One way to make this deterministic is to actively use the Dispose pattern. The COM support in .NET uses those. When implementing them yourself, you usually don’t have to write finalizers, especially since the introduction of SafeHandle in .NET 2.0 (they and the COM support in .NET implement the finalizers for you).

RCWs: the COM references are embedded in Runtime Callable Wrappers

The .NET COM support wraps RCWs around COM references: they make the transition from the managed .NET world into the unmanaged COM world. RCWs are automatically created when you access the COM objects described in an imported type library. When the garbage collector determines the RCW is not referenced any more, the RCW finalizer is called, decrementing the COM reference count. When all COM references to an object have been released, the COM object is removed from memory.

The trick is in this little piece of the Runtime Callable Wrapper documentation:

Each RCW maintains a cache of interface pointers on the COM object it wraps and releases its reference on the COM object when the RCW is no longer needed. The runtime performs garbage collection on the RCW.

This is where RCW and non-deterministic finalization come together.

As long as the CLR has not garbage collected the RCW (remember this event is non-deterministic!), it keeps a COM reference. As long as the COM references to a COM object exist, that COM object is being kept alive. Which means that WINWORD.EXE can be kept alive even though you think you are not using it any more. Arthur has written a nice SO answer about when COM references get incremented: Every time the COM object is passed from COM environment to .NET.

Combining RCW and memory management: make it as deterministic as possible

To make the management more deterministic you have to do these things:

In addition, read the Avoid the PIA events by Amit Mittal.

Finally something I need to research further: NetOffice – MS Office in .NET was mentioned by BTownTKD. It is supposed to be like PIA, but better, and more deterministic. And it is maintained.

References for further reading

COM inteoperability:

Garbage collection and memory management:

–jeroen

via:  Why doesn’t WINWORD.EXE quit after Closing the document from Delphi? – Stack Overflow.


Filed under: .NET, Delphi, Development, Software Development

by Jeroen Pluimers at September 08, 2014 05:00 AM

September 07, 2014

The Wiert Corner - irregular stream of stuff

September 06, 2014

twm’s blog

Autosave Wizard for Delphi 6 to XE7

Since the stability of some Delphi IDE versions leave something to desire, people have asked for an autosave feature for a long time.

Delphi 2010 eventually got “Save on compile” while older versions only had “Save on run”.

Ray Lischner originally wrote an AutoSave wizard for Delphi 5 (if I remember correctly) and ported it to Delphi 6 and 7 later. I have taken his code, extended it and ported it to all later Delphi versions.

The wizard does the following:
Whenever triggered it checks for files that have not been saved yet. It saves these files as ~filename.ext. When the file is saved, it deletes these ~files again. In the event of the IDE crashing, it will on restart ask the user whether he wants to load the regular file or the last autosave file.
The wizard can be configured to trigger

  • every x minutes
  • whenever the IDE “compiles”

I recommend to activate the latter setting. You will be surprised how often the IDE “compiles” stuff.

There are no precompiled packages. Just get the sources, open the package that corresponds to your Delphi version, compile and install it.

You can find the current sources on the dzAutoSave page on sourceforge.

by dummzeuch at September 06, 2014 05:03 PM

Andy's Blog and Tools

IDE Fix Pack 5.71 for XE7 – bug fix release

During the search for all function parameter name mangling changes in XE7, I disabled many IDE Fix Pack patches and forgot to enable them before I released version 5.7 for XE7. So here is version 5.71 that enables all patches again.

By enabling all the patches, I found three patches that weren’t necessary anymore or only partly necessary. Embarcadero fixed the rlink32.dll maximum resources limitation (QC 111917) and the debugger local variable watch memory leak (QC 115248). Furthermore they partly fixed the “operator In” class completion bug (QC 102047). Only the “complete implementation” part that is explained in the QC entry is fixed, the “complete interface” part still uses “&In” instead of “In”, IDE Fix Pack 5.7 fixes the missing part for you.

Download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 5.7 XE IDEFixPackXEReg57.7z 111.7 KB 458 times 2014-08-25
IDE Fix Pack 5.7 XE5+UP2 IDEFixPackXE5Reg57.7z 131.52 KB 515 times 2014-08-25
IDE Fix Pack 5.7 XE6 IDEFixPackXE6Reg57.7z 271.54 KB 1015 times 2014-08-25
IDE Fix Pack 5.71 XE7 IDEFixPackXE7Reg571.7z 265.42 KB 1092 times 2014-09-06
IDE Fix Pack 5.71 2009+UP3 IDEFixPack2009Reg571.7z 134.53 KB 0 times 2014-09-16
IDE Fix Pack 5.71 2010 IDEFixPack2010Reg571.7z 123.72 KB 1 times 2014-09-16

Download:

Name IDE Version File Size Downloads Added
fastdcc 5.7 2009+UP3 fastdcc2009v57.7z 75.74 KB 121 times 2014-08-25
fastdcc 5.7 XE fastdccXEv57.7z 81.61 KB 132 times 2014-08-25
fastdcc 5.7 XE5 fastdccXE5v57.7z 111.38 KB 158 times 2014-08-25
fastdcc 5.7 XE6 fastdccXE6v57.7z 139.83 KB 296 times 2014-08-25
fastdcc 5.7 2010 fastdcc2010v57.7z 79.62 KB 182 times 2014-08-26
fastdcc 5.71 XE7 fastdccXE7v571.7z 133.61 KB 900 times 2014-09-06

by Andreas Hausladen at September 06, 2014 10:35 AM

twm’s blog

Autosave on compile in Delphi?

Did you know that the Delphi IDE automatically saves all files when you compile a project? I didn’t.

In order to activate it, go to the Tools/Options dialog and there on the “Environment Options” page. There, you will find an “Autosave options” group. Set the checkmark for “Editor files” (and close the dialog with “OK” of course).

What, you knew that option was there but you thought that it only saved when running the program in the debugger not when just compiling? Welcome to the club! So did I.

I did some tests today and found that this behaviour changed with Delphi 2010. Up to Delphi 2009 autosave took place when running (in the debugger), since Delph 2010 it is done when compiling.

So, now I know that my upcoming new autosave wizard release only needs to support Delphi up to 2009…

by dummzeuch at September 06, 2014 08:54 AM

September 05, 2014

Firebird News

.NET Provider pulse on github

Github model for contributions really works : here is the project pulse for last month. There are quite a few pull requests closed and merged for .NET Provider

by mariuz at September 05, 2014 12:33 PM

Te Waka o Pascal

The BDE is Finally, Properly (Almost) Dead

As of the XE7 release of Delphi/RAD Studio, the long deprecated BDE is finally dead. And almost properly this time. From the “What’s New in XE7” page: BDE, our oldest database solution, has reached the final stage of deprecation, and has been removed from RAD Studio. This includes the Bde.DBBdeWeb and Bde.DBTables units. Instead, use […]

by Jolyon Direnko-Smith at September 05, 2014 09:27 AM

Firebird News

Firebird FreeBSD port is updated to 2.5.3 version

FreeBSD port is updated to Firebird 2.5.3 . Please consult the release notes ps: Unicode patch is not needed anymore (Fix included in 2.5.3 release)

by mariuz at September 05, 2014 07:49 AM

September 04, 2014

twm’s blog

Experimental GExperts Version 1.37-2014-09-04 released

The latest version is the first version that supports Delphi XE7.

There is nothing really new about the formatter code. But the new release can be installed even if you don’t have the official GExperts installer (yet). This is an extract from the readme file:

** Installing without an official installer **
   
With two Delphi Releases per year and Erik Berry being busy otherwise,
new GExperts releases have been lagging behind. So in case there is no
official GExperts installer yet, these are the steps to install the
experimental version by hand:

1. Create a suitable GExperts directory. It doesn't have to be a
   subdirectory of %ProgramFiles% but may be anywhere, even on a network
   share if you are sure this share will always be available.
2. Extract all files from the ZIP somewhere
3. Copy all files from the extracted directory to the GExperts directory.
   (Do *NOT* copy the subdirectories!)
4. Copy the appropriate GExperts DLL from one of the subdirectories
   EditorExpert or RegularExpert to the GExperts directory.
5. Copy the files from the subdirectory FromRegularRelease to the
   GExperts directory.
6. Copy the appropriate cmd from the install subdirectory. To the GExperts
   directory.
7. Make sure that the Delphi IDE is not running
8. Run the cmd file. It will register the GExperts dll with the Delphi IDE.
9. Start Delphi and check that the new GExperts DLL has been loaded by
   opening the GExperts About dialog.

In theory it is possible to install GExperts for all Delphi versions into
the same GExperts directory. But be warned: This has not been tested
thoroughly.

Head over to the Experimental GExperts page to download the new version.

by dummzeuch at September 04, 2014 08:53 PM

Andy's Blog and Tools

IDE Fix Pack, DDevExtensions and DFMCheck for XE7

I’ve re-released the IDE Fix Pack 5.7, DDevExtensions 2.82 and DFMCheck 1.5 versions with support for XE7. The only change is that X7 is now supported (and one compiler patch was removed from IDE Fix Pack because it is fixed in XE7). Other than that it was just adjusting the build script, adjusting to the new ABI (name mangling of interface function parameters has changed) and building the projects.

IDE Fix Pack download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 5.7 XE IDEFixPackXEReg57.7z 111.7 KB 458 times 2014-08-25
IDE Fix Pack 5.7 XE5+UP2 IDEFixPackXE5Reg57.7z 131.52 KB 515 times 2014-08-25
IDE Fix Pack 5.7 XE6 IDEFixPackXE6Reg57.7z 271.54 KB 1015 times 2014-08-25
IDE Fix Pack 5.71 XE7 IDEFixPackXE7Reg571.7z 265.42 KB 1092 times 2014-09-06
IDE Fix Pack 5.71 2009+UP3 IDEFixPack2009Reg571.7z 134.53 KB 0 times 2014-09-16
IDE Fix Pack 5.71 2010 IDEFixPack2010Reg571.7z 123.72 KB 1 times 2014-09-16

fastdcc download:

Name IDE Version File Size Downloads Added
fastdcc 5.7 2009+UP3 fastdcc2009v57.7z 75.74 KB 121 times 2014-08-25
fastdcc 5.7 XE fastdccXEv57.7z 81.61 KB 132 times 2014-08-25
fastdcc 5.7 XE5 fastdccXE5v57.7z 111.38 KB 158 times 2014-08-25
fastdcc 5.7 XE6 fastdccXE6v57.7z 139.83 KB 296 times 2014-08-25
fastdcc 5.7 2010 fastdcc2010v57.7z 79.62 KB 182 times 2014-08-26
fastdcc 5.71 XE7 fastdccXE7v571.7z 133.61 KB 900 times 2014-09-06

DDevExtensions download:

Name IDE Version File Size Downloads Added
DDevExtensions 1.61 5-2007 DDevExtensions161Setup.zip 734.07 KB 15424 times 2009-01-10
DDevExtensions 2.8 Features PDF DDevExtensionsFeatures.pdf 602.92 KB 4625 times 2014-08-25
DDevExtensions 2.4 7, 2007 DDevExtensions24Setup7_2007.zip 535.41 KB 6947 times 2011-07-25
DDevExtensions 2.82 2009-XE6 DDevExtensions282.7z 908.68 KB 920 times 2014-08-25
DDevExtensions 2.82 with XE7 2009-XE7 DDevExtensions282.7z 950.79 KB 485 times 2014-09-04

DFMCheck download:

Name IDE Version File Size Downloads Added
DFMCheck 1.5 5-XE7 DfmCheckSetup15.7z 683.73 KB 234 times 2014-09-04

by Andreas Hausladen at September 04, 2014 08:23 PM

September 03, 2014

Firebird News

Report of the 11th Firebird Developers Day

The report of the 11th edition of the Firebird Developers Day Conference  is now available either in English and Portuguese, and contains several pictures from the conference day.

by Cantu at September 03, 2014 11:57 PM

Database developer tool Database Workbench 5 now available

Upscene Productions is proud to announce the availability of the next major version of the popular multi-DBMS development tool: ” Database Workbench 5 “ There have been numerous improvements to existing tools and the new, more consistent user interface is better than ever and works fine under Wine on Linux. Database Workbench now comes in […]

by Martijn Tonies at September 03, 2014 10:12 AM

TPersistent

Delphi Dead Code Elimination

Delphi’s compiler tool chain may automatically eliminate some dead code, but with an older or “mature” product there are bound to be lots of units that are no longer used but are still present as part of a project or referenced indirectly by some other unit. Having a good gatekeeper on your team can help, as can these tools, but it can never replace a team that is concerned about keeping it lean.

For instance, I stumbled across code that was written to compensate for a database column not being a consistent length. That change management issue was addressed a long time ago, yet the code remained, running a very expensive query on Oracle for absolutely no benefit. Some people may not think that is a big deal, but multiply that by 1000 other such things in the main thread of an application and it can start to make Delphi programs look pretty sluggish.

If your team keeps units around because it ‘might’ need them, or older methods because not every call has been replaced, you might want to rethink that.  It’s easy to spend time maintaining code that may no longer be relevant.  Time means money, and there is no ROI if you are a code hoarder.  A VCS makes it easy to restore code in the event you ever need it, or disposed of it by accident.

by Larry Hengen at September 03, 2014 08:57 AM

Delphi Code Monkey

Delphi XE7 has been released



As Embarcadero mentioned a few hours back, Delphi XE7,  and C++ Builder XE7,  known collectively as "RAD Studio XE7", have been released.

After I get it installed, I'll be posting some thoughts on what's new and notable.

The Parallel Computing Library, and some memory-use improvements when working on large projects, are the two things that I'm looking forward to getting to use with my employer's big Delphi codebase, which is currently running very well in XE6.

There are also some mobile "FireUI" designer improvements, and a new "EMS" middleware service offering, and other interesting stuff.  The PAServer Manager looks like it will make iOS and Mac OS X FMX development a little nicer.

For a quick look, check the docwiki "What's New in XE7" page.

Update:   I installed XE7.  I have been unable to find the AQTime installer for Delphi XE7 so far.  Maybe it's on the full ISO image, but it didn't get installed in the web-installer.  Or maybe it will take a while before that comes out.  Or maybe AQTime has been removed.  The folks at SmartBear seem to have a hard time fixing the bugs in the AQTime IDE package, it always crashed on me before, but each time a new Delphi IDE comes out and they updated it for XE5, XE6, I hoped against hope that they'd fix their product.


by Warren Postma (noreply@blogger.com) at September 03, 2014 07:53 AM

September 02, 2014

Andy's Blog and Tools

System.ByteStrings support for XE7

The unit System.ByteStrings reintroduces the following String types for the mobile compilers:

  • ShortString
  • AnsiString
  • AnsiChar
  • PAnsiChar
  • PPAnsiChar
  • UTF8String
  • PUTF8String
  • RawByteString
  • PRawByteString

Usage:
Add the System.ByteStrings.dcu’s path to the compiler’s search path and add the unit to your uses clauses.

There is no *.PAS file because the DCU is patched with a hex editor to get access to the hidden types.

Name IDE Version File Size Downloads Added
System.ByteStrings XE5 RTM/UP1 only XE5ByteStrings.7z 2.45 KB 696 times 2013-10-23
System.ByteStrings XE5 UP2 only XE5Up2ByteStrings.7z 2.85 KB 645 times 2013-12-20
System.ByteStrings XE6 XE6ByteStrings.7z 2.89 KB 642 times 2014-04-16
System.ByteStrings XE7 XE7ByteStrings.7z 2.89 KB 175 times 2014-09-02

by Andreas Hausladen at September 02, 2014 04:52 PM

DelphiTools.info

Operator precedence changes

Here is a summary of recent DWScript changes, the major one is a change in operator precedence to something similar to Delphi and FreePascal. Other changes are related to sets and bug fixes. The precedence of operators has been changed to be inline with Delphi & FreePascal, this means that AND, AS, SHL, SHR and SAR…

by Eric Grange at September 02, 2014 03:29 PM

Tim Anderson's ITWriting

Embarcadero RAD Studio XE7 (Delphi, C++Builder): is seven the magic number?

Embarcadero has released version 7 of its XE programming suite. The main products included are Delphi and C++ Builder, RAD development tools that share the same underlying libraries and visual designers but give developers a choice of language. Delphi uses an object-oriented evolution of Pascal.

Delphi is best known as a Windows Programming Tool

...continue reading Embarcadero RAD Studio XE7 (Delphi, C++Builder): is seven the magic number?

by tim at September 02, 2014 09:39 AM

Firebird News

pyfirebirdsql Version 0.9.4 is released

pyfirebirdsql Version 0.9.4 is released with following changes: - Fixed Cursor.rowcount. - Cursor.callproc() return out parameters. - Cursor.execute() return cursor instance itself. You can consult the Commit History

by mariuz at September 02, 2014 09:23 AM

The Wiert Corner - irregular stream of stuff

Castle Game Engine news

September 01, 2014

Žarko Gajić

Generating QR Codes Using Delphi – DelphiZXingQRCode – Open Source Unit by Debenu

TDelphiZXingQRCode
A QR code (Quick Response Code) is a specific 2D barcode that gained popularity during the last years when mobile phones with cameras allowed mobile phone users to quickly scan the image and get more info on a product, business, event, offer, URL address, …

If you need to include the generation of QR barcode images in your Delphi application, you might want to take a look at Debenu’s open source “DelphiZXingQRCode” – a Delphi port of the QR Code functionality in ZXing, an open source barcode image processing library.

QR codes are used to encode URL, text or other data. Most smartphones like iPhones and Android phones have apps that let you to read QR codes. When your mobile reads (scans) a QR Code, the QR code will then send you to a website or online voucher or an online business card.

There are several Delphi-style QR code implementations but only a few are free and/or include source code.

DelphiZXingQRCode is a single-unit implementation you simply add to your (new or) existing project, set a few properties and paint the image. DelphiZXingQRCode (for the moment) supports auto, numeric, alphanumeric, ISO-8859-1, UTF-8 without Bom and UTF-8 with Bom encoding.

Just a few lines of code, TDelphiZXingQRCode related, and your QR is ready:

var
  QRCode: TDelphiZXingQRCode;
  Row, Column: Integer;
begin
  QRCode := TDelphiZXingQRCode.Create;
  try
    QRCode.Data := edtText.Text;
    QRCode.Encoding := TQRCodeEncoding(cmbEncoding.ItemIndex);
    QRCode.QuietZone := StrToIntDef(edtQuietZone.Text, 4);
    QRCodeBitmap.SetSize(QRCode.Rows, QRCode.Columns);
    for Row := 0 to QRCode.Rows - 1 do
    begin
      for Column := 0 to QRCode.Columns - 1 do
      begin
        if (QRCode.IsBlack[Row, Column]) then
        begin
          QRCodeBitmap.Canvas.Pixels[Column, Row] := clBlack;
        end else
        begin
          QRCodeBitmap.Canvas.Pixels[Column, Row] := clWhite;
        end;
      end;
    end;
  finally
    QRCode.Free;
  end;
end;

If you only need the image generated out of your application, you might want to try this fantastic free online QR Code Generator from the ZXing Project.

What Delphi-style QR generator are you using? Have something Delphi-style to read QR Codes?

by zarkogajic at September 01, 2014 05:14 PM

FireMonkey / Mobile (Android, iOS) QR Code Generation Using Delphi XE 5 / DelphiZXingQRCode

fmx-TDelphiZXingQRCode
The DelphiZXingQRCode unit, ported from ZXing by Debenu, allows to easily add QR Code generation to your Delphi VCL applications.

While the DelphiZXingQRCode was designed to support VCL applications (and be used in newer as well as in older Delphi versions), it can also easily be “upgraded” for Fire Monkey applications – be it desktop or mobile (Android, iOS).

DelphiZXingQRCode -> FireMonkey Support

To FireMonkey-enable the DelphiZXingQRCode unit a few changes to the source code were required.

The unit uses “contnrs” (System.Contnrs.pas) unit which implements TObjectList (used by the unit) and other container like classes. Under FireMonkey for mobile, more specifically under ARC, the classes contained in System.Contnrs.pas cannot be used because they are not ARC compliant.

Equivalent classes are to be found in System.Generics.Collections.pas (ARC compliant) where generics versions of TObjectList is defined.

Therefore, the first change is to replace “uses contnrs, …” with “uses System.Generics.Collections, …”

This also requires to make changes like: from “Blocks: TObjectList;” to “Blocks: TObjectList<TBlockPair>;” – that is to use strongly typed generics list classes.

Further, there are lots of “ansistring” and “widestring” types used for parameters in various functions inside the unit. If you want to go mobile, those are not supported and you should use “string”. More info here: Migrating Delphi Code to Mobile from Desktop.

Therefore, the second change to the unit would be to replace “widestring” with “string” and “ansistring” with “array of byte” (or something else as explained in the article).

Single Pixel Drawing (and Other Canvas Drawing) FireMonkey Style

In the VCL, the TCanvas class allows accessing single pixels through the “Canvas.Pixels()” property. In FireMonkey this is not supported and you have to use the SetPixel property of a TBitmapData instance.

Once the qr code is generated, to convert it to a bitmap image, in FireMonkey:

var
  QRCode: TDelphiZXingQRCode;
  Row, Column: Integer;
  pixelColor : TAlphaColor;
  vBitMapData : TBitmapData;
  rSrc, rDest : TRectF;
  s : widestring;
begin
  QRCode := TDelphiZXingQRCode.Create;
  try
    QRCode.Data := edtText.Text;
    QRCode.Encoding := TQRCodeEncoding(cmbEncoding.ItemIndex);
    QRCode.QuietZone := StrToIntDef(edtQuietZone.Text, 4);
    QRCodeBitmap.SetSize(QRCode.Rows, QRCode.Columns);
    for Row := 0 to QRCode.Rows - 1 do
    begin
      for Column := 0 to QRCode.Columns - 1 do
      begin
        if (QRCode.IsBlack[Row, Column]) then
          pixelColor := TAlphaColors.Black
        else
          pixelColor := TAlphaColors.White;

        if QRCodeBitmap.Map(TMapAccess.maWrite, vBitMapData)  then
        try
          vBitMapData.SetPixel(Column, Row, pixelColor);
        finally
          QRCodeBitmap.Unmap(vBitMapData);
        end;
      end;
    end;
  finally
    QRCode.Free;
  end;

  //refresh image control imgQRCode is a TImage
  {code below}
end;

Note: compare this with the VCL approach of TDelphiZXingQRCode usage.

VCL’s Canvas.StretchDraw to FMX’s Canvas.DrawBitmap

There’s no StrecthDraw in FMX’s Canvas class. There’s DrawBitmap. StretchDraw by default does no antialiasing. FMX does. So I had to play a little until I was able to make it work correctly.

I’ve decided to use TImage and not TPaintBox as I was simply not able to make TPictureBox in FireMonkey draw what I wanted :(

Using TImage, the code to get/display the generated QR Code is as follows:

  //refresh image. imgQRCode is a TImage

  imgQRCode.Bitmap.SetSize(QRCodeBitmap.Width, QRCodeBitmap.Height);

  rSrc := TRectF.Create(0, 0, QRCodeBitmap.Width, QRCodeBitmap.Height);
  rDest := TRectF.Create(0, 0, imgQRCode.Bitmap.Width, imgQRCode.Bitmap.Height);

  if imgQRCode.Bitmap.Canvas.BeginScene then
  try
    imgQRCode.Bitmap.Canvas.Clear(TAlphaColors.White);

    imgQRCode.Bitmap.Canvas.DrawBitmap(QRCodeBitmap, rSrc, rDest, 1);
  finally
    imgQRCode.Bitmap.Canvas.EndScene;
  end;

Aliasing – Do Not Need It!

By default, in FMX, when using DrawBitmap to resize it, antialiasing is used by default. There are two properties you need to set to ensure a bigger copy of your (small) qr code is drawn pixel-copy-perfect.

begin
  imgQRCode.DisableInterpolation := true;
  imgQRCode.WrapMode := TImageWrapMode.iwStretch;
end;

In a FireMonkey Desktop application, this works as expected.

On FireMonkey Mobile it does not :( – the resized image is still blurred (antialiasing used).

That’s it. QR Codes generation in FireMonkey – both desktop and mobile!

Download the FMX version of DelphiZXIngQRCode.pas: FMX-DelphiZXIngQRCode

Comments are welcome (even more if you know how to resize a bitmap in FireMonkey on mobile without antialiasing)!

by zarkogajic at September 01, 2014 05:13 PM

Te Waka o Pascal

Sign Here Please… (Using This Specific Pen)

My original Android version of TXT-2-PARK has been in the Google Play Store for a little over a week now. But it was only on Saturday that I decided to install the release version onto my phone from the store itself, and found a problem. The application would download just fine, but at the point […]

by Jolyon Direnko-Smith at September 01, 2014 09:15 AM

twm’s blog

Showing a dropdown menu when clicking a button

A rather common question on StackOverflow, the Delphi newsgroups and elsewhere is how to display a drop down menu when the user presses a button.

ButtonWithDropdown

There are many proposed solutions and even something built into newer versions of Delphi (Which doesn’t work for me for some reason.)

Here is mine (which is based on this answer on StackOverflow):
First, I create a helper class based on TComponent. It links the button (which can be TButton or TBitBtn or anything else derived from TCustomButton) to the popup menu and hooks its OnClick event. To access the OnClick event, which is protected in TCustomButton, we need to cast it to TCustomButtonHack. The OnClick event then displays the popup menu. For convenience I set the helper class’s parent to the button, so it automatically gets freed when the button does get freed.

type
  TButtonPopupMenuLink = class(TComponent)
  private
    FBtn: TCustomButton;
    FMenu: TPopupMenu;
    FLastClose: DWORD;
  public
    constructor Create(_btn: TCustomButton; _pm: TPopupMenu);
    procedure doOnButtonClick(_Sender: TObject);
  end;

{ TButtonPopupMenuLink }

type
  TCustomButtonHack = class(TCustomButton)
  end;

constructor TButtonPopupMenuLink.Create(_btn: TCustomButton; _pm: TPopupMenu);
begin
  inherited Create(_btn);
  FBtn := _btn;
  FMenu := _pm;
  FMenu.PopupComponent := FBtn;
  FBtn.OnClick := Self.doOnButtonClick;
end;

procedure TButtonPopupMenuLink.doOnButtonClick(_Sender: TObject);
var
  Pt: TPoint;
begin
  if GetTickCount - FLastClose > 100 then begin
    Pt := FBtn.ClientToScreen(Point(0, FBtn.ClientHeight));
    FMenu.Popup(Pt.X, Pt.Y);
    { Note: PopupMenu.Popup does not return until the menu is closed }
    FLastClose := GetTickCount;
  end;
end;

And just for some more convenience I add a procedure that just creates that helper class, so I don’t have to expose the class through the unit’s interface but only that procedure:

procedure TButton_AddDropdownMenu(_btn: TCustomButton; _pm: TPopupMenu);
begin
  TButtonPopupMenuLink.Create(_btn, _pm);
end;

To use it I call that procedure from the form’s constructor:

constructor TMyForm.Create(_Owner: TComponent);
begin
  inherited Create;
  // other stuff
  TButton_AddDropdownMenu(b_MenuButton, pm_MenuButton);
end;

I have put that code into u_dzVclUtils, which is part of my dzlib library.

by dummzeuch at September 01, 2014 08:07 AM

Te Waka o Pascal

While I Was Waiting For Apple…

So Saturday morning I finished the iOS version of my application and published it to the App Store. Of all of the app stores, the approval process with Apple evidently takes the longest. So, whilst waiting for my app to be released, I developed (and published) the Windows Phone version of my app. There really […]

by Jolyon Direnko-Smith at September 01, 2014 08:00 AM

August 30, 2014

Te Waka o Pascal

Oxygene Constructor Magic on Cocoa

Earlier this week I mentioned that I had published my TXT-2-PARK app for Android in the Google Play Store. Today I published the iOS version to the Apple App Store (still awaiting approval at this stage). As with the Android version, I implemented the iOS version using Oxygene, and things proved a little less straightforward. […]

by Jolyon Direnko-Smith at August 30, 2014 08:21 AM

August 29, 2014

The Wiert Corner - irregular stream of stuff

Žarko Gajić

TToolBar’s TToolButton AutoSize Width Issues (Empty Captions)

tlbr5If you are using the TToolBar control with TToolButtons in your Delphi application (are you not?, in at least one :\) with “Enable runtime themes” enabled for your project, you might have noticed you cannot easily alter the width of an individual button. What’s worst, if you are using button images and for some of the buttons you want the Caption to be displayed and for some not – the empty-caption tool bar buttons will have a too long width.

Is there a way to fix the width of the no-caption buttons so they “match” the width of the bitmap/glyph/image? For a long time I thought there’s no way to fix this, as whatever property I would change, the display, at run time, simply did not look right. Until I’ve found (as you will see: a very) simple solution.

Typically I would have a TImageList filled with button images assigned to the Images property of the Toolbar – so that each button has a nice image – similar to what we have in the Delphi IDE. I would have a few tool buttons added to the toolbar. Leaving all the default properties as they are by default, the display will look like this:

tlbr1

Now, I would really love to have only some buttons display their caption. For this to happen I need to set the ShowCaptions property and also the List property:

  ToolBar2.ShowCaptions := true;
  ToolBar2.List := true;

And the display is as:

tlbr2

Note: the List property determines if the caption of the button appears below the button image or right to it.

Ok, so I now simply set an empty caption to all buttons except the “Insert” one (this is the one I want to have the Caption displayed – others not) – and case closed.

tlbr3

Uops, this is not what I want to be displayed – I would want all buttons to have much shorter width, enough to have only their image displayed (if their Caption is empty)!

Setting the AutoSize property of each TToolButton to True would probably do the trick, and the result is:

tlbr4

Hm, not good. All buttons have an empty Caption (except the “Insert” one) but there’s some extra space right to the image – buttons are too wide for no real purpose (my visual feeling).

At this moment you (and I) would start thinking “why not simply set the Width property of each button”? Ha! This would not work as Delphi’s internal implementation of this standard Windows control determines button width automagically – even if you try to change the Width property of a button – it will stick to its value. The “why” for this would require explaining how the Windows tool bar control works with its messaging and the rest – never mind at this point – you simply cannot set “by hand” the width of each button separately.

So, how to fix this? How to have smaller width for those buttons that are “captionless”? Here’s how:

  1. Set Autosize to False for all no-caption buttons.
  2. Set Autosize to True for the buttons you want the Caption to be displayed
  3. Call the following inside Form’s OnCreate event
//tbtnInsert3.AutoSize := true;
SendMessage(ToolBar3.Handle, TB_SETBUTTONWIDTH, 0, MAKELPARAM(0, 24));
  1. Make sure you do not alter the Visible property of any buttons before the above call – as it will fail for those buttons that are not visible.
  2. Also, ensure you have “CommCtrl” in the uses list for TB_SETBUTTONWIDTH message.

That’s it, now my toolbar displays correctly:

tlbr5

No extra space to the right of the button image for those buttons with no Caption.

Case closed.

p.s.
The weird “24”, for button width, in a call to TB_SETBUTTONWIDTH was a try-fail approach. In my real word application I’m setting this value to the value of the Width of another toolbar button (where all buttons do not have a caption). The actual required value depends on the Windows version, Windows theme, if themes are enabled and so on – so it’s best determined at run time by “looking” at other toolbar buttons.

by zarkogajic at August 29, 2014 01:38 PM

Firebird News

Node-Firebird 0.1.3 is released with small fixes and documentation updates

The pure JavaScript Node.js Firebird driver is updated with a few code cleanups and documentations updates  Added Detaching event loop example Charset warning : Charset for database connection is always UTF-8 Added License info to the package.json Cleanup unused constants (Dead platforms : VMS …)   You can install or update from npmjs and you can consult the Commit History

by mariuz at August 29, 2014 08:22 AM

The Wiert Corner - irregular stream of stuff

jpluimers

Thanks Asbjørn Heid for sharing this:

I made this!  -

So this week I’ve been mostly trying to add some GMail integration to our app. Google now requires OAuth2 authentication when using IMAP, unless you turn off some scary-sounding security setting on your account.

While Indy‘s IMAP component supports SASL authentication, there was no XOAuth2 SASL component out of the box. Thanks to the new REST stuff in Delphi, the OAuth2 basics where there so just had to tie them together.

In case others might find it fruitful, I’ve shared my results here: https://github.com/lordcrc/IndySASLOAuth2

notes:

–jeroen

via: So this week I’ve been mostly trying to add some GMail integration to our app.….


Filed under: Delphi, Delphi XE5, Delphi XE6, Delphi XE7, Development, Software Development

by Jeroen Pluimers at August 29, 2014 06:32 AM

August 28, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Quiz questions:

  1. Does the below unit test succeed or fail?
  2. Why?
procedure TestHResult.Test_EOleException;
var
  OleException: EOleException;
  IResult: LongInt; // == HResult
  UResult: Cardinal; // == DWord
begin
  IResult := $800A11FD;
  UResult := $800A11FD;
  try
    OleException := EOleException.Create('message', $800A11FD, 'source', 'helpfile', -1);
    raise OleException;
  except
    on E: EOleException do
    begin
      if E.ErrorCode = $800A11FD then
        Exit;
      Self.CheckEquals(E.ErrorCode, $800A11FD, 'E.ErrorCode should equal $800A11FD');
    end; // E: EOleException
  end;
end;

I partially gave away the answers in the title of the title of the post.

But first some background information:

The above code is inspired by code I see in a lot of applications at clients: tons of compiler warnings (and even more hints).

That is not the way you should program your applications (be it Delphi or any other): always make them Warning free. And try to make them Hint free too.

This particular test came of an application that tried to do handling of EOleException using the ErrorCode field which is of type HResult which – like for instance the .NET ExternalException.ErrorCode – is a 32-bit signed Integer (the 32-bit unsigned data type is Cardinal).

HResult is the Delphi equivalent of the Windows (and in the past OS/2) HRESULT. Most documentation will give you error codes in hexadecimal, is it is much easier to formulate the bit fields in HRESULT using hexadecimal values than decimal ones.

Now for the Warnings and why they are caused.

The assignment of the hexadecimal literal value to IResult will give the first warning: the literal is larger than the High(Integer) value (which is the same MaxInt). It won’t fit in a 4-byte Integer, but the compiler – despite the warning – will make it fit. If you ask the debugger for the hexadecimal value of IResult, it will happily return $800A11FD.

The signed decimal equivalent that gets assigned to UResult is 2148143613: no warning as it will fit.

  // [DCC Warning] TestHResultUnit.pas(35): W1012 Constant expression violates subrange bounds
  IResult := $800A11FD; // Does not fit, but will cast 4-byte Cardinal into a 4-byte Integer with value -2146823683 ($800A11FD)
  UResult := $800A11FD; // Fits, will have value 2148143613 ($800A11FD)

The second warning is the same one as the first. Which means that OleException.ErrorCode will get the same value as IResult:

    // [DCC Warning] TestHResultUnit.pas(41): W1012 Constant expression violates subrange bounds
    OleException := EOleException.Create('message', $800A11FD, 'source', 'helpfile', -1);

The difference btween IResult and UResult also explain the next two warnings: they basically come down to comparing  -2146823683 (the stored value in E.ErrorCode) and 2148143613 (the signed equivalent of $800A11FD).

Since $800A11FD is bigger than MaxInt, the comparison will always be false.

      // [DCC Warning] TestHResultUnit.pas(48): W1021 Comparison always evaluates to False
      // [DCC Warning] TestHResultUnit.pas(48): W1023 Comparing signed and unsigned types - widened both operands
      if E.ErrorCode = $800A11FD then // Integer can never match a Cardinal larger than High(Integer);
        Exit;

You can workaround these warnings in two ways – either cast to HResult or to Cardinal:

      if E.ErrorCode = HResult($800A11FD) then
        Exit; // Succeed
      if Cardinal(E.ErrorCode) = $800A11FD then
        Exit; // Succeed

Finally no warning, but still a failure: both E.ErrorCode and $800A11FD is now passed as Int64 because there are no better overloads for TTestCase.CheckEquals in the TestFramework unit of DUnit.

Which again means that -2146823683 is compared to 2148143613. Which fails the test case.

      // No warning, but both are passed as Int64, so comparison fails
      Self.CheckEquals(E.ErrorCode, $800A11FD, 'E.ErrorCode should equal $800A11FD');

To answer the questions:

  1. Does the below unit test succeed or fail?
    Fail.
  2. Why?
    Because of compiler warnings, and the TTestCase.CheckEquals overload chosen by the compiler.

–jeroen

unit TestHResultUnit;

interface

uses
  TestFramework, System.SysUtils;

type
  TestHResult = class(TTestCase)
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure Test_EOleException;
  end;

implementation

uses
  System.Win.ComObj, Winapi.Windows;

// 1 Fool the optimizer
procedure Touch(var X);
begin

end;

procedure TestHResult.Test_EOleException;
var
  OleException: EOleException;
  IResult: LongInt; // == HResult
  UResult: Cardinal; // == DWord
begin
  // [DCC Warning] TestHResultUnit.pas(35): W1012 Constant expression violates subrange bounds
  IResult := $800A11FD; // Does not fit, but will cast 4-byte Cardinal into a 4-byte Integer with value -2146823683 ($800A11FD)
  UResult := $800A11FD; // Fits, will have value 2148143613 ($800A11FD)
  Touch(IResult);
  Touch(UResult);
  try
    // [DCC Warning] TestHResultUnit.pas(41): W1012 Constant expression violates subrange bounds
    OleException := EOleException.Create('message', $800A11FD, 'source', 'helpfile', -1);
    raise OleException;
  except
    on E: EOleException do
    begin
      // [DCC Warning] TestHResultUnit.pas(48): W1021 Comparison always evaluates to False
      // [DCC Warning] TestHResultUnit.pas(48): W1023 Comparing signed and unsigned types - widened both operands
      if E.ErrorCode = $800A11FD then // Integer can never match a Cardinal larger than High(Integer);
        Exit; // Succeed
      // No warning, but both are passed as Int64, so comparison fails
      Self.CheckEquals(E.ErrorCode, $800A11FD, 'E.ErrorCode should equal $800A11FD');
    end; // E: EOleException
  end;
end;

procedure TestHResult.SetUp;
begin
end;

procedure TestHResult.TearDown;
begin
end;

initialization

RegisterTest(TestHResult.Suite);

end.

Filed under: Delphi, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, Software Development

by Jeroen Pluimers at August 28, 2014 05:00 AM

August 27, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Interesting, as I didn’t think this was possible. Thanks Oliver Funcke!

Notification when a `TFrame` becomes visible.

TMyCommonFrame = class(TFrame)
  private
    FOnShow: TNotifyEvent;
    procedure CMShowingChanged(var M: TMessage); message CM_SHOWINGCHANGED;
  public
    property OnShow : TNotifyEvent read FOnShow write FOnShow;
  end;
...
procedure TMyCommonFrame.CMShowingChanged(var M: TMessage);
begin
  inherited;
  if Showing and Assigned(FOnShow) then
    FOnShow(Self);
end;

–jeroen

via Is there any way for a VCL TFrame to be notified when it is actually shown to….


Filed under: Delphi, Delphi 2007, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Development, Software Development

by Jeroen Pluimers at August 27, 2014 04:01 PM

jpluimers

Though I’ve done this automation in Delphi, this applies to automation from any development platform. In this particular project, the documents used Bookmarks. Those have changed over time, so has the Word support for it.

From Word 2000 until Word you could disable the showing of Bookmarks by setting the ShowBookmarks property to False like this:

<br />ActiveDocument.ActiveWindow.View.ShowBookmarks := False;<br />

Well, when doing this, Office 2013 can throw an error like this:

EOleException: The ShowBookmarks method or property is not available because this command is not available for reading
ErrorCode: 0x800A11FD
Source: Microsoft Word
HelpFile: wdmain11.chm

The full error message does not give any useful search results. But a partial search finds a Word 2013 issue towards the top of the results:

sometimes Words opens the document in Reading layout. Reading layout does not allow all operations in Word 2013.

If a document is protected, and you try to change something you should not, you get an error message like this:

This method or property is not available because the document is a protected document.

Usually, Cindy Meister is very accurate. However this time here code

...ActiveWindow.View = wdPrintView

should have been like

...ActiveWindow.View.Type = wdPrintView

Of course you also have to save/restore this property while you are enabling the ShowBookmarks property.

So you get Delphi code like this:

var
  CurrentView: View;
  OldViewType_: WdViewType;
begin
  CurrentView := ActiveDocument.ActiveWindow.View;
  try
    CurrentView.ShowBookmarks := False;
    // Word 2013 might raise a EOleException: The ShowBookmarks method or property is not available because this command is not available for reading
  except
    on E: EOleException do
    begin
      if E.ErrorCode = $800A11FD8 then
          begin
            OldViewType_ := CurrentView.type_;
            try
              CurrentView.type_ := wdPrintView;
              CurrentView.ShowBookmarks := False;
            finally
              CurrentView.type_ := OldViewType_;
            end;
          end
          else
            raise;
        end; // E: EOleException
      end;
    end;

This probably gives similar errors in other mistakes when you want to alter the document in Office 2013: basically the wdReadingView mode is readonly, the wdPrintView is read-write.

Another solution is for all your users to disable the Reading View mode in Word 2013.

Below is a table with the relevant objects, properties and method documentation links for the various Office versions (documentation for Office XP and Office 2000 is not available any more):

Office 2013 release. Microsoft Office 2010. Microsoft Office 2007. Microsoft Office 2003. Microsoft Office XP. Microsoft Office 2000. Remarks
Document Object (Word). Document Object (Word). Document Object [Word 2007 Developer Reference]. Document Object.
Document.ActiveWindow Property (Word). Document.ActiveWindow Property (Word). ActiveWindow Property [Word 2007 Developer Reference]. ActiveWindow Property.
Window Object (Word). Window Object (Word). Window Object [Word 2007 Developer Reference]. Window Object.
Window.View Property (Word). Window.View Property (Word). View Property [Word 2007 Developer Reference]. View Property.
View Object (Word). View Object (Word). View Object [Word 2007 Developer Reference]. View Object.
Window.View Property (Word). Window.View Property (Word). View Property [Word 2007 Developer Reference]. View Property.
View.ShowBookmarks Property (Word). View.ShowBookmarks Property (Word). ShowBookmarks Property [Word 2007 Developer Reference]. ShowBookmarks Property. True if square brackets are displayed at the beginning and end of each bookmark. Read/write Boolean.
View.Type Property (Word). View.View Property (Word). Type Property [Word 2007 Developer Reference]. View Property. WdViewType enumeration:
Name Value Description
wdMasterView 5 A master view.
wdNormalView 1 A normal view.
wdOutlineView 2 An outline view.
wdPrintPreview 4 A print preview view.
wdPrintView 3 A print view.
wdReadingView 7 A reading view.
wdWebView 6 A Web view.

wdConflictView=8 (documentation about it is very sparse)

–jeroen


Filed under: Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, Office, Office 2000, Office 2003, Office 2007, Office 2010, Office 2013, Office Automation, Power User, Software Development, Word

by Jeroen Pluimers at August 27, 2014 05:00 AM

August 26, 2014

Andy's Blog and Tools

DDevExtensions 2.82 and IDE Fix Pack 5.7 released

DDevExtensions 2.82 is a rather small update. It fixes the “Switch to the module’s project” incompatibility with XE6 and adds the option to disable alpha-sort for the IDE’s class completion (Ctrl+Shift+C).

DisableAlphaSortClassCompletion

If alpha-sort class completion is disabled and you press Ctrl+Shift+C all methods from the class declaration are appended to the already existing implementation methods in the order that they appear in the class declaration with the exception for constructors and destructors. They are positioned before every other method (class ctor, class dtor, ctor, dtor, methods). This function does not resort your existing implementation methods, nor does it prevent the IDE from sorting the methods that are added to the class declaration because they only have an implementation.

IDE Fix Pack 5.7 increases the max. number of resources per binary from 3626 to 65534 (for the command line compiler you need fastdcc). The installer IDEFixPackReg*.exe now supports the “/EXTRACT” command line switch that extracts the installation files to the sub-folder “Files” instead of installing them. This version also adds some smaller optimization, especially for Delphi 2009 and extends the LineEditorEnd.ttr workaround by not creating the file in the first place.


DDevExtensions download:

Name IDE Version File Size Downloads Added
DDevExtensions 1.61 5-2007 DDevExtensions161Setup.zip 734.07 KB 15424 times 2009-01-10
DDevExtensions 2.8 Features PDF DDevExtensionsFeatures.pdf 602.92 KB 4625 times 2014-08-25
DDevExtensions 2.4 7, 2007 DDevExtensions24Setup7_2007.zip 535.41 KB 6947 times 2011-07-25
DDevExtensions 2.82 2009-XE6 DDevExtensions282.7z 908.68 KB 920 times 2014-08-25
DDevExtensions 2.82 with XE7 2009-XE7 DDevExtensions282.7z 950.79 KB 485 times 2014-09-04

DDevExtensions Version 2.82 (2014-08-25)

  • Added: Disable Alpha-Sort Class Completion (Default off)
  • Fixed: XE6 broke “Switch to module project” dialog

IDE Fix Pack download:

Name IDE Version File Size Downloads Added
IDE Fix Pack 5.7 XE IDEFixPackXEReg57.7z 111.7 KB 458 times 2014-08-25
IDE Fix Pack 5.7 XE5+UP2 IDEFixPackXE5Reg57.7z 131.52 KB 515 times 2014-08-25
IDE Fix Pack 5.7 XE6 IDEFixPackXE6Reg57.7z 271.54 KB 1015 times 2014-08-25
IDE Fix Pack 5.71 XE7 IDEFixPackXE7Reg571.7z 265.42 KB 1092 times 2014-09-06
IDE Fix Pack 5.71 2009+UP3 IDEFixPack2009Reg571.7z 134.53 KB 0 times 2014-09-16
IDE Fix Pack 5.71 2010 IDEFixPack2010Reg571.7z 123.72 KB 1 times 2014-09-16

fastdcc download:

Name IDE Version File Size Downloads Added
fastdcc 5.7 2009+UP3 fastdcc2009v57.7z 75.74 KB 121 times 2014-08-25
fastdcc 5.7 XE fastdccXEv57.7z 81.61 KB 132 times 2014-08-25
fastdcc 5.7 XE5 fastdccXE5v57.7z 111.38 KB 158 times 2014-08-25
fastdcc 5.7 XE6 fastdccXE6v57.7z 139.83 KB 296 times 2014-08-25
fastdcc 5.7 2010 fastdcc2010v57.7z 79.62 KB 182 times 2014-08-26
fastdcc 5.71 XE7 fastdccXE7v571.7z 133.61 KB 900 times 2014-09-06

IDE Fix Pack changelog

  • Added: Fix for “class operator In” class completion
  • Added: IDEFixPackReg*.exe supports command line parameter /EXTRACT that extracts the files instead of installing them
  • Added: Disable creation of EditorLineEnd.ttr (2009-2010)
  • Added: Fix for QC 111917: RLINK32: Too many resources to handle. Instead of 3626 it can now handle 65534 resource items (also in fastdcc for command line compiler)
  • Added: TObject.FieldAddress optimization for DFM loading
  • Added: String function replacements without STRINGCHECKS (2009-2010)
  • Changed: Disabled “.NET Windows\Globalization search I/O optimization” patch for Windows 8 (2009)
  • Added: TComponent.Remove optimization (2009)

by Andreas Hausladen at August 26, 2014 10:24 AM

The Wiert Corner - irregular stream of stuff

jpluimers

Though I’ve done this automation in Delphi, this applies to automation from any development platform. In this particular project, I had to update Word documents. That is fine, unless your documents are protected. You can find out if a document is protected by probing the ProtectionType property of a Document object.

If a document is protected, and you try to change something you should not, you get an error message like this:

This method or property is not available because the document is a protected document.

If you have control of the documents or templates involved, then you can take the recommended steps from Document Handling with protected Microsoft Office Word Template:

Microsoft Office Word offers the possibility to enable document protection only to certain sections of a document. So you can place Bookmarks used by Dynamics AX in a section that is kept unprotected and the Form Controls in a section where Document Protection is enabled.

If you don’t, then you have to check for protection, unprotect, do the modifications, then re-protect the document.

If you are working on the ActiveDocument of a word application, then the property to check is ActiveDocument.ProtectionType.

Note there is no way to ask Word for the current protection password.

VBA code would look like this (adapted from Macro to Unlock a Locked Word 2007 Document and Use ActiveDocument.Unprotect only if document is protected):

Dim OriginalProtection As WdProtectionType
OriginalProtection = ActiveDocument.ProtectionType
If OriginalProtection <> wdNoProtection Then
  ActiveDocument.Unprotect
  ' If password protected, pass a password in the above call, as otherwise it can fail.
  MsgBox "I'm unlocked. Do your deed."
Else
  MsgBox "I wasn't locked to start with"
End If
' Perform the business logic on the word document
If OriginalProtection <> wdNoProtection Then
  ActiveDocument.Protect Type:=OriginalProtection, NoReset:=True
  ' If password protected, pass a password in the above call, as otherwise the document can be unprotected without password.
  MsgBox "I'm back in chains."
End If

Delphi code like this:

Below is a table with the relevant objects, properties and method documentation links for the various Office versions (documentation for Office XP and Office 2000 is not available any more):

Office 2013 release. Microsoft Office 2010. Microsoft Office 2007. Microsoft Office 2003. Microsoft Office XP. Microsoft Office 2000. Remarks
Document Object (Word). Document Object (Word). Document Object [Word 2007 Developer Reference]. Document Object.
Document.ProtectionType Property (Word). Document.ProtectionType Property (Word). ProtectionType Property [Word 2007 Developer Reference]. ProtectionType Property. value: readonly WdProtectionType
  •  1=wdAllowOnlyComments,
  •  2=wdAllowOnlyFormFields,
  •  3=wdAllowOnlyReading,
  •  0=wdAllowOnlyRevisions,
  • -1=wdNoProtection.
Document.Protect Method (Word). Document.Protect Property (Word). Protect Property [Word 2007 Developer Reference]. Protect Method. parameters:
  • type: WdProtectionType
  • NoReset Optional VARIANT False to reset form fields to their default values; True to retain the current form field values if the document is protected. If Type is not wdAllowOnlyFormFields, NoReset is ignored.
  • Password Optional VARIANT If supplied, the password to be able to edit the document, or to change or remove protection.
  • UseIRM Optional VARIANT Specifies whether to use Information Rights Management (IRM) when protecting the document from changes.
  • EnforceStyleLock Optional VARIANT Specifies whether formatting restrictions are enforced for a protected document.
Document.Unprotect Method (Word). Document.Unprotect Method (Word). Unprotect Method [Word 2007 Developer Reference]. UnProtect Method. parameters:
  • Password Optional Variant The password string used to protect the document. Passwords are case-sensitive. If the document is protected with a password and the correct password isn’t supplied, a dialog box prompts the user for the password.
Section Object (Word). Section Object (Word). Section Object [Word 2007 Developer Reference]. Section Object. Section.ProtectedForForms Property (Word). Section.ProtectedForForms Property (Word). ProtectedForForms Property [Word 2007 Developer Reference]. ProtectedForForms Property. value: Read/write Boolean.
  • True if the specified section is protected for forms.

–jeroen


Filed under: Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, Office, Office 2000, Office 2003, Office 2007, Office 2010, Office 2013, Office Automation, Power User, Software Development, Word

by Jeroen Pluimers at August 26, 2014 05:00 AM

August 25, 2014

DelphiTools.info

String Hashing Shootout

Following a recent post by A. Bouchez about an optimized CRC32 hash, I took it as an opportunity to re-run a small String Hashing Shootout on the worst hash function collision torture test I know: ZIP codes in UTF-16 (Delphi’s default String format). Contenders CRC32 using the SynCommons CPU implementation (based on Aleksandr Sharahov asm version) KR32 hash…

by Eric Grange at August 25, 2014 10:01 AM

Te Waka o Pascal

Small Post, for a (Very) Small App

On Saturday I was out and about with my family and found myself inspired to write an app. By Sunday evening, it was done and in the Google Play store. We were in an area of Auckland called Parnell and needed to park the car on street, where a fairly standard “pay and display” system […]

by Jolyon Direnko-Smith at August 25, 2014 07:16 AM

August 24, 2014

twm’s blog

Translating Windows messages to strings

I could not find anything like this so I wrote it myself:

This class translates most Windows message ids into their symbolic name.

type
  TWmMessageToString = class
    function MsgToString(const _WmMsg: Cardinal): string; overload;
    function MsgToString(const _Msg: TMessage): string; overload;
  end;

The names are taken from

  • Delphi 2010’s messages.pas
  • Delphi 2010’s controls.pas
  • Wine

It seems pretty complete, but if a message cannot be found, the MsgToString methods return its hexadecimal and decimal representation.

The code is part of my dzlib its the u_dzWmMessageToString unit.

by dummzeuch at August 24, 2014 08:42 PM

Preventing a dialog from closing while autocomplete is active

In an older blog post I wrote about AutoComplete for TEdits using SHAutoComplete.

I just actually tried to use that function in one of my applications and found that there is a quite annoying problem with it: If you have set the OK button’s Default property to true (so it gets “clicked” when you press return), selecting an entry from the autocomplete list with the return key also closes the form, which is usually not what the user wants.

I turns out that I am not the first to stumble upon that problem.

The suggestion posted there by mghie is a bit ugly because it hooks the Application.OnMessage event which might conflict with other code that uses it.

I had another problem anyway (see below) so I extended a class that hooks a TEdit’s WindowProc method instead. Here is the code:

procedure TAutoCompleteActivator.NewWindowProc(var _Msg: TMessage);
begin
  if (_Msg.Msg = CM_WANTSPECIALKEY) then begin
    if (_Msg.wParam = VK_RETURN) or (_Msg.wParam = VK_ESCAPE) then begin
      if IsAutoSuggestDropdownVisible then begin
        _Msg.Result := 1;
        Exit; //==>
      end;
    end;
  end;
  inherited NewWindowProc(_Msg);
end;

The IsAutoSuggestDropdownVisible function is directly taken from mghie’s answer:

function EnumThreadWindowsProc(AWnd: HWnd; AParam: LParam): BOOL; stdcall;
var
  WndClassName: string;
  FoundAndVisiblePtr: PInteger;
begin
  SetLength(WndClassName, 1024);
  GetClassName(AWnd, PChar(WndClassName), Length(WndClassName));
  WndClassName := PChar(WndClassName);
  if WndClassName = 'Auto-Suggest Dropdown' then begin // do not translate
    FoundAndVisiblePtr := PInteger(AParam);
    FoundAndVisiblePtr^ := Ord(IsWindowVisible(AWnd));
    Result := False;
  end else
    Result := True;
end;

function IsAutoSuggestDropdownVisible: Boolean;
var
  FoundAndVisible: Integer;
begin
  FoundAndVisible := 0;
  EnumThreadWindows(GetCurrentThreadId, @EnumThreadWindowsProc,
    LParam(@FoundAndVisible));
  Result := FoundAndVisible > 0;
end;

This works fine in my program compiled with Delphi 2010 and running on Windows 8.1 (your mileage may vary).

Now to the other problem mentioned above:
In the old blog post I published a TEdit_SetAutocomplete function that activates autocomplete for a TEdit control. This function works fine as as long as you don’t try to call it in the form’s constructor. If you do, it does nothing. The reason is that the TEdit’s handle gets destroyed and recreated after the form’s constructor was called, which results in autocomplete being turned off again. One option would have been to put the function call into the form’s OnShow handler, but I am no fan of distributing code that in my opinion belongs into the constructor to these event handlers, so I wanted a different solution.

It turned out that I already had one in my dzlib.u_dzVclUtils unit: TWinControl_ActivateDropFiles returns a TObject that hooks the TWinControl’s WindowProc and handles the WM_NCCREATE and WM_NCDESTROY messages. I refactored that class a bit to create a generic TWindowProcHook ancestor and derived TAutoCompleteActivator from it. Its WmNcCreate method now looks like this:

procedure TAutoCompleteActivator.WmNcCreate;
begin
  inherited;
  SetAutoComplete;
end;

procedure TAutoCompleteActivator.SetAutoComplete;
begin
  TEdit_SetAutocomplete(FCtrl as TCustomEdit, FSource, FType);
end;

So every time the window handle gets created anew, it activates autocomplete for it again.

The full code can be found in my dzlib library on SourceForge. It’s in the u_dzVclUtils unit.

by dummzeuch at August 24, 2014 08:20 PM

The road to Delphi

VCL Styles Utils – New Feature : Non Client Area Controls

I’m very pleased to introduce a very cool new feature to the VCL Styles Utils project. This is the support for controls in the Non Client Area of the forms through the TNCControls component.

Check the next form with the Auric Vcl Style applied.

1

Now the same form but with a set of NC Buttons in the title bar.

2

To use in your forms you only need to add the Vcl.Styles.NC and Vcl.Styles.FormStyleHooks units to your project and create a TNCControls component in each form where do you want use the NC Controls.

Check the next sample code

procedure TForm1.FormCreate(Sender: TObject);
begin
 NCControls:=TNCControls.Create(Self);
 //Add a NC Button
 NCControls.List.Add(TNCButton.Create(NCControls));
 //Set the style of the button
 NCControls.List[0].Style := nsSplitButton;
 //Set the style of the image
 NCControls.List[0].ImageStyle := isGrayHot;
 //Set the image list
 NCControls.List[0].Images := ImageList1;
 NCControls.List[0].ImageIndex := 3;
 //Set the bounds
 NCControls.List[0].BoundsRect := Rect(30,5,100,25);
 NCControls.List[0].Caption := 'Menu';
 //Assign the menu and events.
 NCControls.List[0].DropDownMenu:= PopupMenu1;
 NCControls.List[0].OnClick := ButtonNCClick;
end;

And this is the result

4

Screenshots

3

Exist 4 kind of buttons which you can choose.
5

Also you can use a custom Vcl Style to draw the controls.
6

Try the sample application from the project repository.
Also you can download a compiled demo from here.

Remember report any bug o made your suggestions via the issue page of the project.


by Rodrigo at August 24, 2014 06:59 PM

Castle Game Engine news

Choosing skin when loading Spine animation :)

Choosing skin when loading Spine animation :)

August 24, 2014 02:11 AM

August 23, 2014

Castle Game Engine news

Weekend news: 1. Spine ( http://esotericsoftware.com/ ) support in Castle Game Engine is now official...

Weekend news: 1. Spine ( http://esotericsoftware.com/ ) support in Castle Game Engine is now official, 2. introducing named animations support, 3. scene manager fine-tuned for 2D games :)

Read more for details:

1. Spine ( http://esotericsoftware.com/ ) is a great program to design 2D skeletal animations for games. It has several advantages over alternatives (like Flash): offers many features for animators (not just skeletons, also skins, also animations by mesh deformation...), and is friendly for engines (the format of Spine is designed for interoperability, it is small and nice, and it is documented --- at least the JSON version). This makes reading a Spine animation in our engine a natural thing.

You can use view3dscene to open Spine animations already! Grab view3dscene from snapshots http://michalis.ii.uni.wroc.pl/castle-engine-snapshots/ , and use "File->Open" to open any Spine xxx.json file. Be sure to check "View->Sort Transparent Shapes (2D...)" for best results.

Our implementation of Spine converts the Spine animation under the hood into an X3D node graph. This means that under the hood, Spine animation is actually 3D (although you can use SceneManager with RenderStyle := ds2D to render it under/above other 2D controls, as you wish), and the animation uses existing X3D features for animations (interpolators and such) and you can use all existing X3D rendering/processing tools to extend the Spine animation (for example, you can use sensors, texture settings, screen effects, you can cast shadows!, you can use shaders etc.).

To support correct slots order when rendering (this is not determined by bone hierarchy, Spine has separate slot order) we actually move quads by epsilon to back/front in 3D. To make it work with blending (depends on texture, all Spine examples uses texture atlas with smooth alpha channel on edges), we add new BlendingSort value: bs2D.

To use Spine animations for your games:

A.1) Easiest: Load them using T2DScene, and add to T2DSceneManager.Items.
A.2) Alternative: Load them using TCastleScene, add to TCastleSceneManager.Items --- just like 3D entities. Remember to possibly adjust TCastleScene.Attributes.BlendingSort to bs2D (to guarantee good drawing order for textures with smooth alpha channel), and possibly adjust TCastleSceneManager.RenderStyle to rs2D (then scene manager is rendered above/below other 2D controls, depending on their relative order on Window.Controls list).
B) To start a concrete Spine animation, use TCastleScene.PlayAnimation. Use TCastleScene.Animations to list named animations. This simply uses X3D named TimeSensor nodes underneath.

Underneath, we also support multiple Spine skins, although there is no easy API to change them at runtime yet (you can only choose skin at loading).

2. Named animations: many 3D and 2D models define multiple animations that can be started by an external code (for example, by a programmer using Castle Game Engine). Our engine detects now such animations by looking at X3D TimeSensor node names. Name starting with "Animation_xxx" indicates an animation, with name "xxx". Some converters (right now, our Spine to X3D conversion) follow this convention, so our engine immediately "knows" the Spine animation names and can play them.

The benefits of such "named" animations:
- view3dscene displays a user-friendly menu in "Animation->Named Animations->" to run animation by name. You can force the animation looping state when running it, if needed. (For example, useful for "walk" and such animations designed in Spine, as you cannot mark them "looping" in Spine.)
- TCastleScene offers a simple API for programmers to browse and run animation by name, see TCastleScene.Animations and TCastleScene.PlayAnimation. PlayAnimation automatically stops the previous animation too.

3. Scene manager for 2D: We have a new T2DSceneManager, best suited for 2D worlds (for example, using Spine animations). The rendering, with TUIControl.RenderStyle, was reworked to be more flexible for 2D stuff: RenderStyle 2D vs 3D now only determines the drawing order. This means that 2D and 3D rendering using our scene manager is almost identical, and yet they are both comfortable for programmer.

August 23, 2014 10:55 PM

Firebird News

Ruby Firebird Extension Library 0.7.4 released

Ruby Firebird Extension Library 0.7.4 release fixes a scaling bug in fb for 32-bit architectures and now builds cleanly and passes tests on Ruby 1.8.6 thru 2.1.0 News via Brent Rowland

by mariuz at August 23, 2014 03:18 PM

The road to Delphi

A new way to select and apply a VCL Style in Runtime

Typically we use a combobox or listbox to allow to the final user select and appy a VCL Style, Today I will show you a new way using the system menu of the form.

First you need to use the GetSystemMenu WinApi function  to get a  handle to the system menu of the form. Then using the AppendMenu or the InsertMenuItem methods you can customize the system menu, from here you must store the identifier of the new menu item added and finally process the WM_SYSCOMMAND message to launch an action.

Check the next commented code

uses
  System.Rtti,
  System.Classes,
  System.Generics.Collections,
  WinApi.Windows,
  WinApi.Messages,
  Vcl.Themes,
  Vcl.Styles,
  Vcl.Forms;

type
  TMethodInfo=class;

  TProcCallback = reference to procedure(Info : TMethodInfo);
  TMethodInfo=class
   Value1 : TValue;
   Value2 : TValue;
   Method : TProcCallback;
  end;
  TVclStylesSystemMenu=class(TComponent)
  strict private
    FVCLStylesMenu : HMenu;
    FOrgWndProc: TWndMethod;
    FForm : TForm;
    FMethodsDict : TObjectDictionary&lt;NativeUInt, TMethodInfo&gt;;
    procedure CreateMenus;
    procedure DeleteMenus;
    procedure CreateMenuStyles;
    procedure WndProc(var Message: TMessage);
  public
    constructor Create(AOwner: TForm); reintroduce;
    destructor Destroy; override;
  end;

implementation

uses
  Vcl.Controls,
  System.SysUtils;

const
 VCLStylesMenu=WM_USER + 666;

//Add a new Menu Item
function InsertMenuHelper(hMenu: HMENU; uPosition: UINT; uIDNewItem: UINT_PTR; lpNewItem, IconName: LPCWSTR) : BOOL;
var
  LMenuItem : TMenuItemInfo;
begin
  ZeroMemory(@LMenuItem, SizeOf(TMenuItemInfo));
  LMenuItem.cbSize := SizeOf(TMenuItemInfo);
  LMenuItem.fMask  := MIIM_FTYPE or MIIM_ID or MIIM_BITMAP or MIIM_STRING;
  LMenuItem.fType  := MFT_STRING;
  LMenuItem.wID    := uIDNewItem;
  LMenuItem.dwTypeData := lpNewItem;
  Result:=InsertMenuItem(hMenu, uPosition, True, LMenuItem);
end;

//Add a new separator
procedure AddMenuSeparatorHelper(hMenu : HMENU; var MenuIndex : Integer);
var
  LMenuInfo    : TMenuItemInfo;
  Buffer       : array [0..79] of char;
begin
  ZeroMemory(@LMenuInfo, SizeOf(TMenuItemInfo));
  LMenuInfo.cbSize := sizeof(LMenuInfo);
  LMenuInfo.fMask  := MIIM_TYPE;
  LMenuInfo.dwTypeData := Buffer;
  LMenuInfo.cch := SizeOf(Buffer);
  if GetMenuItemInfo(hMenu, MenuIndex-1, True, LMenuInfo) then
  begin
    if (LMenuInfo.fType and MFT_SEPARATOR) = MFT_SEPARATOR then
    else
    begin
      InsertMenu(hMenu, MenuIndex, MF_BYPOSITION or MF_SEPARATOR, 0, nil);
      inc(MenuIndex);
    end;
  end;
end;

{ TVclStylesSystemMenu }

constructor TVclStylesSystemMenu.Create(AOwner: TForm);
begin
  inherited Create(AOwner);
  //Get an instance to the form
  FForm:=AOwner;
  //Init the collection to store the menu ids and callbacks
  FMethodsDict:=TObjectDictionary&lt;NativeUInt, TMethodInfo&gt;.Create([doOwnsValues]);
  //store the original WndProc
  FOrgWndProc := FForm.WindowProc;
  //replace the WndProc of the form 
  FForm.WindowProc := WndProc;
  //Modify the system menu
  CreateMenus;
end;

destructor TVclStylesSystemMenu.Destroy;
begin
  DeleteMenus;
  FForm.WindowProc := FOrgWndProc;
  FMethodsDict.Free;
  inherited;
end;

procedure TVclStylesSystemMenu.CreateMenus;
begin
  CreateMenuStyles;
end;

procedure TVclStylesSystemMenu.DeleteMenus;
begin
   if IsMenu(FVCLStylesMenu) then
   while GetMenuItemCount(FVCLStylesMenu)&gt;0 do
     DeleteMenu(FVCLStylesMenu, 0, MF_BYPOSITION);

   FMethodsDict.Clear;
end;

procedure TVclStylesSystemMenu.CreateMenuStyles;
var
 LSysMenu : HMenu;
 LMenuItem: TMenuItemInfo;
 s : string;
 uIDNewItem, LSubMenuIndex : Integer;
 LMethodInfo : TMethodInfo;
begin
  LSysMenu := GetSystemMenu(FForm.Handle, False);

  LSubMenuIndex:=GetMenuItemCount(LSysMenu);
  AddMenuSeparatorHelper(LSysMenu,  LSubMenuIndex);

  FVCLStylesMenu   := CreatePopupMenu();
  s:='VCL Styles';

  uIDNewItem := VCLStylesMenu;
  ZeroMemory(@LMenuItem, SizeOf(TMenuItemInfo));
  LMenuItem.cbSize := SizeOf(TMenuItemInfo);
  LMenuItem.fMask  := MIIM_SUBMENU or MIIM_FTYPE or  MIIM_ID or MIIM_BITMAP or MIIM_STRING;
  LMenuItem.fType  := MFT_STRING;
  LMenuItem.wID    := VCLStylesMenu;
  LMenuItem.hSubMenu := FVCLStylesMenu;
  LMenuItem.dwTypeData := PWideChar(s);
  LMenuItem.cch := Length(s);
  //Add the new menu item to the system menu
  InsertMenuItem(LSysMenu, GetMenuItemCount(LSysMenu), True, LMenuItem);
  inc(uIDNewItem);
  LSubMenuIndex:=0;

  //Iterate over the registered styles and create a new menu entry for each style 
  for s in TStyleManager.StyleNames do
  begin
    InsertMenuHelper(FVCLStylesMenu, LSubMenuIndex, uIDNewItem,  PChar(s), nil);
    if SameText(TStyleManager.ActiveStyle.Name, s) then
      CheckMenuItem(FVCLStylesMenu, LSubMenuIndex, MF_BYPOSITION or MF_CHECKED);
    inc(LSubMenuIndex);
    inc(uIDNewItem);
    LMethodInfo:=TMethodInfo.Create;
    LMethodInfo.Value1:=s;
    //set the method to execute when the item is clicked
    LMethodInfo.Method:=procedure(Info : TMethodInfo)
                        begin
                          TStyleManager.SetStyle(Info.Value1.AsString);
                        end;
    //register the menu id and the callback function.
    FMethodsDict.Add(uIDNewItem-1, LMethodInfo);
  end;
end;

procedure TVclStylesSystemMenu.WndProc(var Message: TMessage);
var
  LVerb : NativeUInt;
begin
  case Message.Msg of
    //Detect when the window handle is recreated
    CM_RECREATEWND: begin
                      DeleteMenus;
                      FOrgWndProc(Message);
                      CreateMenus;
                    end;
    //Track the system menu calls
    WM_SYSCOMMAND : begin
                     if FMethodsDict.ContainsKey(TWMSysCommand(Message).CmdType) then
                     begin
                      LVerb:=TWMSysCommand(Message).CmdType;
                      FMethodsDict.Items[LVerb].Method(FMethodsDict.Items[LVerb]);
                     end
                     else
                      FOrgWndProc(Message);
                    end
  else
    FOrgWndProc(Message);
  end;
end;

end.

And this the result

Windows

Amakritz

Cobalt

To use this class, only you need create an new instance passing a reference to the form.

procedure TForm1.FormCreate(Sender: TObject);
begin
  TVclStylesSystemMenu.Create(Self);
end;

You can check the full source code here.


by Rodrigo at August 23, 2014 12:55 AM

Te Waka o Pascal

Nullable Types. Not!

I recently mentioned that RemObjects have placed their OS X native IDE – a.k.a. Fire – into public beta. I haven’t been using it myself (yet) but have been following developments in the RemObjects Talk forums with interest, and a new feature in the Elements 8.0 compiler (also part of the Fire beta) caught my […]

by Jolyon Direnko-Smith at August 23, 2014 12:04 AM

August 22, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

While updating a project to a more recent version of Delphi, I also updated the JEDI.INC reference.

Note that since writing Delphi – finding the VERxxx define for a particular Delphi version: use JEDI.INC, the Delphi JEDI project moved from SoureForge to GitHub.

The fun thing: JEDI.INC got updated a few months ago to support Delphi XE7 provisionally.

Given the Delphi release cycle of twice a year, the Delphi Carpathia aka XE7 rumours this summer, I presume Delphi XE7 is near because of:

By then the list of Delphi Versionen | Delphi-Treff will likely also be updaed.

I’m anxious to see if the (Dutch + English) BIG Delphi Conference organized by Barnsten and Blaise from September 11-12 in the Netherlands will be part of the launch tour.

Anyway: here is the JEDI.INC portion with defines:    

    {$IFDEF VER280} // RAD Studio XE7
      {$DEFINE BDS}
      {$DEFINE BDS15}
      {$DEFINE COMPILER21}
      {$IFDEF BCB}
        {$DEFINE BCB21}
      {$ELSE}
        {$DEFINE DELPHI21}
        {$DEFINE DELPHIXE7} // synonym to DELPHI21
        {$DEFINE DELPHICOMPILER21}
      {$ENDIF BCB}
      {$DEFINE RTL280_UP}
      {$UNDEF UNKNOWN_COMPILER_VERSION}
    {$ENDIF VER280}

–jeroen

via: jedi/jedi.inc at master · project-jedi/jedi.


Filed under: Delphi, Delphi 1, Delphi 2, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi 8, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Development, Software Development

by Jeroen Pluimers at August 22, 2014 06:54 AM

Castle Game Engine news

Spine implementation in Castle Game Engine is moving forward very fast :) Try our Spine support yourself...

Spine implementation in Castle Game Engine is moving forward very fast :) Try our Spine support yourself:

1. grab view3dscene from snapshots http://michalis.ii.uni.wroc.pl/castle-engine-snapshots/ (under Windows, remember to grab also the appropriate dlls),
2. just run it and open (File->Open) any Spine (json) model.
3. Using "View->Sort Transparent Shapes (2D, using Z)" is also usually a good idea.

Today we implemented "mesh" attachment type for Spine. This optimizes the rendering (at least the fill rate) and opens the door for animations using mesh bending --- good e.g. to deform character face (to raise eyebrows or such). See http://esotericsoftware.com/spine-in-depth#Features for description how mesh is useful in Spine.

Also attaching screenshots showing how 2D Spine animation can be inserted in 3D models in Castle Game Engine. You just "Inline" a Spine file (xxx.json) inside another (for example, inside VRML/X3D file). Things like screen effects (that enhance colors or make grayscale), or wireframe rendering modes, just work.

August 22, 2014 01:18 AM

August 21, 2014

Firebird News

Firebird Language basic Reference progress for DML chapter

Paul Vinkenoog wrote about the Language Reference Progress (Select section 80% complete in DML chapter) The latest sources are in CVS (manual/src/docs/refdocs/langref/langref25/) The SELECT section is now about 80% ready. The only subsections that still need to be completed are ORDER BY, FOR UPDATE and WITH LOCK. The other DML sections should be complete and […]

by mariuz at August 21, 2014 09:31 AM

August 20, 2014

TPersistent

Making Delphi 64 Bit/Large Address Aware

In the 18+ years Delphi has been out, some rather large applications having been built.  Between the number of units developers are using, the size of the component sets installed in the IDE and the transition to the Galileo IDE with .NET subsystems, Delphi now requires more memory than ever.  What is interesting is that Delphi is still a 32 bit IDE even after release of the 64 bit compiler.  In the old days when Delphi was built using the Object Pascal compiler, one would have thought a 64 bit version would be forthcoming shortly after the compiler was available.

I would venture that most developers run a 64 bit version of Windows natively or in a VM for development so it begs the question as to why a 64 bit version of Delphi is not at least available.  Apple’s testing showed compiling their desktop software for 64 bit provided for about a 20% speed gain.  Pretty impressive for just a re-compile.

In addition to a performance benefit, 64 bit apps of course have access to more memory.  Considering the Out of Memory issues perhaps the additional memory would have at least delayed failure of the IDE.  Even more interesting is the fact that the current bds.exe is not Large Address Aware.

Delphi is not Large Address Aware

Delphi is not Large Address Aware

This could have been enabled by simply adding the {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} to the project.

If you are experiencing Out of Memory issues you could of course use a utility like PE Viewer to make the EXE large address aware, but then you would get directed here the next time you launch Delphi because the copy protection code would prevent it from launching.

Isn’t it about time that EMBT supported 64 bit OS/X apps, and a 64 bit version of Delphi or at least made Delphi Large Address Aware?

by Larry Hengen at August 20, 2014 07:56 PM

Firebird News

Last day to subscribe for the Firebird Developers Day

Today (20-Aug) is the last day to subscribe for the Brazilian Firebird Developers Day Conference.

by Cantu at August 20, 2014 01:30 PM

The Russian Misson Control Center uses Firebird Database

The Russian Misson Control Center uses Firebird. I quote Alex Peshkoff on the Firebird Development list FYI – our colleagues from the Mission Control Center tested format of VMT in the following environment Intel(R) Itanium(R) Processor 9310 HP-UX B.11.31 HP C/aC++ Version A.06.26 and it differs from what we have on windows/linux. I do not […]

by mariuz at August 20, 2014 11:32 AM

The Wiert Corner - irregular stream of stuff

jpluimers

Depending on how you organize locks (for instance via waiting on semaphores or mutexes or spinlocks), deadlocks can become livelocks:

Inability to make forward progress because of conflicting spinlocks is usually referred to as ‘livelock’.

Thanks to Martin James for reminding me of that and Danny Thorpe for describing different ways of locking.

Be sure to read on deadlock prevention as well.

–jeroen

via: c++ – Do deadlocks cause high CPU utilization? – Stack Overflow.


Filed under: .NET, C++, Delphi, Development, Software Development

by Jeroen Pluimers at August 20, 2014 11:00 AM

Te Waka o Pascal

Visual Studio Pro for Just $45 !!

It’s true. Visual Studio Professional can be had for as little as $45, though it can take a little digging to find this option. And there is a catch (or two). It’s available at this price through Visual Studio Online. And the first catch is… it’s a subscription. That $45 is going to have to […]

by Jolyon Direnko-Smith at August 20, 2014 07:14 AM

August 19, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Since this did not make it to DelphiFeeds yet: I’ve seen the function PaletteFromDIBColorTable in Graphics.pas go back as far at least until Delphi 2006, and references on the web as far back as Delphi 4.

So: this bug is old, but as it is a security one, make sure you patch soon.

For Delphi XE6, download 29913 BMP Buffer Overflow hotfix – Delphi, C++Builder, RAD Studio XE6.

For older Delphi versions, read this piece that was adapted from the EDN article Delphi and C++ Builder VCL Library Buffer Overflow:

For users of prior versions of Delphi and C++Builder: these steps should be followed to modify the VCL source code and add it to your application.

For each application:

  1. Add the modified Edit Vcl.Graphics.pas or Graphics.pas or Borland.Vcl.Graphics.pas to your project
  2. For C++Builder: Under Project | Options | Packages | Runtime Packages, set “Link with runtime packages” to false
  3. Rebuild your application

Once for the native VCL and .NET VCL:

  • Note: Variable names and scoping might be slightly different depending on your product version.
  1. Edit Vcl.Graphics.pas or Graphics.pas or Borland.Vcl.Graphics.pas
  2. Locate the function PaletteFromDIBColorTable.
  3. Add the following code just before the line assigning a value to Pal.palNumEntries when the DIBHandle = 0
    if ColorCount > 256 then 
      InvalidGraphic{$IFNDEF CLR}@{$ENDIF}SInvalidBitmap;;

–jeroen

via Delphi and C++ Builder VCL Library Buffer Overflow.


Filed under: Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi 8, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Development, Software Development Tagged: Buffer Overflow, Delphi, Delphi versions, vcl

by Jeroen Pluimers at August 19, 2014 12:25 PM

jpluimers

I mentioned Delphi managed types is in Delphi “Variant Records”, a few notes indicating they are special.

Managed by the RTL, you can use them to your advantage when you have record types that – when on the stack – are only partially initialized by the RTL: only the managed types are initialized.

Given there is still no support to support “Initialize” and “Finalize” operators (vote for it on QualityCentral) the best you can do was mentioned by LU RD (an alias a very smart Swedish guy Leif Unéus):

Add a dummy string member into your record. Since a string is a managed type it will be initialized to an empty string when the record comes in scope.

So when calling your Clear method, test if the dummy string is empty first. Set the string to a value when appropriate to the use logic to mark the record as initialized.

It reminded me of a managed types idea that former Delphi compiler engineer Barry Kelly once posed to me when I was struggling with the initialization state of nullable records: I wanted the default to be NULL, so I added an extra field managed field “IsInitialized” and the “IsNull” property would negate that field.

Use the Delphi compiler to your advantage (:

–jeroen

via: delphi – Guarantee initialisation of stack record – Stack Overflow.


Filed under: Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development

by Jeroen Pluimers at August 19, 2014 05:00 AM

Castle Game Engine news