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

DelphiTools.info: Publishing pictures from an HTML5 app

$
0
0

imgur-logoThis is a belated followup to the L-System Fiddle series from last year (more like a forgotten article), which ended with a Pascal-based HTML5 app being used to generate fractals and publish them to imgur.

Why imgur? Well because they have a well-documented API and they don’t require registration, authentication or other personal data for uploads, making it a good candidate for a demo anybody can try online, and where you may not want to enter your personal credits.

L-System Fiddle

You can try the L-System web app for yourself, it comes with a few sample L-System fractals, and it allows tweak the grammar, iterations and basic simple rendering parameters.

 

In SmartMobileStudio 1.1 final, the whole L-System Fiddle source is included, and there is an “ImgurUtils” unit which exposes a class that facilitates asynchronous uploading of images to Imgur. Below is an excerpt of the upload method:

...
   FReq : TW3HttpRequest;
...
procedure TImgurUpload.Upload(canvas : TW3Canvas);
beginvar img := canvas.toDataURL('image/jpg');
   var imgParts := StrSplit(img, ',');

   FReq.Open('POST', 'http://api.imgur.com/2/upload.json');
   FReq.SetRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

   FReq.Send( 'key='+APIKey
             +'&title='+EncodeURIComponent(Title)
             +'&caption='+EncodeURIComponent(Caption)
             +'&image='+EncodeURIComponent(imgParts[1]));
end;

The first two lines get the base64-encoded image data from the canvas, the next lines perform the imgur API call. They’re using inline variable declaration with type inference.

Imgur answers with a JSON (asynchronously), here is handler that retrieves the URL of the uploaded image:

procedure TImgurUpload.DoReadyStateChange(Sender: TW3HttpRequest);
beginif Sender.ReadyState<>rrsDone thenexit;
   ...
   if Sender.Status in [200..299] thenbegin
      FResponse := JSON.Parse(Sender.ResponseText);
      FImgurPage := FResponse.upload.links.imgur_page;
   end;
   ...
end;

So as you can see, getting the basic behavior running is quite simple, and here is what it’ll look like after the upload has completed:

Picture uploaded to imgur

Picture uploaded to imgur


Firebird News: ANN: FB TraceManager V3.0 has been released!

$
0
0
Upscene Productions is excited to officially release a new major version of FB TraceManager: FB TraceManager V3.0 is available! New on-the-fly aggregated analysis capabilities on trace events (so-called “Hotspots”), improved throughput and stability, trace configuration templates and more is included in V3. For more information, check out the news item here: http://www.upscene.com/displaynews.php?item=20130315b A high-level overview [...]

Firebird News: YiiFirebird 1.0 is marked as stable we need more volunteers for writing and doing tests

$
0
0
It seems that now the YiiFirebird extension is stable enough (please let me know it is not so) for merge in YiiFramework master repo. Now, the next step is to create the automated tests for this extension. Volunteers? Ideas? We need to add a “tests” directory for that purpose in our local repo before committing Yii [...]

Lazarus Team Anouncements: Lazarus book for sale in Brazil

$
0
0
Hello, I still have some unsold copies of the official Lazarus book in english in Brazil, which I would like to sell. The price is R$125 with free shipping for the whole country. Payment via bank deposit to Banco Itaú.

Índice com o conteúdo do livro aq...

Firebird News: German court case confirms validity of the LGPL on Firebird related project FreeadhocUDF

$
0
0
Buhl Data Service GmbH, the developer of the WISO Mein Büro2009 software has agreed to pay €15,000 (approximately £13,000) to adhoc dataservice GmbH for using its LGPL-licensed FreeadhocUDF open source library in his business software without observing the LGPL’s licensing terms. The GNU Lesser Public Licence allows software to be used free of charge, but it stipulates that developers must [...]

Behind the connection: Multithreading and PostMessage performance

$
0
0
Windows messaging system is very useful for doing asynchronous programming, including multithreading. But what about performance?   In asynchronous operation, including multithreading, a developer frequently needs a message queue to serialize processing and notifications. Windows has his own message queue which is mostly used for the user interface but also for many asynchronous tasks such as

Firebird News: Important #debian security fix is uploaded to sid related to CVE-2013-2492

$
0
0
Important Debian security fix is uploaded to sid http://packages.qa.debian.org/f/firebird2.5/news/20130318T154817Z.html You can check Firebird 2.5/2.1 packages security status for this bug CVE-2013-2492 on this page https://security-tracker.debian.org/tracker/CVE-2013-2492

The road to Delphi: Getting Memory Device Info using Object Pascal (Delphi / FPC) and the TSMBIOS

$
0
0

dram-moduleIf you need to know what type of RAM is installed in your system or how is the manufacturer of your memory device, you can try reading the SPD (Serial presence detect) info directly (but not all the memory devices exposes the SPD info and reading the SPD require Kernel Mode access) , use the Win32_PhysicalMemory WMI class (but depending of the manufacturer the WMI fails to get info about some memory properties like the memory type) or using the SMBIOS.

