こける Wired-プログラムのページ(詳細)


PeepDiary

PostPetで「自分ちに来たゲストの書いたひみつ日記を表示する」ツールです。
PostPetが送信するメールを一旦このツールで受けとって、それをSMTPサーバに転送します。
で、自分のなかを通過していくメールを監視して「ひみつ日記」であれば表示します。
更にペットが書いたメールを表示する機能もつけました。
また、ペット(ゲストも自分のペットも)の出発を監視し、相手先でのトラブル等で迷子になったとき、再送できるようにしました。
詳しくはHelpを見てください。


KJnlHook

WindowsのJournalHookをカプセル化したコンポーネントです。
2つのコンポーネントがあり、TKJnlRecordHookとTKJnlPlayBackHookです。
TKJnlRecordHookは、JournalRecordingHookをカプセル化し、ユーザが入力したキーボード操作やマウス操作を一定のフォーマットで取得できます。
TKJnlPlayBackHookは、JournalPlaybackHookをカプセル化し、TKJnlRecordHookで取得したキーボード操作やマウス操作を復元します。

Windows3.1時代に存在した「マクロレコーダ」に使ったり、操作を例示してみせる「チュートリアルプログラム」に使う事が出来るでしょう。
サンプルプログラムは非常に簡単な「マクロレコーダ」になっています。
#スクリーン座標で記憶してますので、例えば記録した時にはボタンを押しとしても再生時に全く同じ位置にWindowが無いと関係ないものをクリックしてしまいますからあまり実用にはなりません。
TKJnlRecordHookとTKJnlPlayBackHookを使ったアプリケーションをLANで結べば「ソフトウェアキーボード・マウススイッチャ」を作成する事も出来るでしょう。

TKJnlRecordHookとTKJnlPlayBackHookは対で使う事を考えていますが、単独で使用しても面白いでしょう。
TKJnlRecordHookは他のアプリケーションも含めてPCに対するマウスとキーのユーザの操作全て(Ctrl-Alt-Del等例外有り)を監視できます。
TKJnlPlayBackHookは、VBのSendKey(他のアプリケーションにキー操作を送り付ける)代わりに使うには少し難しいですけど、マウスの操作も含めて送り付ける事が出来ます。


KAftrout

FormのOnShowではちょっと早い、表示した後にイベントがあればなぁとか、もうちょっとだけ遅いイベントが欲しいときってのが時々あります。
で、KAftroutです。Fireメソッドを呼び出すと、そのちょっとあとにOnDelaiedイベントが発生します。
OnShowでFireを呼び出すと、表示してからOnDelaiedイベントが発生しますから、まぁそういうときに使ってください。

よく使うのが、「時間がかかる処理のプログレス表示」です。
プログレス表示を行うフォームをShowModalで表示すると、「時間がかかる処理」というのは何処に書けば良いでしょう?
ShowModal直前にこのコンポーネントのFireメソッドを呼び出すと、モーダルダイアログボックスであるプログレス表示フォームを表示してからOnDelaiedイベントが発生します。
このOnDelaiedイベントで時間がかかる処理をしてしまえばOKですね。

Fireメソッド
procedure Fire(wParam:Integer;lParam:Pointer);
OnDelaiedイベント
procedure OnDelaied(Sender:TObject;wParam:Integer;lParam:Pointer) of object;

FireメソッドのwParamとlParamはそのままOnDelaiedの引数になります。
好きなように使ってください。別に使わないのなら使わないで構いません。


KThdComp

スレッドコンポーネントは、Delphi標準のスレッドクラス TThreadをコンポーネントにラッピングしたものです。
スレッドを扱うのにDelphi標準のTThreadを使えば生のままのWindowsAPIを扱うより格段に楽ですが、メソッドをオーバライドするよりもイベントを記述する方が楽だと思い、コンポーネントの中に閉じこめてみました。

「使い方」
スレッドコンポーネントをフォームに貼り、OnExecuteイベントを設定します。
スレッドを実行したいタイミングになったら、スレッドコンポーネントのStartメソッドを呼び出して下さい。
OnExecuteイベントがサブスレッドで動作します。
OnExecuteイベントはサブスレッドで動作しますから、基本的にVCLを操作できません。
しかし大抵のWindowsAPIはサブスレッドから呼び出しても大丈夫です。Winsockのブロッキングモードを扱ったりすることができます。
OnExecuteイベントが終了すると、メインスレッド側でOnTerminateイベントが発生します。

