Planet Object Pascal

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?
    Yes.
  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, 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

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.



by Warren Postma (noreply@blogger.com) at August 27, 2014 10:34 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, 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 15335 times 2009-01-10
DDevExtensions 2.8 Features PDF DDevExtensionsFeatures.pdf 602.92 KB 4316 times 2014-08-25
DDevExtensions 2.4 7, 2007 DDevExtensions24Setup7_2007.zip 535.41 KB 6812 times 2011-07-25
DDevExtensions 2.82 2009-XE6 DDevExtensions282.7z 908.68 KB 243 times 2014-08-25

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 2009 IDEFixPack2009Reg57.7z 134.19 KB 58 times 2014-08-25
IDE Fix Pack 5.7 XE IDEFixPackXEReg57.7z 111.7 KB 94 times 2014-08-25
IDE Fix Pack 5.7 XE5 IDEFixPackXE5Reg57.7z 131.52 KB 82 times 2014-08-25
IDE Fix Pack 5.7 XE6 IDEFixPackXE6Reg57.7z 271.54 KB 186 times 2014-08-25

fastdcc download:

Name IDE Version File Size Downloads Added
fastdcc 5.7 2009+UP3 fastdcc2009v57.7z 75.74 KB 21 times 2014-08-25
fastdcc 5.7 XE fastdccXEv57.7z 81.61 KB 29 times 2014-08-25
fastdcc 5.7 XE5 fastdccXE5v57.7z 111.38 KB 32 times 2014-08-25
fastdcc 5.7 XE6 fastdccXE6v57.7z 139.83 KB 69 times 2014-08-25

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

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 2006/2007 (if you have Windows 8 you need to use version 4.3 instead of 4.4)

by Andreas Hausladen at August 15, 2014 01:52 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

The Podcast at Delphi.org

How to Get Answers to Your Questions

I love helping people out with technical challenges. I don’t always have as much time as I would like to dive into the details of their code though. Occasionally I get requests for help that are completely unactionable on my part. A while back Eric S. Raymond wrote a great guide for How to Ask Questions the Smart Way. If you haven’t read it I recommend it. I’ll summarize some of my tips here, which may or may not agree with his write-up. Hopefully these will be useful as you ask for help elsewhere. These are the steps I use when I ask others for help, or post on Stack Overflow.

One note, this isn’t intended to be taken as a complaint or rant. Just some useful tips to expedite the process of asking for help.

  1. What are you trying to do? – Just saying “This doesn’t work” is not enough information. Let me know what you are trying to accomplish. Also, if you can tell me some context and why, then I might be able to suggest an alternative method to accomplish the objective – you may be trying to do something the hard way. A while back a friend of mine asked me of the DOS Interrupt to reverse the scroll direction of text. I didn’t know, so he spent a few more hours researching it. When he was done he showed me the assembly routine he wrote to delete a line of text and then move the text bellow it up to take it’s place. Once I knew what he was trying to accomplish I could tell him there was already a routine in the CRT unit that did exactly that.
  2. What have you tried? – What debugging steps have you taken? Did you set a breakpoint? Did you try it on a different device? Did you consult the documentation? Did you consult the platform APIs? Did you reboot the device? Did you read what the error message said and try adjusting your code appropriately? Depending on what you are doing, there are different troubleshooting steps you should be taking. If you can tell me what you have done, and what the results were then that saves me from asking you if you “tried turning it off and back on again?” I’ve forgotten that simple step many times, and it is amazing how often it fixes the problems. If you haven’t tried anything else yet, do that first.
    We've tried nothing and we're all out of ideas
  3. Include a link to related documentation – Believe it or not, I don’t have every API memorized. To save me from doing some Googling, include some links to the pages you consulted in your troubleshooting. If you don’t have any links, then either you need to do some searching, or you need to let me know there is no documentation for what you are working on. Also, this may explain better what you are trying to do, and where you are getting your information. If you are reading an outdated document then that may be the problem, but if I don’t know where you are getting your information then I probably won’t know to suggest that. Also, by showing me the resources you’ve already tried then I won’t waste your time by sending you those links.
  4. Let Me Google That For YouTry searching Google, Stack Overflow, Forums, etc. first – Occasionally it is nice to get the question that I can answer just by pasting it into Google and replying with the first link. Makes me look smarter than I really am, but after a while it gets old. Often times I’ve found that after I search for something and don’t find any results, I’ll compose my question to a real person differently than my original search terms. I then take that question and paste it back into Google and the answer appears.
  5. Be Specific and Relevant - For example if you are having some issues calling the Facebook API from a FireMonkey mobile application, it is useful to know you are only seeing the issue from your rooted Android tablet, using XE5, running the beta of Android “L”. On the other hand, I probably don’t need to know the color of your device’s case or your Facebook password.
  6. Don’t send source unless asked – Please don’t paste in your entire project source code, including forms, etc. unless I ask you to. Often times it just results in an unwieldy long email message or blog comment that I need to scroll through to find the pertinent information. Sometimes it is useful to send source though, and I generally recommend trying to recreate the issue in a sample program before asking for help, just as a troubleshooting step. That isn’t always possible though, so explain why in your email too. Now when asking on other forums, etc. observe the tradition there. If you are submitting a bug report then a test case is a good place to start.
  7. Avoid Personal Attacks – I used to work with a guy that whenever dealing with someone else’s code, software, library, tool, etc. would say “If I wrote code like that I’d lose my job.” One time I pointed out it was his code. He didn’t learn. It is never necessary to insult someone, even if you believe you’ve found a bug. I’d wager that any programmer who has not written any bugs has not written enough code. Even if you are not attacking me, I don’t like working with people who feel it necessary to belittle others.
  8. Stack OverflowDo some leg work yourself – This one is kind of hard to explain, but on sites like Stack Overflow they call them “homework questions.” Sometimes someone ask a question that sounds like it was part of their homework. The corollary is if you are asking a question like “What happens if I try to reference an object after I free it?” Or even more complex questions, but where the answer is obtained by simply doing what you ask and observing the outcome. I might know the answer off the top of my head, but often times I would need to do the same level of work you would to test it. Now if you are curious if “X works on Y” where you don’t have access to Y, then let me know in your question. Likewise if you did test something, and are getting inconsistent results and what a better understanding, explain that as well.
  9. Explain it to a Teddy Bear – The Teddy Bear PTeddy Bearrinciple is where you try to explain the problem out-loud to a Teddy Bear, as if you are trying to get an answer. It is amazing how often just going through the process you will answer your own question, or maybe realize your question doesn’t make any sense. If you don’t have a Teddy Bear you can use your dog, child, spouse, statue of Blaise Pascal, picture of Niklaus Wirth, shrine to Charles Babbage, etc. You can take it to the next step by imagining what answers, questions or challenges might be offered to your question. It is OK to have a full on conversation with an inanimate object.

Personally I’ve found that frequently when I prepare a proper question I find the answer before I need to ask it. Especially if I try to create a test case. That won’t always be the case though, and that is fine.

What tips do you have for getting better answers? What do you do before asking for help?

by Jim McKeeth at August 07, 2014 03:47 AM

August 06, 2014

Firebird News

IBSurgeon FBDataGuard 3.0 is available

IBSurgeon is glad to announce new version of Firebird maintenance, backup and anti-corruption tool FBDataGuard 3.0. New version contains many visual improvements, including completely new web interface with enhanced localization (English, Russian and Brazil Portuguese). ​ Now FBDataGuard also supports compression of backups up to 12Gb in size. There are also several minor bug fixes. […]

by IBSurgeon News at August 06, 2014 04:14 PM

The Wiert Corner - irregular stream of stuff

jpluimers

A long while ago, I wrote about a (then overdue post) on .NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class.

I had been using a similar technique in Delphi since before I found out about the TRecall class and thought: I think my TTemporaryCursor is smarter, as it is based on interfaces.

TRecall (and the Vcl.Graphics descendants TBrushRecall, TFontRecall, and TPenRecall) store TPersistent properies using the Assign method. They were introduced in Delphi 6.

