(08/12/01~)

08/12/04

お江戸
 未だにお江戸に居ります。でも、明日には帰ります。

第11回エンバカデロ・デベロッパーキャンプ
 参加してきました。もうバレバレですが講師として。

 SE みたいな事は確かにやりますが、営業地域が殆ど九州なのでプレゼンやっても熊本弁で全然 OK なのですが、セッション開始 10 秒は頭の中が真っ白になりましたね。

「やっべ、フランクな標準語(モドキ)以外知らねーし。」

 私だって、いちデベロッパー (開発者) であり、"社内ニート" に等しい生活をしてますから、喋りが上手い訳もなく。普段は熊本弁なので、ガイジンサンが日本語喋るようなもんですよ (脳内翻訳が追いつきません!!)。参加者の方達を見ながら、「オイラ、そっち側の人間なんだけど?」と何度思った事か。エンバカさんも、チャレンジャーというかなんというか...ともあれ、お聞き苦しい点があった事をお詫びしておきます m(_ _)m

 小ネタも用意してあったのですが、披露できたのは "タイ語の話" 位のものでした (後日、詳細を書きます)。実際に動作する業務アプリのスケルトン (2007 / 2009 用で全く同じ動作をする) は不発。数時間前にエンバカの高橋さんが 「デモすると時間が足りなくなります」 「何故か動かなかったりします」 と言っていましたが、まさにその通り。その日の朝5時に動作確認して、VM で状態保存、実機で休止状態を保って現地入りしても動きませんか、そうですか。

 G7 の直前に藤井さんが動画を流していましたが、そういえば "Unicode の話 (習作)" なんてのがありましたね。これは "吉(𠮷)野家コピペ" のパロな FLASH で、元となった投稿は 2001 年に行われています (FLASH が何時作られたのかは知りませんが)。"サロゲートペアと吉(𠮷)野家" の組み合わせってのは、「座布団一枚」です。でもコレを流した所で、元ネタ知らないとドン引きだろうしなぁ。

 講師という点を除いてみれば、久しぶりにイロイロな方に会えましたし、totonica さん にもお初にお目に掛かれましたし、とても有意義でした。

 伝え足りなかった事もありますので、エクストラセッションは後日このサイトでやる事にします。


08/12/05

エクストラセッション
 CP874 という特殊なコードページがあります。これはタイ語で、Windows がネイティブ対応している ANSI コードページです。CP874 のコード表を確認してみましょう。0xD0 辺りから変な文字が並んでいますね?とりあえず気にせずに以下の文字列を見てみましょう。

สวัสดี

 これは「サワディー」という挨拶の文で、意味は「こんにちは」です。本来はこの後に男性/女性で別の言葉が続くのですが、例文なので「サワディー」だけにしておきます。さっきのコード表をもう一度確認してみましょう。え?2 文字目と 4 文字目に該当する文字が表に見当たらない?そんなハズはありません。CP874 は SBCS なので、0x00~0xFF の範囲にあるハズです。もう一度よーく見てみましょう。

 ...気付きましたか?タイ語は ANSI でも結合文字で表されるという事に。「サワディー」を Unicode のコードポイントで表すと "U+0E2A U+0E27 U+0E31 U+0E2A U+0E14 U+0E35" になります。ANSI (CP874) だと、"0xCA 0xC7 0xD1 0xCA 0xB4 0xD5" です。あなたはもう一つ既成概念を捨てなくてはなりません。

"SBCS ではバイト単位で文字を切り出せる" というのは誤った認識です

 多言語化を考えた場合、Unicode から CP874 (ANSI) へコンバートしてタイ語を扱うのと、ANSI のままタイ語に対応するのとどっちが楽なのでしょうね?少なくともタイ語は例外的に "結合文字列の見かけ上の1文字は1文字として扱う" のがベストのように思えるのですが?

 それと、私も勘違いしていたようですが、タイ語の結合文字列に対応する合成文字は存在しないようです。いずれにせよ、世界中の ANSI 文字を調べて、ANSI で多言語化アプリケーションを作るのはまず無理です。Unicodeであってもタイ語のように一筋縄ではいかないものもありますが、少なくとも Unicode アプリケーションの方が例外処理は少なくて済むハズです。

