(10/04/01~)

10/04/01

このサイトにエイプリルフールネタはありません
 とりあえず、断り入れとかないとね。

Web セミナー
 またイロイロとあるようです。

 Live Meeting 利用方法はこちら。  連続しますね。

4/15 の Web セミナー
 毎度毎度 "スライドの通りに喋らない事で定評のあるH・T氏" ですが、また違う事を喋るのでしょうか?

 今度も新ネタを投下する模様ですが、時間内にまとまるんでしょうかね?氏は無意味に自信ありげなのですが根拠が全く不明です。それよりも、次回は "何本の電車が通過するのか?" 本当に楽しみです。

QC#83508 - XE3 で修正されています
 元ネタはこちら。うーん、参ったな。サロゲートペアを扱うのに重要な RTL にバグがあるとは...。" Delphi 2009 と Unicode : 番外編 (サロゲートペア) " にある Copy_S() も正しく動作しないって事になるからなぁ...。

 MECSUtils の類似関数である MecsCharToElementIndex() ではこの問題は起きない (内部実装が別物) ので、当面は代替策として MECSUtils を使って貰うしかないかも。

 サロゲートペアを扱おうとすると、CharToElementIndex() / CharToByteIndex() のバグで UTF-16 を文字 (コードポイント) 単位で処理するのが難しい。では、UTF-32 ヘ変換して処理すればいいかと言うと、UnicodeStringToUCS4String() / WideStringToUCS4String() がバグってるので変換もままならない (QC#67959)、か。

 このサイトのネタとしては "MECSUtils 作っててよかったね" で済ませられるのだろうけれど...セッションやる方の身にもなってくれ (ToT)


10/04/03

MECSUtils 1.47
 リリース。あ、累積 DL 数が 1,000 を超えてますね。

・MecsAnsiStringOf() を廃止
・MecsStringOf() を追加
・MecsBytesOf() / MecsStringOf() は、AnsiString だけでなく UnicodeString でも使えるようになった。

 思う所あって、MecsAnsiStringOf() は廃止しました (ゴメンナサイ)。代わりに MecsStringOf() を追加したのですが、SysUtils.StringOf() とは使い方が異なります。詳しくは MECSUtils リファレンス を参照して下さい。

QC#83566
 速攻で Pending になっていますが、要は "TBytes から AnsiString へ変換する方法がない" という事です (先のセッションで「えー」と書いていたのはこういう事です) 。 オーバーロードされた "function StringOf(const Bytes: TBytes): AnsiString;" が作れないのは理解できますが (引数が同じになるので)、戻り値が UnicodeString な WideStringOf() が存在するのですから、BytesOf() の戻り値は AnsiString であるべきだと考えます。

 StringOf() のヘルプには "デフォルトのシステム ロケールを使用して、バイト配列を Unicode 文字列に変換します。" とありますが、"デフォルトのシステム ロケールを使用して、バイト配列を Unicode 文字列に変換されても嬉しくない" という事です。ANSI->Unicode 変換は代入でも行えるのですから。

 現行の StringOf() の定義は以下の通りですが、

function StringOf(const Bytes: TBytes): UnicodeString;

 これが

function StringOf(const Bytes: TBytes): AnsiString;

 と変更になったとしても、以下のコードは同じ結果になるハズです (代入互換性のワーニングは出るでしょうが)。

var
  S: UnicodeString;
  B: TBytes;
begin
  S := 'あいうえお';
  B := BytesOf(S);
  S := StringOf(B);
  ShowMessage(S);
end;

 MecsAnsiStringOf() が仕様変更されて MecsStringOf() になった理由もここにあります。StringOf() の戻り値が AnsiString でないのなら、せめて AnsiStringOf() を作るべきかと。

PlatformBytesOf() / PlatformStringOf()
 使い道のない関数。これらは内部で、OS が NT がどうかを判定している。NT だったら TBytes は UTF-16 のバイト列、9x だったら デフォルトコードページのバイト列とみなす。

 しかし、これらの関数は Delphi 2009 で新設されたもので、Delphi 2007 にはバックポートされていない。Delphi 2009 以降は Win9x で動作するバイナリは作れない事になっているから、PlatformBytesOf() / PlatformStringOf() は WideBytesOf() / WideStringOf() と同じ動作にしかならない。

 "All Access" に含まれる Delphi 2007 の RTL は Delphi 最新版のものがバックポートされているのだろうか?それとも将来 ANSI / Unicode 両対応の Delphi を出すつもりなのだろうか?

そもそも
 TBytes を ANSI のバッファとして使わせるのであれば、"システムロケールを使用してバイト配列を(へ)変換する" という仕様はマズかったかと。これでは必ず ANSI デフォルトコードページとの暗黙の文字コード変換が行われてしまい、TBytes を任意の ANSI のバッファとして使う事ができなくなってしまう。

 何がマズいって、"任意の ANSI バイト列が格納されている TBytes を TFileStream とかに喰わせてファイルへ書き出す" なんて事が簡単にできなくなってしまうじゃないか。

MECSUtils 1.48
 リリース。

・MecsAnsiBytesOf() を追加
・MecsAnsiStringOf() を追加
・MecsWideBytesOf() を追加
・MecsWideStringOf() を追加

 MecsStringOf() の使い勝手がイマイチよくないので、ラッパー関数を用意した。


10/04/05

Microsoft Word だけ、起動と終了が遅い (Word XP / 2003)
 解決する方法。

  1. 開いている Microsoft Word を終了する
  2. %Appdata%\Microsoft\Templates をExplorer で開く
  3. Normal.dot / ~$Normal.dot を削除するか、他の場所に移動する
 これでも解決しない場合には、"Word の起動、印刷、文書の読み込みが遅い" を試してみて下さい。


10/04/07

ネクスト・セッション!
 もう、来週の話ですねぇ。大筋は同じですが、全く同じ話をする気はありません (同じ漫才を 2 回続けて観ても笑えません) ので、

 前回の資料を先に読んでおいて頂けると、新ネタをやる時間があると思います。
 ちなみに、今回は 90 分のセッション です。"デベロッパーキャンプ、バーチャルの可能性を語る (30 分)" を足して...ではありません。私の担当部分のみで 90 分です。

クローゼットNASキット KURO-Z/NAS-KIT
 こいつは面白そうだ。何で PCI Express の形状なんだろ?電源供給は FDD 4 ピンからだから、何もピンは接続されていないハズ。固定が甘いかもしれないけれど、PCI スロットでもイケそうな気が...。

アプリケーション・コンテストを開催します (Embarcadero)
 ...だそうですよ。

  1. 便利ツール部門:
    話題のTwitter対応の便利ツールや日頃の生活の中の意外な所で便利に使えそうなツールなど
  2. おもしろ部門:
    実行すると思わず、”にんまり”としてしまうような、ホット一息出来るような安らぎを与えるようなアプリ
  3. コンポーネント部門:
    いろいろな環境で利用可能な、仕事の生産性向上につながるようなコンポーネント
  4. ビジネス部門:
    業務改善やエコロジー、生産性の向上など社会貢献につながるようなものなど
 ...おバカな奴はいっぱい思いつくけど、脳内の時点で却下だな。


10/04/08

今日から新学期!
 我が家には新しい洗濯機がきましたよ。Panasonic NA-V1600L(R) です。

 別に買い直した訳じゃなく、リコールによる無償交換でして...。「SANYO 製品を買ったらいつの間にか Panasonic 製になっていた」というポルナレフ状態です。5 年も使っというて新製品へ無償交換ってのも若干気が引けるトコロではあります...いくらリコールとはいえ。何度も無償修理/点検があった末の無償交換なので、根本的な解決ができなかったのでしょうね。

フォームを新規作成したらまずやる事 (Delphi)
 幾つかあります。

 何度もこの作業を行うのは面倒なので、私はこれらの設定を行ったフォームをリポジトリに追加しています。リポジトリに追加する方法は このTips の最後の方に記述があります。


10/04/10

Delphi 6 では Int64 が使えない!
 初めて知ったわ (w

 D6 の DiskFree() では 2GB を超えるディスク容量を調べられないのですか、そうですか。


10/04/13

キーボードが壊れた
 仕方がないので、社内にあったメンブレンタイプのキーボードを分解洗浄して使っている。

 ちなみに、以前使っていたのは FILCO の "隼 (FKB-109J-II)" って奴で、購入したのは 12 年前 の事...当時、僕の PC は K6-2 300MHz だった。隔世の感があるなぁ...ともかく、はやぶさタンお疲れ様でした。

 ...さて、次のキーボードは何にしよっかなー?


10/04/15

アンコールセッション
 「コッペパンを要求する!」とはサージェント・ソースケ・サガラの有名なセリフです。ご存知でない方はあまり気になさらないでください(w

 イロイロと新ネタを盛り込んだ今回のセッションですが、文字コード系の話はだいぶ端折ったのに やっぱり予定を過ぎました ...orz

 だって、この資料のフルサイズ版は 129P あるんですもの。今回のセッションは "前回のセッションの文字コードの説明部分で既にやった所を削った 89P のショートバージョン" でしたからね。前回のセッションで心残りだった "Delphi 側の問題点と問題を回避/解決する具体的な方法" をご紹介できたのがせめてもの救いでした。今回のセッションの資料ダウンロードは...どうなるんでしょうね?まぁ、エンバカさんから追って沙汰があるでしょう。

 なお、セッション中で紹介した TAltEncoding は ディスカッションフォーラム に掲載されています。

先日の実家の風景

 春ですなぁ。庭で BBQ やりました。仕込みは僕で (w


10/04/17

4/15 のアンコールセッションの資料
 追って沙汰がありましたので、近日ダウンロードできるようになるでしょう。"セミナーで使ったもの""前回のセッション + 新ネタ (フルサイズ版)" の 2 つが用意される...のではないかと思われます。

 フルサイズ版の前半部分は "文字コード" の話で、後半は "Delphi 絡み" の話という具合に完全に分離されていますので、Delphi 以外の言語をお使いの方も、前半部分は役に立つ事があるかもしれませんね。

 ...しかし、あの資料。"コッペパンだらけ" なんだけど大丈夫なのだろうか?


10/04/18

マルチプラットフォームとクロスコンパイラ
 最近のホットなトピックに "iPhone アプリ開発の制限強化、Flash他から変換を締め出し (engadget)" というのがありますが、この記事中に 「短く言えばクロスコンパイラの禁止。」という一文があります。これは誤解を生む表現であると思います。

マルチプラットフォーム(クロスプラットフォーム)
 マルチプラットフォームはフレームワーク層を構築して、ほぼ同一のソースコードで同じアプリケーションを異なるプラットフォームで動作させるものです。全く同じように動作させようとすると、フレームワークは各プラットフォームで共通に実現できるものだけが含まれる事となり、結果各プラットフォームが独自に持つ最新の機能を利用できない事になります。

 .NET はバイナリレベルでのフレームワーク層であり、同一バイナリを各 .NET 環境で同じように動作させられる...ハズなのですが、各 OS のフレームワークの実装度合により、同じように動作しないものもあります。.NET Compact Framework はサブセットですし、OS 固有の機能を使うにはアンマネージドなコードを書かなければならない事があります。

クロスコンパイラ
 クロスコンパイラは実行する環境とは別の開発する環境で動作するコンパイラです。デバッグはエミュレータ上で行う事が多いです。GCC なんかは古くからクロスコンパイル機能がありましたので、ターゲットマシンが遅くてコンパイルに時間が掛かる場合には、クソ速い最新のマシンでクロスコンパイラを利用するなんて事ができました。

混同してはいけない
 例えば、組み込み用のコンパイラはクロスコンパイラですが、ターゲットとなるマシンの全機能を使う事ができます。マルチプラットフォームとクロスコンパイラは別に考えなくてはなりません。マルチプラットフォームだと "クロスコンパイラを使う事が多い" というだけで、"クロスコンパイラでは OS 固有の機能を利用できない" という事にはならないのですから。

 組み込みやってるヒトに 「開発はクロスコンパイラでやってるんですか?全ての機能が使えないと不便な事が多くないですか?」なんて言わないようにしましょうね。鼻で笑われちゃいますよ。

 ...という事で "短く言っちゃダメ" なのですよ。多分、記事の内容に一番近いのは *一貫して* "フレームワーク層設置の禁止" だと思われます。「(例:互換レイヤーやツールを用いて公開APIにリンクするアプリは禁止する)」って自分で書いているのに...。

Delphi の Tips
 3 つ程追加しました。

 Firebird 関連は どこぞでモメた時の奴のコピー です。前回のデブキャンセッションや、今回のアンコールセッションを聴かれた方は "ShortString で処理" とか言われて私がブチ切れた心情をご理解頂けると思います (w

 マイグレーション (移行) の件は厳しい事が書いてありますが、英語の情報しかない状況であれば、"資料がない" と言われても反論しませんが、これだけ日本語で書かれた資料があっても "資料がない" と言われちゃったら流石にエンバカさんが可哀想です。


10/04/19

コッペパン
 ...違うって。アンコールセッションの資料が公開されました

 関連して当サイトの Tips "とりあえず、デベロッパーキャンプの資料を読んでみようか。" も更新してあります。

 先にご案内した通り、資料にはセミナー版とフルサイズ版があります。フルサイズ版はセミナー版を包括していますので、資料として用いるならフルサイズ版をオススメします。但し、フルサイズ版は PDF で 129P ありますので、環境によっては DL してから閲覧しないと死にます。"参考データ" とあるのは TAltEncoding.pas を ZIP で固めたもので、フォーラムに投稿したものと内容は同じです。

 コッペパンの謎が今解き明かされ...たりはしない。

Delphi の Tips
 2 つ追加しました。

 "94." は飛び飛びでしか Delphi を購入していない方向けの情報です。"95." は...Delphi コミュニティでの質問者って「何故にバージョンを明記しないのだろうね?」 という話です。


10/04/21

もう一つ
 エンバカさん絡みではもう一つネタがある(ハズ)のですが...忘れられてる訳じゃないのですよねぇ?

Webセミナー「Delphi / C++Builder 旧バージョンからの移行」
 本日 18:00 より開演です。C++Builder 中心の話になるようですね。

 追記 (19:20): 拝聴致しました。結構なお点前で...勉強(&参考)になります。

 Q&A の補足をしなきゃいけない気がするので (時間切れ気味だったので) 補足しておきますと、Unicode 文字を半角/全角変換したり、ひらがな/カタカナ変換をしたい場合には、Windows API の LCMapString() を使う事ができます。

 Delphi での使用例は、毎度お馴染み Mr.XRAY さんの Tips "881_ToHankakuKana" を御覧下さい。C++Builder の場合には、これまたお馴染み 山本隆 さんの "C++Builder 2010によるひらがな・カタカナの変換" を御覧下さい。また、ご要望があれば、MECSUtils にラッパー関数を用意したいと思っております。

あ。
 忘れてた。早く保険屋さんへ資料送らなきゃ。
 実は、アンコールセッションの数日前に子供が自動車にはねられまして。幸いタンコブだけで済みましたので、大事には至っておりませんけどね。

MECSUtils 1.50
 リリース。MecsStrConv() を追加。VisualBasic の StrConv() っぽい関数になっています。
 また、コードページを引数に持つ関数をデフォルトパラメータで記述するようにしたので、オーバーロード関数が減っています。ソースもマニュアルも幾分スッキリしました。

デフォルトパラメータ
 Delphi のどのバージョンから使えたのか記憶が曖昧だったので、従来はオーバーロード関数にしていました。デフォルトパラメータは Delphi 4 から 使えたのですね。

 MECSUtils は正式には Delphi 2007 またはそれ以降のサポートですが、Delphi 6 でコンパイルできる事を目指しています (現バージョンも 0 エラー / 0 ワーニングでコンパイル可能です)。


10/04/22

Delphi の Tips
 4 つ追加しました。

 Microsoft Office をツールとして使うテクニック関連です。Microsoft Office を Delphi から操作する方法ではないのでご注意下さい。


10/04/27

Delphi の Tips
 1 つ追加しました。

 ご参考になれば。

日曜日
 恒例の行事で自衛隊行って戦車に乗ってきました。

雑談は文字コード成分が大目?
 03/11、04/15 とセッションがありましたのでね...仕方ないかと。ちなみに "文字コードのハンドリングについて" というヘビィなお題を出しちゃってくれたのはエンバカさんです。受けるかどうか何日か悩みました (実話)。

Delphi / C++Builderの価格でフルセットのRADツールを手に入れよう!
 2009 の時にもありましたね。2007 の時は R2 で Blackfish が付属しちゃってちょっぴり頭にきましたっけ...(遠い目)

 Delphi 2010 のアップグレード版はお安く買えるのですが、2010/02/01 以降、アップグレード価格で買えるのは BDS 2006 以降を持っている場合に限られます。

 ですが...

Q: 2010年2月1日以降に、2005、または、それ以前のバージョンから、2007や 2009にアップグレードすることはできますか ?
A: はい。2009にアップグレードすることが可能です。
ただし、通常は、Windows 7 やタッチアプリケーションの開発、C++クラスエクスプローラーや、
最新のデータベースドライバなどの最新の機能を利用できる最新バージョンへのアップグレードを推奨しています。

 どういう事かと言うと、"D1~D2005 ユーザは現在でも 2007 や 2009 のアップグレード版を購入する事が可能" という事です。

 もう少し簡単に言えば、在庫として存在する "D2007 / D2007 R2 / D2009 のアップグレード版を購入すれば、D2010 のアップグレード版を購入する事が可能" です。最低グレードの D2007 / D2009 Professional 版アップグレードを購入し、D2010 の任意のアップグレード版を購入すればいい事になります。実際のアップグレードパスを例示してみましょう。

  1. Delphi 2007 R2 Professional アップグレード版 -> Delphi 2010 [任意] キャンペーン アップグレード版
  2. Delphi 2009 Professional アップグレード版 -> Delphi 2010 [任意] キャンペーン アップグレード版
  3. Delphi Delphi 2010 [任意] キャンペーン 通常版
 D1~D2005 ユーザには、この 3 つのアップグレードパスがあります。購入する D2010 が Professional 版の場合、価格はどれも同じようなものですが、上位エディションを購入する場合には価格差が出てきます。もちろん、Professional 版であっても D2007 / D2009 アップグレード版からだと同じ価格でも "所持できるライセンスが多い" というメリットがあります。

 "D2010 キャンペーン 通常版" をそのまま購入してもお得感がありますが、同じ金額を出すなら、"Delphi 2007 R2 Professional アップグレード版 (HDB0007JAUP192)" を探すのがいいでしょう。D2007 には QuickReport STD も付いています から、ANSI 版 Delphi のメンテナンスにはもってこいです。

 EnterPrise / Architect 版狙いなら、比較的入手し易い "Delphi 2009 Professional アップグレード版 (HDB0009JACS190)" を探してもいいのかもしれませんが、機能的に 2009 と 2010 は近いので、2009 がタンスの肥やしになりかねません (w

 このキャンペーンは 2010/06/28 までのようです。新しい Delphi を購入する予定がある方は 2007 / 2009 のアップグレード版の在庫があるうちに どうぞ。

Delphi 2007 R2 / 2009 のアップグレード版購入対象製品
 こうなっています。

 ちなみに、"Delphi 2007 R2 / Delphi 2009" は共に旧バージョンですが、2007 R2 は通常版、2009 はアップグレード版も販売継続対象製品となっています。

もう一つの選択肢
 単に、D2007 / D2009 を一緒に使いたいのであれば、"Delphi 2010 に ToolCloud ライセンス を追加する" という方法もあるようです。ただ、いかんせん価格体系が不明瞭なので一般的には受け入れられづらいと思います。"All-Access" にしろ "Tool Cloud" にしろ、参考になる価格が表に出ていないと "最初から選択肢に入らない" 可能性が高いのですが...価格 (料金体系) シミュレーションのページ等作られてみてはいかがでしょうか?>エンバカデロ様。


10/04/28

DEKO タン Delphi で大いにハマる。
 これは Delphi 2010 でのお話。

 Delphi で TActionManager を使うと、メニューにも TActionMainMenuBar を使いたくなるのが心情。でも、ActionMainMenuBar には初期値で通常のメニューのフォント (システムメニューフォント) はセットされていない。ぶっちゃけ、

// システムメニューフォントを ActionMainMenuBar に適用
ActionMainMenuBar1.Font.Assign(Screen.MenuFont);

 ってやれば終わりな話なのだが、"引越しをすると古い雑誌を読んでしまう衝動に駆られる" のに似た衝動に駆られてしまい、古いソースではどうやっていたのか引っ張り出して眺めてみた。

var
  NONCLIENTMETRICS: TNonClientMetrics;
begin
  // システムメニューフォントを ActionMainMenuBar に適用
  NONCLIENTMETRICS.cbSize := SizeOf(NONCLIENTMETRICS);
  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(NONCLIENTMETRICS), @NONCLIENTMETRICS, 0);
  ActionMainMenuBar1.Font.Name := NONCLIENTMETRICS.lfMenuFont.lfFaceName;
  ActionMainMenuBar1.Font.Size := -MulDiv(NONCLIENTMETRICS.lfMenuFont.lfHeight, 72, Screen.PixelsPerInch);
end;

 API すか...(´ー`)y-~~ ま、勉強になっていいよね...等と思いながら、このソースを Delphi 2010 に貼り付けてコンパイル...当然の事ながら普通に動く (Vista)。ふと見ると傍らに Virual PC が起動しており、XP が動いていた。戯れに XP で動かしてみた...ら?

「なんじゃこのフォントわぁ!!」

 明らかにメニューのフォントがおかしい。ShowMessage() を挟んで NONCLIENTMETRICS.lfMenuFont.lfFaceName を確認してみると文字化けしている。「ん?バッファはクリアしとかなきゃいけなかったっけ?」と思い、ZeroMemory() を追加した。

  // システムメニューフォントを ActionMainMenuBar に適用
  NONCLIENTMETRICS.cbSize := SizeOf(NONCLIENTMETRICS);
  ZeroMemory(@NONCLIENTMETRICS.lfMenuFont.lfFaceName, SizeOf(NonClientMetrics.lfMenuFont.lfFaceName));
  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(NONCLIENTMETRICS), @NONCLIENTMETRICS, 0);
  ActionMainMenuBar1.Font.Name := NONCLIENTMETRICS.lfMenuFont.lfFaceName;
  ActionMainMenuBar1.Font.Size := -MulDiv(NONCLIENTMETRICS.lfMenuFont.lfHeight, 72, Screen.PixelsPerInch);

 それでも状況は好転しない。以前はこれで動いていたのに...?
 そして四苦八苦しているうちにこういう記事を見つけた>"例えば構造体にひとつ要素を追加すると,無関係な API でバグ疑惑が発生するという話 (NyaRuRuの日記)"

 ハッとして、Delphi 2010 にある TNonClientMetrics 構造体を調べてみる。

  tagNONCLIENTMETRICSW = record
    cbSize: UINT;
    iBorderWidth: Integer;
    iScrollWidth: Integer;
    iScrollHeight: Integer;
    iCaptionWidth: Integer;
    iCaptionHeight: Integer;
    lfCaptionFont: TLogFontW;
    iSmCaptionWidth: Integer;
    iSmCaptionHeight: Integer;
    lfSmCaptionFont: TLogFontW;
    iMenuWidth: Integer;
    iMenuHeight: Integer;
    lfMenuFont: TLogFontW;
    lfStatusFont: TLogFontW;
    lfMessageFont: TLogFontW;
    iPaddedBorderWidth: Integer; // Requires Windows Vista or later
    ...

 「うぉ、iPaddedBorderWidth が最初からあるじゃねーか」ってな訳で、ソースを修正した。

  // システムメニューフォントを ActionMainMenuBar に適用
  NONCLIENTMETRICS.cbSize := SizeOf(TNonClientMetrics);
  if not SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NONCLIENTMETRICS.cbSize, @NONCLIENTMETRICS, 0then
    begin
      NONCLIENTMETRICS.cbSize := SizeOf(TNonClientMetrics) - SizeOf(TNonClientMetrics.iPaddedBorderWidth);
      SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NONCLIENTMETRICS.cbSize, @NONCLIENTMETRICS, 0);
    end;
  ActionMainMenuBar1.Font.Name := NONCLIENTMETRICS.lfMenuFont.lfFaceName;
  ActionMainMenuBar1.Font.Size := -MulDiv(NONCLIENTMETRICS.lfMenuFont.lfHeight, 72, Screen.PixelsPerInch);

 先のリンク先にあった記事を参考にした、"SystemParametersInfo() に失敗したら、iPaddedBorderWidth 分のサイズを引いてリトライするようにしたロジック" だ。これで Vista / XP でちゃんと動作するようになった。

 ...のだが、これはあまりにメンドイ。「SPI_GETNONCLIENTMETRICS やるときは自分で NONCLIENTMETRICS 構造体書いた方がいいかも...」と思って Delphi での定義をよく見てみた。そして構造体に奇妙な関数がくっついている事にやっと気が付いた。

  ...
    lfMessageFont: TLogFontW;
    iPaddedBorderWidth: Integer; // Requires Windows Vista or later
    class function SizeOf: Integer; static;
  end;

 「あ゛ーーー!」と叫び、確認のために Screen.MenuFont の実装がどうなっているか調べた。そしてソースコードはこうなった。

  // システムメニューフォントを ActionMainMenuBar に適用
  NONCLIENTMETRICS.cbSize := TNonClientMetrics.SizeOf;
  SystemParametersInfo(SPI_GETNONCLIENTMETRICS, NONCLIENTMETRICS.cbSize, @NONCLIENTMETRICS, 0);
  ActionMainMenuBar1.Font.Name := NONCLIENTMETRICS.lfMenuFont.lfFaceName;
  ActionMainMenuBar1.Font.Size := -MulDiv(NONCLIENTMETRICS.lfMenuFont.lfHeight, 72, Screen.PixelsPerInch);

 案の定、TNonClientMetrics.SizeOf() は "XP 以前では構造体サイズから SizeOf(Integer) を引いたサイズを返すようになっていた"。なるホド...高度なレコード型はこういった用途にも使えるのか。今更ながら、ちょっと感心しちゃったぞ (w

TNonClientMetrics
 このような構造になっているのは、Delphi 2010 から。Delphi 2009 またはそれ以前の TNonClientMetrics には iPaddedBorderWidth メンバが存在しないので、"class function SizeOf()" も存在しない。

そういやさ。
 昨日の "キャンペーンの話" で思い出したけど、Delphi 2009 にも "ニコイチキャンペーン" ありましたよねぇ...確か "「Buy One, Get One Free Promotion」キャンペーン"。これって期間限定で、2009年8月24日が締め切りでしたね。で、Delphi 2010 が発売されたのはいつでしたっけ?

その締め切り翌日の 2009年08月25日 でしたね。 [参考]

 ...で、今回のキャンペーンの締め切りはいつでしたっけ?


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