Too bad there are only very few people using TRecall as lots of TPersistent things warrant sasaving and restoring.

My TTemporaryCursor class only stores an integer, so it cannot derive from TRecall. Besides it is based on IInterface which got introduced.

Note I’m not the first to publish about such a class (Malcolm Grooves wrote TCursorSnapshot, SwissDelphiCenter has TMyCursor, Nick Hodges published about TAutoCursor), it’s just that it has been in my tool box for so long, and written memento classes that you will see 2 articles on it this week.

In the mean time (this works with Delphi 2009 and up), I also wrote a small class that does similar things for any anonymous method. More on that tomorrow.

Back to TRecall: it is an example of the memento pattern in Delphi. The memento pattern allows you to restore state.

SourceMaking.com a.k.a. Design Patterns and Refactoring is a great site about Design PatternsUMLAntiPatterns and Refactoring.

Most pattern example code is available in all of the C#, C++, Delphi, Java and PHP languages.

Great stuff!

One of the constructs for restoring state is a try … finally … end construct: it allows you to always execute something in the finally block, for instance restoring the state to right before the try block.

For instance something like this:

procedure TTemporaryCursorMainForm.TemporaryCursorButtonClick(Sender: TObject);
var
  Button: TButton;
  SavedEnabled: Boolean;
begin
  Button := Sender as TButton;
  SavedEnabled := Button.Enabled; // save state
  try
    Button.Enabled := False; // set state
    Sleep(3000); // sleep 3 seconds with the button disabled
  finally
    Button.Enabled := SavedEnabled; // restore state
  end;
end;

Basically the save/set/restore state code can be anything: nothing/open/close file for instance.

Time for an example memento base class:

unit MementoUnit;

interface

uses
  TemporaryCursorUnit;

type
  IMemento = interface(IInterface)
  ['{529987B4-0C7C-4103-BCE7-EB9651E88E58}']
  end;

  TMemento = class(TInterfacedObject, IMemento)
  strict private
    FObject: TObject;
  public
    constructor Create(const AObject: TObject);
    destructor Destroy; override;
    procedure Restore(const AObject: TObject); virtual; abstract;
    class function CreateMemento(const AObject: TObject): IMemento;
  end;

implementation

{ TMemento }
constructor TMemento.Create(const AObject: TObject);
begin
  inherited Create();
  FObject := AObject;
end;

destructor TMemento.Destroy;
begin
  Restore(FObject);
  inherited Destroy();
end;

class function TMemento.CreateMemento(const AObject: TObject): IMemento;
begin
  Result := TMemento.Create(AObject);
end;

end.

The cool thing about Delphi interfaces is that they are reference counted. The Delphi base interface is IInterface. When the reference goes out of scope, it calls _Release, and when the reference count gets to zero, the Destroy destructor is called. TMemento forwards that to Restore.

There is a little trick with Delphi interfaces: you do not have to assign the result of TMemento.CreateMemento. Even if you do not assign it, Delphi will automatically keep the reference until the calling method ends: Delphi adds an implicit try … finally … end block where the finally … end will decrease the reference count.

Based on the TMemento idea, I created the TTemporaryCursor class and ITemporaryCursor interface. They could have been derived from TMemento and IMemento, but to keep it simpler, I have made the unit self-contained:

unit TemporaryCursorUnit;

interface

uses
  Vcl.Controls;

// .NET/C# Equivalent: http://wiert.me/2012/01/26/netc-using-idisposable-to-restore-temporary-settrings-example-temporarycursor-class/

type
  ITemporaryCursor = interface(IInterface)
    ['{495ADE0F-EFBE-4A0E-BF37-F1ACCACCE03D}']
  end;

  TTemporaryCursor = class(TInterfacedObject, ITemporaryCursor)
  strict private
    FCursor: TCursor;
  public
    constructor Create(const ACursor: TCursor);
    destructor Destroy; override;
    class function SetTemporaryCursor(const ACursor: TCursor = crHourGlass): ITemporaryCursor;
  end;

implementation

uses
  Vcl.Forms;

{ TTemporaryCursor }
constructor TTemporaryCursor.Create(const ACursor: TCursor);
begin
  inherited Create();
  FCursor := Screen.Cursor;
  Screen.Cursor := ACursor;
end;

destructor TTemporaryCursor.Destroy;
begin
  if Assigned(Screen) then
    Screen.Cursor := FCursor;
  inherited Destroy();
end;

class function TTemporaryCursor.SetTemporaryCursor(const ACursor: TCursor = crHourGlass): ITemporaryCursor;
begin
  Result := TTemporaryCursor.Create(ACursor);
end;

end.

You use it like this:

procedure TTemporaryCursorMainForm.TemporaryCursorButtonClick(Sender: TObject);
begin
  TTemporaryCursor.SetTemporaryCursor();
  Sleep(3000); // sleep 3 seconds with the crHourGlass cursor
  // Delphi will automatically restore the cursor
end;

What you see is no try … finally … end at all. That makes the code simpler to read and maintain.

The next post will introduce a memento class that allows you to perform a restore operation at the end of any method.

–jeroen


Filed under: Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development

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

The road to Delphi

VCL Styles Utils – New feature

I just uploaded a new release of the VCL Styles Utils project improving the support for ListViews and TreeView controls. When you uses a TListView setting the CheckBoxes property to True and with the VCL Styles enabled the control will look like so

ListView_NoHook

As you can see the Checkboxes is using the Windows native look and feel, this is because the OS draw these controls directly and not the VCL. Some time ago I show a workaround for this owner-drawing the TListView, unfortunately this implies modify the source code for each TListView in the project which means a lot of work in some scenarios. But now with this new addition to the VCL Styles Utils only adding the VCL.Styles.Hooks unit to your project the checkbox control is properly drawn using the current active VCL Style.

ListView_Hook

The same improvement goes for the TTreeview controls, by default the opened and closed glyphs are draw using the native look and feel

TreeView_NoHook

And now using the VCL.Styles.Hooks unit

TreeView_Hook

Remember which this unit also include a fix for the system colors when the VCL Styles are enabled as is show on this article.

Without Vcl.Styles.Hooks

List_Hook

With Vcl.Styles.Hooks

List_Hook

Note : The VCL.Styles.Hooks unit works hooking the UxTheme dll, this means which using this unit on your project will cause which all the calls to the DrawThemeBackground and DrawThemeBackgroundEx methods with the BP_RADIOBUTTON, BP_CHECKBOX, TVP_GLYPH, TVP_HOTGLYPH parts will be affected.


by Rodrigo at August 06, 2014 04:11 AM

Castle Game Engine news

Michalis is working on something cool for 2D animations in Castle Game Engine. See the latest view3dscene...

Michalis is working on something cool for 2D animations in Castle Game Engine. See the latest view3dscene screenshots, can you guess what new animation format are we going to support? :)

August 06, 2014 01:38 AM

August 05, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

I’ve done a bit of WinWord automation and came across different locations for the API:

New Style:

Old Style:

Fun fact: there is no Old Style Word 2007 documentation any more. You might expect it at http://msdn.microsoft.com/en-us/library/ms263641(v=office.12) but it is not there.

Not so fun fact (and the reason I was looking for the Documents documentation), is because of this big bug ONLY in Office 2010 (it does not occur in Office 2000 .. 2007, and is fixed in 2013): The WordMeister » Bug Word 2010: Documents collection is not correctly maintained.

The only workaround is to run an Office Add-in, or VBA Macro. Both not feasible for external clients.

–jeroen


Filed under: Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Office, Office 2007, Office 2010, Office 2013, Office Automation, Office VBA, Power User, Scripting, Software Development, VBScript

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

August 04, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Short answer: do not use the GlobalContainer.

Long answers are in this Spring4D thread: How is the GlobalContainer intended to be used? Are there important don’ts? – Google Groups.

Especially read this message by Stefan Glienke that shows you to setup your main program without using GlobalContainer at all.

Note that this doesn’t mean you should avoid a container at all.

Background information:

–jeroen


Filed under: Delphi, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE5, Delphi XE6, Development, Software Development, Spring4D

by Jeroen Pluimers at August 04, 2014 12:58 PM

