(2015/06/01~)
2015/06/02

MyBase と FireDAC のインメモリテーブル

Google 先生からも Bing からもハブられ、サイト更新モチベーション絶賛低下中です。そんな事はどうでもいいですが、先日のデブキャンにおける田中さんのセッションは非常に参考になりました。

さて、インメモリテーブルなら FireDAC でなくとも DBX4 でも使えました…これは MyBase と呼ばれています。

では FireDAC のインメモリテーブルは積極的に使う理由がないのでしょうか?これがあるんですねー。なんと FireDAC のインメモリテーブルでは SQL が使えます

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, uInMemTableUtils;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    InMemTable: TInMemoryTable;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  // インメモリテーブルの準備
  InMemTable := TInMemoryTable.Create(Self);
  // メモリテーブルを登録
  InMemTable.AddDataSet(0'TEST');                // テーブル名は 'TEST'
  // メモリテーブルの準備
  with InMemTable.MemTables[0do
    begin
      FieldDefs.Add('ID'  , ftInteger,     0, False);
      FieldDefs.Add('Name', ftWideString, 20, False);
      CreateDataSet;
    end;
  // 接続
  InMemTable.Connect;
  // DBGrid にデータソースを設定
  DBGrid1.DataSource := InMemTable.DataSources[0]; // DataSources[0] は Queries[0] のデータソース
  // 選択クエリーを実行
  with InMemTable.Queries[0do
    begin
      SQL.Clear;
      SQL.Add('SELECT * From TEST');
      Open;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  // 挿入クエリーを実行
  with InMemTable.Queries[1do
    begin
      SQL.Clear;
      SQL.Add('INSERT INTO TEST (ID, NAME) VALUES (1, "ABC")');
      ExecSQL;
    end;
  // 表示用のクエリーを更新
  InMemTable.Queries[0].Refresh;
end;

end.

インメモリテーブルを簡単に使うためのユニット uInMemTableUtils を作ってみました。フォームには DBGrid とボタンが二個貼ってあり、Button1 を押すと DB に接続し、Button2 を押すとデータが Insert されます。このサンプルではテーブルが一つしかありませんが、複数のテーブルを作って結合クエリを実行する事もできます。

接続はこのようになっています。各コントロールの Connection プロパティを TFDConnection に設定し、仮想テーブルである TFDMemTable を TFDLocalSQL に登録すると、TFDQuery で TFDMemTable が DB のテーブルであるかのように使えるようになります。ローカル SQL のエンジンとしては SQLite が使われています…つまり、このインメモリテーブル機構は FireDAC C/S パックなしの Professional 版でも使えます (XE5 以降)。

インメモリテーブルの用途は主に他データベースのワークとなるでしょう。テーブルのファイルは作られませんが (インメモリなので)、作りたいのなら作る事も可能です。田中さんのセッション資料を今一度確認してみてください、面白い用途を思い付くかもしれませんよ。

ぇ?「素直に SQLite 使え!」ってですか?ローカル SQL は "あらゆる TDataSet 派生データセットのワークに使える (BDE / IBX/ dbGo / DBX4 / FireDAC etc...)" ってトコに真価があると思っているのですが…!?

See Also:


2015/06/09

ドメイン取得

Google 先生からも Bing からもハブられたので、協議の結果ドメインを取得する事に相成りました。ht-deko.com です。このサイトや Delphi Forum の RSS をご利用の方は変更をお願い致します。

Delphi XE7 で FireUI のカスタムビューを作る。

XE7 で FireUI が実装され、マルチな解像度のフォームを作ることができるようになりました。FireUI を簡単に言えば解像度毎の継承フォームです。

では AQUOS K (SHF31) のカスタムビューを作ってみましょう。まずはカタログスペックから画面の解像度を拾っておいてください。SHF31 の画面解像度は 540x960 です。次に、Android アプリケーションを作ります。フォームに alClient で TMemo を貼り、Form の OnShow イベントハンドラを記述します。全体的なコードは以下のようになります。

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormShow(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
  System.TypInfo, System.Devices, FMX.Platform, System.Rtti;

procedure TForm1.FormShow(Sender: TObject);
var
  disp: IFMXDeviceMetricsService;
  dev: IFMXDeviceService;
  devCls: TDeviceInfo.TDeviceClass;
begin
  OnShow := nil;
  if TPlatformServices.Current.
    SupportsPlatformService(IFMXDeviceMetricsService) then
  begin
    disp := IFMXDeviceMetricsService(
      TPlatformServices.Current.GetPlatformService(IFMXDeviceMetricsService));

    Memo1.Lines.Add(Format('Physical: %dx%d',
      [disp.GetDisplayMetrics.PhysicalScreenSize.cx,
      disp.GetDisplayMetrics.PhysicalScreenSize.cy]));
    Memo1.Lines.Add(Format('PPI: %d',
      [disp.GetDisplayMetrics.PixelsPerInch]));
  end;

  if TPlatformServices.Current.SupportsPlatformService(IFMXDeviceService) then
  begin
    dev := IFMXDeviceService(TPlatformServices.Current.GetPlatformService(
       IFMXDeviceService));
    devCls := dev.GetDeviceClass;
    Memo1.Lines.Add('Class: ' + GetEnumName(TypeInfo(TDeviceInfo.TDeviceClass),
       ord(devCls)));
  end;

  // Will return 0x0 if the screen is off
  Memo1.Lines.Add(Format('Logical: %dx%d', [Self.Width, Self.Height]));

end;

end.

これを実機に転送して実行してください。

追記: GetResolutionInfo というツールを作成しました。物理画面解像度の取得ができるようになっているのと、論理解像度が 0x0 で返らないようになっています。

実際に実行した結果が以下になります。

画面解像度 540x960
物理解像度 540x864 (ボタン領域が引かれている)
論理解像度 360x540 (ボタン領域と通知領域が引かれている)
PPI 328
デバイスクラス スマートフォン

この情報を元に、%APPDATA%\Embarcadero\BDS\15.0 にある MobileDevices.xml を書き換えます。最後辺りに以下を追加してください。

        <MobileDevice>
                <Name>shf31</Name>
                <DevicePlatform Default="False">3</DevicePlatform>
                <Portrait Enabled="True" Width="360" Height="604" Top="140" Left="41" StatusbarHeight="64" StatusBarPos="1" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\15.0\Artwork\shf31_normal.png"/>
                <UpsideDown Enabled="True" Width="360" Height="604" Top="310" Left="41" StatusbarHeight="64" StatusBarPos="1" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\15.0\Artwork\shf31_reverse.png"/>
                <LandscapeLeft Enabled="True" Width="640" Height="324" Top="77" Left="274" StatusbarHeight="64" StatusBarPos="3" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\15.0\Artwork\shf31_Left.png"/>
                <LandscapeRight Enabled="True" Width="640" Height="323" Top="77" Left="103" StatusbarHeight="64" StatusBarPos="3" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\15.0\Artwork\shf31_right.png"/>
                <Displayname>AQUOS K (SHF31/SHF32)</Displayname>
                <UserData>True</UserData>
                <FormFactor>2</FormFactor>
        </MobileDevice>

値の意味は MobileDevices.xml の要素(DocWiki) で確認してください。

そしてカスタムビュー用の画像を用意します。クライアント領域のサイズが論理解像度と一致するように作るのがミソです。例ではボタン領域 (ステータスバー) を考慮してありますが、XE8 の [マルチデバイスプレビュー] でのプレビューが少々アヤしいので、ボタン領域 (ステータスバー) は指定せず、単純にクライアント領域 (通知領域とタスクバー領域を除いたもの) を指定した方がいいかもしれません…現状ではステータスバー部の指定に何の意味もありませんし。

画像ファイルは %APPDATA%\Embarcadero\BDS\15.0\Artwork に置く事にします (どこでもいいのですが)。画像ファイル (アートワーク) は必須ではありませんが、雰囲気が出るので用意したほうがいいでしょう (XE7 では必須ではありませんが、XE8 では必須です)。画像の種類は普通の PNG で構いません。画像ファイルを用意しない場合には、XML の Top / Left は 0 を指定します。

次にパッケージを作ります。パッケージに以下のユニットを追加し、コンパイルしてインストールします。

unit uSHF31Reg;

interface

implementation

uses
  system.Devices, system.Types, system.SysUtils;

const
  ViewName = 'shf31'// カスタムビューの名前 (識別子)

initialization
  TDeviceinfo.AddDevice(
    TDeviceinfo.TDeviceClass.Phone, // デバイスクラス
    ViewName,                       // カスタムビュー名
    TSize.Create(540864),         // 物理スクリーンサイズ (Width, Height)
    TSize.Create(360540),         // 論理スクリーンサイズ (Width, Height)
    TOSVersion.TPlatform.pfAndroid, // プラットフォーム
    328);                           // PPI

finalization
  TDeviceinfo.RemoveDevice(ViewName);

end.

ViewName の定数と XML の <Name></Name> は一致させておく必要があります。デバイスクラスが Phone になっていますが、タブレットの場合には Tablet となります。その他は収集したデータを突っ込むだけです。

ここまでできれば、新規作成でマルチデバイスアプリケーションを作って SHF31 用のカスタムビューを利用することができます。

実機で (実行時に) カスタムビューを使うには、アプリケーションのプロジェクトにパッケージで使用したユニット (*.pas) を追加する必要があります

Delphi XE8 で FireUI のカスタムビューを作る。

XE8 はもっと簡単です。[デバイスマネージャ] でカスタムビューを追加できるので XML に自分で追記する必要はありません (パッケージ以降の作業は XE7 と同じ)。

イメージマップを GUI で操作できます…無駄に使いやすいです (褒め言葉)。

XE8 での注意点としては、画像ファイル (アートワーク) が必須なのと、XML にビュー名が自動で付加される (UUID のような数値の羅列) ので、%APPDATA%\Embarcadero\BDS\16.0\DevicePresets.xml を開いてこれを控えておかなければなりません…何というか片手落ちですね。

        <MobileDevice>
                <Name>2273C9B9F2EB4ED0BB6BF60D2A228964</Name>
                <DevicePlatform Default="False">3</DevicePlatform>
                <Portrait Enabled="True" Width="360" Height="540" Top="140" Left="41" StatusbarHeight="0" StatusBarPos="1" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0\Artwork\shf31_normal.png"/>
                <UpsideDown Enabled="True" Width="360" Height="540" Top="310" Left="41" StatusbarHeight="0" StatusBarPos="1" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0\Artwork\shf31_reverse.png"/>
                <LandscapeLeft Enabled="True" Width="576" Height="324" Top="77" Left="274" StatusbarHeight="0" StatusBarPos="3" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0\Artwork\shf31_Left.png"/>
                <LandscapeRight Enabled="True" Width="576" Height="323" Top="77" Left="103" StatusbarHeight="0" StatusBarPos="3" Artwork="C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0\Artwork\shf31_right.png"/>
                <Displayname>AQUOS K (SHF31/SHF32)</Displayname>
                <UserData>True</UserData>
                <FormFactor>2</FormFactor>
                <Thumbnail>C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0\Thumbs\2273C9B9F2EB4ED0BB6BF60D2A228964</Thumbnail>
        </MobileDevice>

値の意味は DevicePresets.xml の要素(DocWiki) で確認してください。XE7 と XE8 で編集する XML ファイルの名前が違う事に注意してください。

…なので、カスタムビュー登録ユニットの ViewName 定数を変更するか、XML の方を書き換える必要があります…ちなみに、XML の方を書き換えても [デバイスマネージャ] で保存するとまた書き換わってしまうので、編集できないように <UserData>False</UserData> に変更しておくといいでしょう。

また、XE8 では[マルチデバイスプレビュー]が追加されており、[デバイスマネージャ] で XML を生成するとマルチデバイスプレビュー用のサムネイルが自動生成されるため、XML に直接追記するのはやめておいたほうがいいかもしれません。

追記: カスタムビューを登録できるスレッドを Delphi Forum に作っておきました。SHF31 用のカスタムビューもこちらにアップしてあります。

See Also:

デブキャン関連

ビデオと資料が出揃ったようなので、"とりあえず、デベロッパーキャンプの資料を読んでみようか。" を更新してあります…神様ェ。


2015/06/21

XE8 Update1

RAD Studio XE8 用の Update1 がリリースされました。

アップデートサブスクリプション加入者向けと未加入者向けがあります。

今更言うまでもない事かもしれませんが、Update1 はアップデートという名のフルインストーラなので、XE8 無印をアンインストールしてからインストールします (されます)。XE8 無印でインストールした時の Slip ファイルが C:\ProgramData\Embarcadero に残っているので、これを Update1 インストーラで指定すればシリアル入力&再アクティベーションを回避できます。

※ アップデートサブスクリプション未加入者向けの Update1 はフルインストーラではありません。アップデータです。

XE8 Update1 のイロイロ

* アップデートサブスクリプション未加入者向けの General Update1 でも提供されている機能です。

Android Screen View

この雑談では書いていなかったのを思い出しました。

これは Android Screen View というアプリケーションで、adb 接続された端末の画面をキャプチャしてくれるものです。軽いので Android のスクショにはもっぱらこれを使っています。エンバカさんの Youtube 動画などにたまに出てきます。

少々使いにくいトコもありますが、大した問題ではないのです…何故ならこのアプリは Delphi 製 (FireMonkey) で、ソースコードも公開されているからです。ソースコードは XE5 用のものですが XE8 でも特に問題なくコンパイルできました。

コンパイル済バイナリも配布されていますが、僕も独自ビルドしました。改変版の変更点は以下の通りです。

改変版のダウンロードはこちらからどうぞ。

See Also:

Component Initializer

単にコンポーネントの初期化を行うだけであれば、Delphi 3 からできる方法があります…覚えてないですか?

  1. 任意のコンポーネントをフォームデザイナに貼る (複数でも可)
  2. プロパティを変更する。
  3. 任意のコンポーネントを選択する (複数でも可)
  4. [コンポーネント | コンポーネントテンプレートの作成]
  5. テンプレートに任意の名前を付ける
  6. ツールパレットの [Templates] にテンプレートが登録される。
  7. コンポーネントツールバーの方は場合によっては IDE がリフレッシュされた時に [Templates] に表示される (例えば [新規作成 | VCL アプリケーション] を行った時) 。

このようにして、プロパティを変えただけのコンポーネントをテンプレートとして保存すればよいのです。テンプレートを削除するにはツールパレットからテンプレートアイコンを右クリックして ["(テンプレート名)" ボタンの削除] を行います。

ちなみに僕は一時期自作ツールでコンポーネントの初期化をやっていましたが、今はやってません…何故って複数のバージョンの Delphi を使っていると面倒なのです…設定をエクスポートする方法がないし、エクスポートできたとしてもバージョンによってプロパティが増減していたりするからです。

さて、Component Initializer の場合にはそれだけではなくもっと柔軟な運用ができます。

Component Initializerのちょっと便利な使い方。 http://t.co/eE36SQZ9dw #delphi_jp

— Lyna (@lynatan) 2015, 6月 20

続きは Web で (w

XE8 Update1 と FireUI カスタムビュー

XE8 無印の時は [マルチデバイスプレビュー] 用にサムネイルが生成されていましたが、XE8 Updatw1 ではファイルとしてのサムネイルが生成されなくなったようです。%APPDATA%\Embarcadero\BDS\16.0\DevicePresets.xml からも記述が消えていますし、%APPDATA%\Embarcadero\BDS\16.0\Thumbs にもサムネイルキャッシュが作られません。

また、XE8 無印の時は XML 中に相対パスや環境変数が使えなかったのですが、Update1 では $(BDSCOMMONDIR) のような環境変数が使えるようになったようです (相対パスは使えません)。なので IDE で環境変数 BDSCUSTOMVIEW を C:\Users\(アカウント名)\AppData\Roaming\Embarcadero\BDS\16.0 に設定しておき、

        <MobileDevice>
                <Name>shf31</Name>
                <DevicePlatform Default="False">3</DevicePlatform>
                <FormFactor>2</FormFactor>
                <Portrait Enabled="True" Width="360" Height="540" Top="140" Left="41" StatusbarHeight="0" StatusBarPos="1" Artwork="$(BDSCUSTOMVIEW)\Artwork\shf31_normal.png"/>
                <UpsideDown Enabled="True" Width="360" Height="540" Top="310" Left="41" StatusbarHeight="0" StatusBarPos="1" Artwork="$(BDSCUSTOMVIEW)\Artwork\shf31_reverse.png"/>
                <LandscapeLeft Enabled="True" Width="576" Height="324" Top="77" Left="274" StatusbarHeight="0" StatusBarPos="3" Artwork="$(BDSCUSTOMVIEW)\Artwork\shf31_Left.png"/>
                <LandscapeRight Enabled="True" Width="576" Height="323" Top="77" Left="103" StatusbarHeight="0" StatusBarPos="3" Artwork="$(BDSCUSTOMVIEW)\Artwork\shf31_right.png"/>
                <Displayname>AQUOS K (SHF31/SHF32)</Displayname>
                <UserData>True</UserData>
                <Thumbnail>$(BDSCUSTOMVIEW)\Thumbs\shf31</Thumbnail>
        </MobileDevice>

このような指定ができるようになりました。カスタムビューを他の人に配布するのが簡単にできるようになりましたね (XML は手動で編集しなきゃですけど)。


2015/06/26

ソースコードを UTF-8 にする。

ソースコードのデフォルトを UTF-8 にするプラグインをらいなタンさんが作られました。

UTF8ize Plugin。 http://t.co/S9KAcyzgeT #delphi_jp

— Lyna (@lynatan) 2015, 6月 18

ソースコードを UTF-8 にするメリットは元記事にも書いてありますが、コンパイル速度が上がります。実はもう一つあって、ファイル検索の速度も上がります。日本語を検索するとたまに検索から漏れたりしませんか?実はアレも直ります (もう一つじゃねーじゃねーか)。

さて、このプラグインとは別にプロジェクトのソースコードを UTF-8 に変換するツールを作りました。

コンソールアプリケーションで、自前でコンパイルする必要があります。使い方は書いてある通りですが、海外のドイツ語やロシア語で書かれたソースコードもコードページを指定して変換できるので文字化けがなくなります。

XE8 発売キャンペーン

6/28 迄となっていますのでお早めに。

まぁ、アップデートサブスクリプションに加入する事をオススメしますけれど。


 BACK   古いのを読む   新しいのを読む