[DFって何?][日記][コマンド一覧][関連リンク][予定表][他のファイラー][逃げ帰る]
BITMAPINFOHEADERのbiSizeImageを0にしてデコードするプラグインに対する処理を追加。
このメンバ、0になることがあるので.BMPを展開する時には0だったら計算するような処理を要れてあるのだけど、Susieプラグインを使った時にはこの処理が抜けていた。
というか、もう少しで共通化できそうなんだけどなあ。
0.03β22として公開。
ファイル一覧にファイルが無い時にShift+Enterを押すと落ちるという報告を頂く。
コレって、Shift+Enterで反対側ウィンドウのディレクトリを変更するようにしてからのバグだと思う。
DFはコマンド番号で、
を決めている。
Shift+Enterの「エディタで編集」コマンドはカーソルがファイルを指していればOkだったのでbit14をONにしていた。
それから、ディレクトリを変更するコマンドにした時にファイルを指していなくても使えるのだから、とうっかりbit13,14をOFFにした番号を割り当ててしまったため特に制限無く使用できる処理に分類してしまった。
このために、この時点で判定していたはずのファイルがあるかどうかという処理をスキップしてしまい落ちていたという。
個々のコマンド処理部分で実行できるかどうか判断したほうが安全なのは判っているけど(というか、チェックは多ければ多いほど安全にはなる)80個のコマンドがあるなかでそれぞれでチェックするのは無駄が増えるので一ヶ所でチェックしている。
ソートで落ちる、というのも呼び出し元でチェックしていたのでソート処理を行う時には安全であることが保証されていたのでソート処理の中ではチェックしていなかったのが裏目に出たもの。
フォルダ、ウィンドウ位置、ウィンドウサイズ、を指定して 開けて、出来たらマスクを指定できるやつ。
このくらいならすぐ…かな? できなくはないし、あっても良さそうなので付けましょう。
あ、起動時のマスク指定はは面倒なのでやらないかも。少なくとも、今はやらない。後でやるかも知れない。
追加したオプションは次の2つ。
ウィンドウ位置指定オプション。INIファイルの指定より優先されるハズ。
-pos0,0でウィンドウを座標(0,0)に表示します。
-pos と 座標指定の間には空白があっても構いませんが、X座標とY座標の間に空白があってはいけません。
たとえば -pos 320, 200と,の後に空白を書いてしまうと200は初期ディレクトリの指定だと解釈します。-pos "320, 200"ダブルクォーテーションでくくっても無駄です。
Y座標は省略できます。省略した場合にはINIファイルで指定された初期表示位置のY座標が使用されます。初期表示位置を指定していない場合にはとんでもない場所(画面外)に表示されるようになるので注意してください。
ウィンドウサイズ指定オプション。INIファイルの指定より優先されるハズ。
-size320,200でウィンドウの大きさを横320ピクセル、縦200ピクセルにします。
-posと同じく、-size と 座標指定の間には空白があっても構いませんが、X座標とY座標の間に空白があってはいけません。
縦のサイズは省略できます。省略した場合にはINIファイルで指定されたウィンドウサイズの縦が使用されます。INIファイルでも指定されていない場合には初期値のままです。
ダブルクォートでくくられた文字列の扱いに何かの間違いがあり、それ以降のオプションを正しく取り扱っていないバグを修正。
文字列をパースする時、パーサの戻り値を次に処理する文字へのポインタとしていたのだけども、ダブルクォートでくくられていた場合は終わりのダブルクォートをポイントして返していたため、次のオプションとしてダブルクォートを処理しようとして破綻。
abcde 12345をパースした時の戻り値は「abcde」の次の空白を指したポインタで、空白はスキップするから問題なし。正しく次の「12345」を処理できる。
"abcde" 12345をパースした時の戻り値は「"abcde」の次の"を指したポインタを返してしまっていたので「" 12345」を処理しようとしてしまう。
ヘルプファイルに14日(β24)で追加したオプションについて記述する。
DFでゴミ箱送りにするときに確認のダイアログはWindows任せにせずにDFが出してくれたら速くていいかも。ってできるんだっけ?
できますがやってません。そういうフーには作っていません。
ダイアログを自前で出しても、遅いのはシェルのナニの問題というか仕様というか制限なので削除が終わるまでの時間は早くならないような気が。
切断機能が動いてない。
いや、前から動いてなかったんだけどまれに動いていたのでてっきりWindows 98だからこんなものか、という程度にしか考えてなかった。
Windows XPでも動かないとなるとこちらの問題なので(っていうかWindows 98で動いてなくてもこっちの問題であることが多いのだけど)調べる。
ダイアログで何を選択したか、というのをうまく返せていない。行き当たりばったりな返し方をすれば回避できるけど、ちょっとイヤなのでダイアログに渡すパラメータを増やして対応する。
いや、動けば正義なんだけども。
アクセス権のないディレクトリにカレントディレクトリを変更しようとすると無限ループしやがる。
という感じにしていたら、WNetAddConnection2()が成功したと返ってきている。こうなるとDFは接続できたと思いこんでいるからSetCurrentDirectory()を試みる。失敗する。何かの間違いかと思って再度WNetAddConnetion2()を試みる、という流れ。流れてないから回転。
よくわからないけど、ディレクトリに対するアクセス権というのが接続権と参照権みたいなのがあるんだろうな。unixでいうところのr権限とx権限みたいな。
NTFSにもあったような気がするけど忘れた。WRCFのどれが該当するのだろう。
昨日、ダイアログパラメータを増やした時、トレースしにくいのでコンボボックスのサブクラス化をしないでテストしていた。
うっかりとそのことを忘れてアップロードしてしまい、コンボボックスでキーを押しても何も起きないバージョンになってしまった。
安易に完成したと思い込むのはどうにかならないものか。
コマンドラインでカレントディレクトリを指定されたときに、長すぎるとバッファオーバーフローを起こすコードになっていたので対策。
処理中にうっかりしてまたダブルクォートの取り扱いを間違えるというミスをやってしまい、メールでご指摘いただいた。感謝。
0.03β28として公開。
間違えて別のファイルを削除するのが怖くて、ここ最近はマークしてファイル名を確認してから消している。
どうせならこれを、マークしてないと消せないようにしてしまおう。
削除だけ対応しているのも不自然だから、コピーとか移動にもセーフティーをつけよう。
なんかあふっぽい。
そういえば、あふの動作オプション、マーク無しファイル操作の存在を知っていればDFを作らずにあふを使っていたかもしれず。
セーフティーはDF.INIの[OPT]、MARKOPを記述する。
bit0 | コピーのセーフティー |
---|---|
bit1 | 移動のセーフティー |
bit2 | 削除のセーフティー |
なんで削除の方がビットが上なんだろう。
ものはついで、ということで2画面時にはコピー先、移動先を問い合わせないという動作を復活。オプションにする。
このオプションの名前が思いつかない。
[OPT]
XXX=1
さてなんて名前にしよう。
このままというのもアグレッシヴでナイスだが。
オプションが増えたので、多少なりともコードを小さくなるように書き換える。
各スイッチは32ビット整数のビットに対応させていたのだけども、気分的な美しさから分野ごとに隙間が開いていた。
これを連続させて詰め込んでしまう。
で、
if(GetPrivateProfileInt("OPT", "EXTCMD", 1, szCfg)){
vdwOption |= USE_EXTCMD;
}
なんて書いてあったのをテーブルで処理するように書き換える。
選択ファイルの一覧ウィンドウの位置が気に入らない。
今まで解像度が低かったので気にならなかったけど。
という感じを目指していたのだけど、今の動作は
でちょっち違う。
問題は、どのくらいずらすか何だけども。かっこいいズレ具合というのは無いものか。
生成コードは小さくなったのに実行バイナリは大きくなった。うーん。
拡張子にこだわらず動かせるものは動かす、というというのりで作っていたのだけど、最近のワームを見ているとちょっとよろしくないような気がしていた。
DF.EXEをDF.GIFにリネームし、DFからDF.GIFを実行するとちゃんとDF.GIFが起動する。しかし、スタートメニューのファイル名指定して実行だと.GIFに関連付いたもの(ビューアとか)が起動するだけでDF.GIFは起動しない。
最近は拡張子やcontent-typeを偽って実行ファイルを送り込みクライアント側で実行させてしまうという技が流行しているのでこれはマズい。画像だと思ってANIKI.BMPを開こうとEnterキーを押したら実はデスクトップマスコットで画面中にとんでもないものがあふれかえってしまうという恐怖れが。
というわけで、CreateProcess()で実行するのを止めて、ShellExecuteEx()で実行するように修正。
するとどうよ、ANIKI.EXEを動かしたくてコマンド入力で「ANIKI」と入力するとカレントディレクトリにあるANIKIディレクトリが開くではないか。Explorerで。こりゃダメだ。
それならばとSearchPath()で実行可能ファイルを探してからフルパスで実行してやろうじゃないか。
ダメだ、SearchPath()が先にカレントディレクトリにある、同名のディレクトリを見つけてしまう。ディレクトリは要らないんだってば。ファイルだけ検索するようなオプションは無いのか。
仕方がないのでSearchPath()に拡張子「.EXE」を指定して検索させる。おー、うまく動きそうだ。これでいこう。
あ、FDうごかねーや。FD.COM。
という感じで何度も検索しないとダメってことか? それはいやだ。別の手を考えよう。
拡張子を探して、見つからなければCreateProcess()で実行してみる、というようにしてみた。拡張子が.GIFな実行ファイルも実行できなくなった。よし。
まだ仮の部分があるけれども、マズい動作をするよりはマシだろうと思って0.03β29として公開。
#define LOAD_POS 0x00002000 /* OPT:POSITION 0x01 */ #define STORE_POS 0x00004000 /* OPT:POSITION 0x02 */
/* 位置記憶、復元 */ dw = GetPrivateProfileInt("OPT", "POSITION", 0, szCfg); dw &= 0x03; /* マスクする */ vdwOption |= (dw << 17);
違うよ、17ビットもシフトしたら0x0002000になっちゃうよ。一桁多いよ。
0.03β30として公開
拡張子を判定するために、実行ファイル名とパラメータを分割、それから拡張子を取り出していた。
その後で実行する時に、実行ファイル名とパラメータを連結するのを忘れていたので、外部プログラムにパラメータを渡すことができていなかった。んがー。
0.03β31として公開。
今考えれば、拡張子まで一致した同名のディレクトリが存在していたらダメじゃん。
SearchPath()捨て。
アクセス権のないディレクトリにカレントディレクトリを変更しようとすると無限ループしやがる。
という感じにしていたら、WNetAddConnection2()が成功したと返ってきている。こうなるとDFは接続できたと思いこんでいるからSetCurrentDirectory()を試みる。失敗する。何かの間違いかと思って再度WNetAddConnetion2()を試みる、という流れ。流れてないから回転。
よくわからないけど、ディレクトリに対するアクセス権というのが接続権と参照権みたいなのがあるんだろうな。unixでいうところのr権限とx権限みたいな。
NTFSにもあったような気がするけど忘れた。WRCFのどれが該当するのだろう。
コピー先入力のダイアログプロシージャを書き換えたら、こちらにも影響が。
コピーのデフォルト動作が
とちょっち違うので、このフラグの扱いを書き換えたら失敗。
内部的にコピーの時の「ディレクトリ付きコピー」ボタンと、貼り付けボタンが同じなもので。
ビューアウィンドウで仮名漢字変換を無効にしていないため、仮名漢字変換を起動させることができてしまう。
そのため、辞書がロックされてしまいメンテナンス出来なくなるという不具合。
テキストビューアのタイトルバーに文字コードと改行コードを追加。
ヘルプの説明と実際の動作が食い違ってた。
ヘルプをそのままにしてソースを修正。
テキストビューアからエディタを起動する時のコード。
n=GetWindowTextLength(hwnd);
if(n){
CloseHandle(txt->hFile);
txt->hFile=NULL;
pszTarget=malloc(n+3);
GetWindowText(hwnd, pszTarget+1, n+1);
pszTarget[0]='\"';
pszTarget[n+1]='\"';
pszTarget[n+2]='\0';
ExecProcess(hwnd, vpszEditor, pszTarget, txt->w.pList->szCurDir);
bFree(pszTarget);
goto CLOSE;
}
ウィンドウキャプションにファイル名を表示しているのでそれをそのまま使っている。
ここに文字コードを表示すると破綻する。
というわけで、しかたなくウィンドウキャプションとは別にファイル名を保持するメモリを確保。ううっ、もったいない。
0.03β33として公開。
掲示板にて、Windowsを終了させることができない、との報告を頂く。
手元のSRX3(Windows XP)だと終了できるので(できなければ気づいているはず)わけがわからない。
どういう時にExitWindowsEx()が失敗するのか調べてみる。
This behavior is caused by the design of the hardware or driver.
INFO:ExitWindowsEx() Does Not Shut Down or Restart Win 95/98/Meより
んがー。
どのドライバがワガママ言っているのか調べる方法は無いのだろうか。
コマンドラインに、対応していないオプション文字列、誤ったオプション文字列を指定すると、それをディレクトリ指定だと解釈してしまう不具合発見。
オプションに-hequil と指定すると、-を認識してオプション解釈を始めるのだけど、オプション文字列テーブルにはそんなものが無いので検索してもヒットしない。
で、次の解析を行うのが-の次の文字からになっていたのでhequilという文字列を認識する。-が無いのでこれをディレクトリ指定だと解釈する。
これでは困るので、オプション文字列テーブルにヒットしなかった時には空白が見つかるまでポインタをずらす。
-dオプション追加。
すでに起動しているてきとーなDFのウィンドウのカレントディレクトリを変更するように修正。
簡単にWindowメッセージによるプロセス間通信を突っ込む。約1秒でタイムアウトする。
Mutexを使うまでもないと思ったので、FindWindow()でウィンドウを検索して見つかったらすでに起動済みと判定する。
CreateMuex()と違ってFindWindow()、CreateWindow()の連続はatomicな動作ではないので、運がいいと二重起動を防止してても複数起動してしまうが、そこは残念な思いをしていただく。
そこで、できる限り早くウィンドウを作成することを考える。プログラムが起動してからできるだけ早くウィンドウを生成しておけば、誤作動して残念な思いをする確率を減らすことができる。
一つめのDFがもたもたしている間に後から起動した二つめのDFが追い越してウィンドウの検索できずにウィンドウを作ってしまう、ということが減らせるわけだ。無くせるわけではない。
という訳でウィンドウを作るまでに行っている処理を調べる。
ウィンドウを表示するには、表示する位置と大きさが決まってないといけない。あらぬところに表示されてから移動するのではみっともない。
位置を決めるにはDF.INIのPOSITIONを読み込んだり、コマンドラインの-pos、-sizeを解釈する必要がある。
そのため、
は必要。
カレントディレクトリ決定は後でもいいだろう。
設定ファイルの読み込み、この処理はDF.INIをとにかく読み込んでいるけど
の二つに分けるというのはどうだろう。
こうすることで、若干ながらウィンドウの生成までの時間を短くできる。
試しに実験してみたら、設定ファイルからウィンドウの背景色を読まないとウィンドウクラスの登録で変なものを登録してしまうので描画がおかしくなった。
これはイマイチ。
-f オプション追加。
この間、-pos/-sizeオプションのためにコマンドライン解析ルーチンを作り直したのでだいぶ楽。
0.03β34として公開。
0.03β35として公開。
この間、設定ファイルの読み込みを分割することでウィンドウ生成までの時間を短縮しようとして失敗したけども、
に分けるというのを思いついた。
static const struct option_param tab[]={ {"d" , CL_NOP}, {"f" , CL_STRING}, {"pos" , CL_POSITION}, {"size", CL_POSITION}, }; p++;/* スイッチ文字列スキップ */ for(stat=0; stat < (sizeof(tab)/sizeof(tab[0])); stat++){ len = lstrlen(tab[stat].param); if(_memcmp(p, tab[stat].param, len) == 0){ p+=len; goto FOUND; } } goto NOTFOUND;
DFのソース、CMDLINE.Cより
この部分なんですがforの継続条件は最初
for(stat=0; stat < 2; stat++)
だった。
書いた時は2個しかないし、面倒だし、と手を抜いたんですが、書き換える時に手を抜いたことをすっかり忘れてました。
で、オプションをテーブルに追加した時にこの部分を2から4に書き換えるのを忘れたので-posと-sizeが無視されると。
こういうのは定数にするよりは機械に計算させたほうが間違いは無いので、#defineで定数を作るよりは、今回書いたような式にするのが吉。というか定説。
判っちゃいるけどやめられない。
DFなんか動作が変です。
んがー。
- abcdef-1.jpg
- abcdef-2.jpg
- abcdef-3.jpg
- abcdef-4.jpg
- abcdef-5.jpg
- abcdef-6.jpg
- bcdefg-1.jpg
- bcdefg-2.jpg
- bcdefg-3.jpg
- bcdefg-4.jpg
- bcdefg-5.jpg
- bcdefg-6.jpg
とある時は、*1.jpgのマスクでちゃんとabcdef-1.jpg,bcdefg-1.jpgになるのですが
- abcdef-1.jpg
- abcdef-2.jpg
- abcdef-3.jpg
- abcdef-4.jpg
- abcdef-5.jpg
- abcdef-6.jpg
- abcdefg-1.jpg
- abcdefg-2.jpg
- abcdefg-3.jpg
- abcdefg-4.jpg
- abcdefg-5.jpg
- abcdefg-6.jpg
- bcdefg-1.jpg
- bcdefg-2.jpg
- bcdefg-3.jpg
- bcdefg-4.jpg
- bcdefg-5.jpg
- bcdefg-6.jpg
とある時に*1のマスクをするとabcdefg-5.jpg,abcdefg-6.jpg,abcdef-1.jpg,abcdefg-1.jpg,bcdefg-1.jpg になります
再現しねー。abcdefg-5.jpgなんて選択されねー。どこだー。何が悪いんだー、日ごろの行いかーっ!
昔はFindFirstFile()などの検索パターンにマスクパターンを直接突っ込んでいたので、8.3形式のDOSファイル名がヒットする可能性もあったけど、;区切りで複数指定できるようにしてからはそんなことはしていない。
何が起きているのか。
SE_SHUTDOWN_NAME特権が必要らしい。
DFを作った時にはNT4SDKを参照していたので、まだこのAPIがNT系OSには実装されていなかったため、そんなことは記載されていなかった。だからDFではサスペンドする時にはこの特権を有効にしていない。
ログアウトとかWindows 9x系の時にはSE_SHUTDOWN_NAMEはいらないので、処理の流れをねじ曲げてみる。訳がわからないことになる。
もう少しすっきり書けないものか。
Windows 98がシャットダウンできん。
- uFlags
- シャットダウンのタイプを指定します。次の値のいずれかを指定します。
日本語版MSDNだとこうだ。いずれかとなっている。select one、という感じ。
- uFlags
- [in] Specifies the type of shutdown. This parameter must include one of the following values.
こっちはinclude oneだ。んがー。
ちなみに、このページブラウザがIEでないと別のところに飛ばそうとするのでJava Scriptオフ推奨。
Double Windowでも同様の現象が発生している模様。あちらの掲示板にも書いておく。
β37として公開。
またデグレードしてるし。
Ctrl+Wで検索した後のコピーで、ディレクトリ付きコピーボタンが表示されていない。
goto使うのがイヤで、無理やりねじまがるようなコードを書いていたら見通しが悪くなってしまった。最初からgoto使ったほうがよっぽどキレイだ。
β38として公開。
β39として公開。
入れ換えるのを忘れていた。
β40として公開。
マークファイルを展開するための下準備として、登録コマンド展開ルーチンを捨てて書き直す。
突然ハングアップするバグ。
何事かと思ったらLeaveCriticalSection()を一回多く呼び出すことがあった。
DFをちまちま書き直していたらファイルサーバにアクセスできなくなってびびる。
原因がさっぱりわからないので、無意識のうちに変なところをいじってしまったのかとおもってかなりあたふた。あーでもない、こーでもないといじくりたおしていたら、どうということはない、サーバの方の同時アクセス数制限にひっかかっていただけだった。
辺り全員ログイン不能。なんてこったい。
んが、DFもおかしかった。
イキナリWNetAddConnection()よんだらダメな場合もあるのねー。くそー。
UNCのルートって\\SERVER\\SHAREだっけ、\\SERVER\\SHARE\だっけ。GetCurrentDirectory()で取得すると\\SERVER\SHAREの形式なんだけど、なんかのAPIで\\SERVER\\SHARE\じゃないとうまく動かないものがあったような記憶がある。だけど日記に残ってない。
んがー。
メールはこちらCopyrigiht © 2002 びい(@nifty ID:RXA01732)