テストの効率化をねらって、DUnit を試してみたので、DUnit テストプロジェクト作成の手順をまとめてみた。
2024年9月11日(水) 19:17 JST
テストの効率化をねらって、DUnit を試してみたので、DUnit テストプロジェクト作成の手順をまとめてみた。
条件に合致するファイルを探し出し、見つかったファイルに対して何か作業ができるようにイベントを発生させています。
指定フォルダ以下のサブフォルダに対しても検索をかけています。サブフォルダの階層を制限する場合や、サブフォルダの検索が不要な際には、イベント中で DigDir 引数に対し False を返すとそれ以上のサブフォルダを処理しません。
見つかったときの処理を直コーディングせずにイベントにしたことでクラス化が行え、再利用性が高まっています。別にライブラリでもよかったのですが、コンポーネントのほうが視覚的に見えてダブルクリックでコーディングしていけるので皆さんに使ってもらいやすいかな?というぐらいのものです。
Delphi で Excel の機能を使う場合に、CreateOleObject など COM の機能を使って呼び出すのだが、この際に下記のメッセージが表示されることがある。
CoInitializeが呼び出されていません
GUI アプリケーションを作っている場合には、Forms ユニットあたりで CoInitialize が呼び出されているのだろうが、CUI アプリだと100% エラーが表示される。
このため、CUI アプリケーションでこのエラーメッセージを回避するには、CoInitialize を呼び出すなどの対策が必要になる。また、CoInitialize と対で CoUninitialize を呼び出さないといけない。
実際の対策は実に簡単で、
COM を使うとその部分は、結構長くなることが多いと思うので、クラス化して、その Create と Destroy に それぞれ CoInitialize と CoUninitialize を追加するのがオススメである。
※複数回 COM 機能を使うときにも、全体を CoInitialize と CoUninitialize で囲むように追加すれば OK !
TControl を継承したオブジェクトはドラッグ&ドロップ関連のプロパティやメソッドを持つが、これはそのアプリ内でDelphiのコンポーネントをドラッグする場合にしか使用できない。プロセス外からのドロップを受け取るには、Windows API を使用する必要がある。
ドロップを受け取る Delphi コンポーネント側で、DragAcceptFile を使用して Windows にドロップを受け取ることを伝える。(ShellAPI を uses に追加する必要があります。)
下記は TForm1 でドロップを受け取るための例。
TForm1.Create(AOwner: TComponent); begin inherited; DragAcceptFiles(Handle, True); end;
これで、このForm上にファイルをドラッグすると、マウスカーソルがドロップ可能な形状になる。
実際にドロップが発生すると、WM_DROPFILES メッセージが発生するので、このメッセージのハンドラを作成する。
protected procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
ドロップされたファイル名の取得は、DragQueryFile を使う。ドロップされた個数を調べるには、以下のようにする。
hDrop := THandle(Msg.Drop); DropCount := DragQueryFile(hDrop, UINT(-1), nil, 0);
個々のファイル名の処理は、以下のようにする。
var hDrop: THandle; i: Integer; FileName: PChar; begin FileName := StrAlloc(MAX_PATH); for i := 0 to Pred(DropCount) do begin DragQueryFile(hDrop, i, FileName, MAX_PATH - 1); // FileNameの処理 ListBox1.Items.Add(StrPas(FileName)); // 処理の一例 end; end;
MainFormのどこにドロップしたか知りたい場合は、DragQueryPointを使用する。
※注意 ドロップ処理が終わってファイル名を格納した領域が不要になったところで使用したメモリの解放が必要。
DragFinish(hDrop);
まとめると...
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles); var hDrop: THandle; i, DropCount: Integer; FileName: PChar; begin hDrop := THandle(Msg.Drop); try FileName := StrAlloc(MAX_PATH); DropCount := DragQueryFile(hDrop, UINT(-1), nil, 0); for i := 0 to Pred(DropCount) do begin DragQueryFile(hDrop, i, FileName, MAX_PATH - 1); // FileNameの処理 ListBox1.Items.Add(StrPas(FileName)); // 処理の一例 end; finally DragFinish(hDrop); end; end;
Delphi2005 Win32, Delphi 2010で動作確認を実施。
DateTimePicker で中身の日付を表示したくない場合、どの様な対応をしているだろうか?
Delphi に関わらず、他の言語処理系にも共通する問題なのだ。この問題を解決するために、DateTimePicker に最初からあるチェックボックスを使用して空白を表現している方もいるのではないだろうか?くろねこも最初そう考えた。
しかし、ある時とある設定ミスから発見したある方法がこの問題の解決にぴったりだと思った。
その方法は、書式設定に "g" を使うという物である。
Windows 上での日付書式フォーマットでは "g" は元号を表す記号である。しかし、DateTimePicker はこの元号に対応していないらしく、"g", "gg", "ggg" などのフォーマットが指定された時に何も表示しない。これを逆手にとって表示すべき日付が無いときに、これを設定するのだ。
これで、データベース中の日付を表示するときなどに現れる Null を DateTimePicker で表現できる。
このときの書式には Delphi の書式ではなく、Windows の日付書式を使用する。また commctrl ユニットを uses 節に追加する必要がある。
※ Delphi で月をあらわす書式は "mm" だが、Windows では "MM" となる。
uses commctrl; procedure NullDateFormat; var szFormat: PChar; begin szFormat := 'g'; // Windows の日付書式 SendMessage(DateTimePicker1.Handle, DTM_SETFORMAT, 0, longint(szFormat)); end;
2012/04/07 追記
Delphi2010 on Windows7 で上記を試してみたところ、"g", "gg", "ggg"のいずれも"西暦"と表示された。よってこの方法はすでに使えなくなっている。おそらくOSに依存しているものと思われる。
よって、何も表示しないDateTimePickerの実現方法を別途考えないといけないようだ。