重要:だいたい下記のように考えればスッキリするんですよね。でも確たるドキュメントがまだ見つけられなくて,ちょっと自信がありません。間違った事を書いてる可能性もあるのでご注意。
かねてからトライ & エラーを繰り返してきた印刷処理ですが,なんとか基本が見えてきた気がします。Microsoft はこれまで印字処理やその他ビジネス関連のハードウェアを簡単に制御できるべく API を懸命に模索して来たわけですが,やっぱしまだまだ複雑じゃありませんか?>MSたん
さて昨日の概念的コードのツッコミを入れて行きます。これはかなりの作業かも・・・。
GetDevMode() 関数は 2002-08-03 のようなものを想定していますが,これ,ゆくゆくは使い辛くなるはずです。
昨日の概念的コードのように ( .. 以上,削除っ。下の追記を見てください ) 2002-08-03 では DEVMODE 構造体のメンバをいじり,それを保存しないのならば問題はないようです。つまり今回の印刷限りの設定,もっと正確には「今回のデバイスコンテキスト限りの設定」というわけですね。これを次回 GetDevMode() を呼び出した時に,前回設定した内容がそのまま渡って来るようにするには,DocumentProperties() API で設定を反映してやる必要があります。DocumentProperties() API を DEVMODE 構造体の読み出しの目的で使っていますが,この API は読み出しだけでなく設定もできてしまうわけです。
// DEVMODE を更新するコード
DocumentProperties(
NULL, // HWND
hPrinter, // HANDLE
pszPrinterName, // LPTSTR
pDevMode, // PDEVMODE
pDevMode, // PDEVMODE
DM_IN_BUFFER | DM_OUT_BUFFER );
そこで気になるのが DocumentProperties() API に渡す引数。第一引数は HWND 型で,ここに任意のウィンドウハンドルを渡し,第 6 引数で DM_PROMPT フラグを立ててやると,ウィンドウハンドルを親ウィンドウとして印刷設定プロパティシートを表示するようになります。今回の私の仕事ではプロパティシートを表示しないので NULL を渡します。
そして問題は次の HANDLE 型。これは OpenPrinter() API で取得できるプリンタのハンドルを渡しますが・・・
ええっと,要するに DEVMODE 構造体周辺でこんなコードも書けるようにしたいんですよね:
// このコードは概念的なものです
// 現在の DEVMODE 構造体を得る
DEVMODE *pDevMode = GetDevMode("K-M Printer MkII");
// いじる
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
pDevMode->dmFields |= DM_DUPLEX;
// プリンタの設定を更新する
DocumentProperties( ... );
// これに渡すプリンタハンドルはどうしよう??
// これだけのためにわざわざ OpenPrinter する?
// DC 生成
HDC dc = CreateDC(NULL, "K-M Printer MkII",
NULL, pDevMode );
先にも説明した通り,DocumentProperties() API にはプリンタのハンドルが必要です。そういえばここで使っている GetDevMode() 関数内でも OpenPrinter() API でプリンタハンドルを取得していますが・・・速攻で閉じちゃってます ( ClosePrinter() ) 。
こういうの,もったいないですよね。
そんなもったいないことを避けるために,どうせだから GetDevMode() 関数内でプリンタハンドルを得たりするのを止めてみます。その代わり,外部でプリンタハンドルを得るようにしてみてはどうでしょうか。
HANDLE hPrinter;
// プリンタのハンドルを得る
OpenPrinter(&hPrinter);
// 現在の DEVMODE 構造体を得る
DEVMODE *pDevMode = GetDevMode(hPrinter, "K-M Printer MkII");
// いじる
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
pDevMode->dmFields |= DM_DUPLEX;
// プリンタの設定を更新する
DocumentProperties( NULL, hPrinter, ... );
// ここでプリンタのハンドルを破棄
ClosePrinter(hPrinter);
// DC 生成
HDC dc = CreateDC(NULL, "K-M Printer MkII",
NULL, pDevMode );
これにならい,前に示した GetDevMode() 関数を改造します。改造後のコードは,今はとりあえず割愛。ひとまず DEVMODE 構造体取得方法のツッコミはこんな感じでオッケーかな。。。
疲労度:53468
上記の DocumentProperties() 関数の位置付けが心配です。本当に「『今設定した DEVMODE を次回にも使いたい』場合に設定を保存するものであり,『この設定は今回のデバイスコンテキストに適用するだけでいい』場合には不要」という解釈でいいのかなあ? MSDN ではストレートには触れられていませんでした。
あー,だめだ。DocumentProperties() で DEVMODE を設定してやっても,その設定が次まで引き継がれません。むしろ,あの DocumentProperties() を記述しなくてもちゃんと期待通りに動きます。まさに「あってもなくても関係ないもの」な状態になってしまいました。上記の本文のところ,かなり大胆に削除しちゃったですよ。本当に,何のために呼び出すんだろう??
ちなみに,このようにウソを書いてても,重大な勘違いというわけではない場合は黙ってこっそりと書き換えたりしています。この雑記のコンセプトは「なるべく正確な情報のみを置いておこう」てことなんで。
両面印刷を行う時に注意しなければならない点を発見。ODBC で遊んでる暇はないようです。
普段からよく両面印刷を利用している人は多くはないので,ネット上にもあまり有用なリソースが転がってないんですよね。しかしドツボにハマりました。
少なくとも私の会社にあるプリンタは,「部単位で印刷」すると両面印刷が行えません。当然世の中は広いんで,可能な機種もあるんでしょうけど。
今日まで,両面印刷の時には大体こんなコードを書けばいいんじゃないかなあと思ってました。
// 注意:実際にコンパイルして試したわけではありません
// また,これは悪いコードです
// DEVMODE 構造体の初期値を得て,両面印刷の設定をする
HANDLE hDevMode = GetDevMode("K-M Printer MkII");
DEVMODE *pDevMode = ::GlobalLock(hDevMode);
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
pDevMode->dmFields |= DM_DUPLEX; // 明示的に設定した方が安心
// デバイスコンテキストを生成
HDC dc = ::CreateDC(NULL, "K-M Printer MkII", NULL, NULL );
// ドキュメント情報を簡単に設定して印刷開始
DOCINFO doc_info = {0};
doc_info.cbSize = sizeof(DOCINFO);
doc_info.lpszDocName = "Document";
::StartDoc(dc, &doc_info) // 印刷の開始
::ResetDC(dc, pDevMode); // DEVMODE 構造体の設定を反映 ... してるつもり
::StartPage(dc); // ページ開始
/*
dc に何か描く
両面印刷時には紙の表側に描画される
*/
::EndPage(dc); // ページ終了
::StartPage(dc); // 次のページを開始
// ただし,両面印刷時には「裏面」の開始ということになる
/*
dc に何か描く
*/
::EndPage(dc);
::EndDoc(dc);
::DeleteDC(dc);
上のコードは,大方の処理の流れとしては間違っていないコードです。しかし細かい部分でツッコミどころ満載。ちなみに GetDevMode 関数は 2002-08-03 を参照なんですが,どうもこれもマズかった模様。。。
とりあえず詳細なツッコミは明日からということで。。。おやすみなさい。。。
涼しさ:100
って,冷やし中華じゃないんだから>自分・・・。
ODBC,なんだかあちこちで聞くような気はするんだけど,なんとなく難しそうで腰が引けてた,というのが実情。でも触ってみると,意外に簡単でした。
現在,私がコードを書く際に参考にしているのは IBM のサイト。
ODBC を汎用的に解説しているというワケではありませんが,主要な API は詳細に解説してくれていたりします。本当にこのページのおかげで助かった感じです。
そうそう,案の定,コーディング中に気をつけなければならない点がちらほら出てきたんで,これからしばらく ODBC ネタと参りましょうか。
疲労度:22
ネタ元は /.J より。リリースされたらしいっすねえ。。。もうこれ以上 "Netscape" と名を冠するモノが叩かれるのは見たくないんですが,何とかならないのかなあ。
やはり,会社の上の方の人間が正確な情報を持つことが重要だと思いました。NC4.x でも IE でもまったく同じに見えるようなサイトを作る場合の収益/費用のバランスと,NC4.x での多少の表示の崩れには目をつぶる場合の収益/費用をよく比較検討した上で,デザイナさんに仕事を発注するべきかと。
なんていうか,こう,世の中ってのはうまく出来ているように見えて,実はあんましうまく行ってない場面も多いんですね。鬱ちょっと増。
昨日に引き続き,HDD が壊れちゃった〜ネタです。今日は,もはや風前の灯火となった HDD からなんとかデータを救出するまでの作業を紹介。
HDD の状態はあまり芳しくなく,数分ほど稼動させていると認識しなくなってしまいます。スキャンディスクでは,普段はお目に掛けないような,セクタに関係するらしいカウントが表示されていました。これがまた異常に時間がかかり,とうとう HDD はスキャンディスクを完了しないまま認識しなくなります。挙句の果てには再起動直後のブートストラップにさえ耐える事が出来なくなるので涙を誘いました。
とりあえず新しく買ってきた HDD は Maxtor の流体軸受 60Gb。何だか評判らしいです。
故障寸前の HDD は熱を持つとチップがアレになって認識しなくなってしまうとの事。そこで少し考えました。必要な時だけちょこちょこっとアクセスするような使い方ならば,多少は延命が出来るのでは? まず新しい HDD に OS をインストールし,そこへ古い HDD から少しずつデータをコピーすれば,なんとか救出が完了するはずです。
この時点で古い HDD が IDE-0 に接続されていました。これを外し,新しい HDD を接続します。簡単。
特筆する部分はなさそうですね。単純に OS をインストールします。
古い HDD から新しい HDD にデータをコピーするためには,当然,古い HDD もマシンに接続する必要があります。新しい HDD とマスター/スレーブ関係として接続するにはなんだか HDD 背面のジャンパの設定が必要らしく,面倒なので避けました。代わりに IDE-1 に接続している CD ドライブを外して古い HDD を接続します。随分卑怯な手かも知れませんが,大丈夫,どうってことはありません。
ところで,私は常に HDD を 3 つのパーティションに区切って使うようにしています。基本 MS-DOS 領域と拡張 MS-DOS 領域 2 つ,てな具合ですね。
ここで「エクスプローラ」を見ると,ドライブの構成が少し面白い事になっています。
| ドライブ | fdisk で作成した領域 |
|---|---|
| C: | 新 HDD の基本 MS-DOS 領域 |
| D: | 旧 HDD の基本 MS-DOS 領域 |
| E: | 新 HDD の拡張 MS-DOS 領域 その1 |
| F: | 新 HDD の拡張 MS-DOS 領域 その2 |
| G: | 旧 HDD の拡張 MS-DOS 領域 その1 |
| H: | 旧 HDD の拡張 MS-DOS 領域 その2 |
ここで注意しなければなりません。あくまでも,少しずつコピー,です。なるべく旧 HDD の発熱を抑えなければなりません。そうでなければ旧 HDD のチップがイカれ,認識されなくなってしまいます。
こんな事を考えるのはプログラマだからですかね・・・調子に乗って一気に大量のファイルをコピーした場合,もしその最中に旧 HDD が認識されなくなったら,オープンされているファイルストリームはどうなってしまうのでしょう? 果たして Windows はそんな奇特な状況も想定してコーディングされているでしょうか? さもなければ最悪,新 HDD までアハハハという事になるかも・・・て,考えすぎ?
・・いやいや,何にしてもこのような緊急時には最悪の状況を想定して作業を進めるべきです。この作業,結局 2 日ほど掛けてしまいました。
こんな感じでなんとか全てのデータを退避させる事に成功しました。あと,USBXchange の限界を感じてやっぱり SCSI ボード ( これまたアダプテック社製 ) も買ったし。これでしばらくの間は快適な生活が送れることでしょう。
・・・んーと,マザーボードに乗ってる,何だかよくわかんない小さなファンが回りにくいようなんですが・・・何これ?
疲労度:9064637652885538343
案の定,里帰りの間は雑記を更新しませんでした。実は,里帰りの最終目的地は私の実家である大分市街地ではなく,さらに母の実家である国東半島の山奥の村でした。ここには PHS の電波は届きません。無論 C@rd-H" も例外でなく,物理的に機能しなくなります。
母の実家にはもう誰も住んでいません。別荘? いえ,買い手のつかない空家と言うべきです。この日ばかりは両親も私もキャンプ気分。だから 12,13日 はともかく,14 or 15 日あたりには食料その他を買いに街まで降りるはずで,その機会を狙って雑記を更新しようとしたのですが,甘かったようで。。。近所の人がいろいろ差し入れを持ってきてくれるんですよね。。。
ていうか,そんな事はこの際どうでもいいです。
生まれて初めての事件っすよ。HDD が イ カ れ た な ぞ 。
私はもう「パソコン」なるものを触り始めて 10 年になりますが,なぜかそれまでは HDD のクラッシュなんてものに立ち会った事がありませんでした。実家に置いてある FM-TOWNS HR20 の HDD だって,きっとまだちゃんと動くと思います。一番酷使していると思われる会社のマシンの HDD も,この一年 + 半年で不良セクタ一つ出しません。
さて明日から仕事だー。帰省中にやってた仕事を,ノートパソコンから普段使ってるマシンの HDD に移して,そうだ,ノートパソコンをちょっと整理しようかな。とりあえずこういうデータは全部消しちゃって・・・。
HDD 「ンカッ ンカッ」
む,普段使ってるマシンの HDD が何やら自己主張しています。しかし私はノートパソコンの整理に夢中。
HDD 「ンカッ ンカッ ンカッ」
むーん・・・うるさいので,とりあえず電源を落とそうかな・・マウスが利かない? とりあえず Ctrl+Alt+Del で・・リセット掛からない? 仕方がないのでリセットスイッチ・・利かない? かなり危険だけど,電源スイッチで・・電源切れないし?
これはプログラマの勘なんかじゃなくて,なんていうか,本能的な勘だと思いますが,あれだ,致命的なナンカが起こってますか?
こういう場合はおもむろに深呼吸し,落ち着きます。今日の夜は何を食べようかな。冷蔵庫の中身は帰省前に片付けてしまって空っぽです。買い物に出かけなくちゃ。ところでコイツの電源を切らないといけないなあ・・・。
電源ボタンを数秒間押し続けてみましょう。4 秒くらい押し続けると,強制的に電源を落とすことが出来ます。これを「電源の長押し」と言うらしいので,もしもの時のために覚えておくとよいですね。
事態の把握を急ぐため,数分のクールダウンの後に再度電源を投入。既に何かを感じていた私は,早速 HDD 内の重要なデータを CD-R に焼く作業に取り掛かりました。CD-R ドライブは SCSI 機器ですが,マシンには SCSI ボードは付けていません。この場合,アダプテック社の「USBXchange」で接続が可能なのです。しかしやはり USB の速度に合わせざるを得ないらしく,TEAC 社自慢の 8 倍速で CD-R を焼く事はできません。なんとか CD-R を焼くことの出来る最速のスピードは・・・なんと 1 倍速。
CD を本当に焼く前に,私は絶対に「テスト」を行います。これがまた本番さながらのテストなので,本番と同様の時間が掛かるのです。結果,1 枚 CD を焼く所要時間はおよそ 2 時間半。これが私のやり方。潔癖症だと言われようが,石橋を杭打ち車でガッシンガッシン男と言われようが,これだけは譲れません。
で,CD が焼けるのをボーッと待ってたわけですが・・・ええ,途中で何も反応しなくなりましたとも。しかも Ctrl+Alt+Del などであちこちいじくっていると,見慣れないブルースクリーン:
C: ドライブへの書き込みに失敗しました。ファイルやデータが破壊されたかも云々...
いよいよヤバい事になったかも知れません。再度「電源の長押し」でマシンの電源を落とし,情報を収集することにしました。
結論は次の通り。すなわち,富士通製,型番 MPG 云々...の HDD は,コントローラチップに異物の混じったものが使用されたため,熱で徐々に変質してしまうとのこと。私の買った HDD は MPG3204AT-E で,まさにクリーンヒットだったようです。2ch でもわりと騒ぎになっていたようで,もう少し早く気づけばよかったのですが。。。まさか自分がこの騒ぎに巻き込まれるなんて思いもしませんもんね。
もっとも,今でも連続運用さえしなければ数分間は稼動が可能なようです。その間にデータを別の HDD に少しずつ退避させることで,なんとかほぼ全てのデータの救出に成功しました。
というわけで,明日は今回のデータの復旧作業の模様をまとめてみようかなと。といっても HDD がダメになる理由はそれこそ様々なんで,果たして参考になるかどうかは疑問なんスけどねー。
疲労度:897054723
恒例の里帰りの予感。12日から18日まで実家でまったりするのです。
とりあえずノートパソコンとかと一緒に持って帰るつもりですが・・・雑記の更新がどうなるか分かりません。というのも,果たして C@rd-H" でちゃんと NewCOARA さんに接続できるかどうか分からないからです。普通ならば今試せばよいのですが,ここで私のマヌケぶりが大活躍。その C@rd-H" は今,実家の方にあるのです。実は去年実家に帰った際に,C@rd-H" だけを実家に置き忘れてしまいました。どうせ東京では殆ど使わないし送料もアホにならないという理由で,1 年間ずっと実家で眠っています。しかもよせばいいのに母曰く「どこにやったか分からん・・・」。
くわっ,こんな事で雑記の更新を止めてしまってよいのでしょうかっ・・・いや,いいんですよね。毎日更新したかったわけじゃないし。
ただし InternetJAH さんにはどうあがいてもアクセスが出来なくなるので,ブラクラチェッカーのメンテナンスが出来ません。ヘンなアタックを受けたらどうしよう?
ネタ元は「内務省」さんの「日本新聞」より。
元の記事は ( 上のアンカの title 属性にある通り,笑ぃ ) 例の猫虐待事件の犯人が書類送検に止まらず起訴されたという出来事に絡めて,「2ch での世論が暴走してる〜」とか「実は 2ch にはプロの削除屋がいるのだ〜」みたいなネタ。ナナメ読みしかしてなかったんだけど,とにかくかなりトンデモな内容でした。速やかに「怪文書保存館」さんに寄付するべきです。
冗談はともかくとして,正直な意見:少なくとも昨今の“インターネット事情”とやらを冷静に見続けてきた人間の文章ではないと思いました。さもなければ,インターネットの利用者のうち,ある共通項を持つ“っぽい”人たちを安易に「2ちゃんねらー」とくくってしまうのには相当の抵抗があるはずですもんね。
果たして当局にメールを寄越した人間の何 % が 2ch で事件を知った人だったのか,少なくとも記者はその点について考えてみることに気付くべきでした ( 実際に調べるのは難しそうだけど )。例の記事はそのあたりについて何の考察もなく,ただヤケクソに「2ch はドス黒いぜ hehehe」と宣伝しただけ。
削除処分は妥当だと思いましたが,その前に,どうして掲載しちゃうかなあ・・・。
これからが「ジリ暑」てなやつなんですよね。意外なことに,東京は 10 月を迎えるまで涼しくなりません。そして 11 月には寒くなるというオチ。
これから東京に出てくる皆様,んーと,その,生きてください。力の限り。
NewCOARA さんはユーザが CGI を動かす場所として,私たちに WWW サーバとは別の CGI サーバを用意してくれています。CGI サーバが独立しているため,WWW サーバの忙しさに惑わされることがありません。ここが NewCOARA さんのナイスでイカスな部分。
さらに NewCOARA たんは cgiwrap というモノを用いて,“悪意ある”NewCOARA たんユーザに不正にファイルを操作されることを心配せずに済むよう CGI サーバを実現しているということなので萌え。
CGI の URL はこんな感じになります。
http://cgi.server.net/cgi-bin/cgiwrap/user/bbs.cgi
今日,ginzi さんという方が掲示板でこーんな URL を書いてました。
http://cgi.server.net/cgi-bin/cgiwrapd/user/bbs.cgi
d に注目。何? デーモンってこと? それともデバッガって意味なのかなあ? このあたりはまだよく勉強してないんだけど,これで CGI をデバッグできたりします。CGI に送られた QUERY_STRING が表示できたりね。
実はこの cgiwrapd に XSS 脆弱性! IEは ( ・・IE6 はそれなりに強固らしいけど ) Content-type を無視し放題という話は有名ですが,やはりそこを突かれました。IE をお使いの方は次の URL へジャンプしてみて下さい。「kiken」というダイアログが出れば大成功です。
XSS 体験 URL ( ginzi さんが教えてくれた仕掛けをほぼそのまま使ってます )
これはあれだ,cgiwrapd は text/plain を出力する以上,わざわざ '<' を '<' とエスケープできないし,する筋合いもありません。Mozilla とか Lynx とかのような通常のブラウザではそのまま '<' が見えてしまいますもんね。
すなわち cgiwrapd に落ち度はなく,イケナイのは IE5.5 とかっすか。とっとと IE6 をインストールしろ>自分 ( ていうか,普段は Mozilla を使ってるんでどうでもいいんですが )
疲労度:74
academic office さんの掲示板 Tea Room for Conference in academic office(記事番号978) でも記事を確認ー。Opera でも起こるとですか。滅多に使わないんだけど,どうしようかなあ・・・
あと,パッチも出てる模様。・・・CGIWrap の方も修正しちゃいますか。ユーザエージェントによってエスケープするかしないかを判別するとか・・・かなあ???