Using the SMBIOS you can get most of the info related to the memory devices installed like manufacturer, type, speed, serial number and so on. The next snippet show how using the TSMBIOS and Delphi (or FPC) you can retrieve such data.

{$IFDEF FPC}{$mode objfpc}{$H+}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}

uses
  Classes,
  SysUtils,
  uSMBIOS;

procedure GetMemoryDeviceInfo;
Var
  SMBios : TSMBios;
  LMemoryDevice  : TMemoryDeviceInformation;
begin
  SMBios:=TSMBios.Create;
  try
      WriteLn('Memory Device Information');
      WriteLn('-------------------------');

      if SMBios.HasMemoryDeviceInfo then
      for LMemoryDevice in SMBios.MemoryDeviceInformation do
      begin
        WriteLn(Format('Total Width    %d bits',[LMemoryDevice.RAWMemoryDeviceInfo^.TotalWidth]));
        WriteLn(Format('Data Width     %d bits',[LMemoryDevice.RAWMemoryDeviceInfo^.DataWidth]));
        WriteLn(Format('Size           %d Mbytes',[LMemoryDevice.GetSize]));
        WriteLn(Format('Form Factor    %s',[LMemoryDevice.GetFormFactor]));
        WriteLn(Format('Device Locator %s',[LMemoryDevice.GetDeviceLocatorStr]));
        WriteLn(Format('Bank Locator   %s',[LMemoryDevice.GetBankLocatorStr]));
        WriteLn(Format('Memory Type    %s',[LMemoryDevice.GetMemoryTypeStr]));
        WriteLn(Format('Speed          %d MHz',[LMemoryDevice.RAWMemoryDeviceInfo^.Speed]));
        WriteLn(Format('Manufacturer   %s',[LMemoryDevice.ManufacturerStr]));
        WriteLn(Format('Serial Number  %s',[LMemoryDevice.SerialNumberStr]));
        WriteLn(Format('Asset Tag      %s',[LMemoryDevice.AssetTagStr]));
        WriteLn(Format('Part Number    %s',[LMemoryDevice.PartNumberStr]));

        WriteLn;

        if LMemoryDevice.RAWMemoryDeviceInfo^.PhysicalMemoryArrayHandle>0 then
        begin
          WriteLn('  Physical Memory Array');
          WriteLn('  ---------------------');
          WriteLn('  Location         '+LMemoryDevice.PhysicalMemoryArray.GetLocationStr);
          WriteLn('  Use              '+LMemoryDevice.PhysicalMemoryArray.GetUseStr);
          WriteLn('  Error Correction '+LMemoryDevice.PhysicalMemoryArray.GetErrorCorrectionStr);
          if LMemoryDevice.PhysicalMemoryArray.RAWPhysicalMemoryArrayInformation^.MaximumCapacity<>$80000000 then
            WriteLn(Format('  Maximum Capacity %d Kb',[LMemoryDevice.PhysicalMemoryArray.RAWPhysicalMemoryArrayInformation^.MaximumCapacity]))
          else
            WriteLn(Format('  Maximum Capacity %d bytes',[LMemoryDevice.PhysicalMemoryArray.RAWPhysicalMemoryArrayInformation^.ExtendedMaximumCapacity]));

          WriteLn(Format('  Memory devices   %d',[LMemoryDevice.PhysicalMemoryArray.RAWPhysicalMemoryArrayInformation^.NumberofMemoryDevices]));
        end;
        WriteLn;
      end
      else
      Writeln('No Memory Device Info was found');
  finally
   SMBios.Free;
  end;
end;

begin
 try
    GetMemoryDeviceInfo;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

memoryInfo

Note: Remember if you uses FPC, you can use this library in linux as well :)



The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

When porting some communications code that used records as properties from Delphi 2006 to Delphi XE2, I came across a tightened compiler error “E2197 Constant object cannot be passed as var parameter“.

Let me first explain the good old occurrence of E2197 with some code that uses my last Variant Records example:

Just look at TPacket.InitializePacket and TPacketBase.InitializeFPacket: Basically even though the Packetproperty has storage specifiers indicating it directly reads from a field and directly writes to a field, you cannot pass it as a var parameter in the FillChar method.

Of course you can with a field, you can pass it to FillChar without trouble as TPacketBase.InitializeFPacket shows.

unit PacketWrapperUnit;

interface

uses
  VariantRecordUnit;

type
  TPacketBase = class(TObject)
  strict private
    FPacket: TPacket;
  strict protected
    procedure InitializeFPacket; virtual;
  public
    property Packet: TPacket read FPacket write FPacket;
  end;

  TPacketWrapper = class(TPacketBase)
  strict private
    procedure InitializePacket;
  end;

implementation

procedure TPacketBase.InitializeFPacket;
begin
  FillChar(FPacket, SizeOf(FPacket), MarkerChar);
end;