Extending Delphi 2009 With OpenTools API: Getting Started
 うぉう!! OTA の記事が!!

ってな感じでサッパリでしたが、ここへきてマトモな記事が。是非、記事の翻訳を願いたいものです。

デブキャン関係者のその後

 時間が許せば、また皆さんと実際にお会いしたいですねぇ。

デベロッパー・ワークショップ
 今回のデブキャン...つーか、僕のセッション。自分が喋る時間が少なくなるというリスクを冒して「挙手によるインタラクティブ性」を持たせようとした。

 開発者ってのは少なからずプライドが高く、一家言を持っているヒトも少なくない。コードを書いていて「俺スゲー」と自画自賛し、ふと我に返って恥ずかしくなってしまうという経験を持つ方も少なくないようだ。職人タイプの開発者はいぶし銀というか、渋いんだけど、積極性/協調性に欠けるんだけど、(いい意味で) 確固とした信念はあるという。挙手という最小限のコミュニケーションではあるけれど、普段喋らない方の意思を引き出してみたかった。

 そして確信したのだけれども、一度"ワークショップ"やった方がよくない?あらかじめ議題を決めておいて、各自資料を持ち寄って...って奴。

 だってさ、Delphi 2009 のマニュアルって何ページあると思う?33,688 頁あんのよ?これにはレポートツール/インストーラなんかのサ-ドパーティ製品は含まれないから、もう Delphi の機能を一人で把握するのは無理な訳。世の中の映画をすべて観るのが不可能なのと同じレベル。つまり、誰かの助け (クチコミ情報の類) がどうしても必要って事。

 デブキャンはいわばマスコミュニケーションで、重要情報を一斉に伝播させるには有効だけれども、内容が偏ってしまうのは否めない。で、得意分野ってのは開発者それぞれ微妙に違うんだから、ちょっとしたネタを少しづつでも持ち寄れば、「その情報/手法は知らんかった!」てな話になりはしないかと。要はパーソナルコミュニケーションって奴ね。

 自分では当たり前だと思ってるテクニックが、他の人間から見たら 「目からウロコ」 「あんた神!!」 と思えるかもしれない。自分を評価していないのは、他ならぬ自分自身かもしれない。そんな潜在的な重要情報を引き出す手段がないものかと思案中だったりする。

 あなたにも一家言あるんじゃないんすか?ゲロっちゃってくださいよ。是非。

まぁ聴け。
 "やがていつか自分の子供が生まれ、彼に何を与えてあげられるのか... I don't know. 伝えたい"
 この歌詞で何か思うトコロがあったらアクションを起こすべき。


08/12/06

第 11 回エンバカデロ・デベロッパーキャンプの感想
 私が参加 (予定も含む) したセッションは以下の通り。

 その後、コーヒーショップで場外バトルと相成りました。

Delphi のパッケージ
 レジストリの "HKEY_CURRENT_USER\Software\CodeGear\BDS\6.0\Library" と "HKEY_CURRENT_USER\Software\CodeGear\BDS\6.0\Disabled Packages" を保存 / 読込する事でパッケージを切り替えられる (D2007 なら "HKEY_CURRENT_USER\Software\Borland\BDS\5.0")。ランチャを作ってレジストリの情報を読み込んだ後で Delphi を起動するようにすればいいのかも。プロジェクト毎に別パッケージにしないのは "プロジェクトグループ" の概念があるからだと思う。

 2008/12/12 追記:
 詳細情報は こちら に記載しておきましたので、ご参考下さい。

IBX + Firebird で Unicode
 この組み合わせで Uniocode 対応データベースアプリケーションが作れる。Firebird で DB を作成する時に文字コードとして "UNICODE_FSS" を指定し、IBX の TIBDatabase の Params に "lc_ctype=UNICODE_FSS" を指定するだけ。後は AsString で Unicode 文字列を普通に読み書きできる (ちなみに "UNICODE_FSS" は内部表現 "UTF-8"。但し、Interbase / Firebirdの バージョンによっては 3 バイト文字までしか使えない = BMP のみの対応となる)。問題になるのはどっちかと言えば表示用のフォントだと思う。

 デブキャンの自セッションで不発だったのは "D2007 + Firebird + IBX" の ANSI アプリケーションと、全く同等の動作をする "D2009 + Firebird + IBX" な Unicode アプリケーションだった事を付け加えておきます。


