Planet Object Pascal

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

August 16, 2014

Firebird News

Firebird driver support in #PHP 7

PHPNG (next generation) is the branch for the next php release (PHP 7). There are a few steps for firebird extension (ibase) in order to work with the new engine : You can clone the repository and test php master branch from git. The extension changelog is here. (There are a few patches already submitted […]

by mariuz at August 16, 2014 06:52 PM

August 15, 2014

twm’s blog

Sabotaged by Windows Update

Microsoft released a Windows Update this week that caused quite a problem for Delphi developers still using Delphi 2006 to 2010. When starting a second instance of the IDE they now get the error

Cannot create file C:\Users\Admin\AppData\Local\Temp\EditorLineEnds.ttr

The update in question is a security update for all supported Windows versions and has the number KB2982791. It prevents the file EditorLineEnds.ttr to be created/overwritten because that file is a Truetype font and changing it while it is active is apparently a security risk.

Unfortunately this prevents a meaningful use of these Delphi versions. So what can we do?

There is this question on StackOverflow from which I got the above information. As far as I know there are the following workarounds:

  1. Uninstall the Windows update KB2982791, which might not be such a good idea. After all it’s a security update. Daniel Magin blogged about this.
  2. Use Andreas Hausladen’s IdeFixpack (Delphi 2007 version, beware that version 4.4 does not work under Windows 8, version 4.3 seems to work), (for later Delphi versions). Note that the editor option Show Lineends will use a different character if you use this fix because the IDE won’t load the EditorLineEnds.ttr font any more.
  3. Rename the file every time you want to start Delphi. This is what I will be writing more about.

Of course you don’t want to rename the file by hand every time you start Delphi. So either, you use a batch file to do that for you (see Daniel Magin’s post), or you use the program I wrote for this particular task.

It’s called dzEditorLineEndsFix and is a Tray Icon application that uses FindFirstChangeNotification / FindNextChangeNotification (I always wanted to use these API functions but never had an appropriate use case.) to detect when the file is being created and then moves it to its own unique subdirectory under %temp%.

In theory it will clean up after itself, but that might fail because the file(s) are still in use. So once in a while you should have a look into your %temp% folder and delete all subdirectories called ttr* from it.

Sources are available from the dzEditorLineEndsFix page on SourceForge. There is also a precompiled executable if you don’t want to compile it yourself and trust me not to have added a Trojan to it ;-)

by dummzeuch at August 15, 2014 08:52 PM

Daniel Magin's Logfile

Windows update disable Delphi 2007 .. 2010 – EditorLineEnds.ttr

EasyMethod to solve the problem install IDE FIXPACK

http://andy.jgknet.de/blog/2014/08/editorlineends-ttr-idefixpack-users-are-not-affected/


More Detail:

With a new windows update Delphi 2007 to Delphi 2010 did not start anymore.

you get a error delphi can not create ...Temp\EditorLineEnds.ttr

most important information by microsoft:

http://support.microsoft.com/kb/2982791

 Known issues with this security update

After you install this security update, fonts that are installed to a location other than the default fonts directory (%windir%\fonts\) cannot be modified when they are loaded into any active session. Attempts to change, replace, or delete these fonts will be blocked, and a "File in use" message will be presented.

you can rollback easy in two ways

1: create a batch file with following lines

wusa /uninstall /kb:2982791

wusa /uninstall /kb:2970228

this batch file you run on start up of windows. but with auto update both updates installs every time 

2: disable the KB's from autoupdate

after update goto WindowsUpdates in your system. disable both KB's so on new updates it will be not installed again

these are only workarounds. with newer Delphi Versions like XE6 this error will not be come. Hope Embarcadero will create a patch for "older" Delphi Versions.

--

New Infos found in: http://www.delphipraxis.net/181428-editorlineends-ttr-kann-nicht-erstellt-werden-2.html#post1268750

New Info 1:

it looks like Andreas Hausladen IDE Fix for Delphi is also a solution. A similar Problem with Vista and/or Adobe TypeManger for many years produce same the problem. So install the IDE Fix and all is done. 

IDE Fix Pack is a collection of unofficial bug fixes and performance optimizations for the RAD Studio IDE, Win32/Win64 compiler and Win32 debugger.

http://andy.jgknet.de/blog/ide-tools/ide-fix-pack/

New Info 2:

for persons without the chance to rollback the KB's and not allowed to install IDE Fix Pack here a other solution before starting delphi:

@echo off
tskill bds

cd \
cd %Temp%
del *.ttr