Firebird News

TurboBird Version 1.2.0 is released

Read this page for the new features. This version contains huge modifications done by Reinier Olislagers (BigChimp). There are Linux 32/64 bits, Windows 32/64 bits Download binaries. You can install the source and compile it using Lazarus in any other Platform that already supported by Lazarus.

by mariuz at August 04, 2014 11:25 AM

August 02, 2014

Castle Game Engine news

"Mountains Of Fire" http://castle-engine.sourceforge.net/mountains_of_fire.php release 1.1.0! "Mountains...

"Mountains Of Fire" http://castle-engine.sourceforge.net/mountains_of_fire.php release 1.1.0! "Mountains Of Fire" is a free (and open-source) game where a human and a worm cooperate to survive in a deadly lava world. For single player or 2 players. By Michalis, using Castle Game Engine :)

The 1.1.0 release adds restart and quit buttons at the end of the game (when you die or win). The engine also gains an important fix for old Intel GPUs (low-end graphic cards on many laptops).

August 02, 2014 04:15 PM

July 31, 2014

Te Waka o Pascal

Did you get the Memo ?

People looking for a cheap Android tablet have a new option from a respected player: The Asus Pad 7 Although not exactly falling over themselves in excitement (it is an entry level, budget device after all), reviewers are finding a lot to like in this device. But Delphi developers hoping to sell their apps to […]

by Jolyon Direnko-Smith at July 31, 2014 07:34 PM

The Podcast at Delphi.org

Developer Skill Sprint: Effectively Using Delphi Generics with Ray Konopka

There was some confusion and a mix up with Ray Konopka’s developer skill sprint on Effectively Using Delphi Generics. We decided to move it to August 5th. So be sure to register for the new round of skill sprints and join us then.

August 5 Effectively Using Delphi Generics with Ray Konopka
August 7 Refactoring Object Pascal with Alister Christie
August 12 Behavior-Driven Development (BDD) with Roman Yankovsky
August 14 DataSnap Simple Calculator Service with Pawel Glowacki
August 19 Build an MVVM App in Twenty Minutes with Nick Hodges
August 21 JSON: The New INI File with Jeff Lefebvre
August 26 TMS Specifics with Bruno Fierens
August 28 New Object Pascal Language Features
September 2 Controlling Dynamic Field Creation in TDataSets with Cary Jensen

You can still catch the replays from the last series too, including the YouTube playlist and watch them all.

by Jim McKeeth at July 31, 2014 12:54 PM

Firebird News

Firebird International Conference 2014: Main Topics

Here is the list of the most interesting topics at Firebird conference. It will be updated when new descriptions from speakers will arrive. http://www.firebirdsql.org/en/firebird-international-conference-2014-main-topics/

by mariuz at July 31, 2014 11:07 AM

July 29, 2014

Firebird News

What languages do you use with Firebird?

We have a new poll in the site, about what languages are most used with Firebird. Please vote going to our mainpage and voting in the poll displayed in the right sidebar. Please vote and spread this poll to other Firebird users.

by Cantu at July 29, 2014 06:30 PM

Firebird 2.5.3 Final for LTS Ubuntu releases is uploaded into Firebird stable ppa

Here you can find the latest stable release Firebird 2.5.3 for LTS supported Ubuntu releases.Follow the Firebird 2.5.x guide for usage and installation.

by mariuz at July 29, 2014 04:39 PM

Firebird 2.5.3 released to Debian unstable

Firebird (2.5.3.26778.ds4-1) is uploaded to Debian unstable with the following changelog

by mariuz at July 29, 2014 12:05 PM

Database .NET 12.3 released

Database .NET is an innovative, powerful and intuitive multiple database management tool, With it you can Browse objects, Design tables, Edit rows, Export data and Run queries with a consistent interface. New features from 11.8 to 12.3 (2014/07/29) Updated to FirebirdSql.Data.FirebirdClient.dll 4.5.0 Added SQL File Version Control Added Vertical Browsing Mode Added Results to Text […]

by fishcodelib at July 29, 2014 08:58 AM

The Wiert Corner - irregular stream of stuff

jpluimers

ModelMaker Code Explorer (MMX for short) stores the keyboard shortcuts in the registry.

I’ve had it occur once that somehow most (about 95%) of the shortcuts got lost.

Two thinks I learned from resurrecting the shortcuts:

  • MMX writes these settings when you exit Delphi
  • Only a few keys (with lots of values under them) store the keys.

To resurrect them,

  1. Exit Delphi
  2. Backup your registry
  3. Delete the registry keys mentioned below
  4. Start Delphi
  5. Exit Delphi

Summary of what was wrong

The values under these keys got emptied

[HKEY_CURRENT_USER\Software\ModelMaker\MideX\10.0\Explorer\ContentsShortcutsEx]
[HKEY_CURRENT_USER\Software\ModelMaker\MideX\10.0\Explorer\DetailsShortcutsEx]
[HKEY_CURRENT_USER\Software\ModelMaker\MideX\10.0\Explorer\MainShortcutsEx]

Some of values under this keywere removed, but not all of them

[HKEY_CURRENT_USER\Software\ModelMaker\MideX\10.0\KeyBindingsEx\BDS 9]

The values under this key were OK

[HKEY_CURRENT_USER\Software\ModelMaker\MideX\10.0\Explorer\DocShortcutsEx]

–jeroen


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

by Jeroen Pluimers at July 29, 2014 05:00 AM

July 28, 2014

Firebird News

ADO.NET provider 4.5.0.0 for Firebird is ready

I’m pleased to announce new version of .NET provider. You can read more at http://blog.cincura.net/233471-ado-net-provider-4-5-0-0-for-firebird-is-ready/.

by Jiri Cincura at July 28, 2014 08:35 AM

July 26, 2014

Firebird News

FDD will receive people from 14 different states

Brazil is a really big country, and the 11th edition of the Firebird Developers Day conference will receive attendees from 14 different states. There are people travelling more than 2.000km to come! The map below has a partial list of the origins of those people (click the marks to check the distance to the conference place). It […]

by Cantu at July 26, 2014 01:59 PM

twm’s blog

Delphiversions.inc

In the olden days[tm] there was a project for maintaining a Delphiversions.inc file which created human readable conditional defines from the VERxx conditional defines of the Delphi compilers. Since it seems to have vanished from the face of the Internet[tm], I have just added a new page to the Delphi Wiki which you can just copy to a file and use. It allows you to do things like this:

{$include 'Delphiversions.inc'}
{$IFDEF Delphi6up}
{$WARN unsafe_type off}
{$WARN unsafe_code off}
{$WARN unsafe_cast off}
{$ENDIF}

(This turns the annoying dotNET warnings off that are just so unnecessary for native code.)

For a more comprehensive version of such a file, see jedi.inc from Project JEDI.

by dummzeuch at July 26, 2014 11:28 AM

July 25, 2014

Te Waka o Pascal

Come on Baby Light My Fire

These are exciting times in the mobile development space, especially for followers of RemObjects work. Whilst the likes of Xamarin and Embarcadero pursue their cross-platform abstractions, with varying degrees of success, RemObjects have been focussing on delivering genuinely native solutions and the long term vision that underpins their compiler architecture is proving itself in their […]

by Jolyon Direnko-Smith at July 25, 2014 10:45 PM

TPersistent

Using Object Pointers in a DataSet TField

I have seen code where an object pointer is stored in each row of a TDataSet, and referenced by code.  So skipping the question of the validity of such code, how do you support X86 and X64 bit code, especially if you use persistent TFields (use Delphi’s Form Designer RAD approach for the UI)?

For 32 bit development a TIntegerField works just fine.  Compile for Win64 (the OS/X compiler still doesn’t support 64 bit code) and everything seems fine until you run the app and exercise the code to find an AV.

A NativeInt scalar type is variable depending on the word size of the CPU, but there is no equivalent TField descendant (TNativeIntField), so you are forced to choose a different TNumericField descendant depending on your target (32 or 64 bit) or one that can support both.  The TLargeIntField uses a largeint (equivalent to an Int64) for internal field storage so it is the only possible choice that could support both targets and still provide design-time support.  The overhead of such an approach is questionable.  Otherwise, if you create the fields in code I would suggest conditional compilation using the CPUX64/CPUX86 directives.