constructor TPacketWrapper.Create;
begin
  inherited;
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacket;
begin
//[Pascal Error] PacketWrapperUnit.pas(74): E2197 Constant object cannot be passed as var parameter
//  FillChar(Packet, $AA, SizeOf(Packet));
  InitializeFPacket(); // alternative: use the field
end;

end.

Since TPacket is a record, and often you only want to initialize some fields, I have added the methods InitializeFPacketData1..3 to TPacketBase and InitializePacketData1..3 to TPacket with various gradations of with depth.

Since the methods in TPackketBase methods all refer the FPacket field, they all compile.

The methods in TPackket methods all refer the Packet property, you might suspect they won’t compile, but they all do except for InitializePacketData3.

unit PacketWrapperUnit;

interface

uses
  VariantRecordUnit;

type
  TPacketBase = class(TObject)
  strict private
    FPacket: TPacket;
  strict protected
    procedure InitializeFPacket; virtual;
  public
    procedure InitializeFPacketData1; virtual;
    procedure InitializeFPacketData2; virtual;
    procedure InitializeFPacketData3; virtual;
    property Packet: TPacket read FPacket write FPacket;
  end;

  TPacketWrapper = class(TPacketBase)
  strict private
    procedure InitializePacket;
  public
    constructor Create;
    procedure InitializePacketData1; virtual;
    procedure InitializePacketData2; virtual;
    procedure InitializePacketData3; virtual;
  end;

implementation

procedure TPacketBase.InitializeFPacket;
begin
  FillChar(FPacket, SizeOf(FPacket), MarkerChar);
end;

procedure TPacketBase.InitializeFPacketData1;
begin
  InitializeFPacket();
  with FPacket do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  with FPacket do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData2;
begin
  InitializeFPacket();
  with FPacket.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar);
  with FPacket.Data do
    FillChar(Zero, SizeOf(Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData3;
begin
  InitializeFPacket();
  FillChar(FPacket.Data.Contents, SizeOf(FPacket.Data.Contents), SpaceChar);
  FillChar(FPacket.Data.Zero, SizeOf(FPacket.Data.Zero), NullChar);
end;

constructor TPacketWrapper.Create;
begin
  inherited;
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacket;
begin
//[Pascal Error] PacketWrapperUnit.pas(74): E2197 Constant object cannot be passed as var parameter
//  FillChar(Packet, $AA, SizeOf(Packet));
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacketData1;
begin
  InitializePacket();
  with Packet do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  with Packet do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;

procedure TPacketWrapper.InitializePacketData2;
begin
  InitializePacket();
  with Packet.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar);
  with Packet.Data do
    FillChar(Zero, SizeOf(Zero), NullChar);
end;

procedure TPacketWrapper.InitializePacketData3;
begin
  InitializePacket();
//[Pascal Error] PacketWrapperUnit.pas(101): E2197 Constant object cannot be passed as var parameter
//[Pascal Error] PacketWrapperUnit.pas(102): E2197 Constant object cannot be passed as var parameter
//  FillChar(Packet.Data.Contents, SizeOf(Packet.Data.Contents), SpaceChar);
//  FillChar(Packet.Data.Zero, SizeOf(Packet.Data.Zero), NullChar);
end;

end.

So: you can work around error “E2197 Constant object cannot be passed as var parameter” by clerverly(?) using with.

There is a better solution as of Delphi 2005 (CompilerVersion 17): you now have records on methods, so you can work around it by putting the initialization logic there:

unit VariantRecordUnit;

interface

{...}
  TPacket = packed record
    EntryType : Byte;
    ReturnKey : TVariantKey;
    DataType  : Byte;
    Data      : TVariantData;
{$if CompilerVersion >= 17}
  public
    procedure InitializeData;
{$ifend CompilerVersion >= 17}
  end;

const
  MarkerChar = #$AA;
  NullChar = #$00;
  SpaceChar = #$20;

implementation

{$if CompilerVersion >= 17}
procedure TPacket.InitializeData;
begin
  FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;
{$ifend CompilerVersion >= 17}

end.

The cool thing is that before Delphi 2005, the old code used to work, so now you can change the calling code to become this and have it work in all Delphi versions:

unit PacketWrapperUnit;

{...}

procedure TPacketWrapper.InitializePacketData3;
begin
  InitializePacket();
{$if CompilerVersion >= 17}
  Packet.InitializeData();
{$else}
//[Pascal Error] PacketWrapperUnit.pas(104): E2197 Constant object cannot be passed as var parameter
//[Pascal Error] PacketWrapperUnit.pas(105): E2197 Constant object cannot be passed as var parameter
  FillChar(Packet.Data.Contents, SizeOf(Packet.Data.Contents), SpaceChar);
  FillChar(Packet.Data.Zero, SizeOf(Packet.Data.Zero), NullChar);
{$ifend CompilerVersion >= 17}
end;

end.

When porting methods like InitializePacketData1..2 to TPacket to Delphi XE2, I found out that those too will cause the E2197 error. Som the various gradations of with depth trick doesn’t work any more, and you have to use these methods on records.

unit PacketWrapperUnit;

interface

uses
  VariantRecordUnit;

type

  TPacketBase = class(TObject)
  strict private
    FPacket: TPacket;
  strict protected
    procedure InitializeFPacket; virtual;
  public
    procedure InitializeFPacketData1; virtual;
    procedure InitializeFPacketData2; virtual;
    procedure InitializeFPacketData3; virtual;
    property Packet: TPacket read FPacket write FPacket;
  end;

  TPacketWrapper = class(TPacketBase)
  strict private
    procedure InitializePacket;
  public
    constructor Create;
    procedure InitializePacketData1; virtual;
    procedure InitializePacketData2; virtual;
    procedure InitializePacketData3; virtual;
  end;

implementation

procedure TPacketBase.InitializeFPacket;
begin
  FillChar(FPacket, SizeOf(FPacket), MarkerChar);
end;

procedure TPacketBase.InitializeFPacketData1;
begin
  InitializeFPacket();
  with FPacket do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  with FPacket do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData2;
begin
  InitializeFPacket();
  with FPacket.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar);
  with FPacket.Data do
    FillChar(Zero, SizeOf(Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData3;
begin
  InitializeFPacket();
  FillChar(FPacket.Data.Contents, SizeOf(FPacket.Data.Contents), SpaceChar);
  FillChar(FPacket.Data.Zero, SizeOf(FPacket.Data.Zero), NullChar);
end;

constructor TPacketWrapper.Create;
begin
  inherited;
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacket;
begin
//[Pascal Error] PacketWrapperUnit.pas(74): E2197 Constant object cannot be passed as var parameter
//  FillChar(Packet, $AA, SizeOf(Packet));
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacketData1;
begin
  InitializePacket();
  with Packet do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar); //[Pascal Error] PacketWrapperUnit.pas(82): E2197 Constant object cannot be passed as var parameter
  with Packet do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar); //[Pascal Error] PacketWrapperUnit.pas(84): E2197 Constant object cannot be passed as var parameter
