[DFって何?][日記][コマンド一覧][関連リンク][予定表][他のファイラー][逃げ帰る]
NTFSのマウントボリュームを使用していると、空き容量などがマウント元の値を表示していたのを修正。
パラメータで、ディスクのルートディレクトリを指定する必要がないことに注意してください。この関数は、ディスク上の任意のディレクトリを受け付けます。
ドライブ指定ではなくて任意のディレクトリを指定できるようになっていたのは、このために使うのか。なるほど。
掲示板にて.が二つあるディレクトリに移動するとエラーメッセージがでてしまうと報告をいただく。
/を\に置換する処理を入れたせいかな、とか思いつつ試してみると発生しない。
のどちらをカレントディレクトリに指定しても何も起きない。
移動とは、ファイルの移動のことかと思ってチャレンジ。やはり何も起きない。
途方に暮れたところでデスクトップはWindows 98なのでこっちで試す。
出たッ!
Win9x系限定の罠。GetDiskFreeSpaceEx()にc:\hoge..hogeとか食わせると失敗する。
どうしろっていうんだ。
パラメータで、ディスクのルートディレクトリを指定する必要がないことに注意してください。この関数は、ディスク上の任意のディレクトリを受け付けます。
嘘つきッ!
ファイル一覧を取得した時に情報ウィンドウを更新していたのだけども、ここにアクティブだったら情報ウィンドウを更新するというように条件をつけていた。にも関わらず、非アクティブ側が更新されると情報ウィンドウを更新してしまうのはなぜだ。
…と思ったらソートした時にもついでに情報ウィンドウも更新していた。
DoSort()の内部で情報ウィンドウを更新するのを止めて、DoSort()を呼び出したあとに情報ウィンドウを更新するように修正。
一応これで勝手に更新されるということはなくなるハズ。
β56として公開。
位置が気に入らない。
はみ出そうになったら、メインウィンドウと同じ座標にでてきてしまう。
こんなところにこだわって実行ファイルが大きくなる罠。
まだソート処理中に情報ウィンドウを更新する部分があった。
ついでに、実行ファイルを削るために情報ウィンドウ更新処理を呼び出すところを、ソート処理の中だけにしてしまう。ディレクトリ一覧を取得した時にはソート処理を呼び出すので。
ソート処理を呼び出すとなぜかソートするだけではなくて情報ウィンドウまで更新してしまうという。普通に考えると余計なお世話という感じ。
でも、これで1KB削れた。
β57として公開。
主ウィンドウと副ウィンドウを切り替えたときに情報ウィンドウが隠れてしまわないように対策。
非アクティブ時に表示内容を更新すると、情報ウィンドウまで再描画してしまうのを修正。
表示位置を微妙に調整。
共有プリンタにカレントディレクトリを設定できてしまう、という話なので対策としてリソース一覧にはディスクリソースだけを表示するように修正。
β58として公開。
ソート処理の中で情報ウィンドウを更新するようにし、内部の処理の流れにあったムダをいろいろ削除。
この時に削除し過ぎた。ソートしない時に、画面の再描画をスキップして何もせずに戻すようにしたら、描画しなくなってしまった。
ここ、消す時に悩んだんだよなあ。基本的にこの後で描画し直すハズ、と判断して削除したのだけども、その後でさらに描画し直すところも削除したとかいう。脳内の作業領域が足りない模様。
β59として公開。
さらに、表示するファイルが無い時には
ということで何もせずにぶっ飛んで戻るようにしていたのを見逃してしまう。
ファイル一覧はないけど、上のパス表示部分とかは描画が必要だよな。あと、画面消さなきゃいけないし。
β60として公開。
Gのカレントディレクトリ変更コマンドで、入力ダイアログの初期値として、カレントディレクトリまたはカーソル位置のディレクトリを使うようにしているのだけども、1つもファイルがない状態だと初期値を決める時にカーソル位置がディレクトリかどうか判定しようとしてこける。
β61として公開。
SetCurrentDirectory("\\Server\Printer");
が成功しやがる。
で、その後にFindFirstFile()を呼ぶと失敗する。GetLastError()は1。
Cygwinのls(ってbash?)だとこのあたりのエラーハンドリングはどうしてるんでしょうか。
まさかプリンタにcdできるとは予想外で。GetLastError()が1というのはハンドリングしてませんでした。
まあ、FindFirstFile()を呼ぶ時には何らかの形でそのパスが存在しているのは確認済みのハズだから無視してもいいような気もする。
嫌なバグ発見。ってナイスなバグって無いか。DFのファイル作成機能で、クリップボードからBMPファイルを作ったら、ビットマップマスク分ずれている。
またBI_BITFIELDSのあれだ。
キーボードドロップで非表示ウィンドウも出てくるのは不便、という話がありとりあえず対応。
言われた時点でさくっと対応して「これでどうよ」とかやったらかっこいいかなとか思ったら意外と時間がかかってしまい全然かっこよくなかったりする。ちぇっ。
β62として公開。
メールをいただいたのでちょっと改造して送り返してみるテスツ。
内容は、インクリメンタルサーチ状態から即座にカレントディレクトリを変更できないか、というもの。一度EnterなりEscで閉じてからもう一度Enterを押すのが面倒、と。
とりあえず無条件にEnterを押したらファイルを開くコマンドを実行するようにして送り返してみる。
そのまま自分で使ってたら、日記。を更新しようとしてインクリメンタルサーチでindex.htmlにカーソルを合わせてEnterを押した途端にブラウザが起動してぐんにょり。
使い分けられるようにしないとダメだと思う。
switch(LOWORD(wParam)){ case VK_TAB: case VK_F3: if(GetKeyState(VK_SHIFT)&0x80000000){ case VK_UP: PostMessage(GetParent(hwnd), WM_COMMAND, IDM_INCSEARCHPREV, 0); }else{ case VK_DOWN: PostMessage(GetParent(hwnd), WM_COMMAND, IDM_INCSEARCHNEXT, 0); } return 0; }
いや、DFのコードの一部なんだけども。
自分でも、これはどうかとか思った。つーか、こんな書き方を許してしまうC萌え。
昨日の改造内容は、インクリメンタルサーチ中にEnterを押すことで、カーソル位置でEnterを押したのと同じ効果を持たせる、というもの。
やってみると、Enterで閉じるクセがついているので私的にはイマイチだ。あと、ファイルにカーソルを合わせたときに開いてしまうというのがわずらわしい。
というのはどうだろう。
ってのも欲しいかも。
痛みを伴う構造改革。
タブキーやファンクションキーで次の候補にカーソルを移動させたい。というわけで、それらの入力を拾う必要がある。
タブキーだとかファンクションキーの入力を拾うために、ダイアログのエディットボックスをサブクラス化している。
で、エディットボックスからダイアログに該当するキーが押されたことを通知する。ダイアログはその通知を受けてインクリメンタルサーチを行うようにメインウィンドウにリクエストを出す。
の3つのウィンドウがリクエストを出して動いている。OO的もいいのではないかと。
で、このリクエストをだす、というのが非効率的に見えてくる。インクリメンタルサーチ中にマークしたりディレクトリ移動を行おうとすると、それらの処理を追加した上にこれらのウィンドウ間のリクエストを増やさなきゃいけない。直接メインウィンドウが保持しているデータを操作することで中間流通経路をカットして不要なコストを抑えることが可能なのではないか。
それに直接操作する分、機能の追加にも柔軟に行き当たりばったりに対応できそうだ。
というわけで、今までstaticだったマークセット関数、再描画関数をグローバルスコープにしたら、テキストビューア/ビットマップビューアの再描画関数と関数名がバッティングしてやな感じ。
引き数の形式も同じだったらなあ(危険)。
今までメインウィンドウもビューアも再描画はRedraw()という同じ名前で統一感があったのだけど、残念ながら名前を変えることにする。
選択ファイル数をクリアするのを忘れていたので、選択ファイルがある状態で二画面モードに切り換えると世界が破滅するバグがあることを掲示板で教えていただく。
ちょっと前までは隠れていたのだけども先日、選択ファイル一覧を自前で描画するようにした時に顕在化したと思う。
β63として公開。
拾えねー。
つーか、拾ってるんだけどそのままWM_COMMANDまでいってしまう。エディットボックスのウィンドウプロシージャではダメなのか?
拾えねー。
昨日、拾えてると思ったのは錯覚だ。気の迷いだ、何かの間違いだ。
WM_KEYDOWMもこないでいきなりWM_COMMAND/IDOKが来ている。
別にこだわる必要もないのでインクリメンタルサーチの結果、ディレクトリを移動するかどうかの判定はIDOKで行うことにする。
β64として公開。
掲示板でのぐーさんに紹介されたページ。これを見て WM_GETDLGCODE の存在を思い出す。
で、DFのコードを見てみると…。
return uMsg==WM_GETDLGCODE ? (n | DLGC_WANTARROWS|DLGC_WANTCHARS|DLGC_WANTTAB) : n;
解ってるじゃないか、私。ってファンクションキーとかカーソルキーを拾ってるのだから当然といえば当然。ここでこの存在を思い出せなかったのと、DLGC_WANTALLKEYSを忘れていたのが敗因か。
掲示板で報告をいただいた、ビューアが出てくるまでに異様に時間がかかってしまう問題。
前回は再現できなかったのだけども、今回は再現できたので調査。
ということで逆アセンブルして追いかけるハメになる。
あたりをつけたところでマップファイルとアセンブルコードを見比べて、スタックダンプを見てみるとFindFirstFile()してないのにFindClose()を呼び出しているところを発見。これだっ!
FindFirstFile()のハンドルはローカル変数に突っ込んでいるので、そのときのスタックの状態によって挙動が変わってしまう。そのために、デバッグ用のルーチンを突っ込むと再現しなくなったり、最適化を解除すると再現しなかったり、ファイルの内容によっては再現しなかったりとなかなかに厄介。
β65として公開。
マークしたまますべてのファイルが消滅すると、内部でマークしているという情報が残ってしまっていたために外部コマンドのマクロ$Fなどを使おうとしたときに落ちてしまう。
β66として公開。
リストボックスに表示する文字列を生成する時に、仮想キーコードと文字コードの判定を間違っていたために仮想キーコードから文字列を生成するつもりで文字コードだと判定していた部分があった。
圧縮・展開コマンドが動作しない、という話だったので調べてみると、UnXXX()を呼び出すところをコメントアウトしていた。なぜ?
なんかテストした時に戻し忘れたのだと思うけど、何をテストしていたのだろう。割と最近の話のようだ。
β67として公開。
省略時はMS 明朝を使用なんて書いてあるけどウソ。FILEの値、ファイル名表示用のフォントを使っている。これはどうしようか。固定ピッチにしたいんだけどココだけ省略値を入れ換えるのも気に入らない。処理結果の妥当性から考えるとヘルプのとおりにしたいんだけども、ソースコードの妥当性(?)というか、他の処理との整合性というか統一感からすると現状動作にしたい。
これを調べるためにCONFIG.Cを見ていたのだけとも、呼び出している関数がCONFIG.Cに見つからなくてgrepした。すると、DF.Cにstatic関数として存在しやがる。異常。
1月頃、INIファイルを読み込んで初期設定する部分をDF.Cから抜き出してCONFIG.Cに分けたつもりでいたのだけども、実はこのソースはコンパイル対象になっていなかったという。で、今まで通りDF.Cにある初期化ルーチンが使われていた。
そもそもなんで分けようと思ったんだっけな。コンパイルが遅いから?
とかいうわけでカスタマイザとバージョンアップ支援ツールを作って同梱してアップロード。
ヘルプまで書き直す根性はなかったのでこれは後日。
実行すると、カレントディレクトリのDF.EXEを削除してから書庫を展開する動作をしていた。
そのため、書庫が存在しない場合には実行ファイルを削除した後でどうにもこうにもなら無い状態に陥っていたため動作を変更する。
ファイル表示用フォントのサイズを、他のフォントサイズの初期値として使用するように変更。
キー定義ファイル名が消えてしまうバグの修正。
プロパティシートのフォントページを初期化するときに、キー定義に関する部分まで初期化していたため。
β68として公開。
書き直しの作業に入ろうと思って読み返していたら、カスタマイザで対応していない設定が見つかる。
今までカッコを意味するブレイスのつづりを「blace」と記憶していたのだけど、辞書を引いたらbraceと出てきたのでびっくりする。
β69として公開。
shed.exeなんてキライだッ!
ホットスポットの座標、タブオーダー、コンテキスト文字列をExcelみたいに編集できるエディタってないかね。
ヘルプ用のグラフィック作るのが大変。
キーワードって二重までしかぶら下げられないのか…。
圧縮オプション、Hall compressionを有効にしたらヘルプコンパイラが死ぬ。なんでやねん。
処理が終了したらDFを起動したほうがいいね。
黙々とファイルを削除して書庫を展開するのもどうかと思ったのでウィンドウを作るように作り変えてみる。
DFのバージョンアップ支援ツールを使ってみるテスト。
おー、動いた動いた。昔のバージョンのバージョンアップ支援ツールが。
なんでやねん、とか思いつつ調べて見たらXのファイル名を指定して実行、で実行ファイルを検索する順序がおかしい。
カレントディレクトリではなくて、実行ファイルが有るところのが優先されてしまう。回避策は有るのか。
CreateProcess()自体が実行ファイルのあるディレクトリを優先して検索してしまうから、CreateProcess()を使わずに処理するしかないのか。自分で検索するとか。コマンドプロンプトはどうやっているのだろう。
というか、ココまで書いた時点ですでに諦めの境地。
長年の懸念事項だったカスタマイザも一段落したので、正式版リリースに向けてヘルプを書こう。
SHED.EXE使いにくいんだよコンチクショウ。
せっかくだからUTF-16対応の作業を開始。
改行コードの取り扱いでハマる。
現状のテキストビューアは、改行コードがCRLFと設定されている時、CRLFを2バイト文字として取り扱っている。CRを発見した時には続くLFが有るかもしれないのでファイルからバッファに先読みを行う。
UTF-16の場合は、1バイト目だけをみても仕方がないのでとにかく後続バイトがあることを確認するために先読みし、それがCRだった場合にはさらに先読みを行うというまわりくどいコードになってしまった。
さらに、内部バッファでは行頭をポイントするインデックスを用意しているのだけども、これも改行コードの取り扱いが変わるのでインデックスを張り直さなくてはならない。ちょほいと厄介。
まあ、今日のところは変更点が判ったということでこの辺にしといてやる。覚えてやがれ。
読み込みバッファには、4,096バイト単位で読み込んでいるので、少なくともCRLFの最初のCRはバッファサイズの確認をしなくてもアクセスできることに気付く。
というわけで、バックアップからソースをロールバックしてコーディング。
あれ、改行が化ける…。
TextOutW(draw->dc, x, draw->y, (LPCWSTR)p, len);
len(描画するバイト数)ぢゃねーよ、1だよ1!
もしかして、寝る前にうまくいかなかったのはここだけだったとか?
β70として公開。
最後に選択したところからカーソル位置までを選択するコマンドを追加する。
β71として公開。
晩ご飯は焼肉。食べ放題。
で、食べながら脳内でコードの検証を行う。
ファイルが奇数バイト長の時にマズイ。有るものだ、という前提の元(そういう仮定の元でコードを書いたから)16ビット読もうとする。
x86のページが奇数バイト長だったりして、運悪くその長さのファイルをビューアで開こうとすると一般保護例外が出るハズだ。
実際にはx86のページは4,096バイトなので一般保護例外を出す余地は無いのだけど修正が必要だろう。
というわけでUTF-16の改行コードの処理を修正する。
β72として公開。
ディレクトリを装飾するためのカッコを変更できるように仕様変更。
DIRBRACEにカッコを直接記述する。空白を指定したときには表示しないので、末尾に何かつけるといった芸も可能。
β73として公開。
manifestファイルを埋め込んでみる。
するとダイアログの中身が一部欠けたりすることが解ったので少し隙間を空けるように配置しなおす。
ダイアログリソースを修正するついでに、キーボードドロップダイアログの「非表示ウィンドウを隠す」チェックボタンにアクセスキーを設定する。
せっかくだから付けてみる。イマイチ。
β74として公開。
範囲選択する際の、開始位置をどうやって求めるか。
最後に選択した位置を覚える、というのは覚えるためのメモリがもったいない。ので、次のようなコードを書く。
no = selects;/* 選択している数 */ for(i = 0; i < files; i++){ if(file_list[i].sel_no == no){ /* コレだッ! */ goto FOUND; } } i=0; FOUND:
こんなにだらだら書くなら、最後に選択した場所を覚えた方がコードが短い。
このコードを削除することで30バイト短くなった。選択した場所を覚えるために6バイト消費。選択した場所を記憶するために8バイト使う。差し引き16バイト短くなった。
頭文字検索をShiftキーとかを押さなくても出来るようにしてみるテスト。
割とあっさり出来た。というか、このキーをある程度変更できるようにコードを組み立てていた。偉いぞ昔の私。
で、困ったのがINIファイルの書式。CTRLSEARCHってCtrlキー以外のことを考えていない名前だ。なんかいい名前無いかな。
反転にしてみるテスト。
とあって、aを選択する。
とあって、cにカーソルを合わせて+を押す。
aの位置から選択状態を反転すると
となる。なんか違う。
aの次から選択状態を反転すると
となる。よさげ。
次に解除してみる。
この状態からaの位置にカーソルをあわせて+を押す。
最後に選択したcの次、つまりbから選択状態を解除する。
なんか違う。
β75として公開。
β76として公開。
そこで逆転ホームランですよッ!?
CTRLSEARCHというのは、CtrlキーでSearch、という意味ではなく、SearchをControlするオプションなのだ。
と解釈すると現状のままでまったく問題が無いことになる。どうよ。
β77として公開。
8:00起動。
掲示板にDFのテキストビューアの不具合についての報告。調べる前に、読んだことを示すために簡単な返答を付けてから調査。
なんか予想外の事態なんですけど。
とりあえず、寝る。
UTF-16だと2バイト単位のハズなのに、なぜか1行のバイト数が奇数になっているなあ。
改行コードをCRLF以外にすると化ける。何故だ。
キーボードドロップで、非表示ウィンドウを隠すオプションを最初からONにするオプションを追加する。
β78として公開。
テキストビューアでUTF16の改行位置が1バイトズレているバグを修正。改行コード切り替えでの不具合対応。
β79として公開。
[OPT]セクションにDOTオプション追加。DOT=1で"."と".."を表示(既定値)。DOT=0で非表示。
β80として公開。
想定している初期値と同じ値が指定されたら、設定ファイルからも削除するような仕組みを作っていたのだけども、本体とカスタマイザで初期値を間違えていた。
おかげでキー定義のUSEDEF=0が記録できないバグ。この辺りの処理って本体と共通化できるといいんだけど、作り方が悪いのでうまくいかない。
更新遅延中に、再度更新要求を受け付けると、遅延時間を延長せずに即更新していたのを修正。
β81として公開。
ファイルを選択して外部コマンドを実行すると、$Fが使われているときには$Fを選択したファイルに置き換えて、繰り返して実行する。5つのファイルを選択しているときには、ファイル名を入れ替えながら5回繰り返す。
こういう仕様で作っていたのだけども、$Pに関しては繰り返す理由が無い。にも関わらず繰り返していたし、それで正しいと思っていた。繰り返すつもりで作ってテストしたので見逃してしまう。
β82として公開。
DFCUSTでACTIVEの値を書き込むのを忘れていた。
インストール。
途中でファイルが無いとか言われてエラーが出たが、CD-ROMを入れ換えると先に進めた。だったらDISK2を入れてくれとかいうメッセージを出して欲しい。
レジストリのRestrictRunがあるとコンパイルできないという罠にハマる。
さっそくDFをコンパイルしてみる…がコンパイルオプションの設定方法を探すのに手間取る。
出来上がったバイナリは88KB。Windows 95OSR2でも動作した。
無印のWindows 95が動いているマシンが手元に無いので(Libretto 30は譲ってしまった)試せない。
Alt+Enterでディレクトリのサイズを計測すると、F2を使ってサイズを表示している時に表示が乱れるバグを修正する。
DFでファイル検索をサブディレクトリごと出来ますよね。
で、それで*.htmlとしてサブディレクトリの中の全部のhtmlファイルが表示されました。
次にそれらのファイルを全部index.htmlにしようとして、ファイル全部選択してr押して 「連続名前変更」ダイアログを出したまでは良かったんですが、そこからどうやれば全部をindex.htmlに変えられるのか分かりません
もちろんファイルの場所は変更しません。変えたいのはファイル名だけ。
どうしましょう。
*.txtとかhoge.*とかそういう使い方は想定して作りましたが、こういう使い方は想定してませんでした。考えてみよう。
というシンタックスだと違和感無く使えますかね。今の判定ルーチンがいいかげんで、.の有無だけで判断しているのですぐには変更できませんけど。
っていうか、他にも1文字単位の置換とか文字の削除とかもサポートしたいのだけど。
この程度で正規表現使うのも面倒。というか、書き間違えた時の被害がちょっち。
というわけで(なにが)、Tのウィンドウ切り替えで一覧に出すウィンドウの選別方法を変えてみる。WS_EX_TOOLWINDOWなウィンドウは一覧に出さないようにして、親ウィンドウがあるかないかの判断を簡略化する。
114バイトしか縮まなくてぐんにょり。
単に、ディレクトリ部分はそのまま保存したほうがいいのか?
123.TXTをA*.TXTに置換したときにA23.TXTにするのとA123.TXTにするのは、どっちが好ましいのだろう。好みの問題でどちらでもいいのだろうか。
1.2を??????.*でリネームすると1.2.2になってしまった。
?については、.が現れるまでは.までをコピーする仕様とした。現状の*と同じ動作。
これでまた100バイトほどサイズが増えてしまった。この間114バイト削ったので差し引き0って感じ。
結局次の構文を用意した。
ちょっちパイプライン乱せば縮まるところがあるので縮めにかかる。Pentium !!!ならあまり影響の無いパイプラインの乱れかただし、Pentium 4ならパイプラインがストールしてもトレースキャッシュに収まっていればデコードしなくてもいい分速くなるかも。持ってないので試せない。
そもそも、差が小さすぎて計測できないので概ね問題なし。
っていうか、本来はPentium(Libretto 60)とかMediaGX(FIVA 101)で速くなるように書かなきゃいけないのだが。
β83として公開。
DFで$MF使った時に、マーク無しの時も""を付けてもらえると有り難いんですけど、どーでしょうか?
ということで付けてみる。
β84として公開。
オプションを増設する。
でも、二画面になるだけで意味がない。
どうせなら、二画面目のディレクトリも指定できるようにしたいのだが、今用意してある関数はディレクトリを指定する仕組みが無い。主画面を複製する関数として作ってある。この関数を作り替えるか、別バージョンを作るかしないと。
というわけで、
というパラメータを持つ関数に作り変える。
アクティブにはならないけど、後からウィンドウを作るために手前にきてしまうのが難点。
β85として公開。
-wオプションで副ウィンドウのカレントディレクトリが指定できるようになったものの、なぜか主ウィンドウのカレントディレクトリが指定できなくなってしまったので修正。
β86として公開。しかし更新作業に失敗したため、バグが修正しきれていなかった。
β87として公開。
-wオプションを使用した時、ソートとかの表示条件を主ウィンドウから引き継いでいなかったのを修正。
β88として公開。
WM_ACTIVATEのハンドラで、アクティブになったらカーソルを表示するように仕組んでみたら他のアプリのウィンドウをアクティブにした時には非アクティブが先に来るらしくカーソルを非表示にできなかったりした。
仕方がないので、個別に1ビットずつ使ってアクティブか非アクティブかフラグを持つようにした。
最大化した状態から二画面にすると、ウィンドウのサイズは最大化する前のサイズなのに、描画は最大化したサイズで行うため描画が乱れていた。
パラメータを丸ごと引き継いでいたのを止めて、一部のパラメータだけをコピーするように修正する。
コピーしやすいように構造体のレイアウトを変更する。
β89として公開。
構造体定義を変更したものの、それが反映されないままコンパイルしてしまいマクロ展開部分がクラッシュするようになってしまった。
makefileを修正し、念のために全モジュールをコンパイルする。
β90として公開。
メールはこちらCopyrigiht © 2002 びい(@nifty ID:RXA01732)