Swanman's Horizon

性欲をもてあましつつなんらかの話をするよ。

Delphi

for-in-doにもっと頑張ってもらう。

var s: string; for s in ['a', 'b'] do ... ふと何気なくこのようなコードを書いたら構文チェックが通ったので、「あれ?これ何気に便利じゃね?」と思ったら致命的エラーとやらでコンパイルは通らず。がっかり。でももしやと思い次のようなコードを試して…

配列の添字にスコープ付き列挙型が使えないバグ。

まず列挙型と配列のおさらい type TGender = (Male, Female); // これが列挙型 var population: array[TGender] of UInt64; // こうやって添字に指定できる begin population[Male] := 15; population[Female] := 20; end; 列挙型の一部を添字にしたいとき t…

カスタム属性でクラス定数っぽいものの振る舞いを継承先で変えたりしてみる。

事の発端 http://pc12.2ch.net/test/read.cgi/tech/1259667697/312-315n 312 :デフォルトの名無しさん:2010/02/26(金) 13:16:25 TBase = class public class const Value: Integer; abstract; end; TBaseClass = class of TBase; TExtend1 = class(TBase) …

バンクーバーオリンピックとDelphi。

この一見関係ないような組み合わせ、実は巨大五輪のLED制御部分がDelphiで書かれているらしい。こういう表舞台で使われることってまだあるんだなーとか書いちゃうと怒られそうだけど、それにしても今まで書かれたDelphiプログラムで一番巨大なんじゃないかな…

クラスメソッド版TThread.Synchronizeの使いどころ。

無名メソッドの導入によってSynchronizeメソッドが拡張されたのは知ってる人も多いだろうけど、ついでにクラスメソッド版のSynchronizeも作られたことは俺以外に2人くらいは知らないかもしれない。宣言部を引用してみるとこんな感じ。 type TThread = class …

TStringListのささやかな新機能。

エターナルフォースOwnsObjects*1! type TStringList = class(TStrings) ... constructor Create(OwnsObjects: Boolean); overload; ... end; Create時にTrueを指定しておくと、Freeをしたその一瞬でObjectsプロパティに含まれるインスタンスを解放させる*2…

準公式(?)イベントハンドラを無名メソッドで書く方法。

Entropy Overload: Using anonymous methods in method pointers リンク先の記事でやってることは前書いたのとほぼ同じなんだけど、そこはかとなくあちらの方が華麗なコードぽくて悔しいです>< ただ、参照カウントの問題も同じく解決されてなかったので、…

プロパティのオーバーロード。

本来同名で複数定義することのできないプロパティを、default指定した場合に限りオーバーロードできちゃう、という小ネタ。 type TFoo = class private function GetItem(Index: Integer): string; overload; function GetItem(const Name: string): string;…

呼び出し規約を指定して無名メソッドを書く。

var func: TFunc<Integer,BOOL>; begin func := // NG function(Data: Integer): BOOL stdcall begin Result := True; end; このように書こうとすると、コンパイラに「互換性ねーよ糞が」とか怒られるんだけど、そもそもTFunc<>の宣言を見てみると、 type TFunc<T,TResult> = referenc</t,tresult></integer,bool>…

イベントハンドラを無名メソッドで書く。

2ヶ月ちょっとくらい放置だったのはこの際忘れるとして。C#では次のように無名のイベントハンドラを記述できるので、 wahaa.Click += delegate { MessageBox.Show("わはー"); }; Delphiに無名メソッドが実装された時、きっとできるんだろうと甘く考えてたら…

無名メソッドをその場で呼び出す。

無名メソッドは変数に代入したり、関数に渡して使うものだから、その場で呼び出しちゃうってことは一度きりの使い捨て?再利用できなくね?何の意味があるの?という疑問をお持ちの方もいるかもしれないけど、例えばクロージャを作りたい場合なんかは「クロ…

基本の再確認2 CPUの数。

System.pas内にCPUCount変数が宣言されていて、これを参照することでCPUの数が取得できる。中身はGetSystemInfoで取得した値。 2006のソースを見たところまだ存在しなかったので、2009辺りで導入されたのかな?

基本の再確認1 for..in..doあれこれ。

var c: Char; s: string; arr: TArray<string>; begin s := 'Hello, Wahaa world'; for c in s do { 1文字ずつ取り出す }; for c in Copy(s, 8, Length(s)) do { 8文字目から1文字ずつ取り出す }; arr := TArray<string>.Create('Hello', 'Wahaa', 'world'); for s in arr do</string></string>…

定期ゴミ拾いのお知らせ。

レジストリの"HKEY_CURRENT_USER\Software\CodeGear*1\BDS\x.0*2\Globals"内に"CollectGarbageInterval"という文字列値を作って、ミリ秒で時間を指定するとその間隔でIDEで使ってる.NETに対して強制的にGCを発動してくれるみたい。 ガリレオIDE系で有効だと…

拡張識別子。

海外のDelphiブログを色々見てる時に、変数名だか関数名の頭に&記号が付いてるのを(どこでだったか忘れたけど)目にして、さっき何となくヘルプ見たらあれは拡張識別子というものだった。 拡張識別子(というか&演算子)は予約語を識別子としてコンパイラに…

いつの間にか動的配列はCreateできるようになっていた。