end;

procedure TPacketWrapper.InitializePacketData2;
begin
  InitializePacket();
  with Packet.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar); //[Pascal Error] PacketWrapperUnit.pas(91): E2197 Constant object cannot be passed as var parameter
  with Packet.Data do
    FillChar(Zero, SizeOf(Zero), NullChar); //[Pascal Error] PacketWrapperUnit.pas(93): E2197 Constant object cannot be passed as var parameter
end;

procedure TPacketWrapper.InitializePacketData3;
begin
  InitializePacket();
{$if CompilerVersion >= 17}
  Packet.InitializeData();
{$else}
//[Pascal Error] PacketWrapperUnit.pas(104): E2197 Constant object cannot be passed as var parameter
//[Pascal Error] PacketWrapperUnit.pas(105): E2197 Constant object cannot be passed as var parameter
  FillChar(Packet.Data.Contents, SizeOf(Packet.Data.Contents), SpaceChar);
  FillChar(Packet.Data.Zero, SizeOf(Packet.Data.Zero), NullChar);
{$ifend CompilerVersion >= 17}
end;

end.

I think this change was introduced in Delphi 2009, and the PacketWrapperUnit code below shows how to workaround it.

Finally, it is important that you check the various mechanisms to see if they do initialization correctly (for instance: that the initialization of the record is not done on a copy of the record, but actually on the record field itself).

That’s what this tiny main program does (you can of course make this into a Unit Test using DUnit).

–jeroen

Complete source code

Main program

program D2006XE2MigrationExamples;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  VariantRecordUnit in 'VariantRecordUnit.pas',
  PacketWrapperUnit in 'PacketWrapperUnit.pas',
  Classes;

procedure Test(const Context: string; const PacketWrapper: TPacketWrapper; const Method: TThreadMethod);
var
  Character: TChar;
begin
  Writeln(Context);
  Method();
  for Character in PacketWrapper.Packet.Data.Contents do
  begin
    Writeln(Character, Byte(Character));
  end;
end;

var
  PacketWrapper: TPacketWrapper;
begin
  PacketWrapper := TPacketWrapper.Create();
  try
    Test('InitializeFPacketData1', PacketWrapper, PacketWrapper.InitializeFPacketData1);
    Test('InitializeFPacketData2', PacketWrapper, PacketWrapper.InitializeFPacketData2);
    Test('InitializeFPacketData3', PacketWrapper, PacketWrapper.InitializeFPacketData3);
    Test('InitializePacketData1', PacketWrapper, PacketWrapper.InitializePacketData1);
    Test('InitializePacketData2', PacketWrapper, PacketWrapper.InitializePacketData2);
    Test('InitializePacketData3', PacketWrapper, PacketWrapper.InitializePacketData3);
  finally
    PacketWrapper.Free;
  end;
end.

PacketWrapperUnit:

unit PacketWrapperUnit;