08/12/07

IBConsole 日本語版+α
 リリース。Delphi 2009 で作成した "Unicode Edition" を追加しました。人柱気味なので、ANSI 版との併用をオススメします。

 挙動不審だったので調べてみたら、IBX のバグでした (リリースが遅れたのはそのためです)。普通に IBX を使う分にはこのバグに遭遇するとは思えませんが、近々 QC に投稿しておく事にします。

・Firebird 2.1 の "UNICODE_FSS"
 先述の通り、Interbase / Firebir dの "UNICODE_FSS" は "3 バイト迄の UTF-8" なのだけれど、少なくとも Firebird 2.1 の "UNICODE_FSS" は サロゲートペアを入出力可能...つまりは "4 バイトの UTF-8" となっている。接続文字列 "UTF8" と内部実装は同じなのかもしれない、単にエリアスってだけで。


08/12/08

Interbase/Firebird の Unicode
 (知ってる方は知っている) minon さんから重要な情報を Get。

 ナルホド。IB2009 は "UNICODE_FSS = 3 バイト (BMP のみ) の UTF-8"、"UTF8 = 4 バイトの UTF-8" なのですね。予想通り Firebird (2.x) は "UNICODE_FSS / UTF8 = 4 バイトの UTF-8" だと。

 IBX のエラーの意味がちょっと解った気がします。実は IBX で "UTF8" という接続文字列を使った場合、Firebird な DB だとテーブルを生成する事はできるのですが、イロイロな場面でエラー ("0 による除算") が発生してしまいます。IB6.x 時点で存在した接続文字列を使う分には問題ないようですが、後で実装されたものは IB / FB で互換性がないためにこのようなエラーになる事があるようです。結果から言えば先述の通りなのですが、Firebird で Unicode を使いたければ UNICODE_FSS を使えって事なのでしょう。そして、IB7.x 以前 / FB1.x 以前の "UNICODE_FSS" では Unicode の BMP しか扱えない 訳ですね。

 こうなってくると、何も考えずに IB / FB 両対応は謳えない、と。少なくとも Unicode 絡みではですが。

カーペンターズ・ツールズ
 とーちゃんが、大工の現役を引退したようだ。お世話になった会社に一緒に行って大工道具を引き取りに行った。丸ノコやらバール ("のようなもの" ではない) やらがあったので結構な量。もちろん、金槌やカンナ、ノミ、墨壷等の昔ながらの道具もあった。

 実家にも予備がフルセットあるのだが、手に馴染んだものはやはり実務で使ってこそだし。引退後はこれらで実家の補修をやるとの事。予備の予備の予備あたりの電動ドリルとかがあるらしいので、要らんのは貰ってこようかと思っている。

 今年の正月は "お疲れしたー" ってな感じで、とーちゃんと一杯やろうかな。

IBConsole 日本語版+α
 "Unicode Edition rel.2" リリース。"CSVインポートツール" を同梱。"CSVインポートツール" は文字コードセットを指定できたり、CSV の先頭行がヘッダであるかないかの指定を行えるようにしてみました。それに伴い、IBConsole 本体にも仕掛けを実装しました。

Delphi の Tips
 今日の Tips は Delphi のキーボードショートカットについてです。


08/12/09