cd \
cd %Temp%
set datum=%date%_%time:~3,2%-%time:~6,2%
ren EditorLineEnds.ttr EditorLineEnds%datum%.ttr
start "" "C:\Program Files (x86)\CodeGear\RAD Studio\5.0\bin\bds.exe" -pCBuilder
pause

by admin at August 15, 2014 05:12 PM

Firebird News

FDD in the news

Firebird Developers Day is in today (15/Aug) editions of the “Jornal de Piracicaba” and “A Tribuna Piracicabana” newspapers.

by Cantu at August 15, 2014 11:21 AM

August 14, 2014

TPersistent

Compiling the JWA and JWSCL

Recently I decided to try to incorporate Windows Job Objects into a project to artificially limit the amount of memory available to an application so I could test it’s behaviour under such circumstances.  Originally I had intended on using M$’s Application Verifier for that purpose, but it lacks any real documentation, and apparently does not provide this exact functionality (the low resource utilization provides random failures).

I thought I would use the JWSCL library since it has a class that wraps Job Objects.  Getting it to compile was unfortunately not so straightforward.

To start with, the JWSCL requires the JWA library, so you need to get that compiled first.  I had no luck compiling the downloaded version so I pulled the current source from the trunk.  Then I followed the READMEFIRST.txt file for the JWA library, but got a compilation error:

 E1025 Unsupported language feature: 'import of DLL symbol by ordinal' "

Googling this I stumbled across a reply to a post from Peter Below explaining “This is caused by a change in defaults for the project options. Call up the options dialog, select the Output - C/C++ page, and make sure the “C/C++ output file generation” entry is set to “Generate DCUs only”. I toggled the option, and voila! The JWA compiled.

Then I tried the JWSCL and got a “[dcc32 Error] JwsclLsa.pas(121): E2010 Incompatible types: ‘Cardinal’ and ‘NativeUInt’. Seems that a THandle is used for some definitions and equates to a NativeInt in XE4, but in other places handles are defined as Cardinals. TJwSecurityLsa uses a mixed definition of a property and changing it to use THandle just opens up the proverbial rabbit hole.

I ended up abandoning my attempt to get JWSCL compiling in part because I downloaded another implementation of the Job Object API from here.  Thanks ZigiZ.  It’s unfortunate that such libraries are so difficult to maintain for multiple compilers. I know from personal experience with hcOPF that it is very difficult to change a library and maintain a good user experience for developers using a multitude of Delphi versions.