interface

uses
  VariantRecordUnit;

type

  TPacketBase = class(TObject)
  strict private
    FPacket: TPacket;
  strict protected
    procedure InitializeFPacket; virtual;
  public
    procedure InitializeFPacketData1; virtual;
    procedure InitializeFPacketData2; virtual;
    procedure InitializeFPacketData3; virtual;
    property Packet: TPacket read FPacket write FPacket;
  end;

  TPacketWrapper = class(TPacketBase)
  strict private
    procedure InitializePacket;
  public
    constructor Create;
    procedure InitializePacketData1; virtual;
    procedure InitializePacketData2; virtual;
    procedure InitializePacketData3; virtual;
  end;

implementation

procedure TPacketBase.InitializeFPacket;
begin
  FillChar(FPacket, SizeOf(FPacket), MarkerChar);
end;

procedure TPacketBase.InitializeFPacketData1;
begin
  InitializeFPacket();
  with FPacket do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  with FPacket do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData2;
begin
  InitializeFPacket();
  with FPacket.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar);
  with FPacket.Data do
    FillChar(Zero, SizeOf(Zero), NullChar);
end;

procedure TPacketBase.InitializeFPacketData3;
begin
  InitializeFPacket();
  FillChar(FPacket.Data.Contents, SizeOf(FPacket.Data.Contents), SpaceChar);
  FillChar(FPacket.Data.Zero, SizeOf(FPacket.Data.Zero), NullChar);
end;

constructor TPacketWrapper.Create;
begin
  inherited;
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacket;
begin
//[Pascal Error] PacketWrapperUnit.pas(74): E2197 Constant object cannot be passed as var parameter
//  FillChar(Packet, $AA, SizeOf(Packet));
  InitializeFPacket();
end;

procedure TPacketWrapper.InitializePacketData1;
begin
  InitializePacket();
{$if CompilerVersion >= 20}
  Packet.InitializeData(); // fix the E2197 tightening introduced in Delphi 2009
{$else}
  with Packet do
    FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  with Packet do
    FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
{$ifend CompilerVersion >= 20}
end;

procedure TPacketWrapper.InitializePacketData2;
begin
  InitializePacket();
{$if CompilerVersion >= 20}
  Packet.InitializeData(); // fix the E2197 tightening introduced in Delphi 2009
{$else}
  with Packet.Data do
    FillChar(Contents, SizeOf(Contents), SpaceChar);
  with Packet.Data do
    FillChar(Zero, SizeOf(Zero), NullChar);
{$ifend CompilerVersion >= 20}
end;

procedure TPacketWrapper.InitializePacketData3;
begin
  InitializePacket();
{$if CompilerVersion >= 17}
  Packet.InitializeData();
{$else}
//[Pascal Error] PacketWrapperUnit.pas(104): E2197 Constant object cannot be passed as var parameter
//[Pascal Error] PacketWrapperUnit.pas(105): E2197 Constant object cannot be passed as var parameter
  FillChar(Packet.Data.Contents, SizeOf(Packet.Data.Contents), SpaceChar);
  FillChar(Packet.Data.Zero, SizeOf(Packet.Data.Zero), NullChar);
{$ifend CompilerVersion >= 17}
end;

end.

VariantRecordUnit:

unit VariantRecordUnit;

interface

{ First a few basic types}

const
  TGuidStringSize = 38;

type
  TChar = AnsiChar; { single byte character, as it interfaces with DOS and CoolGen programs through C interface }
  TChar2    = array[0..   1] of TChar;
  TChar8    = array[0..   7] of TChar;
  TChar10   = array[0..   9] of TChar;
  TChar20   = array[0..  19] of TChar;
  T1Char33 = array[1..33] of TChar; { 1-based because the DOS CAS sources expect this }
  TGuidChar   = array[0..TGuidStringSize-1] of TChar;
  TMessageId = array[0..23] of Byte;

{ now the record types }

type
  TVariantData = record
  case Boolean of
    False: (
      ProgramName: TChar10;
      InterChangeFormat: TChar10;
      FunctionCode: TChar2;
      ReturnCode: TChar2;
      ErrorCode: TChar2;
      Zero: TChar2);
    True: (Contents: T1Char33);
  end; { total: 33 bytes }

  TId = packed record
    NetBiosName: TChar20; { historically, as DOS app defined it wrongly }
    TimeStamp: TChar8; { HHMMSShh because a DOS directory name can be no longer than 8 characters }
  end; { total: 28 bytes }

  TVariantKey = packed record
  case Integer of
    0: ( // SNA
      ConversationId: TId; { 28 bytes }
      GuidChars: TGuidChar); { 38 bytes }
    2: ( // MQ
      ConversationIdFiller: TId;
      MessageId: TMessageID); // 24 bytes
  end; { total: 66 bytes }

  TPacket = packed record
    EntryType : Byte;
    ReturnKey : TVariantKey;
    DataType  : Byte;
    Data      : TVariantData;
{$if CompilerVersion >= 17}
  public
    procedure InitializeData;
{$ifend CompilerVersion >= 17}
  end;