OnExecuteイベントからVCLを操作したい場合は、VCLを操作したい部分をOnAsyncEventかOnSynchronizeイベントに記述します。OnExecuteイベントの中でAsyncEventメソッドを呼び出せばメインスレッドでOnAsyncEventイベントが発生します。
またSynchronizeメソッドを呼び出せば、OnSynchronizeイベントがメインスレッドで発生します。
OnAsyncEventとOnSynchronizeイベントの違いは、AsyncEventを呼び出してもOnAsyncEventの終了を待たずにOnExecuteイベントに返ってきますが、Synchronizeを呼び出してOnSynchronizeイベントが発生した場合、OnSynchronizeイベントが終了するまでOnExecuteイベントに返ってきません。
また、OnSynchronizeのvar引数 Resultに設定した値はSynchronizeメソッドの返り値になります。
OnExecuteイベントの中でMessageDlg等を使いオペレータの入力を待ちたい場合、Synchronizeメソッドを使ってOnSynchronizeイベントを発生させ、そこでMessageDlgを呼び出すようにすればよいでしょう。
OnAsyncEventイベントは、プログレスバーやグラフを更新する場合に用いることができます。
OnAsyncEventイベントを用いるとプログレスバーやグラフ更新に時間がかかったとしても、そのあいだにOnExecuteイベントの実行を継続できます。
OnAsyncEventイベントやOnSynchronizeイベントにはAsyncEventメソッドやSynchronizeメソッドの引数がそのまま渡されます。

グローバル変数やForm内のフィールドをOnExecuteイベントからも同時に実行しそうな他のイベント(OnAsyncEventイベントや、ボタンのOnClickイベント等)からもどちらでも変更したい場合、その部分をCriticalEnterメソッドの呼び出しとCriticalLeaveメソッドの呼び出しで挟むことで他からの変更を待たせることができます。
CriticalEnterメソッド実行時からCriticalLeave実行時までは、他のCriticalEnterメソッドの呼び出しはそこで待たされます。このため、資源の競合制御/排他制御に用いることができます。

TThreadに存在するWaitForメソッドやSuspend,Resumeメソッドはこのコンポーネントではわざと実装しませんでした。
これらは扱いを間違えるとメモリリークが発生したりデッドロックを引き起こしたりと多少危険な面があるからです。


KTcp

Winsockの「非同期」「TCP」をラッピングしたコンポーネントです。
MIMEや、SMTP等のプロトコルは実装していません。
主にネットワーク対応ゲームなどの独自プロトコルを使うために作成しました。
この為、短めの文字列の送受信を行うと最も便利に使えます。
Delphi2,3,4で使えます。C++Builderでは確認を行っていません。
Delphi1では動作しません。

コンポーネントは4つ入っています。

