我等が Mozilla も,たまにはこんな醜態を晒す事があったのです。
Mozilla のなんともアレな御姿 (PNG, 877x673)
このような事態に陥るための手段は次の通り:
こうなると Mozilla のウィンドウを一度閉じるまではデザインが元に戻りません。もっとも Quick Launch さえ有効にしていれば再起動は一瞬なので,大した問題ではないとも言えるわけですが。
私たちが作るアプリケーションでこの問題を起こさないためには,各コントロールのサイズについて常に気をつけておく以外にはなさそうです。意外に多くのアプリケーションやコンポーネントは,このあたりを忘れているようです。
ステータスバー ( msctls_statusbar32 ) は鬼門のようです。それぞれ「まめFile2」「サクラエディタ」のステータスバーですが,縦に伸びているのが分かりますか? この後,ウィンドウサイズを変えるなどして再描画させれば,ステータスバーのサイズも正常に戻ります。
疲労度:32
昨日のネタの FAQ を日本語訳してみました。著作権的にアレだけど,多分,大丈夫。。。
Winsock でプログラムする時,既にインターネットに接続されている場合だけ好きな事ができたらわりと便利ですね。多くの場合「インターネットに接続」とはダイアルアップ接続を意味します。そのような接続の検出にはこの例 ( http://tangentsoft.net/wskfaq/examples/rascheck.html ) を参照して下さい。
しかし,これは全ての場合に適用できません。まず最初の問題は,全ての人がインターネットの接続にモデムを使っているわけではない事。コンピュータは LAN に接続され,LAN 上のステーションの一つがインターネットへの通路として振舞います。それらが通路を形成していればシステムのネットワークの設定をいろいろと探ることが出来ますが,単に LAN の通路をインターネットに接続する以外のために使っていると厄介です。LAN がインターネットに接続する事があっても,通路のインターネット接続が使用可能でなかったり,いくつかのサイトへのアクセスをブロックするよう設定されているかもしれません。
別の問題として,PC がちゃんとインターネットに接続できるモデムを備えていても,「自動接続」が設定されていない限りそれは接続されてはいない事もあります。この場合,モデムが接続されていないという事実は問題ではありません:難しい事を考えずにコード内で接続しようとしましょう。すると道は開けます。
このストーリーの教訓は,インターネット接続チェックなんかしないのが一番だって事ですか。単純に,ユーザはあなたのプログラムを実行すると何が起こるかを知っているものと決め付けてしまいましょう。接続を試み,失敗すればそれはインターネットに接続していないからであり,ユーザにそれを報告して問題の修正を任せてしまいましょう。プログラムの接続時の挙動をユーザが設定できるようにすることも考えられます:ダイアルアップネットワークのチェックを行うように修正するか否か,プログラムがただ単に接続を試みるだけにするか否かをユーザはプログラムに伝えるわけです。ユーザは自身のシステムについてプログラムが類推するよりも多くの事を知っている場合も多々あるわけですからね。
やっと見つけたっすよ,「インターネットに接続されているかどうかを知るのは難しい」て記述が。2002-05-07 では「microsoft.com ドメインの中で見つけたはず」とか大嘘こいてますが,過ぎた事なので気にしません。で,どこで見つけたのかと言うと・・・
Winsock Programmer's FAQ -> 3.12 How do I detect if there is an Internet connection?
FAQ でした。笑い
ところで 2002-05-07 では InternetGetConnectedState をちらっと紹介してますが,少なくとも VC++5.0 の wininet.h には定義されていません。恐らく SDK をアップデートしないとだめな模様。MS のサイトに何度か アタック アクセスを試みてはいるのですが繋がりません。今日はネットが異常に重くなる日なのに加えて,IIS って比較的重くないですか? そうでもない?
疲労度:3
CGI と言えば Perl,Perl と言えば Larry などと申しますか。CGI は Perl の専売特許と言っても過言ではありません。Pascal で CGI をやってのけてしまうのはうちの部長くらいのものです。
CGI に欠かせないのがフォームとそれに続く input コントロールたち。コントロールに入力された値に従って動的にページを構築する,というのが CGI の存在意義の一つだと思います。
さて,<form> 要素の中身としてこんな HTML を詰めてみました:
<input type="text" name="T1" value="V1"/>
<input type="text" name="T2" value="V2" disabled="disabled"/>
<input type="submit" name="sub" value="mit"/>
これに送られるクエリはこんなの:
T1=V1&sub=mit
"T2=V2" というクエリが送られてきません。つまり,disabled なコントロールの値は送られないって事ですね。普通,趣味で作っているような CGI では disabled なコントロールを配置/使用する事が滅多にないので,これはなかなか気づきにくい仕様でした。
ていうか IE も Mozilla も同じ挙動だったんだけど,こういう仕様書ってどこにあるんだろう? w3c のサイトをもっとしっかり探すべきか。。。
疲労度:14
いつも何かとお世話になっているせきうちさんからご指摘いただきました。W3C の仕様にもちゃーんと書いてます。ちょっと訳してみると:http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.12.1
disabled がセットされると,要素上ではこんな事になります:
- disabled なコントロールはフォーカスを受け取らない
- disabled なコントロールはタブ移動をスキップする
- disabled なコントロールは successful になれない
で,"successful" とは何かというと:http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.13.2
successful control とは送信物として有効なものです。全ての successful control は送信された form data set の一部を構成するコントロール名と現在の値を持ちます。
つまり disabled なコントロールは successful でない = form data set を構成しない = 送信されないっていう解釈でいいのかな? ちょっと危ないかな・・・
ところで,この追記を書いている今日は実は 12 月 14 日だって話,信じます?
既に過去の案件かと思っていた某お仕事ですが,またまたまたまた仕様変更および追加のお話が舞い込んで来ました。「インクリメンタル開発」は「ソフトウェアの仕様は最初から決めらんない」という実情を踏まえた新しい開発手法としてわりと流行している模様。しかしコレは違うだろコレは。水から徐々にゆっくりと熱せられ,煮られているとも自覚していないカエルさんになった気分です。
先日からの非アクティブなウィンドウの問題も全然解決しないしなー。
それはともかく,これは一体どういう事ですか:
もはや人間の目の管轄下にないバイナリレベルでハカーされてトロイを仕込まれるのはまれに聞く話ですが,まさか人間様の目に常に触れているようなソースがハカーされるとは。今回の件のどの部分についてどうツッコミを入れればよいのか,真剣に悩んでいる識者の皆様の顔が・・・だめだ,ぜんぜん浮かびません。
だめ度:41792308
冷静になって考えて見たら,今日はエンドユーザから生の言葉を聞けた日でした。いつも「これを使う人は本当にこれでいいと思ってるのか?」と疑念を抱いていただけに,滅多にない機会です。
で,肝心のお言葉はというと「それじゃ使いづらいですよー」・・・かなり強調して言われました・・・とほほ・・・
低調度:54738
日記だけなのも寂しいので,最近ちょっと凝ってる分野ネタで。ロールシャッハテストじゃないので注意して下さい。
真ん中の 4 つの点を 30 秒間見続けて,その後ひたすら目を閉じ続けるとオーマイガッ。
ていうか,雰囲気でネタが分かっちゃいますよね。。。最近の私はかなり低調です。。。
低調度:29578
プログラマ御用達のツールやドキュメントを集めたサイト。ホントによく集めるもんだと感心です。
・・・んー,最近雑記が低調なのは,単に非アクティブウィンドウの悪夢ですねぃ・・・
疲労度:853
アンチウィルスソフトを無効化するBugbearが猛威を振るう
/. でも oddmake さんがコメントをされていますが,私たちのようなプログラマが注目したいのはこのウィルスが「非公式関数を利用している」という事実。Microsoft は私たちにも使えるようになっているはずの色んな API を非公開にしているのは有名で,最近も 300 近い API をやっと公開したばかり。
聞いた話によれば,ソフト開発を依頼してくるクライアントさんは「○×のソフトだってこーいう機能があるんだから,アンタもこの機能を実装してくれょ」とゴネるんだとか。「○×のソフト」がサードパーティー製のものならばともかく,Microsoft 製の場合は困難ですよね。果たして公開されている API のみで実装できるのか,それとも実は隠し API なのかを調査し結論を出すのにかなりの時間がかかるはずです。
そういえば私もちょっと苦労した事が。某 OLE オブジェクトを自分のアプリケーションに組み込んでイロイロする仕事があったのですが,どうも正攻法では要求された事が実現できないっぽいのです。仕方がないので OLE オブジェクトのウィンドウハンドルを取得して SetWindowLong() でウィンドウプロシージャを置き換えました。いわゆる「サブクラス化」てやつですね。インストールされている OLE オブジェクトのバージョンによっては正常に動作しない事が分かっているので,製品化の話が持ち上がらない事を祈る日々が続きましたとさ。
もう 1 年以上前のお話ですが。
後日談:まだ祈ってます
脳みそパニックです。元ネタは ClearBrain Systems さんの日々の雑記から。
画像のチェック模様のうち, A の部分と B の部分は同じ色です。本当です。信じてください。・・・ここで A と B を抜き出して並べて「ほらね?」と皆さんを説得しようと試みましたが,私も信じられなくなりました。
元のチェック模様の図に比べて,上の図の B がどうあがいても暗く見えちゃいますね。上の図の A は元のチェック模様の図から抜き出したものだと信じられますが,B はなんか違う気がします。
とりあえずつべこべ言わずに解説を熟読すべきですか。
元ネタは 2ch より。ソフトウェア板「Mozillaスレッド M17」の 185 さんが発見したサイトです。InternetExplorer をお使いの人には全然面白くないので,この機に Opera や Mozilla をダウソしましょう。そして ( トップページはともかくとして ) いろんなページを探検するのです。
すぐに気付いたでしょう? そう,ほぼ全てのページの文章が点滅しています。
原因はほぼ全てのページの font 要素と blockquote 要素のスタイルに text-decoration: blink が設定されているから。おかげで Opera や Mozilla では文章が点滅して見えてしまうのです。一説,QNX のブラウザ「Voyager」でもこの点滅技に対応しているとか。
あろうことか場所は (元) IT の祭典「インパク」関連っ。これは明らかに公的な嫌がらせです。90% 以上の人間が InternetExplorer を使っているからと言って,どうしてわざわざ残り数 % の人を切り捨てちゃったんだろう? 全くの謎です。
・・正直,どうでもいいサイトではあるんですけどね・・。
疲労度:20
2002-12-14 現在,Forbidden になってます。
昨日から悩んでいる「子ウィンドウを SW_SHOWNA で表示させているにも関わらず,親ウィンドウが非アクティブ化してしまう」という問題ですが,今日は解決できませんでした。そういえば,アプリケーション起動時に親ウィンドウが必ず非アクティブとして起動されちゃうんですよね。このあたりからして普通のアプリケーションとは挙動が異なります。ヒントになるかなー。。。
笑っちゃうと言うべきか,大変だと言うべきか・・・私の会社に仕事を発注していた A 社の B さん,行方不明になりました。正確にはそんなに物騒な話ではなく ── でもこれは私の想像なんですが ── 海外に出張したのはいいけど,私の会社から B さんへの連絡手段を A 社の誰かさんにお願いするのを忘れたようです。部長が B さんに連絡を取ろうとすると「B は今出張で連絡が取れない」とか。
こうして 2 つの仕事の検収期間は過ぎて行きました。笑い
そんな事よりも私の今の興味は昨日の雑記です。SW_SHOWNA で ::ShowWindow() を行う事で,親ウィンドウを非アクティブ化せずに子ウィンドウを表示させる技(?)を紹介してみました。実際にちゃんとコードも組み,動作を確認しています。
ところで,ここ半年ほど VC++ 上で VCL@Borland の真似をする事にハマっています。MFC は ドキュメント/ビュー構造が美しいと評判ですが,GUI 設計では VCL に敵いません。だから,その両方の仕組みを理解するのに全力を注いでいるのが最近の私の生態です。ある程度 GUI を楽に設計できるようなクラスを作っているので,その勢いで自前でツールチップコントロールを作る事にしました。表示する時は当然 SW_SHOWNA です。
なんとまあ,親ウィンドウが非アクティブ化してしまうではありませんかっ。
何が間違っているのか皆目検討がつきません。昨日 SW_SHOWNA の動作確認を行ったコードはこれら「VCL もどき」クラスを使いませんでした。という事は,原因は「VCL もどき」クラスにあるのかなあ?
これも課題ですねー。前々から課題にしている分も全然解決していないので大変です。
疲労度:52345
台風が去った後は常に異常なまでの快晴。お陰で今日はあの酷暑が戻って参りました。9 月上旬の気温に匹敵するんじゃないかなと思ったけど調べてません。
さて Windows のコモンコントロールのひとつに "TOOL TIP" というものがあります。ウィンドウの右上のボタンにマウスカーソルを置いておくと,数秒内に「閉じる」「最大化」などの説明が出て来ますが,つまりソレの事ですね。
少し Windows アプリケーションについて勉強した事のある人なら不思議に思うのが,このコントロールの出現時の挙動です。通常は ::ShowWindow() API でコントロールを表示すると,他のウィンドウは ── 無論,親ウィンドウさえも ── 非アクティブになってしまいます。代わりにアクティブになるのは今新たに表示させたコントロール。しかしツールチップは,親ウィンドウを非アクティブにすることなく表示されています。これはどういう事なんだろう?
まず考えられるのは,ウィンドウスタイルに WS_CHILD を指定する事。通常のアプリケーションではウィンドウ上にたくさんの "BUTTON" コントロールがありますが,しかしそのようなウィンドウが表示された時に非アクティブになっている事はあまりありません。これはそれら "BUTTON" コントロールを ::CreateWindow() もしくは ::CreateWindowEx() API で生成する時に WS_CHILD が指定されているからですね。
しかしこの案は却下。WS_CHILD を指定すると,親ウィンドウからはみ出す事が出来ません。対してツールチップは往々にしてはみ出しています。
というわけで,別の方法を考えてみます。
もう一つ考えられるのは,親ウィンドウがメッセージ WM_ACTIVATE を処理する事。非アクティブ化されそうになったらすかさず ::SetForegroundWindow() API で自身をアクティブ化します。するとツールチップが親ウィンドウの影にかくれてしまいそうですが,ツールチップは拡張スタイル WS_EX_TOPMOST を指定しておけばオールオケー。
しかしこれも却下。これを実現するならば,親ウィンドウはなぜ自分が WM_ACTIVATE を受け取ったのかを判断できる必要があります。普通にアプリケーションを切り替えた場合も WM_ACTIVATE を受け取りますが,その時は素直に非アクティブ化されるべきです。しかしそれを管理するのは異常に面倒でしょう?
正解は ::ShowWindow() API の引数でした。第 2 引数 mCmdShow に,普段あまりお目にかかることのない SW_SHOWNA を入れてやることで,現在アクティブなウィンドウを非アクティブにする事なく別のウィンドウを表示させる事が出来ます。
SW_SHOWNA とはかなりマイナーな定数ですが,ちゃんと使い道もあるんですよねー。・・・当たり前か。
疲労度:10