const
  MarkerChar = #$AA;
  NullChar = #$00;
  SpaceChar = #$20;

implementation

{$if CompilerVersion >= 17}
procedure TPacket.InitializeData;
begin
  FillChar(Data.Contents, SizeOf(Data.Contents), SpaceChar);
  FillChar(Data.Zero, SizeOf(Data.Zero), NullChar);
end;
{$ifend CompilerVersion >= 17}

end.

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

Lazarus Team Anouncements: Lazarus 1.0.8 release available for download

$
0
0
The Lazarus team is glad to announce the release of Lazarus 1.0.8.

This is a bug fix release, built with the new fpc 2.6.2. The
previous release 1.0.6 was built with 2.6.0.

Here is the list of changes for Lazarus and Free Pascal:
http://wiki.lazarus.f...

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

I recently had an error like this when building with packages:

[DCC Error] E2201 Need imported data reference ($G) to access 'VarCopyProc' from unit 'SynCommons'

It was a bit hard to find good information about this error, mainly because of two reasons:

  1. the documentation on E2201 Need imported data reference ($G) to access ‘%s’ from unit ‘%s’ isn’t very well written
  2. [dcc error] e2201 need imported data reference ($g) to access ‘varcopyproc’ from unit – Google Search doesn’t yield very good answers

Finally, it was the FastMM and D2007 – Delphi Language BASM – BorlandTalk.com thread pointing me to Hallvard’s Blog: Hack#13: Access globals faster ($ImportedData).

That explained the error was caused by:

  • VarCopyProc being a variable in one package
  • VarCopyProc access being needed from the package that failed to compile
  • Not having {$G+} or {$IMPORTEDDATA ON} in the failing package would prevent that access

Somehow that does not work for all cases. Apparently, the VarCopyProc isn’t exported from the Delphi RTL as that package is compiled in the $G- state.

So I had to add the USEPACKAGES define to the conditional defines list, which forces the SynCommons to use the standard version of the RecordCopy method in stead of a highly optimized one that calls VarCopyProc.

–jeroen


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

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Sometimes, Delphi XE2 gets confused after converting an old Delphi project because the Unit scope names are not correct. When creating a new Delphi XE2 application, the Unit scope names are as follows:

  • System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell

This means that if you don’t prepend a unit with a Unit scope prefix, Delphi will automatically try the list above. The thing is: when importing a Delphi project from an old Delphi version, the Unit scope names are somehow “guessed”, and not always complete:

  • System;Xml;Data;Datasnap;Web;Soap;Winapi

This means it cannot resolve the right name for the VCL units like Controls or Forms, and you get a nice compiler error: But with the default, it cannot resolve the Windows and other units in the Winapi scope. So the list I normally use is one of these:

  • System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;Winapi;System.Win
  • System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;Winapi;System.Win;Bde

(Yes, some apps still store Paradox data locally and use the BDE)

–jeroen


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

Firebird News: The Lazarus team is glad to announce the release of Lazarus 1.0.8.

$
0
0
The Lazarus team is glad to announce the release of Lazarus 1.0.8. This is a bug fix release, built with the current fpc 2.6.2. The previous release 1.0.6 was built with 2.6.0. Here is the list of changes for Lazarus and Free Pascal: http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch#Fixes_for_1.0.8 http://wiki.lazarus.freepascal.org/User_Changes_2.6.2 The release is available for download at SourceForge: http://sourceforge.net/projects/lazarus/files/ Choose [...]

The road to Delphi: Vcl Styles Utils updated to fix QC #114040, #114032 (XE2 and XE3)

$
0
0

I just commit in the Vcl Styles Project two new fixes to patch the QC 114040 and QC 114032 (these issues exist in Delphi XE2 and XE3), both reports are related to the Highlight colors used to draw the TColorBox and TComboBoxEx components when the Vcl Styles are active.

QC 114032

As you can see in the below image the TColorBox component doesn’t use the proper highlight color, but the TColorListBox uses the highlight color of the current Vcl Style.

TColorBoxQC

The TColorBox control doesn’t use a Style Hook, so the fix was done using a interposer class. To apply the path just add the Vcl.Styles.Fixes unit to your uses list after of the Vcl.ExtCtrls unit. And the result will be

TColorBoxFix

QC 114040

The TComboBoxEx control have a similar issue.

TcomboboxExQc

In this case fixing the Style Hook related to the TComboBoxEx control was the key.

TcomboboxExFix

To apply this fix, just register the TComboBoxExStyleHookFix style hook located in the Vcl.Styles.Fixes unit.


TPersistent: California Tops

$
0
0

Just thought I would shout out to all my readers in California who ranked #1 amongst all the US states for visitors to TPersistent, and was the major cause for the US pushing Brazil out of the top spot it’s held for some time.