第 11 回 エンバカデロ・デベロッパーキャンプ -- 資料ダウンロード

 先日のセッション資料が DL できるようになりました。デベロッパーキャンプに参加できなかった方は是非。

 私の担当セッションですが、先頭 13P を華麗にスルーする という荒業をやりました。問題の 13P は当サイトの記事 / CDN の記事のまとめのようなものでして、知っているヒトには退屈な話だろうと思いスルーしました。 この資料とそれに記載してある関連リンクを把握すれば、Delphi 2009 と Unicode について一通りの理解 (完全ではなくとも) ができるようになっています。

 問題なのは、"私が資料通りの事を喋っていない" という事でしょうかね (^^;A でも、大きくは同じなんですよ。あと、コードサンプルは 先日お話した "タイ語" の件のものです。

Interbase To-Go Edition
 早い話が "Firebird Embedded Server" の Interbase 版 です。高橋さんの記事 にあるように、開発手法等も "Firebird Embedded Server" と全く同じです。

 Paradox / dBASE の代替にはもってこいなのですが、社内では喧々諤々だったんだろうな、と勝手に予想。用途的に "Blackfish SQL" とかなりカブりますからねぇ...。


08/12/10

Delphi 2009 で WinProcs のエラーが出る場合には?
 過去のプロダクトのプロジェクトの移行なのであれば、"[プロジェクト | オプション | Delphiコンパイラ | ユニットのエイリアス]" を確認してみて下さい。もし、ここが空になっていたら、以下の文字列を追加してみましょう。

WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; 

 何故か消えてる事があるんですよねぇ...。


08/12/14

Delphi Launcher
 今までは レジストリファイルで対処していた のですが、折角なので作ってみました。

[Delphi Launcher]

 Delphi のどのバージョン、どのパッケージでアプリケーションを構築したのか判らなくなるヒト向けです。

Delphi の Tips
 今日の Tips は Delphi のパッケージについてです。

 Delphi Launcher の補足トピックとなっています。

IBConsole 日本語版+α
 "Unicode Edition rel.3" リリース。DB 登録の際に一部の接続文字コードセットがコンボボックスに出てこない問題を修正。


08/12/16

IBConsole 日本語版+α
 "Unicode Edition rel.4" リリース。

・[ヘルプ | 表示フォントの設定]を追加。
・BLOB (MEMO) 項目で文字化けが起こる問題を修正。
・文字列型の環境設定フィールドがレジストリが反映されない問題を修正。

 いずれも Unicode 化で顕在化した問題です。

 表示フォントに関してですが、DB には世界各国のイロイロな文字が入る事があります。ところが、Windows にはこれらの文字を一度にすべて表示できるフォントがありません。"Arial Unicode MS" でさえ、Unicode 2.1 止まりです。先日のセッションでも触れましたが、本格的な Unicode アプリケーションを作る際には、"フォント指定UIが必要"となるという事です。

 独自ビルド版では、フォントの種類を3つに大別しました。

 最適解ではないかもしれませんが、現時点ではこれがベストのようです。

 BLOB (MEMO) 項目は、minon さん の情報によると、

FB / IB の BLOB 列は接続キャラクタセット毎の変換はしないようです。

 との事なので、独自ビルド版では CJK の各接続文字コードと UTF-8 (含む "UNICODE_FSS") に対して、文字コード変換を行うようにしてみました。補足ですが、Memo フィールドのデータは AsString で取得してから文字コード変換しても無意味で、一旦、Stream で取り出してから任意の文字コードへ変換する必要があります。早い話が、"デフォルト文字コードと IB / FB の DB 文字コードが異なる場合には、Memo 型の読み込みに AsString が使えない (D2009)"という事です。

 "文字列型の環境設定フィールド"の件は、Variantの種類判定で、文字列型が "varString" ではなく "varUString" を返すようになっていたのを見落としていた、というものでした。

IBConsole 日本語版+α
 "Unicode Edition rel.5" リリース。

・データグリッドのフォント名が設定に反映されない問題を修正。
・データグリッドのタイトルフォントも同時に変更するようにした。
・[ヘルプ | 表示フォントの設定] のコンボボックスでフォントをソート表示するようにした。
・インタラクティブ SQL でのフォント指定を廃止した。

 主にバグフィックスです。

うわあ...。
 minon さんからのメールを読み返していて気付いた。そうか..."IB2009 付属の IBConsole は ANSI版"なのね。どうやら D2006 製っぽいんだけど...根拠は以下の通り。

 ...どうすんだ?Unicode は。

 追記:
 InterBase SMP 2009 Hotfix Update 1 for Windows の IBConsole も D2006 製のようです。何故か、XP のテーマに対応していません。


08/12/18

Delphi 2009 への移行
 Delphi のバージョン判定で思い出しましたが、先のデブキャンで、挙手によるアンケートをとってみたのです。内容は「どのバージョンからの移行を考えているのか?」でした。結果をお伝えしていなかったので今更ですが発表。

 "2007 >= 6~7 > 2~5 > 2005~2006 > 1" といったトコロです。デブキャン参加者(A6セッション参加者)に限って言えばDelphi6/7/2007辺りのユーザが多いようでした(重複はあると思いますが)。ちなみに、「2009を購入して実戦投入しているか?」という問いは、これまたポツポツでした。

Delphi の Tips
 IBConsole 関連を Tips に移動しました。先日の "使われた Delphi の判定方法" は別トピックに分離してみました。

IBConsole 日本語版+α

 まとめてリリース。ANSI 版 には Unicode 版 と同等の "CSVインポートツール" を同梱してあります。Unicode 版 の付属物を単純にコピーしたものではなく、こちらも ANSI コンパイラ (Delphi 2007) でちゃんとコンパイルしてあります。

 Unicode 版 にあるフォント指定 UI が ANSI 版 / Linux 版 にないのは、

 ...という事です。

Embarcadero Discussion Forums
 ディスカッションフォーラムでは自作自演は基本的に不可能。何故って?DN アカウントを複数持っていたとしても、IP アドレスが見えてしまうから。ブラウザで適当な投稿を閲覧すると、右上に "Headers" というリンクがありますが、これで投稿者の IP アドレスが見えます。当方、熊本ですから IP アドレスを Whois で引けば (或いは "tracert" とかで) 一発で自演はバレてしまいますね (^ー^)

地球が静止する日(映画)
 タイトルを何回見ても、"地球 (ペコポン) が静止する日" にしか読めません。"惑星麻酔" の話なんだろうか?


08/12/21

柚子湯
 奥さんの実家で柚子を貰ったので、今日は子供達と柚子湯に入ったです。オイコラ、そこの二人!!柚子を投げんな。


08/12/24

PC 環境調査ツールとWMI
 お客さんトコで 50 台近くある PC の調査をする必要があり、IP アドレスとかメモリとかイチイチ調べてられないので、ツールをこさえた。情報取得は API ではなく WMI (wbem) からとなっている。

 EVEREST をシンプルにして追加情報を入力できるようなもので、USB メモリから実行可能。各自USBメモリを持って情報収集に走った。

 お客さんトコには 10:30 入りだったのだけれど、ブツが出来たのは 08:30。会社を 09:30 に出なくては間に合わないから、ギリギリで完成した事になる。 開発環境は "Vista + Delphi 2009" だったのだけれど、直前に Windows 2000 (VM) で確認したら、

エラー出まくり

 そもそも OS によってプロパティがあったりなかったりするのはどういう事だ?Windows Update とかで WMI も統一しやがれ。とりあえず"エラーが出ないようにしたもの"を持っていって事なきを得た...多分。

 WMI についてだけれど、WMI でしか取得できない情報とかがあって、ハードウェア情報とかを引っ張り出すのは楽チンなんだけど、"互換性"という意味では最低。確実に情報を得たいのなら、情報量は少なくても API 叩いたほうがマシな事もあるみたい (先述のツールは情報を取れない場合に API を呼んでいる)。 「Windows のバージョン毎に WQL 書くのって本末転倒じゃない?」って感じだ。そもそも WMI で得られる情報は微妙なのが多い。滅多に必要としない情報はあるくせに、「これは必須でしょ?」みたいなのは 2000 とかには存在しない。Vista の WMI がかなりマトモなだけに、古いプロダクトの WMI を調べるとがっかり度がヒドイ。

 「OS に依存しない Web アプリ...でもブラウザには依存します」に近いものがあったな、今回。

WMI テストコード
 フォームに Edit と Button と ListView (ViewStyle := vsReport) を貼り付けて、以下のコードを記述。

uses
  ..., ActiveX, WbemScripting_TLB, ...

procedure TForm1.ShowWMIData(LV: TListView; WQL: String);
// http://mrxray.on.coocan.jp/Delphi/plSamples/index.htm
// http://www.i-drift.com/?cat=13
var
  i, l: Integer;
  WbemLocator: TSWbemLocator;
  WbemServices: ISWbemServices;
  WbemObjectSet: ISWbemObjectSet;
  WbemProperty: ISWbemProperty;
  WbemValue: String;
  ColEnum, RowEnum: IEnumVariant;
  RowObj, ColObj: OleVariant;
  Value: Cardinal;
  LC: TListColumn;
  LI: TListItem;
  function VarToString(const oleVar: oleVariant): String;
  var
    lowBound,
    highBound,
    i: Integer;
  begin
    if VarIsArray(oleVar) then
      begin
        result := '';
        LowBound := VarArrayLowBound(oleVar, 1);
        HighBound := VarArrayHighBound(oleVar, 1);
        for i:=lowBound to highBound do
          begin
            result := result + Format('"%s"', [StringReplace(VarToString(oleVar[i]), '"''""', [rfReplaceAll])]);
            if i < highBound then
              result := result + ',';
          end;
      end
    else
      result := VarToStr(oleVar);
  end;
begin
  WbemLocator := TSWbemLocator.Create(nil);
  LV.Items.BeginUpdate;
  try
    LV.Items.Clear;
    LV.Columns.Clear;
    WbemServices := WbemLocator.ConnectServer('.''root\CIMV2'''''''''0nil);
    WbemObjectSet := WbemServices.ExecQuery(WQL, 'WQL', wbemFlagReturnImmediately or wbemFlagForwardOnly, nil);
    RowEnum := (WbemObjectSet._NewEnum) as IEnumVariant;
    i := 0;
    while RowEnum.Next(1, RowObj, Value) = S_OK do
      begin
        ColEnum := IUnknown(RowObj.Properties_._NewEnum) as IEnumVariant;
        l := 0;
        while ColEnum.Next(1, ColObj, Value) = S_OK do
          begin
            WbemProperty := IUnknown(ColObj) as SWBemProperty;
            if i = 0 then
              begin
                LC := LV.Columns.Add;
                LC.Caption := WbemProperty.Name;
                LC.MinWidth := LV.Canvas.TextWidth(LC.Caption) + 16;
                LC.Width := LC.MinWidth;
              end;
            WbemValue := VarToString(WbemProperty.Get_Value);
            if l = 0 then
              begin
                LI := LV.Items.Add;
                LI.Caption := WbemValue;
              end
            else
              LV.Items[i].SubItems.Add(WbemValue);
            Inc(l);
          end;
        Inc(i);
      end;
  finally
    LV.Items.EndUpdate;
    WbemLocator.Free;
  end;
end;

 Button の OnClick イベントに "ShowWMIData(Listview1, Edit1.Text);" と書いて実行。Edit には "Select * From W32_Processor" とかを入力してボタンを押下。

totonicaサンタさんからの贈り物
 頑なに...いやいや何でもありません。totonica さん が "UCS4Encoding" なるステキクラスを作られたみたいです。詳細は readme.txt を読んでもらうとして、簡単に言えば LoadFromFile / SaveToFile で "UTF-32 (UCS4)" を扱えるようになるクラスです。

 「IDE は UCS4 対応してんのに、何で "TEncoding.UTF32" とか使えない訳?」等と正論を吐く方にはピッタリかと思われます。Unicode の器としての UTF-32 (UCS4) は 1 コードポイント辺り 11bit...つまり 1/3 の無駄があるので、ファイルフォーマットとして常用する場面てのはそうそうないかと思いますが、できないよりはできたほうがいいのは当たり前のことですしね。


08/12/25

昨日のお客さんトコ
 老健関係の施設だったのだが、入所 / 通所者に甘酒が振舞われていた。「デンプンを糖に変えます×2」という声が聞こえてきた気がした。見事な "かもし" だったよ、オリゼー。

 そういや先日、ウチの下の子の幼稚園のお弁当を作った事がありまして、卵焼きでオリゼーを作ってあげました...てゆーか、キャラ弁?このちょっと前 (デブキャン前後です) に、上の子が "とびひ"、下の子が"アデノウィルス"にやられてまして、「このタイミング、しかも弁当に菌はいかがなものかと」というシュールなツッコミを入れられました。

 ...クリソゲヌムが「るったるった、るーんるーん♪」してるよりはマシだと思うのですが。

 ちなみに、"菌類のふしぎ展" のラクガキで、帽子をかぶっているのはオリゼーではなく ソーエ です。


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