HTMLエディタを作る(19)(2001/05/05)
新着情報 トップメニュー ボードメニュー 掲示板 お手紙はここ!

ううん。ここんとこサバゲ記事ばっかだったんですがこっちもちゃんと進行してますよ……(^^;) 同時進行で、MPStructor の汎用編集型バージョンとか卓上デジタル時計とかも開発していたんで遅れちゃあいますけど。あと SSTP サーバーとかね。

部分的に「全く手付かず」の部分がありますが、実装している部分に付いては細部まで整ってきました。正規化フィルタに若干の致命的バグがあるぐらいで……なんで壊れるんだろ(汗) ByteType() 関数がたまーに間違った値を返すからだな。うん。そう言うことにしとこう。

そう言う事で今回は主にデバッグ中心でやってきまして、後ヘルプが四割ぐらい書けたかな……リファレンスって書くのダルいねぇ。自分で解ってないまま書いてたりとかザラだし、あと機能追加で無意味になった処理とかを、信じて書いてみたりとかしてました。下手をすると Delphi ライブラリの仕様自体が解ってなかったり……。



よくある、メニュー項目でファイルの履歴を並べると言うヤツをやってみた。もー、全然思い付きコーディング(^^;) でもまぁそれなりのモノにはなったと思われる。こんなの。


procedure TfrmAppMain_MPS.AddHistoryList( AFileName:TFileName; Histories:TStrings;
TopMenu,FirstMenu:TMenuItem ); var Idx: Integer; I : Integer; MNU: TMenuItem; begin if (AFileName <> '') then begin (* 履歴リストへの格納 *) Idx := Histories.IndexOf( AFileName ); if (Idx >= 0) then Histories.Delete( Idx ); Histories.Insert( 0, AFileName ); end; (* 履歴リストから五個以上は消しちゃう *) Idx := TopMenu.IndexOf( FirstMenu ); for I:=Histories.Count-1 downto 5 do Histories.Delete( I ); (* 履歴リストからメニュー項目へのセット *) for I:=Histories.Count-1 downto 0 do begin MNU := TopMenu.Items[Idx+I]; MNU.Caption := ExtractFileName( Histories[I] ); MNU.Hint := Histories[I]; MNU.Enabled := True; end; (* 不足分は初期化する(実質的に不要な処理) *) for I:=Histories.Count to 4 do begin MNU := TopMenu.Items[Idx+I]; MNU.Caption := '(なし)'; MNU.Hint := ''; MNU.Enabled := False; end; end;

見たままの処理であるが、綺麗に動いているので納得の算譜である。Histories に相当する TStringList は別の場所で生成・破棄されるオブジェクトで、MPStructor では文書とツールバーの履歴で使っている。まぁその辺は実物を見てどうなってるか確認してみそ。



MPStructor ではエディタの編集コマンドの多くが TAction のショートカットで定義しなおされてるんだけど、これは TEditor がポップアップメニューを切り替えた後で上手く動かないからなのよ! でもってメインフォームでそう言う事をすると、サブフォーム上のエディタとかでも Ctrl+X/C/V/Z とか全然利かなくなるのな。

仕方がないんでサブフォームにも TAction を作って Ctrl+X/C/V/Z を再定義、中身を

procedure TfrmBrowser_MPS.actCutExecute(Sender: TObject);
begin
    ActiveControl.Perform( WM_CUT, 0, 0 );
end;

とする。何かすんげー馬鹿馬鹿しいぞ! しかも、TComboBox のエディット部分はこの方法では WM_UNDO を受け付けないと来たもんだ。コレ以外は WM_CLEAR に至るまでバッチリ通るんだが……謎過ぎる。

そこら辺で Delphi-ML のバックログ見渡すも該当せる回答なし。仕方がないから自分で質問を挙げてみたらすぐに返事か来て良かった良かった。

実際には、コンボボックスのエディタとリスト部分は別のコントロールだと言う知識はあったんだけど、他のメッセージは受け付けるんで WM_UNDO だけ通らない理由が何かあるに違いない……とそう思ってたのだ。

しかしそう言うわけじゃなく、他だ単にコントロールが不親切であるだけらしい(汗) 結局、エディタのハンドルそのものへ送らないと行けないらしい……。無論コレは考えていたのだがスパイして GetWindow() してっての、あんまり好きじゃないんですよねぇ。ゴチャゴチャするし。

TCustomComboBox には Protected フィールドだが EditHandle と言う、エディタのハンドルを返すメソッドが定義されているのでそれを使っても良いとのこと。だけど……それだけの為にクラスを継承してコンポーネントを登録するのはダルいっしょ……

んで、考え付いたのがこれ。

type TReferenceCB = class(TCustomComboBox);

procedure TfrmBrowser_MPS.actUndoExecute(Sender: TObject);
begin
    if (ActiveControl = edtURL) then
        SendMessage( TReferenceCB(edtURL).EditHandle, WM_UNDO, 0, 0 )
    else
        ActiveControl.Perform( WM_UNDO, 0, 0 );
end;


でも、Delphi-ML では「ReferenceCB クラス(およびそのサブクラス)のインスタンスでもない ComboBox1 が、TReferenceCB クラスへキャストされていることのほうがイヤ」と言われてしまいました……とほほ〜。

まぁ美学の問題でしょうが、俺に言わすと「ジジィで定義したメソッドはジジィに化けてアクセスする」ほうが好しと思うんで。むろんインスタンスの雛型である TComboBox でキャストすると辺か、というとそうじゃないんですがこのクラスでは何も動作を拡張していないのだし……。この場合はたった一つの特定のクラスの為にキャストするのだから問題なし。と、思います。

もちろん、動作の方は問題は出てないっすよ。……今のところ(ぉ



と、言うわけで四ヶ月ぶりにリリース。ビルド回数は増えてないけど、ファイルサイズは死ぬほど伸びた(^^;) アバウト画面とかに画像使ったからだな……。偽同盟のバナーも入れたし。とは言うものの、偽春菜をインストールしてないと……いや、これは内緒にしておこう。イースターエッグって言うほどじゃないよ。念のため。


ダウンロードする(mps0202.exe/1,712KB)


新着情報 トップメニュー ボードメニュー 掲示板 お手紙はここ!