TKWinsockInfo:
Winsockのスタートアップ情報を「オブジェクトインスペクタに」表示するコンポーネントです。
実際のアプリケーションで使うというよりも、自分の環境のWinsockの立ち上げ状態を表示するのに使います。(^^;;
オブジェクトインスペクタで表示できるように書き込み可能なプロパティになっていますが、実際には書き込んでも意味がありません。

TKIpFinder:
WSAAsyncGetHostByNameをラッピングしたコンポーネントです。ホスト名からIPアドレスへ変換するのに使います。
Searchメソッドを呼び出すと、OnFindイベントが発生します。見つからないときはOnErrorイベントです。

TKTcpClient:
TCPクライアントとしてラッピングしたコンポーネントです。
TKIpFinderを内蔵しているので、接続先にはホスト名を設定できます。
ServerNameに接続先ホスト名、Portに接続先ポート番号を設定し、ActiveプロパティをTrueにすると接続します。
受信するとOnRecvReadyイベントが発生しますので、RecvメソッドかRecvStringメソッドを呼び出してください。
RecvStringイベントは、受信したデータを文字列として取り出せるので便利です。
送信するときはSendかSendStringメソッドを使います。
ActiveをFalseにすると、未送信のデータがあっても即時に接続を断ちます。
ReserveCloseメソッドを使えば、送りきった後に接続を断ちます。
TKTcpServer:
TCPサーバーとしてラッピングしたコンポーネントです。
Portに待ち受けポート番号を設定し、ActiveプロパティをTrueにすると接続を待ちます。
クライアントと接続したソケットは、ChildSockプロパティで参照できます。
クライアントが接続した場合、OnConnectイベントが発生します。
クライアントに接続したソケットに関するイベントは、すべてTarget引数を持ち、これでソケットを参照できます。
このコンポーネントには2つのエラーイベントがあります。
一つはOnErrorイベントで、サーバーソケットそのもののWinsockエラーです。
もう一つは、個々のクライアントに接続しているソケットのエラーで、OnChildErrorイベントです。

関数は、3つ入っています。

CanUseWinsock:
実行中の環境でWinsockが使用できるか確認します。

LocalHostName:
gethostbynameをラッピングした関数です。

SockErrorString;
Winsockのエラーを表示用の文字列に変換します。


Watcher

Win32では何かを待ちたいとき"WaitForSingleObject"を使うことが多いんですが、メインスレッドで使うわけにもいかず、ちょっと面倒ですね。
というわけで"WaitForSiingleObject"とそれを扱うスレッドをコンポーネントにしてみました。
但し、小細工のために"WaitForMultipleObjects"の方を使っています。
Helpとか書いてないんで、ソースとreadme.txtを参考にしてください。

汎用の"TKWatcher"は、WaitHandleに待ちたいもののハンドルを設定し、ActiveをTrueにすると"OnSignal"イベントが発生します。
例えばCreateProcessやShellExecuteExを使って取得したプロセスハンドルを"WaitHandle"に設定すると、そのプロセスが終了したときに"OnSignal"が発生します。
イベント発生時点で自動的にActiveがFALSEになりますので、続けて監視を行うときはTrueにしてください。
また、"TKWatcher"はWaitHandleを管理していませんので、このハンドルが必要無くなったらアプリケーション側で閉じてください。

"TKDirWatcher"は、「ディレクトリ、又はディレクトリツリーを監視」します。
"DirName"に設定したディレクトリで、「最終更新時刻」又は「サイズ」「ファイル名」「ディレクトリ名」「属性」「セキュリティ」の変更を見つけると"OnChange"イベントが発生します。
但し、セキュリティの変更を指定すると、Win95ではエラーになります。
また、ネットワーク上のディレクトリは監視することができません。指定してもエラーにはなりませんが機能しません。
監視する変化は、"WaitKind"で指定します。しかし何が変化したかは判りませんので、アプリケーション側で別途判断してください。
"IncludeSubDir"をTrueにすると、"DirName"以下のディレクトリすべてが監視対象になります。
"OnChange"が発生しても、ActiveはFalseになりません。続けて監視します。
例えば、「C:¥PrintOut ディレクトリにファイルをコピーすると自動的にそれを印刷する常駐プログラム」とかを作るときには使えるんではないかと思います。

"TKEventWatcher"は、手動リセットイベントを監視します。
"EventName"にイベント名を設定し、ActiveをTrueにすると、そのイベントが発生したときに"OnEvent"が発生します。
これも"OnEvent"が発生してもActiveはTrueのままです。
"TKEventWatcher"が監視できるイベントを発生させるのに便利なように"KEventOut"関数を用意しました。
"KEventOut"関数は、引数にイベント名を指定して使います。何らかの失敗があった場合、関数はFalseを戻します。
プロセス間インタフェースを必要とするプログラムなら、そのタイミングの通知には使えるかもしれません。


フォーム位置保存

フォームの位置やWindowStateを保存し、次回の起動時に復元するコンポーネントです。
割とこの手のコードが必要になることって多いのですが、毎回書くには面倒だし、リポジトリに入れておくにも各種エキスパートが使えなくなるし。
というわけで、コンポーネントにしてみました。
使用方法は、「フォームに張り付けるだけ」です。

保存方法の違いで、IniFile版とレジストリ版があります。

保存の対象となるフォームは、このコンポーネントのオーナーです。
したがって、データモジュールに張り付けることは出来ません。
保存の時期は、対象となるフォームにWM_DESYROYがおくられてきた時です。
復元の時期は、このコンポーネントのLoadedです。


ドロップ機能付加

フォームにエクスプローラからのファイルをドロップさせるコードは割と簡単なのですが、TMemoとかTListBoxとかにドロップするコードってちょっと難しいですよね。
フォームはそのクラスのコードかいてるわけですが、コンポーネントは既に出来上がっているものなので、新たにメッセージ受けさせるのはちょっと面倒です。
というわけで、TMemoやTListBox等のコンポーネントにドロップ機能を付加するコンポーネントを作りました。
ActiveプロパティにTrueを設定すれば、Controlプロパティに指定したコンポーネントにファイルをドロップした時にOnDropFilesイベントが発生します。 OnDropFilesイベントは、TStrings型のDropFiles引数を持っています。このDropFilesにドロップされたファイル名が入っています。
また、Target引数はドロップされたコンポーネントです。Controlプロパティと同じものなので必要ないかとも思ったのですが、イベントを共有して使いたい時には便利かなということで。
LastDropFilesプロパティは、ドロップされた時のDropFilesを保持しています。最新の1回分だけですが。


壁紙付きListView等

ListViewって私はレポート状態で使うことが多いのですが、ラージアイコン状態で使うとゲーム板のように使えそうだなと思います。
ゲーム板として使うのにちと足らない機能をつけようということで「壁紙付きListView」というのをこしらえました。
Delphi2とDelphi3で確認してありますので、どちらでもどうぞ。
おまけといってはなんですが、ほとんど同じコーディングで「壁紙付きTreeView」というのも作りました。
さらに、「既にゲーム用ListView作っちゃった」という人にも使えるように、「壁紙付加コンポーネント」もあります。
スクロールさせたり、レポート状やList状にすると不備も目立ちますが、ゲーム用ということで勘弁してください。

WallPaperプロパティに壁紙として使用したいグラフィックを指定してください。
WallTypeプロパティは「中央に一つ」と「ならべて表示」の切り替えです。
壁紙付加コンポーネント「TKWallDeco」のControlプロパティは、壁紙を付加するコンポーネントを指定するものです。
OnWallPaintイベントは「壁紙を描く」ためのイベントですが、蛇足のような気もします。
CanvasプロパティはOnWallPaintの中でしか使えませんので注意してください。


バッチ起動ツール BatWin

小間物ツールで自分で便利に使えているものを紹介します。
私はWindowsになってからも、結構DOSツールを使うこと多いのですが、皆さんはどうですか。
昔作ったツールとか、awkのスクリプト等を起動するバッチファイルなんかを使うのですが。
これらって、コマンドオプションに入力ファイル名と出力ファイル名を必要とするものが多いのですよね。
エクスプローラやファイルマネージャからドラッグアンドドロップしたいとは思うんだけど、入力ファイル名の拡張子を変えた出力ファイル名を指定できないので結局DOS窓を開いて、ファイル名のフルパス打つのにいらいらしたり。
なんとかならないかなぁ、というので作ったツールです。

一種のスクリプトファイルを作って、ドロップしたファイル名をコマンドラインに仕立て上げ、DOSコマンドとして実行します。
複数のファイルをドロップして、順番に処理させることもできます。

Delphi2で作りました。ソースも公開しますので、好きなように改造なり何なりしてください。
Delphi2を持っていらっしゃるなら、ソースをダウンロードしてコンパイルしたほうがダウンロードサイズが小さくて済むのでお薦めです。


MailSlotコンポーネント

お約束どおり、Delphi2.0用MailSlotコンポーネントです。サーバーとクライアントに分れてまして、サーバーが受信側、クライアントが送信側です。これを使えば、簡単なチャットプログラムぐらいすぐ出来るんではないかな。
サーバー側とクライアント側で同じスロット名つけて、クライアント側にサーバーのコンピュータ名設定すれば、繋がります。クライアント側ではWriteで送信。サーバー側はOnRecvイベントで書き込みが判るのでReadで受信。クライアントからはサーバーが複数設定できるんで、いっぺんに複数送れます。
いずれ、このコンポーネント使ってカードゲームでも書くかな。
Helpがないんで、ソースのコメント見てください。(^^;;
コンポーネントのインストールのしかたは判ってますね?
Delphiのメニューからコンポーネント-インストールとたどって、ファイル名を選択するだけです。


KListsユニット

DelphiのTListって便利でよく使う反面、汎用的過ぎてちと困るってこと、ありませんか?
どっちかってぇとTStringListの方が楽だと思ってしまったり。
というわけで、TListの特殊化版です。ライブラリパスの通ったディレクトリに置いてください。

TIntList
整数専用TListです。
「キャストするだけやんかぁ」そうですがね、それが面倒なんじゃないですか。
というわけで、キャストしときました。IntItemsプロパティでキャスト済みです。
TObjectList
こっちはTObject用TListです。
キャスト済みプロパティObjectsがあるのと、ClearやDelete及び自分が破壊される時、メンバーもFreeします。(上書き時はFreeしませんので注意)
TFreeListとTDisposeList
ClearやDeleteそれに自分が破壊される時、メンバーをFreeMemしたりDisposeしたりします。
そんだけですが、用途によってはめんどくささが随分減るんじゃないかと思うんです。

[戻る]