If you need to support 64 bit targets I would also suggest development using Win64 so you don’t have to test each pathway for a 32 bit application to ensure it runs fine as a 64 bit EXE.

by Larry Hengen at July 25, 2014 10:44 PM

The Podcast at Delphi.org

Mobile Summer School 6: REST & BaaS

Here are the slides and downloads from my mobile summer school session on REST & BAAS. If you just want the slides they are on Slide Share. I’ll post the video and more details here later.

For more information on BaaS, check out Sarina’s excellent series of blog posts.

by Jim McKeeth at July 25, 2014 01:16 AM

July 24, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Late binding sometimes is your friend:

Set objWord = CreateObject("Word.Application")
Wscript.Echo "Version: " & objWord.Version
Wscript.Echo "Build: " & objWord.Build
objWord.Quit

The accompanying Delphi code:

uses
  System.Win.ComObj;

procedure TTestVersionAgnosticWordMainForm.GetWordApplicationInfoButtonClick(Sender: TObject);
var
  WordApplication: OleVariant;
  Version: OleVariant;
  Build: OleVariant;
begin
  WordApplication := CreateOleObject('Word.Application');
  try
    try
      Version := WordApplication.Version;
      Build := WordApplication.Build;
      LogMemo.Lines.Add(Version);
      LogMemo.Lines.Add(Build);
    finally
      WordApplication.Quit;
    end;
  finally
    WordApplication := Unassigned; // release it
  end;
end;

–jeroen

via: How Can I Determine Which Version of Word is Installed on a Computer? – Hey, Scripting Guy! Blog – Site Home – TechNet Blogs.


Filed under: Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Scripting, Software Development, VBScript

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

July 23, 2014

twm’s blog

Displaying a multi line error message without wasting space

I have got a form that usually displays outputs from various sources, each of which has a frame for its own purpose. Now, if an error occurs with any of theses sources, I want to display that error message on the bottom of the form, just above the panel that contains the action buttons. It looks like this:

    P2  **********************************
        *      *          *              *
        *  F1  *   F2     *      F3      *
        *      *          *              *
        **********************************
        *                                *
        *            F4                  *
    L1  *                                *
        **********************************
    P1  *         buttons go here        *
        **********************************

F1, F2, F3, F4 are the output frames for four of the sources, there can be many of various sizes.

My current solution is two panels and a label:
P2 is client aligned and contains all the frames
L1 is bottom aligned and normally invisible
P1 is bottom aligned

If an error occurs, I set the label’s caption and make it visible.

That works fine, if the error messages are short and fit within the window. Unfortunately, that’s not always the case. If the messages are longer, I would like to automatically word wrap them and increase the label’s hight.

I was prepared to start using Canvas.TextExtend etc. to write code for all of that, but it turned out there is a very simple solution:

Set the label’s WordWrap property to true and make sure that its AutoSize property is also true. That way the VCL will automatically take care of both, the word wrapping and increasing the label’s height if necessary.

(I think TLabel.WordWrap was introduce with Delphi 2007, but it might be even older.)

by dummzeuch at July 23, 2014 01:08 PM

Firebird News

Flamerobin binary snapshot 0.9.3-ff8df8e for Linux x86-64 only