Now if only I could find out if it is possible to add a process to a job from that process (I get a security error) :-(

by Larry Hengen at August 14, 2014 04:14 PM

twm’s blog

Using a bar code scanner? Watch out for your keyboard layout!

We are using a bar code scanner to scan the serial numbers of all hard disk drives we buy. This is supposed to make it easier and less error prone to put them into an Excel list for tracking their whereabouts (we use quite a lot of drives for storing video data).

Of course, when I bought 4 TB SATA drives for setting up yet another Linux server, I too put these drives in the list. And since I am a lazy bastard™ I borrowed the scanner to scan them. It worked like a charm so I returned the scanner and started building the raid.

I put labels on the drive bays with our internal number, so in the case of a drive failure I could use the list I mentioned to find out which drive to swap out.

One of the drives apparently was defective to start with, so what did I do? I asked mdadm which drive it was (/dev/sdg) and used

ls -l /dev/disk/by-id

to find its serial number.

lrwxrwxrwx 1 root root  9 Aug 14 08:59 ata-ST4000DM000-1F2168_Z301W61Y -> ../../sdg

Then I opened up the list to find the drive’s internal number. To my surprise, none of the serial numbers in the list seemed to match.

It turned out that on my computer, because I use a UK keyboard layout, the scanner swapped Y and Z. So, in the list the drive had the serial number Y301W61Z while in reality it was Z301W61Y.

Fun with computers, not.

by dummzeuch at August 14, 2014 08:15 AM

August 13, 2014

The Podcast at Delphi.org

What About Blackberry?

One of the most common questions we get when we talk about new features in Delphi, C++Builder and RAD Studio is “What about Blackberry?” which is almost as common as similar questions about Windows Phone or Linux. iOS and especially Android rule the smartphone OS market, but Blackberry still has a place on most charts (unlike Symbian and some others).

IDC: Smartphone OS Market Share 2013, 2012, and 2011 ChartWell, now RAD Studio XE6, Delphi, C++Builder and Appmethod support 96.8% of the shipping platforms thanks to the latest update to Blackberry 10 (10.2.1 or later), it now supports running Native Android APK apps without needing to port. I tested on a Z10 developer device, but it should work on Q10, Q5, Z30, or others. To be clear, Blackberry still runs their own OS, but that OS is able to run Native Android Apps.

Our IDE doesn’t recognize the Blackberry device, again because it is not running Android. But once you build your APK you can transfer it to the Blackberry device using whatever method is most convenient for you. I used Dropbox. Once you have the APK on the Blackberry you simply need to install it.

I built a few samples, including one that takes a picture, and they all more or less worked as expected. When the ShareSheet came up, the usual suspects like Facebook and Twitter were not there, but I didn’t have those set up yet on my test device, so that is to be expected.

You can take things a step further and repackage and sign your app to distribute through the Blackberry store, but that isn’t necessary. You can deploy your APK directly to the Blackberry, or distribute it through the Amazon App Store. Crackberry has a guide on installing APKs too, with a little more detail.

The Blackberry Developer site has useful pages:

by Jim McKeeth at August 13, 2014 07:08 PM

twm’s blog

Windows 7 Blue Screen Of Death with error 0x8B

If you ever had to change the motherboard of your computer and wanted to keep the Windows installation on it, you might have encountered the dreaded Blue Screen of Death with an unhelpful error code.

In my case, this was a Windows 7 installation where the on board SATA controller started to misbehave. These problems didn’t show up in Windows but only when I did my weekly backup using CloneZilla. I wonder what would have happened if I had happily continued to use this computer because Windows didn’t warn me?

First I put the hard disk into a different computer, started CloneZilla and made a backup. No errors showed up, so it wasn’t the hard disk but the controller.

Then I threw out the old motherboard and took a new (cheap) one that still supported my old Dual Core processor and RAM. Connected everything and booted the box. I was expecting for it just to work. This is Windows 7, one of the most modern operating systems available, so driver issues should be a thing of the past, right?

Well, not so. Windows 7 crashed and rebooted, crashed and rebooted, crashed and rebooted. After a while I got tired of this ;-) , pressed F8 for the boot menu and disabled automatic reboot on errors. Then I got the BSOD in all it’s glory: Error code 0x7B, meaning “INACCESSIBLE_BOOT_DEVICE”.

In the olden (Windows XP) days this was a symptom of the SATA controller running in AHCI mode and Windows expecting IDE mode or vice versa. Apparently this is still the same with Windows 7 (When will you ever learn, Microsoft?).

Unfortunately the new board’s BIOS did not really allow me to switch the SATA mode (it seemed to allow me, but it didn’t make any difference). So after swearing a lot I turned to Google and found … a lot, most of it not really helpful. Hours (literally!) later, the solution turned out to be the following:

To allow Windows 7 to boot in IDE as well as AHCI mode, I had to enable the following drivers (by setting “Start” to “0” in the registry, there might be other options to do this):

HKLM\System\CurrentControlSet\services\intelide
HKLM\System\CurrentControlSet\services\pciide
HKLM\System\CurrentControlSet\services\msahci
HKLM\System\CurrentControlSet\services\iastorV

The first two allow Windows 7 to boot from SATA in IDE mode. The second two allow Windows 7 to boot from SATA in AHCI mode.

So, why isn’t that the default? I have no idea.
(Do I have to point out that Linux booted on the updated box without any problems? Which one is the more user friendly system?)

by dummzeuch at August 13, 2014 02:45 PM

Te Waka o Pascal

Making a Noise About on a Thread

I’m working on an Android app at the moment, and for a bit of fun I decided to add a startup sound to brighten the day of every user that launches it. Which gives me another opportunity to present some of the advanced language features in Oxygene that make threading such a breeze. First of […]

by Jolyon Direnko-Smith at August 13, 2014 08:47 AM

Firebird News

Active Record Firebird Adapter for #Rails updated to version 0.8.9

Active Record Firebird Adapter 0.8.9 is updated with a few cleanups and fixes: Changed quotes behavior for dialect 1 (an ancient Firebird dialect)

by mariuz at August 13, 2014 08:40 AM

The Wiert Corner - irregular stream of stuff

August 12, 2014

The Wiert Corner - irregular stream of stuff

In this case, both Self and DisconnectedClient has a property named ClientIdentifier. Note the difference for the mouse-over and the evaluation.

In the With Statement series:

Lars Fosdal – Code Rants

The dreaded with…

Debugging today, I found another gotcha.

In this case, both Self and DisconnectedClient has a property named ClientIdentifier.

Note the difference for the mouse-over and the evaluation.