If any of the EMBT dev team is responsible for the increased numbers, I would like to thank them for their work on my favorite dev tool.  Delphi has come a long way since EMBT acquired it, and although many of my posts might be considered negative, I truly appreciate their efforts.  Especially as of late, since some of my QC items seem to be progressing.  In fact, I reported a new QC item (113570) on March 11th and it was fixed on the 13th.  It doesn’t get any better than that!


The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

While porting a library from Delphi 2006 to Delphi XE2.

The really cool thing is that the Windows Event Log contains details of what I did wrong (:

  • 2277 (08E5) (RC2277): MQRC_CD_ERROR
    Oops, typo on the header file.The MQCD structure supplied was not valid.The value of the ‘CLWLChannelWeight’ field has the value ’0′. This value is invalid for the operation requested.Change the parameter and retry the operation.
  • 2538 (09EA) (RC2538): MQRC_HOST_NOT_AVAILABLE
    Oops, typo in the host name (:Remote host ‘Host.Domain’ not available, retry later.The attempt to allocate a conversation using TCP/IP to host ‘Host.Domain’ for channel WebSphereMQChannelName was not successful. However the error may be a transitory one and it may be possible to successfully allocate a TCP/IP conversation later. &P In some cases the remote host cannot be determined and so is shown as ‘????’.Try the connection again later. If the failure persists, record the error values and contact your systems administrator. The return code from TCP/IP is 11001 (X’0′). The reason for the failure may be that this host cannot reach the destination host. It may also be possible that the listening program at host ‘Host.Domain’ was not running. If this is the case, perform the relevant operations to start the TCP/IP listening program, and try again.
  • 2009 (07D9) (RC2009): MQRC_CONNECTION_BROKENTwo causes:

    - The service job on the AS/400 restarted; need to make the client more robust so it gracefully handles this.
    - WebSphere MQ 7.x needs different initialization than WebSphere MQ 5.x, I didn’t get some of the extra fields initialized correctly.
    Connection to host ‘Host (dot.ted.ip.addr)(TCPPort)’ for channel ‘WebSphereMQChannelName’ closed.An error occurred receiving data from ‘Host (dot.ted.ip.addr)(TCPPort)’ over TCP/IP. The connection to the remote host has unexpectedly terminated. &P The channel name is ‘WebSphereMQChannelName’; in some cases it cannot be determined and so is shown as ‘????’.

    Tell the systems administrator.

  • a
  • a
  • a
  • a
  • a
  • a
  • a
  • a
  • a
  • a
  • a

–jeroen


Filed under: Delphi, Delphi XE2, Development, MQ Message Queueing/Queuing, Software Development, WebSphere MQ

DelphiTools.info: What client-side platforms do you develop for?

$
0
0

What client-side platforms do you develop for? With Delphi/FreePascal or with other tools.

This is a small poll to gauge the audience of this website, check all applicable, but please limit yourself to those you personally develop for (be it work or hobby), not your company or colleagues.

Note: There is a poll embedded within this post, please visit the site to participate in this post's poll.

Lazarus Team Anouncements: Open position for web page admin

$
0
0
Hello

There has been discussion about improving the main page
  http://www.lazarus.freepascal.org
over the years. It cannot be improved with patches like other parts of Lazarus and its documentation can, so nothing has happened.
I see it as a black spo...

Firebird News: Security Updates for Firebird 2.5.2 and Firebird 2.1.5 are released

$
0
0
The Firebird Project releases important security updates addressing a remote stack buffer overflow discovered in the Firebird Server during March, 2013. This vulnerability allows an unauthenticated user to crash the server and opens a gate for remote code execution, so it’s highly recommended to upgrade your server installations. Security updates are available for Firebird 2.5.2 and Firebird [...]

The road to Delphi: Introducing TSMBIOS

$
0
0

logoA few weeks ago I started a new project called TSMBIOS, this is a library which allows access the SMBIOS using the Object Pascal language (Delphi or Free Pascal).

What is the SMBIOS?

SMBIOS stands for System Management BIOS , this standard is tightly related and developed by the DMTF (Desktop Management Task Force).

The SMBIOS contains a description of the system’s hardware components, the information stored in the SMBIOS typically includes system manufacturer, model name, serial numbers, BIOS version, asset tag, processors, ports, device memory installed and so on.

Note : The amount and accuracy of the SMBIOS information depends on the computer manufacturer.

Which are the advantages of use the SMBIOS?

  • You can retrieve the information without having to probe for the actual hardware. this is a good point in terms of speed and safeness.
  • The SMBIOS information is very well documented.
  • You can avoid the use of undocumented functions to get hardware info (for example the RAM type and manufacturer).
  • Useful for create a Hardware ID (machine fingerprint).

How it works?

The BIOS typically populates the SMBIOS structures at system boot time, and is not in control when the OS is running. Therefore, dynamically changing data is rarely represented in SMBIOS tables.

The SMBIOS Entry Point is located somewhere between the addresses 0xF0000 and 0xFFFFF, in early Windows systems (Win95, Win98) it was possible access this space address directly, but after with the introduction of the NT Systems and the new security changes the BIOS was accessible through section \Device\PhysicalMemory, but this last method was disabled as well in Windows Server 2003 Service Pack 1, and replaced with 2 new WinApi functions the EnumSystemFirmwareTables and GetSystemFirmwareTable, Additionally  the WMI supports reading the entire contents of SMBIOS data i using the MSSMBios_RawSMBiosTables class inside of the root\wmi namespace.

Note : you can find more information about the SMBIOS Support in Windows on this link.

The TSMBIOS can be compiled using a WinApi mode (uses the GetSystemFirmwareTable function) or using the WMI Mode (uses the MSSMBios_RawSMBiosTables class)

If you uses the WinApi Mode you  don’t need use COM and the final size of the Application will be smaller, but the WinAPI functions was introduced in Windows Vista and Windows XP x64 (So in Windows Xp x86 will fail). Otherwise using the WMI mode you will need use COM (CoInitialize and CoUninitialize), but also you will get two additional advantages 1) The WMI will work even in Windows Xp x86 systems, 2) You can read then SMBIOS data of local and remote computers.