type TIntArray = array of Integer; var IntArray: TIntArray; StrArray: TArray<string>; begin IntArray := TIntArray.Create(2, 3, 5, 7, 11,); // [2, 3, 5, 7, 11] StrArray := TArray<string>.Create('foo', 'bar'); // ['foo', 'bar'] end; 不覚にもこんな基本的な機</string></string>…

for-in-doを使ったC#のusingもどき。

先日書いたような、インターフェースの参照カウントを利用したスマートポインタは便利は便利なんだけど、基本的に参照カウントの変動は(nilなどを明示的に代入しない限り)手続きや関数を抜ける際に行われるので、使い終わったらさっさと解放して欲しいとい…

TEncodingを拡張する。

普段から何かとデフォルト文字コードがShiftJISだったりして、DelphiでもShiftJISを扱いたい。だけどDelphiで使おうと思ったら、 var enc: TEncoding; begin enc := TEncoding.GetEncoding(932); try // ShiftJISを扱う処理 finally enc.Free; end; end; な…

Delphiでスマートポインタを。

ティファニーで朝食を、みたいな感じで書いたつもりが全然元ネタの香りもしない感じになったのは置いとくとして、Delphiにジェネリクスが実装されたのでスマートポインタも実装し放題な今日この頃、というか時期的にはもう旬は終わった感もあるくらいなので…

TIdHTTP.Getで文字化けしない方法@Delphi2010。

Delphi2010版というよりIndy10最新版でのやり方と言った方が正しいけど、以下のようにすればOK。 IdHTTP1.Response.CharSet := 'Shift_JIS'; これだけであとはGetを呼ぶと内部で変換した上で返してくれる。 もちろん決めうちなので自動で文字コード判別はで…

既存のレコードにヘルパーメソッドを追加する。

SyncObjs.pasを何気なく眺めていたところ、こんな記述が。 TCriticalSectionHelper = record helper for TRTLCriticalSection ... どうやらクラスヘルパーはレコードに対しても使える模様*1。ただ、VCL内でもたったの3箇所*2しか使われていない、"record hel…

ジェネリックレコード(クラス)と無名メソッドの組み合わせでバグ。

まずは再現コード。 // 以下Project1.dpr program Project1; {$APPTYPE CONSOLE} uses SysUtils, Unit1 in 'Unit1.pas'; var foo: TFoo<TObject>; proc: TProc; begin proc := foo.Bar(); // *1 proc; // *2 end. // 以下Unit1.pas unit Unit1; interface uses SysUti</tobject>…

ジェネリッククラスにクラスヘルパーを使う。

結論から言えば無理でした☆ E2508 型パラメータはこの型で許可されません。 とコンパイラに怒られます。 type TListHelper<T> = class helper for TList<T> ... TListHelper = class helper for TList<Integer> ... そのままでも、型引数を指定した上でもダメ。ただし後者は</integer></t></t>…

DiagnosticsユニットのTStopwatch。

時間計測用。かなり目立たない位置にいるけど、こんなのが追加されてた(ひょっとしたら2009からあったかもしれないけど)。 C#使いの人はすぐに分かっただろうけど、どうやら.NETのStopwatchクラスの移植みたい(ちゃんと確認したわけじゃないけど)。少な…

TTouchKeyboardをいぢ(め)る。

2010買ったので何か2010っぽいことをやってみようとした結果がこれだよ!というわけで、とりあえず今回から新たに付属してるコンポーネントであるTTouchKeyboardの描画周りを弄ってみる。 TTouchKeyboardにはDrawingStyleやGradientStart(End)といったプロ…

Delphiでリフレクションもどき その2 メソッド名の取得

Delphi2010で強化されたRTTIを使えばメソッド名の取得なんて超簡単なんだろうけど、まぁそれはそれで。 メソッド名の取得は、 publishedなメソッドであること 専用の関数などがなくUndocumentedな力技であること の2点を除けばわりとシンプルで汎用的に使え…

nilの逆参照

nilもポインタなので逆参照できる。なので先日のnilを渡すサンプルは次のようにも書ける。 ReadProcessMemory(..., PDWORD(nil)^); // 前回の例 ReadProcessMemory(..., DWORD(nil^)); // 今回の例

多次元配列の初期化。

Delphiの多次元動的配列は動的配列の動的配列という実装なので、メモリ上の配置は必ずしも連続しておらず(静的な場合は連続している)、Length(Hoge[0])の要素は10コだけど、Length(Hoge[1])の要素は2コ、というようにそれぞれ別の長さを設定してやることが…

参照渡しのパラメータにnilを渡す

動的配列の参照とほとんど同じだけど、例えばWin32APIのReadProcessMemoryの引数であるlpNumberOfBytesReadは本来オプションであり、nilを渡しても問題のないはずが、Windows.pasでは参照渡しとして宣言されているために直接nilが指定できなかったりする。 …

型なしパラメータに動的配列を渡す

動的配列や長い文字列をFillCharに渡してゼロフィルする、てのは日常的に行われる処理で、 FillChar(HogeArr[0], HOGE_LENGTH, 0); // HogeArr: array of Byte; FillChar(HogeStr[1], HOGE_LENGTH, 0); // HogeStr: string; というのがよく目にする記述だけ…