–jeroen

via The dreaded with… Debugging today, I found another gotcha. In this case,….

In this case, both Self and DisconnectedClient has a property named ClientIdentifier.  Note the difference for the mouse-over and the evaluation.

In this case, both Self and DisconnectedClient has a property named ClientIdentifier. Note the difference for the mouse-over and the evaluation.


Filed under: Appmethod, Borland Pascal, 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 x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Development, Pascal, Software Development, Turbo Pascal, With statement

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

jpluimers

A long while ago, DelphiBasics.info (they are hosted on Google Sites) posted a very interesting via: uExecFromMem unit. It was only a code snippet, not much usage info.

One of the things you can do with this unit, is load the memory image of an executable from a database BLOB, then execute that.

bummi showed this as an uExecFromMemory example on StackOverflow including a small memory leak fix.

It opens way for some interesting deployment scenarios. Not for the everyday ones, but for the occassional situation where a regular deployment is impractical.

–jeroen

via: uExecFromMem by steve10120 – fixed for Win7x64 by testest – DelphiBasics.

Comment by Craig Peterson at G+: https://plus.google.com/109418621512564781181/posts/WZSa6Nt44rK

It’s a handy looking unit, but has a licensing bomb in it: The PerformBaseRelocation routine is lifted directly from BTMemoryModule.pas, which is only licensed LGPL without the binary linking exception.  That means providing your DCUs so anyone can relink your app.  It’s also a bit less maintainable than BTMemoryModule, since they replaced a bunch of declared constants with magic numbers.


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

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

August 11, 2014

DelphiTools.info

DWScript happenings and new logo

Long time, no post here, but not no happenings on the DWScript front Behold a “cleaned up old logo” for DWScript, which will replace the old one until a better one is made The DWS source saw mostly bug fixes and small improvements during the last months, as I became absorbed in the crypto-currency project…

by Eric Grange at August 11, 2014 03:41 PM

Te Waka o Pascal

Delayed POST Response

Way back in September last year, Mason Wheeler blogged about his first experiences with developing for Android using Oxygene. I said at the time that I would look into reproducing his efforts and respond. I didn’t get around to that right away and, as I think I have mentioned previously, then got rather busy and […]

by Jolyon Direnko-Smith at August 11, 2014 09:57 AM

The road to Delphi

Fix to conflict between the Delphi Dev. Shell Tools and AVG Antivirus.

I just detect a conflict with the AVG Antivirus 2014 Shell extension . This cause which the Delphi Dev. Shell Tools menu is not show. To fix this issue you must disable and enable the AVG Antivirus Shell extension.

Please follow the next steps to fix.

  1. Download and Run the ShellExView utility
  2. Locate the AVG Antivirus Shell extensions and disable it as is shown in the below image.
  3. log-off and log-on or restart Windows
  4. Test the Delphi Dev. Shell Tools extension
  5. Run the ShellExView utility again and enable the AVG Antivirus Shell extensions
  6. log-off and log-on or restart Windows
  7. Now both shell extensions should work normally.

AVG


by Rodrigo at August 11, 2014 02:24 AM

August 09, 2014

twm’s blog

Enabling the Developer Tools in Delphi Chromium Embedded

Recently I had to debug some JavaScript code that did not work correctly, when loaded into a Chromium Embedded frame in one of my applications. There is built-in support for the Developer Tools in Chrome, which is also available in Chromium Embedded.

After searching the web, I found that the DCEF3 sources already come with a demo on how to show these tools and also show them externally using Google Chrome (which of course must be installed for this to work).

It’s actually quite simple:

The first thing to do is set the port for remote debugging to something else but 0. This must be done before the Chromium Embedded library is being initialized, e.g. in the initialization section of the form that uses it.

initialization
  CefRemoteDebuggingPort := 9000;

Then you need a Chromium browser window to display the tools, that is, a second TChromium control which can reside either on the same form or on a different form, or even in a different application (like Google Chrome). I chose to go with the first option because it is the least hassle. My TChromium control was set to alClient, so I just added a TSplitter and another TChromium control, set to alBottom to it and set both to Visible=false by default.

Now, to show the Developer Tools, there is only very little code:

procedure TMyForm.SetDebugToolsEnabled(_Value: Boolean);
begin
  chr_Debug.Visible := _Value;
  spl_Debug.Visible := _Value;
  if _Value then begin
    if not FDevToolLoaded then begin
      chr_Debug.Load(chr_Embedded.browser.Host.GetDevToolsUrl(True));
      FDevToolLoaded := True;
    end;
  end;