In order to use the TSMBIOS in your application only you must add the uSMBIOS unit to your uses clause, then create a instance for the TSMBios class using the proper constructor

// Default constructor, used for populate the TSMBIOS class  using the current mode selected (WMI or WinApi)
constructor Create; overload;
// Use this constructor to load the SMBIOS data from a previously saved file.
constructor Create(const FileName : string); overload;
{$IFDEF USEWMI}
// Use this constructor to read the SMBIOS from a remote machine.
constructor Create(const RemoteMachine, UserName, Password : string); overload;
{$ENDIF}

and finally use the property which expose the SMBIOS info which you need. In this case as is show in the sample code the BatteryInformation property is used to get all the info of the batteries installed on the system.

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils,
  uSMBIOS in '..\..\Common\uSMBIOS.pas';

procedure GetBatteryInfo;
Var
  SMBios : TSMBios;
  LBatteryInfo  : TBatteryInformation;
begin
  SMBios:=TSMBios.Create;
  try
      WriteLn('Battery Information');
      WriteLn('-------------------');
      if SMBios.HasBatteryInfo then
      for LBatteryInfo in SMBios.BatteryInformation do
      begin
        WriteLn('Location           '+LBatteryInfo.GetLocationStr);
        WriteLn('Manufacturer       '+LBatteryInfo.GetManufacturerStr);
        WriteLn('Manufacturer Date  '+LBatteryInfo.GetManufacturerDateStr);
        WriteLn('Serial Number      '+LBatteryInfo.GetSerialNumberStr);
        WriteLn('Device Name        '+LBatteryInfo.GetDeviceNameStr);
        WriteLn('Device Chemistry   '+LBatteryInfo.GetDeviceChemistry);
        WriteLn(Format('Design Capacity    %d mWatt/hours',[LBatteryInfo.RAWBatteryInfo.DesignCapacity*LBatteryInfo.RAWBatteryInfo.DesignCapacityMultiplier]));
        WriteLn(Format('Design Voltage     %d mVolts',[LBatteryInfo.RAWBatteryInfo.DesignVoltage]));
        WriteLn('SBDS Version Number  '+LBatteryInfo.GetSBDSVersionNumberStr);
        WriteLn(Format('Maximum Error in Battery Data %d%%',[LBatteryInfo.RAWBatteryInfo.MaximumErrorInBatteryData]));
        WriteLn(Format('SBDS Version Number           %.4x',[LBatteryInfo.RAWBatteryInfo.SBDSSerialNumber]));
        WriteLn('SBDS Manufacture Date  '+LBatteryInfo.GetSBDSManufactureDateStr);
        WriteLn('SBDS Device Chemistry  '+LBatteryInfo.GetSBDSDeviceChemistryStr);
        WriteLn(Format('OEM Specific                  %.8x',[LBatteryInfo.RAWBatteryInfo.OEM_Specific]));
        WriteLn;
      end
      else
      Writeln('No Battery Info was found');
  finally
   SMBios.Free;
  end;
end;

begin
 try
    GetBatteryInfo;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

TSMBIOS Features

  • Source Full documented compatible with the help insight feature, available since Delphi 2005.
  • Supports SMBIOS Version from 2.1 to 2.7.1
  • Supports Delphi 2005, BDS/Turbo 2006 and RAD Studio 2007, 2009, 2010, XE, XE2, XE3.
  • Compatible with FPC 2.6.0 (Windows and Linux)
  • SMBIOS Data can be obtained using WinApi, WMI or loading a saved SMBIOS dump
  • SMBIOS Data can be saved and load to a file
  • SMBIOS Data can be obtained from remote machines

SMBIOS Tables supported

The TSMBIOS is a Open Source project is hosted in the code google site.


Viewing all 1725 articles
Browse latest View live