New Flamerobin snapshot for Linux x86-64 is released this one was built and static linked with WxWidgets 3.0.1 and boost 1.55 to use it from console type : cd Downloads tar -xJvf ~/Downloads/flamerobin-0.9.3-ff8df8e-x86_64.tar.xz sudo mv opt/flamerobin /opt /opt/flamerobin/bin/flamerobin ps:tested on Debian sid and Ubuntu 14.04 (I’m interested if it starts on other linuxes : Fedora […]

by mariuz at July 23, 2014 11:28 AM

The Wiert Corner - irregular stream of stuff

jpluimers

A while ago, some of the TODO comments in my source code disappeared from the TODO list.

I wondered why, so I found this question: How set up todo list categories in Delphi 2010?.

The Delphi TODO item syntax in source code comments is like this (thanks Nelson H C Nepomuceno):

{ TODO 1 -cImportant :Do this!}
// TODO 1 -cImportant: Do this!

My comment there, after I found out I had done a stupid global search replace involving colons:

The important thing is the colon somewhere after the TODO. If you do not have the colon, then the TODO list will not show the comment. Anything after the colon will be the action item in the TODO list.

–jeroen

via: How set up todo list categories in Delphi 2010 – Stack Overflow.


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

by Jeroen Pluimers at July 23, 2014 05:00 AM

July 22, 2014

The Podcast at Delphi.org

Mobile Summer School Lesson 5: App Tethering Round-Up

I substituted for David I. yesterday for Developer Direct Mobile Summer School on Lesson 5: Connecting Mobile and Desktop together using App Tethering. The Summer School landing page and David’s blog maintain a list of downloads for all the previous lessons, but here are the resources from my session in the meantime.

I’ll post the replay videos here when they are available too.

You can download my slides and code samples from Code Central. I believe I fixed the issue where some people were not able to download it.

cc.embarcadero.com/item/29907

Here are the links to more information on App Tethering:

Here is the Developer Skill Sprint I did previously on App Tethering

And this is Al Mannarino’s C++ Mobile Day session on the topic

And some blog posts on the topic too:

There was some interest in the code sample that bypasses App Tethering’s autodiscovery to connect directly to a specific IP address. I’m working on getting that tested before posting it. Leave a comment if you are interest and I’ll see that you are notified when it is ready.

by Jim McKeeth at July 22, 2014 05:57 PM

TPersistent

A Hint About Warnings

Compiler Hints and Warnings are an important indicator of the quality of the code you are compiling.  It dismays me that I have often seen a ton of compiler warnings on commercial component suites when I compile them.  It makes you question the care taken when writing the code.

Compiler Hints and Warnings should be treated as potential coding errors.  Each one should be addressed to ensure it will not cause a errant behaviour at run-time, and the code in question is properly structured.  It is good to see I am not alone in this view.  So take a hint (pun intended), and clean up your hints and warnings.

Sometimes this isn’t so easy.  For instance, if  component requires a given unit, for example Vcl.ImgList, as the TcxCustomTreeList does, it will add the unit to the uses clause automatically.  You might then get a  warning like  W1000 Symbol ‘TImageIndex’ is deprecated: ‘Use System.UITypes.TImageIndex’. Unfortunately, adding System.UITypes and removing Vcl.ImgList just results in the IDE re-injecting Vcl.ImgList back into the uses clause and reporting the same warning.  I really don’t want to turn off this warning globally so the best option that I know of is to add {$WARN SYMBOL_DEPRECATED OFF} to the interface section of the unit in question.  While this solution may not be ideal, it allowed me to “address” the warning so new compiler hints and warnings that may actually indicate a flaw in the code do not get lost in a multitude of messages.  Clean code is less likely to be flawed code.

by Larry Hengen at July 22, 2014 05:28 PM

Every Team needs a Goaltender

It’s been my experience that just like in sports where you have a goal tender, every development team needs a gate keeper or goal tender for their VCS to ensure nothing gets in that they don’t want.  The role of the gatekeeper in the team is not only to manage the promotion/demotion of DEV code to QA on through to PROD (production), but also to ensure the code meets syntax standards, and more importantly architectural standards or conventions.

Even if the standard way of doing things is less than optimal, consistency is king.  If a slower evolutionary method of evolving the code is not possible, at least with consistent code, you can transform it en masse at the beginning of a release cycle and dedicate a lot of QA time to ensure you didn’t break anything.  Developers who understand the “normal” way of doing things can maintain and write code comfortably, with confidence that it will work.

I have seen consultants brought in to author a new system and use it as an opportunity to play with new architecture and methodologies.  While they usually deliver the results, the code most often cannot be effectively supported by on-site developers because it is so radically different from what they know.  The same thing can happen on a team with developers at different skill levels, and different views on the latest design patterns and methodologies.

The important thing is that ‘there is no “I” in TEAM’.  Everyone needs to be able to understand and support all the code.  If an architectural pattern makes software harder to understand, then the benefits of using that pattern may be outweighed by the maintainability of the code by the team.  The team needs to decide as a whole on coding standards and practices.

One example of this is the heavy use of interfaces.  Interfaces are great for decoupling code, but at the same time it makes it harder to follow since the implementer of the interface is “disconnected”.  Using the Delphi IDE to navigate through code, by Ctrl+clicking in order to understand it, doesn’t work as it does with classes.  This isn’t a shortfall of the IDE.  There is simply no way it can know what objects are used to implement that interface (especially if you use injection).

The quality and maintainability of your code is directly related to the strength of the gatekeeper and the cohesion of the team.  Better teams build better code…

by Larry Hengen at July 22, 2014 03:58 PM

The Wiert Corner - irregular stream of stuff

jpluimers

Found out where the StackOverflow Pascal has its origins: What happened to comments in syntax highlighter? – Meta Stack Overflow.

Like any syntax highlighter, it is not perfect (only a Delphi compiler driven highlighter would have a chance to be perfect), but it does a pretty good job and gets better over time.

–jeroen


Filed under: 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 x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, FreePascal, Pascal, Software Development, Turbo Pascal

by Jeroen Pluimers at July 22, 2014 05:00 AM

July 21, 2014

while true do;

ITDevCon 2014, Call4Papers

Dear potential ITDevCon speaker, As every year, I’m building the agenda for next ITDevCon that will be held next october 23th, 24th in Milan (Italy), in a new location. This will be the 6th edition ( we’re getting conference experts J ) The call for papers are officially open right now, so if you want to propose some [...]

by Daniele Teti at July 21, 2014 10:28 AM

July 20, 2014

Firebird News

IB Objects and Lazarus

This post makes me realize I have done very little to make public the work I have done with IB Objects over the past years. For everyone’s knowledge, IB Objects has been available on Lazarus for years now and is very mature there. In fact, several bugs and/or deficiencies in Lazarus have been fixed based […]

by mariuz at July 20, 2014 03:41 PM

Firebird 2.5.3 sub-release is available

Firebird Project is happy to announce general availability of Firebird 2.5.3 — the latest minor release in the Firebird 2.5 series. This sub-release introduces several bug fixes and a few improvements, please refer to the Release Notes for the full list of changes. Binary kits for Windows, Linux and Mac OS X on both 32-bit and 64-bit platforms are […]

by mariuz at July 20, 2014 01:55 PM

A new version, IBX for Lazarus 1.1 is now available

Tony announced new version, IBX for Lazarus 1.1 is now available from http://www.mwasoftware.co.uk/ibx See announcement in the 3rd party Lazarus forum for the change log. Performance increased with 30-50% in some cases. Many thanks to Gabor for pointing out the performance issues and for testing updates. This kicked me into cleaning up this part of […]

by mariuz at July 20, 2014 11:23 AM

July 19, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

Though fully justified text is most often in print, and not much in user interfaces any more, this might come in useful one day (it is based on the GDI functions TextOut and SetTextJustification):

David Millington Posted: Have you ever wanted to draw fully justified text ie, text that adheres to both the left and right sides of the destination rectangle? It’s more complicated than it seems, and there’s definitely no inbuilt support in the VCL. But here’s how to do it, including an open-source unit you can drop into your applications and use.

Drawing fully justified text to a canvas | Parnassus – Delphi Consulting & Plugins.

–jeroen

via:


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

by Jeroen Pluimers at July 19, 2014 08:20 AM

jed-software.com

FireMonkey – TArc and Retina, not the best of friends

Last week I noticed a post on www.fmxexpress.com that showed a different UI for a progress bar. So instead of starting work on something I should have, I turned the code into a component and added the ability to change the colours used when displayed.

I’d known TArc didn’t render nicely on a Retina device because I was using it to render a navigation UI concept. Which I’ve had to shelve because of this issue.

The control does look good under other platforms (untested under Android – issues not anticipated though).

You can download the full source code for the control from the Quality Central report lodged for the rendering issue. It looks like you will need to use a native client to download from the QC report as it doesn’t look like you can from the web client.

The control has the following “license” in the main unit:

{

TCircleProgress is based on code made open source by developer OneChen.

Original Code Link: https://github.com/OneChen/ProgressCircle
How I found out link: http://www.fmxexpress.com/build-a-progress-spinner-using-objects-in-delphi-xe6-firemonkey-on-android-and-ios/

Developer of this component: Jeremy North (jeremy.north@gmail.com)

DO NOT PAY FOR THIS COMPONENT. DONATE TO THE ORIGINAL AUTHOR OF THE IDEA IF YOU WANT TO CONTRIBUTE.

Disclaimer: This code is provided free of charge, bugs and all.

}

 

Windows

 

The Windows capture actually shows another drawing bug with FireMonkey. Notice how the rectangle at the top has two black dots in the top left and top right corners. This happens when you eliminate sides from a rectangle and maintain one full side to be drawn. Something that I’ve reported previously.

Report No: 122616 (RAID: 47827) Status: Open
Removing Sides can leave unwanted dots in corners
http://qc.embarcadero.com/wc/qcmain.aspx?d=122616

 

OS X

 

iOS

 

NOTE: This isn’t an issue for just TArc though, it is an issue with the GPU canvas. In previous versions, you could disable the usage of the GPU canvas, however with XE6 – the option to switch it off has been deprecated.

 

Zoomed view under iOS

 

Report No: 126186 (RAID: 52756) Status: Open
[Retina] [iOS] TArc doesn’t rendering nicely on a Retina device
http://qc.embarcadero.com/wc/qcmain.aspx?d=126186

 

Reported and opened. Hopefully in the next release, this rendering issue is addressed.

by JED at July 19, 2014 05:37 AM

July 17, 2014

The Wiert Corner - irregular stream of stuff

jpluimers

I observe an increase of people not asking questions on Stack Overflow any more…

Today, two interesting questions caught my eye.

The first one was by Martijn Coppoolse about Is it possible to figure out whether a type’s property has a ‘stored’ flag or not, preferably without having to create an instance of that type? (note: emphasis is mine)

Then the most interesting one (note this is about old Turbo Pascal style object syntax that is still available in Delphi, yes polymorphism with the object keyword): Could you please remind me if Objects support polymorphism? by Roman Yankovsky.

–jeroen

PS: Martijn posted the solution he used:

So I tried looking at the StoredProc pointer, and I can differentiate between three states:
  1. nil, which means stored False;
  2. Pointer(1), which means that no stored flag was specified;
  3. an actual pointer, which means that a method was specified; and the pointer seems to point at the relevant method’s CodeAddress. However, we always use private methods for that, and those don’t seem to be enumerated by GetMethods.

Still, those three states are basically what I needed: don’t include an element when StoredProc = nil; when StoredProc = Pointer(1) make it compulsory, and make it optional otherwise when it’s a pointer.
Thanks a lot to all who helped! +Qing-Shan Xiao +Jeroen Wiert Pluimers +Asbjørn Heid

–jeroen


Filed under: Delphi, Delphi 7, Development, Software Development

by Jeroen Pluimers at July 17, 2014 07:47 PM

Firebird News

Jaybird 3.0 snapshot available for testing

Mark Rotteveel published a snapshot of Jaybird 3.0 for testing purposes. This is a very early snapshot, a lot of work still needs to be done before Jaybird 3.0 will be release-ready. We’d appreciate your feedback, but we’d like to emphasize that this version is unstable and not ready for production. The protocol implementation has […]

by mariuz at July 17, 2014 08:52 AM

The Wiert Corner - irregular stream of stuff

jpluimers

I’m not a real expert on LCID (the values like 1033 (aka 0x409 or $409) and 1043 (aka 0x413 or $413), but here are a few notes on stuff that I wrote a while ago to obtain shell32.dll resource strings for various LCIDs.

The most often used way to load resource strings is by calling the LoadString Windows API call which loads the string for the currently defined LCID.

To get them for a different LCID, there are two ways:

  1. Set the LCID for the current thread (don’t forget to notify the Delphi RTL you did this, and update FormatSettings)
  2. Write an alternative for LoadString that gets a string for a specific LCID (so you can keep the current thread in a different LCID)

The first method – altering the LCID of the current thread – is done using SetThreadLocale in Windows XP or earlier, and SetThreadUILanguage in Windows Vista/2008 and up (I’m not sure on the timeline of Windows Server versions, but I guess the split is between 2003 and 2008) as mentioned at SetThreadLocale and SetThreadUILanguage for Localization on Windows XP and Vista | words.

SetThreadLocale is deprecated, as Windows has started switching from LCID to Locale Names. This can cause odd behaviour in at least Delphi versions 2010, XE and XE2. See the answers at delphi – GetThreadLocale returns different value than GetUserDefaultLCID? for more information.

But even on XP it has the potential drawback of selecting language ID 0 (LANG_NEUTRAL) which selects the English language if it is available (as that is in the default search order). Both Writing Win32 Multilingual User Interface Applications and the answers to LoadString works only if I don’t have an English string table and Windows skipping language-specific resources and the Embarcadero Discussion Forums: How to load specific locale settingsd thread that describe this behaviour.

To work around that, you can do two things: store your resource strings in locale dependent DLLs, or (if you don’t write those DLLs yourself), write an alternative for LoadString.

I’ve done the latter for Delphi, so I could load strings for a specific LCID from the Shell32.dll.

For a full overview of all these strings, see http://www.angelfire.com/space/ceedee/shell32stringtables.txt

A few pieces of code.

You can get the full code at the BeSharp – Source Code Changeset 100520.

First a wrapper around LoadString that returns a Delphi String: pretty basic stuff like most Windows API wrappers returning a string with a character buffer and a “SetString(Result, …)” construct.

class function TStringResources.LoadString(const hInstance: HMODULE; const uId: UINT): string;
var
  Buffer: array [0 .. 1023] of char;  // reasonable length; might increase for really long resource strings.
  StringLength: Integer;
begin
  StringLength := Winapi.Windows.LoadString(hInstance, uId, Buffer, Length(Buffer));
  SetString(Result, Buffer, StringLength);
end;

Now the functions that loads the string for a specific ID and a specific LCID.

This one is a bit complex, and based on these posts (some as old as 2004):

Within the bucket, each string consists of a 2 byte length, followed (if length is bigger than zero) by length number of 2-byte characters.

A few more remarks that have nothing to do with STRINGTABLE, but more about how anciant 16-bit Windows API calls translate into the modern world:

  • LockResource is not a lock, but translates a handle into a memory pointer.
  • UnlockResource is a NOP in Win32, so no need to check result and perform RaiseLastOSError();
  • FreeResource in Win32 will return false, so no need to check result and perform RaiseLastOSError();
class function TStringResources.FindStringResourceEx(const hInstance: HMODULE; const uId, langId: UINT): string;
const
  StringsPerBucket = 16;
var
  BucketWideCharsPointer: LPCWSTR;
  BucketResourceHandle: HRSRC;
  BucketGlobalHandle: HGLOBAL;
  BucketPointer: Pointer;
  i: UINT;
  BucketNumber: Cardinal;
  BucketIntResource: PWideChar;
  IndexInBucket: UINT;
  StringLengthPointer: PWord;
  StringLength: Word;
begin
  Result := ''; // assume failure
  // Convert the string ID into a bundle number
  BucketNumber := uId div StringsPerBucket + 1;
  BucketIntResource := MAKEINTRESOURCE(BucketNumber);
  BucketResourceHandle := FindResourceEx(hInstance, RT_STRING, BucketIntResource, langId);
  if (BucketResourceHandle <> 0) then
  begin
    BucketGlobalHandle := LoadResource(hInstance, BucketResourceHandle);
    if (BucketGlobalHandle <> 0) then
    begin
      BucketPointer := LockResource(BucketGlobalHandle);
      BucketWideCharsPointer := LPCWSTR(BucketPointer);
      if (BucketWideCharsPointer <> nil) then
      begin
        // okay now walk the string table
        IndexInBucket := (uId and (StringsPerBucket - 1));
        for i := 1 to IndexInBucket do // skip n-1 entries
        begin
          StringLengthPointer := PWord(BucketWideCharsPointer);
          StringLength := StringLengthPointer^;
          Inc(BucketWideCharsPointer); // skip the length Word
          Inc(BucketWideCharsPointer, StringLength); // skip the content
        end;
        StringLengthPointer := PWord(BucketWideCharsPointer);
        StringLength := StringLengthPointer^;
        Inc(BucketWideCharsPointer); // skip the length Word
        if StringLength <> 0 then
          Result := Copy(BucketWideCharsPointer, 1, StringLength);
        UnlockResource(BucketGlobalHandle)
      end;
      FreeResource(BucketGlobalHandle);
    end;
  end;
end;

Finally a function that tries to find an ID for a string and a specific LCID.

The logic is pretty simple: try all IDs, and find a string that matches the ID. If it matches, return that ID.

class function TStringResources.FindResourceStringId(const resource_handle : HMODULE; const search_resource_string: string; const langId: UINT): UINT;
var
  resource_id: UINT;
  i: Word;
  resource_string: string;
  compare_string: string;
begin
  resource_id := High(resource_id);
  for i := Low(i) to High(i) do
  begin
    resource_string := FindStringResourceEx(resource_handle, i, langId);
    compare_string := Copy(resource_string, Length(search_resource_string));
    if (resource_string <> '') and (SameStr(resource_string, compare_string))
    then
      resource_id := i;
  end;
  Result := resource_id;
end;

Finally a few notes on LCIDs, not the least so see how scattered the information is:

  1. You can add an Excel specific LCID (locale identifier) to a format. Without it, it will use the user’s locale settings.
  2. You can ommit the language hint (like [ENG]) from the formatting.
  3. The Excel LCID is very similar to the LCID Structure using hexadecimal values from the (old now defunct Locale ID Chart and replaced by the new) Microsoft Locale ID Values,  Language Identifier Constants and Strings table or list of Locale IDs Assigned by Microsoft, but with a few twists.
  4. A Locale ID consists of 4 bytes: 16 bits for the Language ID, 4 bits for the Sort ID, and 12 unused bits: Locale
    Identifiers (Windows)
    .
    The MAKELCID macro takes the Language ID and Sort ID to create a LCID.
    The LANGIDFROMLCID macro and SORTIDFROMLCID macro extracts the 2 IDs from the LCID.
  5. The language itself consists of a primary language (10 bits) and a sublanguage (5 bits) as shown in Language Identifiers (Windows).
    You assemble them using the MAKELANGID macro.
    The PRIMARYLANGID macro and SUBLANGID macro brings you back the parts.
    A list of primary and sublanguages is at Language Identifier Constants and Strings (Windows).
  6. The LCID structure (it actually is a 4 byte structure containing a Sort ID and a LanguageID) is explained at 2.2 LCID Structure together with list of Sort IDs and Language IDs.
  7. A list of LCID and supported operating systems (from Windows NT 3.51 until Windows 8) is at 5 Appendix A: Product Behavior with columns Language, Location (or type), LCID, Name and Supported Windows/ELK Version.
  8. A 2005 list of Microsoft Locale ID Values.
  9. Locale IDs Assigned by Microsoft.
  10. Table of LCID, language name, etc for various versions of Windows (7, Vista, 2003, XP) at National Language Support (NLS) API Reference.
  11. LCIDs supported on Older Versions of Windows (Windows 2000 back to DOS 6.x).

And one more: if you really like i18n, L10n and such: read Michael Kaplan’s blog.

Edit: Michael’s MSDN blog is officially dead, but there are the nice web archive and web cache virtues:

–jeroen


Filed under: Delphi, Delphi XE2, Delphi XE3, Delphi XE4, Development, i18n internatiolanization and L10 Localization, Software Development

by Jeroen Pluimers at July 17, 2014 05:00 AM

July 16, 2014

Andy's Blog and Tools

Cause for rlink32 Too many resources to handle

If you have many DFM files and RES files in your project you may run into the rlink32 error “Too many resources to handle”. Every DFM file is one resource and a RES file can contain multiple resources. All together must not exceed 3626 resources.

This limit comes from how rlink32 pre-allocates memory for all resources.  The following pseudo code shows the memory allocator.

function AllocateResourceArray(var AllocatedSize: Word): PResourceArray;
var
  Size: Integer;
begin
  Size := $FF00;
  repeat
    Result := GetMemory(Size);
    if Result <> nil then
    begin
      AllocatedSize := Size;
      Exit;
    end;
    Dec(Size, $400);
  until Size < $400;
  AllocatedSize := 0;
end;

As you can see the max. number of bytes for the whole resource array is limited by $FF00 (65280) bytes. A resource array item’s size is 18 Bytes. That makes 3626 items. If the memory allocator can’t allocate enough memory it tries to allocate again with 1024 bytes less. So the max. number of resources can be lower than 3626. But wait, we have 2014 and not 1992 (rlink32.dll’s copyright message) and RAM is like sand on the beach, at least some developer think that. The 64KB age is long gone, but due to this function rlink32 will fail with “Too many resources to handle” if the 3627’s resource is processed.

There is an easy fix without much code change:
Change the var-parameter from “Word” to “LongWord” and set the initial size to $11FFDC (1,179,612 bytes) which makes room for 65534 resource items which should be enough at the moment. Adjust the code that calls into this function (there is only one call). Recompile rlink32.dll.

Unfortunately I can’t recompile rlink32.dll due to the lack of source code, so I need to patch the machine code. And changing the data type from “Word” to “LongWord” isn’t that easy as you have to patch a lot more places that the compiler would just generate for you (fortunately the 32-bit opcodes are usually smaller than the 16-bit opcodes).

This bug fix for the rlink32 error will be in the next version 5.7 of IDE Fix Pack (for the IDE compiler) and fastdcc (for the command line compiler).

by Andreas Hausladen at July 16, 2014 09:19 PM

The Wiert Corner - irregular stream of stuff

jpluimers

I used to forget about the difference between Variant and OleVariant, and used them like this:

Use OleVariants for OLE, and Variants for non OLE.

There is no need to manually clear them.

Luckily I was right, as the differences are documented in the Delphi on-line help at OLE-compatible Variant type (the oldest I could find was the Delphi 2010 OleVariant documentation):

OleVariant is an OLE-compatible Variant. The main difference between Variant and OleVariant is that Variant can contain data types that only the current application knows what to do with. OleVariant can only contain data types defined as compatible with OLE Automation, which means that contained data types can be passed between programs or across the network without worrying about whether the other end will know how to handle the data.

When you assign a Variant that contains custom data (such as a Delphi string, or one of the new custom variant types) to an OleVariant, the runtime library tries to convert the Variant into one of the OleVariant standard data types (such as a Delphi string converts to an OLE BSTR string). For example, if a Variant containing an AnsiString is assigned to an OleVariant, the AnsiString becomes a WideString. The same is true when passing a Variant to an OleVariant function parameter.

–jeroen

via: System.OleVariant – RAD Studio API Documentation.


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

by Jeroen Pluimers at July 16, 2014 05:00 AM

July 15, 2014

Firebird News

Deadline for submiting papers to international conference

Today, 15/July, is the deadline to submit talks proposals for the Firebird International Conference, to happen in Prague, in the end of October. More information here.

by Cantu at July 15, 2014 01:57 PM

July 14, 2014

Firebird News

Final part of the story with 1.7 Terabyte Firebird SQL database

Tuning 1.7 Terabyte FirebirdSQL database (part 3) For those who did not read the first 2 parts: Firebird Performance Degradation (part 1) More details about 1.7Tb database (part 2)

by IBSurgeon News at July 14, 2014 03:23 PM

July 12, 2014

twm’s blog

Adding fields to a TDataset in code

The Delphi IDE allows you to add fields to a TDataset (descendant e.g. TTable, TQuery, TAdoTable etc.) by right clicking on the component and selecting “Add Field” or “New Field”. For a particular project I didn’t want to do that because I kept changing the query for which I want to add the fields. But since there was one calculated field I had to add fields to the dataset otherwise the OnCalcFields event wouldn’t be called. So I ended up adding the fields in code.

Basically that’s easy, you just create a TField descendant (e.g. TStringField,TAutoIncField, TDateTimeField etc.) set the field name and dataset and that’s it. But there are some pitfalls:

var
  fld: TField;
  ds: TDataset;
begin
  // init Dataset
  // ...
  // add fields
  fld := TWideStringField.Create(ds);
  fld.Name := '';
  fld.FieldName := 'TE_Employee';
  ds.Fields.Add(fld);

While this looks fine, it will not work. You will get the error “Field does not have a dataset” (or similar, I don’t remember the exact error message). The reason is that adding the field to the Dataset’s Fields collection does not automatically tell the field to which dataset it belongs. For that you need to assign the field’s Dataset property.

var
  fld: TField;
  ds: TDataset;
begin
  // init Dataset
  // ...
  // add fields
  fld := TWideStringField.Create(ds);
  fld.Name := '';
  fld.FieldName := 'TE_Employee';
  fld.Dataset := ds;
  ds.Fields.Add(fld);

If you write it like this, it will seem to work, but you will get an access violation when the dataset is being destroyed. Can you spot why?

I had to trace into the RTL sources to find the problem: The field was added to the Fields collection twice, because setting its Dataset property also adds it to the Fields collection. So, when the field’s collection got freed, the Field was freed twice, resulting in the AV.

So the correct and working code is this:

var
  fld: TField;
  ds: TDataset;
begin
  // init Dataset
  // ...
  // add fields
  fld := TWideStringField.Create(ds);
  fld.Name := '';
  fld.FieldName := 'TE_Employee';
  fld.Dataset := ds; // this automatically adds the field to the Dataset's Fields collection.

You might be wondering about the line

  fld.Name := '';

I set the name of all components created in code to an empty string to avoid name collisions with any existing components or even a different instance of the component created by the same code. “A component with the name Edit1 already exists.” has bitten me too often.

Since I also used a TDbGrid to display the dataset, I also added Columns to the DBGrid to set the caption and column width. And since I am lazy (as any good programmer should be), I moved most of that code into a (sub-) procedure to make the code more readable (actually I did it so I had less to type, but the result is the same):

var
  TheDataset: TDataset;
  TheGrid: TDbGrid;

procedure TMyForm.InitDbGrid;

  procedure AddField(_fld: TField; const _Fieldname: string; const _Caption: string; _Width: Integer);
  var
    Col: TColumn;
  begin
    _fld.FieldName := _Fieldname;
    _fld.ReadOnly := True;
    _fld.Dataset := TheDataset;
    Col := TheGrid.Columns.Add;
    Col.Expanded := False;
    Col.FieldName := _Fieldname;
    Col.Title.Caption := _Caption;
    Col.Width := _Width;
  end;

begin
  AddField(TAutoIncField.Create(nil), 'SeNr', _('Number'), 50);
  AddField(TDateTimeField.Create(nil), 'TeArbeitstag', _('Date'), 70);
  AddField(TWideStringField.Create(nil), 'SeVon', _('Start'), 40);
  AddField(TWideStringField.Create(nil), 'SeBis', _('End'), 40);
  fld := TWideStringField.Create(nil);
  fld.FieldKind := fkCalculated;
  AddField(fld, 'Stunden', _('Hours'), 50);
  AddField(TWideStringField.Create(nil), 'PROJ_IDENT', _('Project'), 50);
  AddField(TWideStringField.Create(nil), 'SSchluessel', _('Activity'), 50);
  AddField(TWideStringField.Create(nil), 'SeBeschreibung', _('Description'), 200);
  ResizeGridColumns;
end;

And just to show why this code is actually useful, here are the ResizeGridColumns method and TheDatasetCalcFields and FormResize events.

procedure TMyForm.ResizeGridColumns;
var
  cnt: Integer;
  TotalWidth: Integer;
  i: Integer;
begin
  TotalWidth := 0;
  cnt := TheGrid.Columns.Count;
  for i := 0 to cnt - 2 do begin
    TotalWidth := TotalWidth + TheGrid.Columns[i].Width;
  end;
  TheGrid.Columns[cnt - 1].Width := TheGrid.ClientWidth - TotalWidth - 50;
end;

procedure TMyForm.FormResize(Sender: TObject);
begin
  ResizeGridColumns;
end;

procedure TMyForm.TheDatasetCalcFields(Dataset: TDataSet);
var
  Von: TdzNullableTime;
  Bis: TdzNullableTime;
begin
  Von.AssignVariant(Dataset['seVon']);
  Bis.AssignVariant(Dataset['seBis']);
  Dataset.FieldByName('Stunden').Value := (Bis - Von).ToHourStr(2);
end;

(TdzNullableTime is an extended record type from my dzlib library which is available from sourceforge if you are interested. It is declared in u_dzNullableTime.pas.

by dummzeuch at July 12, 2014 03:42 PM

July 11, 2014

The Podcast at Delphi.org

Skill Sprint: Android Voice – Speech Recognition and TTS

Androids can talk and listen!For my Developer Skill Sprint I was originally scheduled to show how to do a Google Glass Voice Trigger. That is pretty cool because it allows you to launch a Google Glass app with your voice, but I decided to expand on that to also show how the Google Glass app can be launched with the results of additional voice input, as well as how to take dictation and do text to speech everywhere else in Android.

I’ve still got a lot of work to do on the components, but they work as is for now. If you want to modify the component code then take a look at my Skill Sprint and blog post on the Android JNI Bridge.

 

by Jim McKeeth at July 11, 2014 07:19 PM

The road to Delphi

Delphi IDE Colorizer – Open Beta

A few months ago I started to work on a new project called Delphi IDE Colorizer. In the past weeks a beta version was tested for a dozen of Delphi developers on a closed beta. Now it’s time to move forward and a open beta version of the plugin is available. Check the next images and videos which provide a description of the Wizard.

Introduction

The Delphi IDE Colorizer (DIC) is a Wizard which allows to customize the look and feel of the workspace of the RAD Studio IDE.

Some of the features of the plugin are

  • DIC is compatible with RAD Studio XE, XE2, XE3, XE4, XE5, X6.
  • Transparent menus
  • Allow to change the icons, set the colors, and gradient direction of the title bar of the docked windows
  • Set the colors, and gradient direction of the toolbars.
  • Improve the drawing of the disabled icons used in menus and toolbars
  • Compatible with CnWizards and GExperts
  • Replace the icons used in the gutter and the debugger.
  • Includes 90+ themes.

Download

Before to download please read the FAQ of the plugin.
For download the wizard check the page of the project.

Check the next sample images
DeepskyBlue_default_layout

YellowGreen_debug_layout_assembly

DIC_Transparent_Menus

DIC_VCLStyles_Menus


by Rodrigo at July 11, 2014 05:15 PM

DIC now supports VCL Styles

I just released a major update to the Delphi IDE Colorizer adding VCL Styles support. So now you can style the non client area of the floating forms of the IDE and also use the elements of the VCL Styles on the RAD Studio IDE.

The next image shows how the VCL Styles are enabled on the wizard and which elements can you choose, for example you can select only style the forms with the VCL Styles and use the current theme settings for draw the controls and menus.

2014_07_07_23_00_55_Delphi_IDE_Colorizer_Settings

Check the full list of features on this page.

Check the next Video which show how the new feature works.


by Rodrigo at July 11, 2014 12:15 AM

July 08, 2014

The Podcast at Delphi.org

Android JNI Bridge and Custom Classes.dex

By creating a custom Classes.dex you can get access to 3rd party Java JAR APIs from your application. For my Integrate More Android with a JNI Call to your Android App Developer Skill Sprint I created a demo app that demonstrates creating a custom Classes.dex. This is a new feature in XE6 and Appmethod 1.14. [Download the demo] [Download the slides] The Demo app uses the Base64Coder JAR file (included). To build the demo:

  1. Examine the createdex.bat file to make sure it refers to the correct location for your dx.bat utility and the fmx.jar & android-support-v4.jar files.
  2. Run the createdex.bat file to create the classes.dex file which includes the two jar files above, plus the base64coder.jar file.
  3. Double check that the Deployment Manager references the new classes.dex and not the old ones, and that the remote path is “classes\”
  4. Notice that the android.JNI.Base64Coder.pas file wraps and exposes the methods of the base64coder class.
  5. Run the app on your Android device and verify that it works as expected.

The Base64Coder.JAR is Android specific, so it will not work on iOS or Windows. Some additional notes from the Developer Skill Sprint: Some useful units for making JNI calls

  • Androidapi.Jni – Java Native Interface type definitions
  • Androidapi.JNIBridge – The JNI Bridge
  • Androidapi.JNI.JavaTypes – JString and other common types.
  • Androidapi.Helpers – JStringToString and other useful conversions.
  • FMX.Platform.Android– Useful platform methods like GetAndroidApp, MainActivity and ConvertPointToPixel
  • Others useful units: Androidapi.AppGlue, Androidapi.JNIMarshal, Androidapi.JNI.Embarcadero
  • For more see: C:\Program Files (x86)\Embarcadero\Studio\14.0\source\rtl\android (Object Pascal) and C:\Program Files (x86)\Embarcadero\Studio\14.0\include\android\rtl (C++)

You will want to make use of Conditional Defines in Object Pascal and Predefined Macros in C++. In my blog post on Android Settings I showed how to make a JNI call with Object Pascal, but you can also look at the DeviceInfo Mobile Code Snippet in both C++ and Object Pascal. To create your own JNI Bridge wrappers, look at the source code in C:\Program Files (x86)\Embarcadero\Studio\14.0\source\rtl\android (Object Pascal) and C:\Program Files (x86)\Embarcadero\Studio\14.0\include\android\rtl (C++). You can also consider the following 3rd party utilities:

If you just want to include standard Android APIs then check out the FMXExpress (also an Embarcadero MVP) project on GitHub that includes all the Android APIs. Here is the video replay of my skill sprint

Also, check out Brian Long’s video on accessing the Android API with XE5

by Jim McKeeth at July 08, 2014 08:34 AM

July 07, 2014

Smart Mobile StudioSmart Mobile Studio

Smart Mobile Studio 1.1 RC (build 1.1.0.400)

We are very proud to present the release candidate for Smart Mobile Studio version 1.1  (build number v1.1.0.400). If you would like to give this groundbreaking product a test drive before we officially release it, then you can download the installer directly from SmartMobileStudio.com/download/setup_v1_1_0_400_rc.exe (The context menu is replaced with Ctrl+Shift+R (start/stop recording) and Ctrl+Shift+P [...]

The post Smart Mobile Studio 1.1 RC (build 1.1.0.400) appeared first on Smart Mobile Studio.

by Smart Mobile Studio Team at July 07, 2014 09:01 AM

July 05, 2014

twm’s blog

GORM experimental release

GORM is an editor for .po files that was originally written by Lars Dybdahl and to which I have been contributing quite a few features in recent years. Since Lars is too busy to do a release and currently even the original download doesn’t seem to work, I have compiled the current sources and provide a download here:

Gorm_2014-07-05.zip

In addition to the features described on the Gorm homepage this new version can do the following:

  • Edit the po file header.
  • Auto translate, using Google translate (not sure whether it is still available) or Microsoft Translator. Both need an application key that is not part of Gorm.
  • Auto translate from a local translation repository, which is an MS Access database, one per language, that can be shared by multiple developers
  • Auto translate using translation memory, that is a po file that is automatically generated.
  • Load and save translations to be ignored from a ignore.po file.
  • In addition to English, I provide it with German localization, that, of course, is created with Gorm itself.

The sources are available from the dxgettext repository on sourceforge.
Of course I like Gorm much better than PoEdit and other alternatives. If there are any bugs, that’s probably my fault.

by dummzeuch at July 05, 2014 04:59 PM