end;

Where chr_Embeeded is the TChromium control that displays the actual content my programs uses and chr_Debug is the TChromium control that shows the Developer Tools.

Much easier than I originally thought, but far from obvious if you don’t know that the Devoloper Tools are just another browser window (which I didn’t).

by dummzeuch at August 09, 2014 11:15 AM

August 08, 2014

Dr.Bob's Delphi Notes

Delphi XE6 XML, SOAP & Web Services Development

Today, I'm pleased to announced the immediate availability of my Delphi XE6 XML, SOAP & Web Services Development courseware manual in PDF format.

by Bob@eBob42.com (Bob Swart) at August 08, 2014 08:40 AM

August 07, 2014

Dr.Bob's Delphi Notes

Delphi XE6 Development Essentials

I have finally completed the first edition of my Delphi XE6 Development Essentials courseware manual in PDF format, which has been sent to all my customers of Delphi and RAD Studio (with out without subscription).

by Bob@eBob42.com (Bob Swart) at August 07, 2014 06:59 PM

The Wiert Corner - irregular stream of stuff

jpluimers

Following up on yesterdays Delphi: using IInterface to restore cursor at end of mehod (prelude to a memento that executes any code at end of method) here is the memento I meant.

They are based on anonymous methods, which in Delphi are closures: they capture location.

The location is kept just as long as needed, based on a well known Delphi reference counting mechanism: interfaces. The same one I used for the TTemporaryCursor class (and one of the reasons the TTemporaryCursor will keep functioning).

My goal was to simplify code like this:

procedure TTemporaryCursorMainForm.TemporaryCursorClassicButtonClick(Sender: TObject);
var
  Button: TButton;
  SavedCursor: TCursor;
  SavedEnabled: Boolean;
begin
  Button := Sender as TButton;
  SavedEnabled := Button.Enabled;
  try
    Button.Enabled := False;
    SavedCursor := Screen.Cursor;
    try
      Screen.Cursor := crHourGlass;
      Sleep(3000);
    finally
      Screen.Cursor := SavedCursor;
    end;
  finally
    Button.Enabled := SavedEnabled;
  end;
end;

Into this:

procedure TTemporaryCursorMainForm.TemporaryCursorMementoButtonClick(Sender: TObject);
var
  Button: TButton;
  SavedEnabled: Boolean;
begin
  TTemporaryCursor.SetTemporaryCursor();
  Button := Sender as TButton;
  SavedEnabled := Button.Enabled;
  TAnonymousMethodMemento.CreateMemento(procedure begin Button.Enabled := SavedEnabled; end);
  Button.Enabled := False;
  Sleep(3000); // sleep 3 seconds with the button disabled crHourGlass cursor
  // Delphi will automatically restore the cursor
end;

We’ve already seen one of the try…finally…end blocks vanish by using TTemporaryCursor. Now lets look at TAnonymousMethodMemento:

unit AnonymousMethodMementoUnit;

interface

uses
  System.SysUtils;

type
  IAnonymousMethodMemento = interface(IInterface)
  ['{29690E1E-24C8-43A5-8FDF-5F21BB32CEC2}']
  end;

  TAnonymousMethodMemento = class(TInterfacedObject, IAnonymousMethodMemento)
  strict private
    FFinallyProc: TProc;
  public
    constructor Create(const AFinallyProc: TProc);
    destructor Destroy; override;
    procedure Restore(const AFinallyProc: TProc); virtual;
    class function CreateMemento(const AFinallyProc: TProc): IAnonymousMethodMemento;
  end;

implementation

{ TAnonymousMethodMemento }
constructor TAnonymousMethodMemento.Create(const AFinallyProc: TProc);
begin
  inherited Create();
  FFinallyProc := AFinallyProc;
end;

destructor TAnonymousMethodMemento.Destroy;
begin
  Restore(FFinallyProc);
  inherited Destroy();
end;

class function TAnonymousMethodMemento.CreateMemento(const AFinallyProc: TProc): IAnonymousMethodMemento;
begin
  Result := TAnonymousMethodMemento.Create(AFinallyProc);
end;

procedure TAnonymousMethodMemento.Restore(const AFinallyProc: TProc);
begin
  AFinallyProc();
end;

end.

Like TTemporaryCursor, I’ve kept it self-contained.

It uses a TProc parameter – a parameterless anonymous method – called AFinallyProc that needs to be executed right before the memento goes out of scope.

It can be called like any method, as to the compiler it is a method.

–jeroen


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

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