今日はドキュメント(取説)の仕様を考えていました。要は取り説中のサン プルコードをそのまま実行して結果が即座に見れるという工夫です。ドキュ メント自体はMSWORDで書いた方が書式として綺麗なのですが、HTML出力後で も有効なコントロールやスクリプトをMSWORDでの編集状態で記述することは できないような気がします。office固有のコントロールでは意味が無いわけ ですがら。
結局ちょっとしたスクリプトを書いて「HTML中のサンプルコードを認識して innerTextを認識、実行用ボタンを生成する」になりました。これで興味の あるセクションのヘルプを眺めて、即座に実行結果を見れるようになります。 また、エディタが付属するバージョンではサンプルをエディタ上で編集し、 動作の変化を即座に確認できるわけです。
長い間Windows上のHTMLとCOM、そして.NETについてどんな利用の仕方が最も ふさわしいのかを自分なりに結論付けるために重箱の隅をつつくような事柄 を解析してきましたが、すべては「簡単に結果が得られる」ためにある訳で すから、細かなことは有る程度切り捨てて「簡単に見栄えのいいアプリケー ションが書ける」ということを前面に押し出した方向へ重点を置くことにな ります。
HELPファイルとエディタの連動を実装しましたが、まだβではありません。
ttp://kuroda.bglb.jp/htabox/htabox3.zip 今まで分散していたリソースを単一EXEに結合しましたので一気に450kになり
ました。きちんとドキュメントを書くと全体は数Mbになるかも知れません。
ドキュメントを含んだEXEとして、クローン生成用にコンパクトなEXEを別途
用意すべきか、ドキュメントを別ファイルにすべきかを決定しなければなり
ません。
7 :
デフォルトの名無しさん :2011/03/23(水) 16:10:19.13
新スレオメ。 山形も風向きによっては福島の影響を大きく受けるみたいで心配です。 このプロジェクトは日本の復興のためにもなります。頑張ってください。
これを書きながら思ったのですが、従来のアプリケーションは説明と本来操 作すべきGUIが離れざるを得ない構造になるわけですが、HTMLアプリケーショ ンの場合縦長のドキュメント中にボタン等のコントロールを置くことは普通 なわけですから、説明とGUIが一体となった構造とすることができます。また 、全体の見出しを俯瞰できるツリーメニューを付けているので例え長大な説明 だったとしても目的の位置へは即座に到達できるわけです。このことにでより ユーザーフレンドリーなアプリケーションを構築できると感じます。
>>7 ありがとうございます。私のような人間が生きさらばえて、生きるべき方々
の命が奪われたことを想うと心が痛みます。
HELPファイルでのメニュー、ステータスバー、ツールバーサンプルを実装し
ましたが、まだβではありません。
ttp://kuroda.bglb.jp/htabox/htabox3.zip 確かに間違ったことさえ書かなければプログラムは忠実に動くわけですが、
結構複雑な処理を前から知っていたかのような速度で処理するプログラムを
見るとずいぶん遠くへ来てしまった感があります。マシンと人間の距離は広
がる一方ですから、それを埋めるプログラムは次第に複雑なものにならざる
を得ません。WIN32アプリケーションとしての機能を付加したHTABOXのコード
は良く言えば「有機的」悪く言えば「相互の依存関係が複雑」なものになり
ました。
アイコンファイルの構造とアイコンリソースの構造解析にすこし時間を取られ てしまいましたが、納得のゆくモジュールが書けそうです。HTAタグと同等な 実行時ウインドウへのアイコン追加を3.00に実装する予定です。静的ファイル を対象としたアイコンリソース置き換え機能は自分用ツールの場合必要が無い わけですので別途なサービスとする予定です。
コモンコントロールで使用する画像ファイルの検索規則を決定しました。と 言っても表示HTMLのpathnameというごく当たり前な規則ですので通常は意識 する必要が無いと思われます。HTMLから相対パス参照で記述すれば自動的に 絶対パスへ変換して検索します。もし、about:blankに後付けされたエレメン トを対象にコモンコントロールを生成しようとした場合はpathnameが空です から、呼び出しスクリプトのパスを基準にします。呼び出しスクリプトが格 納されている場合はEXEのパスとなります。
リリースに向けて各コントロールのコードを再チェックしているのですが、 C++プロセスからの実行では問題ないページャーがWSHからだとスレッドが ブロックすることに気づき対策を模索しました。で解決策が見つかったの ですが、なぜそうでなければいけないのかという理由は今のところ不明で す。COMの世界では理由がわからないということはまずありえないのですが、 複数のウインドウ同士がメッセージで通信している状態というのは神のみぞ 知る領域というのが存在するような気がします。
今まで、まじめにWIN32でアプリケーションを書いていなかったしっぺ返しに
非常に基本的なことを今更学ぶという時間を過ごしました。特にアイコンと
ビットマップについては、何度もモジュールを書き直し納得のゆくレベルに
できました。バイナリはまだなのですが、SetIcon関数でアイコンを設定し
DrawBitMap関数でウインドウ上の自由な位置へ透過ビットマップを表示した
サンプル画像を置きます。
ttp://kuroda.bglb.jp/htabox/bmp.png
ずいぶんと春めいた陽気になりました。コタツにまるまって指が痛くなるま でコードを打ち続けた日々が遠い過去のようにも思えます。同時に私が強く こだわってきた事柄がとてもちっぽけなものにも感じられます。私の最大の 長所でもあり、欠点でもある「なぜそうなのか知りたい」という欲望を封印 して現状での私の仕事をより正確に把握していただけるようドキュメントの 作成に専念しなければと感じています。
あらためて最も基本的なコントロールであるメニューを省みると、投げやり な状態で放置してしまっていた事に気づきました。スクリプトからの低水準 関数を用意して、より複雑なメニューを作ってもらおうという予定でしたが、 それでは煩雑になることから従来のTABLE形式のメニュー定義に加えUL/LIに よるメニュー定義を追加します。これによりネストしたメニューを簡単に定 義できるようになります。また、従来は文字列が表示されるメニューのみで したが、TDもしくはLIにbackground属性を定義すればビットマップメニュー も表示可能とします。すでにモジュールは完成していてこの拡張されたメニ ューについてのドキュメントを作成中です。
取り説を作るという作業はプログラムを造る側の立場から使う側の立場へ視点 を変える重要な作業だと痛感します。もしこれが分業化されてしまったら結果 として使いにくいものしか生まれないだろうとさえ思います。一人ですべてを 掌握するメリットは例え全体の改訂が必要な事柄でも、面倒な会議を開くこと なく内容に反映できることです。大げさな表現かも知れませんがプログラムと いう存在は一つの人格だと思います。ですから複数のチーム完成させる場合で も、最終的にユーザーの前でどのように振舞いたいのかをプロデュースする一 人の人間がいないと魂の無いプログラムになってしまう気がします。
HTMLファイル単体での実行機序を見直すことにしました。空のダイアログ生成 による独自ディスパッチの取得が今まで何の問題も無く安定動作していること から当該手法を推奨し、window.onCreate()を復活させてHTML中のスクリプトか らでも各種コントロールを生成可能とします。学習初期のプログラマーにとって WSHファイルとHTMLファイルが別だというだけで「面倒」という印象を与えてしま うかも知れませんから単一HTMLで完結できることは歓迎されると思います。
HTABOX3.00を書きながらつくづく思うのですが、結局使う人をうならせるには 愚直に、例え細かいことでも妥協せず書くしかないわけです。ただし、プログ ラムというものは細かく制御すればするほどオーバーヘッドが増えるわけで、 軽快な動作とは相反する要素となります。だからC++のように最小のオーバー ヘッドを実現できる環境でないと愚直が鈍重に変化してしまいます。
今回スクリプトに提供する各種コモンコントロールもAPI呼び出しやメッセージ 送信を公開して実現する手法もあるわけですが、その方向に進むとDHTMLと変わ らない重さになってしまう懸念があります。ですから途中での要素の変更のよう な動作を切り捨てて明快で軽量なことを目指しています。そういった方向では あるのですが、これだけはオプションとして必要と感じられる部分がありました らその都度機能を追加してゆく予定です。
サンプルコードやドキュメントをHTMLで閲覧でき、ドキュメント上のボタンで その実行結果が即座に表示されるということを目的として作業していますが、 細かな現実的問題をクリアするのに思いのほか時間を費やしてしまいました。 幸いにもその動作を想定して設計されたタイプライブラリ主導でのCOMサーバー や.NETスクリプトエンジンは安定して動作していますので、一通りのサンプル を格納してまもなくβと呼べるものをお見せできそうです。
私は福島へ行く心の準備ができています。あれを封じ込める仕事を若い人にさ せてはいけません。早急に一民間企業とは隔絶した処理チームを編成して事に あたらなければ国際的に日本と言う国の信用は地に落ちるものと思われます。 天文学という見地から見れば私達の文明などほんの瞬きほどの時間しか存在し ていません。もし人類が何万年というオーダーで存在したとすれば、今と同程 度の文明は幾度と無く存在し、その数だけ滅びがあったのだろうと推察するの が自然です。愚かしい人類の中でも、群を抜いて愚かしい私ですが、せめて人 の役にたてるのであれば今すぐにでも福島に馳せ参じたい心境です。
25 :
近畿商事大門 大門一三 :2011/04/07(木) 21:32:14.57
まぁ、まぁ、作者さん、ここは冷静になってですね、 今後の日本の復興のために、それぞれが持ってる能力を 得意な分野で最大限発揮するしかないんと違いますか? 山形ゆうたら福島に近いから、いてもたってもいられんのは分からんでもないが ついこの間までキーボード打ってたオッサンが出る幕はおまへん。 日本と世界の英知が集まれば、必ず光明は見えてきますがな。 壱岐君もそう思うやろ?
複数のHTA(正確にはHTMLダイアログ関数で解釈)の表示をタブ切り替えする
ツールを公開します。
ttp://kuroda.bglb.jp/htabox/tab.zip メニューから任意なHTMLファイルをタブに追加し、タブ表題部分(タイトル)
を右クリックすると削除します。現状では実行されるHTMLには相互を認識する
小規模なディスパッチがダイアログ引数として与えられています。
//TABコントロールはダイアログ引数として存在します。 //変数TABにインスタンスを格納したとして各関数を説明します。 var TAB = window.dialogArguments; //表示されているタブの数 var Length = TAB.Length; //ドキュメントの追加(フルパス) TAB.Add("c:\\hoge.htm"); //任意なインデックスのドキュメント取得 var Document = TAB.Get(index); //任意なインデックスのタブを選択 TAB.Set(index); //任意なインデックスのタブを削除 TAB.Del(index);
このタブコントロール習作ソフトに「Trusted Zone Browser」という名前を
付けました。信頼済みゾーン用ブラウザという意味です。ブラウザが解釈可
能なファイルなら画像単体だろうがテキストだろうが何でも開く事ができま
す。最大の特徴は「全くセキュリティーに関心を持たない」事ですので恐ら
く世界で最軽量なブラウザだと思います。自身が作った複数のHTAのランチャ
ーとして使うのもいいかも知れません。すこし外観の微調整を行いました。
ttp://kuroda.bglb.jp/htabox/tab.zip
HTABOX3はリリースビルドでも500kを超えるサイズとなっています。ソースは その半分くらいですが、さすがにこの大きさになると肩がこります。つい書い た対症療法的記述が残らないように基本を確認する意味でコンパクトなアプリ ケーションを書いた結果が上記ブラウザです。あまり拡張する気はありません が、タブ表示中のファイルパス、URLを単一ファイルにテキストで保存し当該 ファイルを開いた場合は複数のタブを一気に再現する機能と、ページ上のハイ パーリンク上で右クリックし、IEではなく本ブラウザの新たなタブとしてリン ク先を表示する機能は是非実現したいと考えています。
一応方向性としては複数HTAを融合した形でのアプリケーション構築に対する 習作ということになります。HTAは一つの窓で実行するものという概念を取り 払うことでHTAをモジュールとみなしたメタHTAの実行を可能としています。 例えば一番最初のタブにマスターHTAを置いて以降のタブに存在する実働HTA へ仕事を依頼して結果を取得するというようなイメージです。また、HTMLとい う規格そのものがマルチスレッドには不向きですが、設計の段階から別スレッ ドは別HTAとすれば、同一オブジェクトや変数に対する競合が発生しませんか らより明確なアルゴリズムで複雑な処理を記述可能になると思われます。
31 :
デフォルトの名無しさん :2011/04/10(日) 00:55:00.62
凄いことが始まろうとしている。
32 :
デフォルトの名無しさん :2011/04/10(日) 01:54:39.60
いろんな動画みてると再臨界が始まってる可能性が高いみたいだね。 京大の専門家先生によると、もしそうなって格納容器が一気に破損した場合は、 福島原発の半径300キロを目安に退避したほうがいいそうだ。風下になったら躊躇なく逃げよう。 いままでと同じ爆発と同じように対応するわけにはいかんそうだ。 みなさんも心の準備、車やガソリンの準備、お金や身の回りの準備、遠くの親戚との連絡だけはしておいて 何事も起きないように祈りましょう。 作者さん、このスレのみなさんに大事が起きないことを祈る。
一括タブ定義ファイルの仕様を決定しました。拡張子TZBのテキストファイル
で単純に改行(\r\n)区切りにフルパスを記述してください。改行のみの行は
無視しますが、何らかの文字列が存在した場合はパス又はURLとみなして生成
を試みますので注意してください。
ttp://kuroda.bglb.jp/htabox/tab.zip にはWindowsXPに標準で存在する4枚のサンプルJPGを一括で表示する例が添付
されています。各自の環境に書き換えて当該ファイルをAppend HTMLで指定
してみてください。
ttp://kuroda.bglb.jp/htabox/tab.zipを更新しました 。
表示ページのハイパーリンク上で右クリックした場合当該リンク先を新たな
タブで表示することができます。マウス座標からのとエレメント特定は基本
的にelementFromPointなのですが、フレーム構成の場合やや複雑な手順が必
要になるようです。また、ヒットしたエレメント自体が<A>とは限りません
ので親エレメント側を巡航し<A>を検索、存在しなかった場合子を列挙して
再帰的に<A>を検索しています。リンク手法が<A>以外だった場合の動作は
考慮していません。これで信頼すべきサイトであればネット上を巡航する
事が可能となりました。
このブラウザのバイナリサイズは380kですが、300kはタイトル画像ですので 実質80kです。MSHTA.EXE並のコンパクトなサイズでイントラネット用タブブラ ウザを実現できたことを素直に喜びたいと思います。現在実装されていない ツールバーとヘルプファイルを整備して企業内イントラネット専用ブラウザと しての需要を掘り起こせればと考えています。
ttp://kuroda.bglb.jp/htabox/tab.zipを更新しました 。
ヘルプは書きかけですが、実用に耐えると思います。正直HTABOX3が大きくな
ってストレスが溜まったものですから、思いっきり軽量なものを書きながら
粛然としない部分を検証しようという意図は思いがけない副産物を生んだよう
です。私はこの子が結構気にいっています。やろうと思えば各タブのHTMLイン
スタンスへHTABOX並の機能を提供することも可能ですが、このブラウザの場合
レスポンスの良さが特徴ですので、あまり欲張ったことは考えていません。
ttp://kuroda.bglb.jp/htabox/tab.zipを更新しました 。
表示ページのタブ部分の右クリックでポップアップメニューが表示され、
タブの削除、HTMLソースの表示、整形XMLでの表示、を選択できます。
特に整形XMLでの表示はHTMLをXHTML化しなければならない時の変換ツールと
して有効だと思います。このXMLは単なる文字列変換ではなくHTMLのDOM
ノードを再帰巡航してXMLのDOMとしていますからコストはかかりますが整形
XMLであることが保障されています。
前から感じていたのですが、結局何らかの分野できちんとしたプログラムを 書けるかということは英文MSDNのどの位置に関連文章があるかを知っている かどうかに尽きる気がします。さらに独創的なプログラムを書けるかどうか は英文MSDNの先にある未解説な部分をいかに実験コードで解析してゆけるか になります。この「解析」に相当する行為は実アドレスを常に参照可能な言 語でなければ困難です。ある推理の元にコードを走らせ、少しづつ変化させ ながらどこでシステムがハングするかを観察する行為だからです。
そういう観点から見ると、ことWindowsに関しては「解析」に使えない言語を 複数習得する必要は全く無く、JScriptかVBScriptで十分に思えます。勿論 現状のJScriptかVBScriptで素敵なアプリケーションというのは書けない訳で 分かっていながら中途半端な言語の知識を習得せざるを得ない状況のように 思えます。私の仕事はJScriptかVBScriptで素敵なアプリケーションが実現で きるようにC++で下支えをすることと表現できるかも知れません。
ttp://kuroda.bglb.jp/htabox/tab.zipを更新しました 。
書きすぎている部分をシェイプしてソースコードを整理しました。さっさと
ドキュメントを書いて個人アカウントの方でVectorにアップするつもりです。
名称は「TZ Browser」キャッチは「HTA用タブブラウザ」になるでしょうか。
その後にHTABOX with Editorを公開することになります。正直、開発を続け
られるかの瀬戸際を通り過ぎてしまった感もあるのですが、なんとか電気代
くらいは稼ぎたいと思っておりますのでよろしくお願いします。
今日はちょっとスランプな日です。考えがまとまらず前へ進もうとして 自分で自分の足を踏んでいるような日です。100%成功するための秘訣は 成功するまで諦めないことなんだそうです。確かにそれなら失敗という 概念が無いので前向きに生きれるでしょうね。
ちょっとだけWindows上のCOMプログラミングについて呟かせてください。 世の中のサンプルコードを眺めているとどうしてそんなコストの高いことを しているんだろう?と思うことがしばしばあります。代表的なのはイベント シンクです。私も現在のスタイルに到達する前はイベントを拾うという実験 もしていますが、もともとCOMはスレッドやプロセスを跨いだメッセージ通信 で実現されていますので双方がCOMであればイベントという概念すら必要あり ません。単にメソッドを公開してコールしてもらうだけだからです。
つまりCOM対COMなら単純なのにCOM対非COMをやろうとするからCOMは難しい という誤解を生んでいると思うのです。COM対COMならC++でもJScriptや VBScriptでディスパッチオブジェクトを扱うのと何ら変わらないのです。 じゃぁなぜ皆さんがそうしないのか?つまりなぜC++でIDispatch継承クラス を書かないのか?問題はそこに帰着すると感じています。
手前味噌ではありますが
ttp://kuroda.bglb.jp/vcpp/index.htm で最短のディスパッチ継承クラス作成コードを解説しています。会員認証
はどんなメールアドレスでもサーバーが自動返信するアカウントを受信
できれば有効ですので気軽に登録してください。コードを眺めても最初は
なんのことやらと感じるでしょうが、動かしながらあちこち書き換えるうち
にCOMの本質が理解できるのではないかと思います。
48 :
デフォルトの名無しさん :2011/04/15(金) 13:57:50.09
震災のどさくさにまぎれて、いまの日本政府がやろうとしていることのひとつ。
↓
【政府調達】韓国ベンチャー企業が、日本政府機関のプロジェクト受注 日本で外国ベンチャー企業がプロジェクトを受注するのは極めて異例
http://toki.2ch.net/test/read.cgi/wildplus/1302842274/ 1+1 :影の軍団(第弐拾八期首席卒業生)ρ ★ [] :2011/04/15(金) 13:37:54.21 ID:???
韓国ベンチャー企業のウィズドメインが、日本の新エネルギー・産業技術総合開発機構
(NEDO)の特許情報収集サービス事業を受注した。
大韓貿易投資振興公社(KOTRA)が 14日、明らかにした。
ウィズドメインは昨年下半期(7〜12月期)からKOTRAが運営する東京の
コリアビジネスセンター(KBC)IT支援センターの諮問を得て、
20社が参加した 今回のプロジェクトで受注に成功した。
日本の政府調達市場で外国ベンチャー企業がプロジェクトを受注するのは極めて異例だという。
何が国益に結びつくのかは難しい判断だろうと思います。理想は政府機関が エンジニアを育成して実現することなのですが、私もかつて役人の端くれと して感じたのは情報処理みたいに日進月歩な世界の勉強をしようとしないん ですね。そうしなくても飯が食えるし、外注することで民間へ税金を還流し ているというばかげた発想でいるんです。で入札を国際的に開放すれば海外 の企業が受注するのはある意味しかたのないことだと思います。 もし私が政治に関与できる立場だったら「情報処理」を統括する官庁を作って 自前で開発させますし、いいものができたら他国へ売り込んで外貨を獲得する という発想で取り組むでしょうね。
私が知りえる情報というのは限られている訳ですのであくまでも「私見」な のですが、この国の状況は将棋で言えば「詰めろ」から「必至」に変化した と感じています。一度「参りました」というのも選択肢の一つだろうと思い ます。私が若い方々に言いたいのはことソフトウェアの分野においてもはや 「国」を意識する必要は無く、貴方の労力は世界が評価してくれるというこ とです。その礎を、せめて礎を置く地ならしをできればというのが私の想い です。
WIN32APIの集積でアプリケーションを書く作業が続いていますが、DOS時代を 経験した者にとっては夢のような環境だとつくづく思います。コンピューター は今も昔も、そしてこれからも単にディスプレイのピクセルを光らせているだ けです。プログラマーは任意なピクセルを何色に光らせるのかをコントロール していると言えます。DOSの時代でもウインドウやボタンを表示させることは できましたし、気の効いたアプリケーションには必須な要素でもありました。 ただし1ピクセルづつコントロールする必要があります。もし複数のウインドウ が重なって下になった領域のピクセルデータを保存、復元しなければならない としたら恐ろしく煩雑な処理を記述するはめになるでしょう。
TZ Browserのソースコードは現在57kです。たった57kでメインウインドウ、 タブコントロール、ツールバー、ステータスバー、任意な数のHTMLウインド ウ任意な数のエディタウインドウとその上のリッチエディットコントロール を制御できるのですから、感心してしまいます。欲を言えば10年前に今の 心境に到達していなかったのが残念です。私はまだ己の知力が低下してきて いるとは思いませんが、体力のほうはもはやぼろぼろな状態です。
サンプルスクリプトを書き始めましたが、例によっていろいろと問題を突きつ けられます。HTABOXの場合はメインになるHTMLインスタンスが複数という状態 は有り得ませんがこのブラウザはすべてのHTMLインスタンスが主役ですのでよ り過酷な面があります。過酷さゆえにHTABOXを書きながら「これでいいのか?」 と感じていた部分をきっちりと指摘してくるので大変勉強になります。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
タブで実行中HTMLへのファイルドロップ、ファイル選択ダイアログを追加し
ました。ファイルドロップについてはHTABOXと同等でwindow.onFileDropが
存在すれば引数としてパスが渡されます。今回はまじめにVB用として
Window_onFileDropが存在するかも検査しています。
ファイルコモンダイアログは短めの名前にさせていただいて。
var path = TZB.FileOpenDlg("タイトル", "text\\0*.txt\\0", "c:\\", "*.txt");
var path = TZB.FileSaveDlg("タイトル", "text\\0*.txt\\0", "c:\\", "*.txt");
こんな感じです。上記例のTZBはdialogArgumentsから取得してください。
いつもCOMとしてコモンダイアログを提供する場合のスレッドやメッセージの 扱いに苦慮するのですが、このブラウザで採用しているスレッドの設計方法は 当りだったようでHTMLウインドウの再描画を阻害することなくごく当たり前に ダイアログを移動することができます。HTABOXの方ではもっと込み入った方法 となっていましたのでフィードバックできればより軽量なものにできそうです。
ちょっと欲が出てText操作を充実させることにしました。ブラウザのコード 表示に使っているエディタウインドウの軽量化版をスクリプトから操作でき るようにしました。通常リッチエディットの書式設定は煩雑な操作を伴いま すが、ラップして簡潔なものとしました。このウインドウは非表示で動作で きます。したがって非表示のままTOM(Text Object Model)を操作すれば任 意なコードページのファイル入出力を行い文字列を取得、保存することが可 能です。追加関数は数個なんですが、ここでは見苦しい解説になりますので サンプルソース付のβ公開をお待ちください。
このエディットウインドウはこの仕様のままHTABOXにも追加される予定です。 何らかの連続動作を行っていて多量のログをリアルタイムで表示しなければ ならないような局面でも威力を発揮すると思います。HTMLの場合setTimeout 等でスタックを開放した再突入を行わなければリアルタイムなinnerTextの 更新、表示はできませんのでこういうのが欲しいと考えていました。
エディタウインドウを見ていたら突拍子もないことを思いつきました。こんな 動作が欲しいと書き込むと具体的なコードを生成してくれるエディタです。 いままであらゆるプログラミング言語は実世界の問題を一旦抽象化したコード という形にしなければなりませんが、そのステップを自動化するんです。 「言語解析」「エディタとサーバーの通信」「モジュールデータベース」 「自身のコードが再利用されても構わない多くのプログラマ」「若干のAI」 そんな要素がそろえば実現できなくもない気がします。
65 :
デフォルトの名無しさん :2011/04/18(月) 11:57:11.42
たとえば 2ch 書き込み 保守 と検索すると、2chに書き込みするクラスと、その呼び出し方がダウンロードされて表示されるわけですね。 本当にありがとうございました。
TZ Browser、見た目にこだわっているせいでVista以降で利用するとダサい。 軽量がコンセプトなのだから変に小細工しなくていいのでは……? もし、見た目にこだわりたいのなら ・クラシック ・XPのLuna ・Vista以降のAero この3つの環境になじむようにすべきでは……?
COM(オートメーション)は「あなたはどんな関数をもっていますか?」を 名前で問い合わせる決まりごとなわけです。もし、仕事の内容で「こういう モジュールもっていますか?」になれば、あながち夢物語でもない気がする のですが、勿論現在の私にそれを実現する力量があるわけではありません。 多くのモジュールからのチョイスなのか、もっと抽象化されたモジュールを 若干の自動化で具象化すべきなのかとか、そのへんのイメージすらありません。
>>66 Vista以降での外観はまだ確認していませんでした。Lunaではテストしていま
すが、「ダサい」の意味が理解できません。いわゆるテーマに対応した外観
を形成しなさいという意味でしょうか?
あらためて表示HTML内に <META HTTP-EQUIV="MSThemeCompatible" CONTENT="Yes"> を入れてテストして確認しましたが、きちんと機能するようです。メニューや タブをオーナー描画でビットマップにしなさいという意味でしょうか?
Vistaで実際に表示しています。確かにデモのエディタのメニューはテカテカ してますけど、TZBのメニューはグレイですね。動作PCのコモンコントロール バージョンを識別した処理が必要なのかも知れません。貴重なご指摘ありがと うございました。
>>68 メニューバーやツールバーやタブや右下のツマミがVistaでもクラシックな表示だったので気になりました。
「ダサい」とはそういう意味です。郷に入らば郷に従って欲しいと思います。
今度から具体的に書くようにします。クレーマーみたいで本当にすいませんでした。
>>71 私の欠点は「書くのは好きでも動かすのは嫌い」なことなんです。なんで2ch
に独白スレッドを作っているかと言えば、動かないとか、ショボイ場合は容赦
なく指摘されるだろうという目的なんです。今回のご指摘でテーマ、マニフェ
ストに関して本腰を入れて勉強する機会をいただきました。本当に感謝してい
ます。
貧弱な開発機しかないものですから、Vistaも推奨スペック以下のPCで最終的 な動作確認のためだけに動かしていましたが、あらためて眺めると結構いろい ろと違うんですね。一番驚いたのが「特大アイコン」です。この大きさの32ビ ットビットマップでアルファマスク付ならそれだけで1Mb近くになるんじゃない でしょうか。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
全表示パス又はURLの保存、再現機能にバグがあったので訂正しました。
全タブ情報TZBファイルはメニューの保存だと自動的にフルパスが保存され
ますが、手で書く場合面倒だと思うので、相対パスと判断した場合TZBファイ
ルの親ディレクトリを付加して絶対パスを合成します。URLの場合は絶対パス
で無ければなりませんが、一旦GETしての存在確認では重いので単純に存在を
信じる仕様としています。
78 :
片山博文MZ :2011/04/19(火) 09:14:35.19
>>74 特大アイコンはPNG形式で埋め込みできる。
>>78 現実にはそういう手法をとるんでしょうね。特大の世界になるとイラストレー
ターとしての才能が試されるし、私にはクールなイラストを書く才能が無いの
で衝撃でした。
このブラウザのヘルプはサンプルを即座に実行して、そのソースも確認でき る造りになっていますが、HTABOX3は更に表示されたソースをその場で編集 して実行できる造りになっています。JScript、VBScript、両者の.NET言語 の4種類をパースして実行します。ただHTABOX3は私にとってフルスイングな プログラミングとなりましたのでどこか余裕の無いものに感じられていまし た。例えば見やすく理解しやすい説明を書く余裕が無いという懸念です。
じゃあ70%のスイングをして自分のフォームを確かめようというのが今回の TZBです。今日の午前中までヘルプHTMLの仕様に悩んでいましたが、決定し てしまえば、HTABOXと比較して機能は多くありませんから半日で概ねの内容 を書き上げることができました。自分で総てを管理しているメリットとして ヘルプを書きながら、「こういう関数が必要」に気づき、さもあるかのよう に説明を書いた後に実装することもあります。結局、取り説を書くという作 業は使う側に立った作業でなければなりませんから、その時に心がぎすぎす していては何も伝わらないものができてしまうと感じています。
実はもう一つこのブラウザには意図があって場合によってはオープンソース にしても構わない設計としています。COMやHTABOXを使わなければHTMLアプリ ケーションの姿は旧態然としたままなわけですが、私のことを気にかけてく ださる開発者の方からバイナリ依存のHTAは検査ができないから商品にならな いというお話を伺ったんです。まぁそう言われれば身も蓋も無い訳ですが、 もし、ソースが公開されていて安全な事が保障されているHTAの機能拡張環 境が存在すればHTAも前へ進むことができるんじゃないかという発想です。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
多分非公式関数扱いなのですが、
TZB.CreateSoundBuffer(location, "test.wav");
TZB.PlaySoundBuffer(0);
をデモするsound.htmとtest.wavが添付されています。
DirectSoundの特徴はWAVバッファを事前に作成し、再生要求に対して即座に
応答することです。デモで使用しているモジュールは全WAVデータを保持しよ
うとします。しかもB級でもオーディオマニアが書いたモジュールですので
16bitステレオPCMのみ対応ですから効果音程度の大きさのファイルで遊んで
ください。
いつのまにか引数起動に対応していますので、TZBrowser.exeへターゲット ファイルのアイコンをドロップするとすべてタブ表示しようとします。 どっさり複数のHTAでも構いませんし、複数パスを記録した拡張子TZBなら 表示順を確実にコントロールできます。DirectSound系モジュールはデモの 効果音再生用の他に長時間録音用、長時間再生用モジュールもありますので こっそり実装するかも知れません。
話題はスレ違いなのですけれど、目という感覚器は数十分の一秒間隔で瞬い ている画像を常に光っていると勘違いするほど時間にルーズなのですが、耳 という感覚器は時間にシビアです。毎秒340m進行する音波を僅か20cm間隔の 両耳で受信しその時間差とエネルギー差から音源の方向を推定するわけです から神様にしか創れないほど精巧な器官だと思います。
ですから耳がリアリティーを感じるということはある意味映像でのリアリテ ィーより高度であると言えます。ただじっと目を閉じてその音が作り出す空 間や、イメージを楽しむようなアプリケーションをいつか書きたいと思って います。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
自分の勉強にもなりますしDirectSound系関数も正式な機能として付加する
ことにしました。DirectSound.htmが添付していますのでexeへドロップすると
デモをご覧になれます。まだDirectSoundスレッドの振る舞いを理解しきれて
いない部分があって、意地悪な操作をすると止まったりするかも知れませんが
ご容赦ください。確かDirectXはスクリプト向けCOMサービスもあった気がし
ているのですが、このモジュールは考えうるかぎり軽量に仕上げました。
一般的なコンピューターのSN比はもともとたいしたものではないのですが、
それでもCPU負荷を抑えることでベストなSN比を目指そうという方向性です。
DirectSoundも _COM_SMARTPTR_TYPEDEF(IDirectSound,IID_IDirectSound); から書き始めると結構見てのとおりな記述ができるのですが、いままでそい う記述をする方を見たことがありません。以前にも書きましたが、DirectX の上層にある機能はハード依存しますので苦労の割りに得るものが少ないと 思いますが、低層な部分は今後も有効だと思われますので、機会があったら 最初からCOMとしてDirectXを扱う解説を書いてみたいと思っています。
簡潔にサウンド系関数を説明します。3種類のサウンドバッファが存在します がメソッドは統一しています。比較的小規模なWAVを再生するSoundBufferで 説明します。 var TZB = window.dialogArguments; var Sound = TZB.CreateSoundBuffer(location, "hoge.wav"); CreateSoundBufferは2つの引数を取ります。第1引数は第2引数に相対パスを 指定する場合locationでなければなりません。第2引数が絶対パスである場合 はnullを指定してください。返却値であるオブジェクトには下記のメソッド があります。引数や返却値はありませんし、そのまんまの名前なので説明の 必要はないと思います。 Sound.Start(); Sound.Pause(); Sound.ReStart(); Sound.Stop();
SoundBufferは一旦全ファイルデータをメモリに保持します。ですから大きな ファイルを保持するのは不利ですが、一旦読み込めば再生要求へのレスポンス は俊敏です。MusicBufferは3分割した環状バッファにより大規模なファイル を部分的に読んで再生します。CaptureBufferも同じく3分割した環状バッファ により再生中の音をキャプチャしてRAWPCMで保存します。Stop()関数が呼ばれ た場合、Create時に指定されたファイルへPCMを再編しWAVファイルとして出力 します。
WAVの形式はCD規格のPCMのみです。また、現状ではファイルサイズを32ビット で認識していますので4G以上のファイルでの動作は未定義です。結構WAVデー タは大きなサイズとなりますので、録音時の一時ファイルを分散させて再編時 に無音を検出し、適切なサイズのファイルを自動生成するというような機能 を追加すべきだろうとは考えています。
DirectX全般に言えることですが、ハードウェアが持たない機能をソフトウェ アでエミュレートしようとします。Draw系なら描画が「もたつく」という結果 になるわけですが、Sound系の場合「ノイズ」に結びつく事があります。です から、多くのエフェクトを追加してゆこうという気はありませんが、是非こ れだけはというご要望がありましたら気兼ねなく書き込んでください。
今までは単にプログラミングの題材としてしかDirectSoundを見ていなかった のですが、あらためて触ってみるとなかなかよくできています。特にPCMクロ ックを再生時に可変できるのが素敵です。勿論ハードがそのクロックに対応 していることが条件でしょうが、48KHzならほぼ総てのハードが対応している のではないでしょうか。だとすれば44.1KHzを伸張しながら補間を加え自分の アレンジしたより高音質な音楽として再生することが可能です。これが96KHz なら補間の仕方によっては劇的な変化を期待することもできると思います。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
再生系バッファにステータス取得、クロック設定、左右バランス、ボリューム
機能を実装しました。録音バッファはステータス取得のみとなります。
var Status = Sound.GetStatus();
Sound.SetClock(48000);//48KHz
Sound.SetPan(0); //中央
Sound.SetVolume(0); //減衰なし
のような使い方になります。解説はTZBのリリースをお待ちください。
再生の場合は五月蝿ければメインボリューム絞ってもらえばいいわけですが、 録音のレベル決定(結局再生音量ですけど)のためにはどうしてもdbレベル をモニターできるウインドウが必要ですから夕方からそれを書いています。 short変数が一秒間に44100*2個流れていてその振幅を検査し、一定間隔で ウインドウへポストする。こうやって書くとそれだけのことですが、現実は 総力戦の様相を呈してきました。
もうすぐ、キーボードのついたコンピューターは珍しい存在になると思いま す。軽量で携帯が便利なら情報端末として、この大きさのコンピューターは 終焉するでしょう。そこで私はこの大きさのコンピューターだから可能な事 をすこしアピールしたいと考えています。その一つのテーマが無圧縮音源で す。TZBは簡単で便利なテキストサービスとサウンドサービスを提供する新た なHTMLアプリケーションのプラットフォームにしたいと考えています。
終わってみればTZBのソースも100kを越えていました。HTABOX系はソース書か ない人にとってみれば「なんのことやら」でしょうし、かといって書かない 人を取り込むほどの魅力はなかったんだと思います。HTABOX3はより洗練され て直感的なものになりますが、それでも今まで束縛の多い環境で書いていた からこそHTABOXに魅力を感じるという部類のものだと思います。 TZBは出発点に帰ってHTMLアプリケーションをモダンなスタイルで実行するに は何が必要か?参入者を引き込むには何が必要か?を自分なりに表現したつも りです。TZBはシェアとしますが、なんら制約は設けません。大げさな言い方 をすれば「この世界に私がいた証」という意味合いのソフトです。
再生系のバッファには再生が終端で終了した場合のコールバック関数をスクリ プトから登録できるようにしたいと思います。これは簡単なことです。録音系 バッファにはコールバック条件を指定された音圧以下の状態が指定された時間 継続したらにしたいと思います。この両者があることによって完全にスクリプ トで制御した状態での自動再生、自動録音ができることになります。
コールバックを実現するためには結構大技が必要なことに気づきました。 今回は音楽プレイヤーを作っているわけではなく、アプリケーションが必要 とするWAVを遅延なく再生する。同時に発音しても問題が起こらない。最後に そのWAVを作成するための録音機能を装備している。にとどめて明日のリリー スを目指したいと思います。
リリース前にDirectSoundとマルチメディアAPIの音質に差異が生じるのかを 確認したくて一日を費やしてしまいました。wave...API系はコールバックル ーチンが無いとまともなことはできないのですが、なんか挙動が変だと思っ たら、この部分ににはごく限られた関数しか使えないという設計ということ で笑ってしまいました。参入者を蹴落とす罠にしか思えません。結局付ける 予定ではなかったレベル表示ウインドウを用意してPostMessageすることに しましたけど、これはこれで一つの分野というか独特の世界ですね。
基底で動くディバイスの機序というのはそう違わないと思うのですが、私の 開発機ではマルチメディアAPIの方がメリハリの利いた音にになります。まぁ 耳でどうこう言うよりも波形分析すればそれぞれの特性が見えてくると思うの ですが、TZBには両方装備する予定ですので皆さんの耳で確かめてください。
1週間くらいで決着するだろうと思っていたタブブラウザ作成に結局2週間を 費やしてしましました。「妥協する」っていうことはイコール「負ける」こ とだと思っていますし、自分が負けたと判断したようなものを世に出すこと は恥ずかしくてできませんから、徹底した作りこみをしてしまいます。結果 、書けば書くほど「どうしてこんなことも分からないんだろう」と落ち込む わけです。特に最近は自分の無能さにほとほと嫌気がさしています。
おまけのつもりで書き始めたサウンド系サービスですが、TZB全体の約半分の コードはサウンド系サービスが占めることになりました。本当はサウンド系 の取り説を書いていたのですが、子供になったつもりで乱暴に操作すると、 まだまだ弱点が見えたものですから、コーディングに戻ってしまいました。 だいぶコードもすっきりしましたので、いよいよリリースできる状態になっ たと考えています。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
DirectSoundでもMMAPIでも録音オブジェクト生成時にPCM識別子が0の場合ダ
イアログが表示されキャンセルの場合先頭要素が選択されたものとして動作
する仕様としました。また、8bitモードでの音圧計算を適正化しました。
ちなみに開発機における8bit無音は0x80ではなく0x7fでした。振幅がなければ
いずれの値でも無音となるわけですが、ちょっと悩む原因となりました。
プログラミングはほとんどの時間が精神的な消耗戦の様相を呈するのですが、 唯一安らかな時間があります。不安無く動作すると確証したコードを何年か 後に読み返しても理解しやすいように整形して、コメントを付加している時 です。それは長い長い戦いの後のほんのひと時の安息なのですが、やっとTZB をリリースできるレベルと判断できました。
長時間再生テストにD minor Choralを繰り返し聴いています。DirectSoundも MMAPIもそんなに違いはありません。ただPCは音楽演奏以外のディバイスも稼 動していますから場合によってはバッファ的にクリティカルな状況も発生する 可能性があります。ですから最も重要なポイントはファイル入出力かも知れま せん。mmioOpen時に適切なバッファサイズを指定する事が結構重要な気がしま す。
このテストでWindows Media Playerはデフォルトの状態でもエフェクトして 再生している事に気づきました。端的に言えばイージーリスニング調に加工 して音を出しています。各楽器には若干残響音が付帯し、音声領域を強調す るように聞こえます。これは圧縮音源を再生する時に粗を隠す目的だと思わ れますが、楽器の配置がぼやけて臨場感がスポイルされます。是非PCのジャ ックをオーディオに繋いでその違いを確かめてください。
いままで素直にwaveInGetDevCapsが返す能力がハードの能力だと思っていたの ですが、試しにに48KHz、96KHzでの録音を実行するとすんなり通ります。もう 数年来使っている低価格ビジネスノートでさえそうなんですから、へたに問い 合わせずに96KHzまで全部選択可能に変更したいと思います。
総括というと大げさですが、サウンド系プログラミングで感じたことを書き ます。「ノイズとは何か?」を考えた時機械周期がもたらす定常的な信号と 考えられます。コンピューターはデジタルな動きが基本ですから物事は一定 周期で起ころうとします。プログラマーも普通割り切りやすい数やアクセス が高速なデータ領域を意識します。しかしそれは結果的に別の周期を作り出 す原因ともなります。周期が存在すれば電圧が変化し結果「ノイズ」を助長 しかねないと推察します。
例えばリング状にバッファを形成し何分割かする場合、個々のサイズが等しけ ればプログラミングは楽ですが、常に一定間隔で何かが起こることになります。 もし、個々のバッファサイズと、ファイル入出力のバッファサイズが整数倍で 両者のフラッシュタイミングが重なるようなことも避けるべきでしょう。要は デジタルに処理するのではなく、いかに滑らかに処理するかというイメージ で取り組めばいいプログラムが書けるのではないかと自戒の意味も込めて感じ ています。
プログラムの動作結果は環境に左右されます、ましてやほとんどハードウェア コールで形成される音楽再生について一概に結論付けるのはよろしくないので すが、当環境に限って言えば長時間音楽を再生しながら別のタスクで負荷をか ける状況においてDirectSoundの方が良好な結果を示します。DirectSoundの場 合は長大な単一バッファ上の任意な箇所にイベント発生ポイントを設定できる のに対し、wave...系は一曲分のバッファを用意できないかぎり異なるアドレス の切り替えを前提とした動作となるからだと思われます。
ですから、もしwave系でループ再生し任意なポイントで負荷無くイベントを 発生させ、システムの制御を奪って当該位置のPCMデータを書き換えれば安定 度を上昇されることは可能かも知れませんが、それはDirextSoundをもう一度 書くという意味の無い行為に思われますので深追いはしないことにします。 したがって両者の位置づけは、特段理由が無い限りDirectSoundを推奨としま す。TZBで採用しているインターフェースは末尾に数字の無いIDirectSoundで すからWindows2000以降で動作しない機体は無いだろうと予測します。
MSDNにはwaveOutProcの解説として 「関数 EnterCriticalSection、LeaveCriticalSection、midiOutLongMsg、 midiOutShortMsg、OutputDebugString、PostMessage、PostThreadMessage、 SetEvent、timeGetSystemTime、timeGetTime、timeKillEvent および timeSetEvent を除き、アプリケーションでコールバック関数内からシステム 定義関数を呼び出さないようにしてください。ほかのウェーブ関数を呼び出す と、デッドロックの原因となります。」 とあるのですが、素直にこれに従うと能動的な処理ができなくなり結果的に システムのメッセージ伝達がビジーな状態となると音が一瞬途切れるという ストーリーのようです。上記解説を方向をしめす指針と解釈すればMMAPIでの 動作は劇的に安定するというのが落ちのようです。
プログラムのコーディングというのは百人百様でいいと思うのですが、どう もファイルの拡張子だけcppで内容はcというソースコードばかり目に付きま す。これには理由があって、WIN32APIを主に扱うとシステムからコールバッ クしてもらいたい局面が多々発生し、そのためには静的なアドレスを準備し なければならないからです。例えばウインドウのプロシージャがそうです。 クラスメンバのように生成しなければアドレスが決定しない要素には書けな いわけです。結果プロシージャからはクラスメンバにアクセスできないとい う縛りが発生してしまいます。
でもこの問題はとても単純に解決できます。ウインドウプロシージャを例に 考えれば問題は「HWNDは自身のクラスアドレスを知らない」を解決する機構 を準備すればいいのです。プログラムの冒頭に高速なハッシュクラスを置き 静的なプロシージャ内でそのハッシュへHWNDに対応するクラスアドレスを照 会し、得られたアドレスを当該クラス型にキャストしてクラスメンバとして 存在するプロシージャを呼び出せばいいのです。
これと同じことをSetWindowLong、GetWindowLongのGWL_USERDATA領域を使って ハッシュ無しに実現することもできますが、自身が設計登録したウインドウで なければGWL_USERDATA領域が真に使用されていないのかを確認することはでき ませんからお勧めできません。特に込み入ったコントロールほどGWL_USERDATA を使用している可能性が高くなります。例えば私の得意分野であるHTML系がそ れに該当します。
このちょっとした機構はC++によるWIN32APIプログラミングを劇的に可読性 の高いものにします。だいいちファイルスコープのプロシージャに動作が記 述されているクラスを量産したら別インスタンス同士の競合で早晩クラッシ ュすることになりますが、クラスメンバとしてプロシージャを持てばどんな に量産されても競合は発生しませんから、JScriptかVBScriptのように記述 できるのです。
COMそしてハッシュを用意したシステムコールバックのクラス内引き込みとい う2つの概念を導入すればCでは到底なしえない、又はCでは到底管理できない 複雑さの仕事をとても単純な記述で処理することができます。しかもそれに 要するオーバーヘッドは極めて小さなものになります。せっかく先人達の苦 労を元に進化したCPPコンパイラを使うことができるわけですからC的C++では なくC++だから可能というコードを書きたいものです。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
低水準wave系にも静的バッファを新設しDirectSound系と対称な構成としました。
これに伴い生成関数の名称を変更しました。
TZB.CreateDirectSound(location, path);
TZB.CreateDirectMusic(location, path);
TZB.CreateDirectCapture(location, path, pcmtype);
TZB.CreateWaveSound(location, path);
TZB.CreateWaveMusic(location, path);
TZB.CreateWaveCapture(location, path, pcmtype);
どうも48kや96kで低水準系APIの動作が不安定なんで悩んでいます。ストーリ ーとしてはあくまでwaveOutGetDevCaps、waveInGetDevCapsが報告してこない モードは使えないとして切り捨てるべきなんでしょうけど、DirectSound系で は何ら問題なく処理するものですから、書き方によっては何とかなるんじゃ ないかと思ってしまいます。
今日は実に憂鬱な日でした。結果的に低水準マルチメディアAPIをプロジェク トから除外する選択をしました。DirectSoundで不可能な機能を今のところ見 出せませんし、私のモジュールはCOM系のメッセージが飛び交っていますので その辺と相性が悪いという事にして前に進みたいと思います。99%動きそうで 1%だめみたいな動きをされると一番疲れます。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
サウンドサービスはDirectSoundエンジンのみとなりました。一時停止、再開
時の動作を適正化しました。録音終了直前バッファを救済して保存するように
しました。各サウンドバッファの生成関数名を変更しました。
TZB.CreateSoundBuffer(location, path);
TZB.CreateMusicBuffer(location, path);
TZB.CreateCaptureBuffer(location, path, pcmtype);
プライマリのレートを上げる努力をしたからだと思いますが、今まで気になっ ていた時間軸方向の揺らぎも無くなり、きちっと芯のある音になったと感じま す。メディアプレイヤーと聴き分けると以前にもましてメディアプレイヤーが エコーをかけて再生していることが分かります。ぜひ器楽曲や声楽曲を聴き比 べてください。96K録音も単純に波形を見た限りは44.1KよりSN比が向上するよ うです。ファイルサイズはさすがに大きくなりますが、退役したノートをクリ ーンインストールして96K再生プレイヤーにするのも素敵だと思います。
対称ファイルの選択、開始、一時停止、再開、停止、停止時コールバック、 音圧レベル確認ウインドウ、再生位置のシークと操作ウインドウ。 以上の動作をスクリプトからコントロールできますので自動録音、自動再生 を目的としたツールなら十分な機能だと考えています。ボリュームと左右バ ランス、動作中ステータスの関数も実装していますが解説はドキュメントの 完成をお待ちください。
録音PCMコード指定部分をサンプルスクリプトに記載するのを忘れていました。 まもなく録音も動作するサンプルに差し替えますのでご容赦ください。
ttp://kuroda.bglb.jp/htabox/tzbrowser.zipを更新しました 。
Open関数の最終引数はPCMの形式を指定する数値です。再生の場合はファイル
の形式となりますので0を指定してください。録音の場合0はダイアログ表示
と解釈します。引数として指定する場合の具体的数値は下記のとおりです。
0x00000001 /* 11.025 kHz, Mono, 8-bit */
0x00000002 /* 11.025 kHz, Stereo, 8-bit */
0x00000004 /* 11.025 kHz, Mono, 16-bit */
0x00000008 /* 11.025 kHz, Stereo, 16-bit */
0x00000010 /* 22.05 kHz, Mono, 8-bit */
0x00000020 /* 22.05 kHz, Stereo, 8-bit */
0x00000040 /* 22.05 kHz, Mono, 16-bit */
0x00000080 /* 22.05 kHz, Stereo, 16-bit */
0x00000100 /* 44.1 kHz, Mono, 8-bit */
0x00000200 /* 44.1 kHz, Stereo, 8-bit */
0x00000400 /* 44.1 kHz, Mono, 16-bit */
0x00000800 /* 44.1 kHz, Stereo, 16-bit */
0x00001000 /* 48 kHz, Mono, 8-bit */
0x00002000 /* 48 kHz, Stereo, 8-bit */
0x00004000 /* 48 kHz, Mono, 16-bit */
0x00008000 /* 48 kHz, Stereo, 16-bit */
0x00010000 /* 96 kHz, Mono, 8-bit */
0x00020000 /* 96 kHz, Stereo, 8-bit */
0x00040000 /* 96 kHz, Mono, 16-bit */
0x00080000 /* 96 kHz, Stereo, 16-bit */
マルチメディア低水準APIの名誉挽回のためにピュアAPIなモジュールを書いた のですが、MSDNどおりでは音がぶつ切り状態なものの、MSDN無視な書き方を するとTZB環境内での気まぐれな動作が嘘のように安定した動作をします。 元々メッセージでハードと交信しているようなのでIDispatch継承クラス中で は何らかの衝突が発生したと考えられます。
TZBrowser手法の可能性を試す意味と低水準マルチメディアAPIとCOMスタイル
プログラミングの親和性を確認する意味で書きかけですがWAVEプレイヤーを
公開します。DirectSoundに比べややデリケートな部分がありますので、音質
重視な方はレベルメーターを停止できますから試してください。これを書きな
がら私のやりたいことってこういうことだったんだと改めて感じました。
ttp://kuroda.bglb.jp/htabox/wave.zip
多分私の書いたアプリケーションは他の方が書くものより外観がそっけない ものになると思います。勿論、生涯に1本2本の作品なら性能とは関りの無い 外観にも十分時間を割くべきでしょう。しかし、私が考えるソフトウェアの 生産サイクルは3日であり、ドキュメントも含めて1週間でリリースするため の手法を目指しているんです。1年に52本アプリケーションを完成できる手法 がHTABOXでありTZBrowserでありたいと考えています。
例えばこのプレイヤーは表示画面のレイアウトを簡略化するためにHTMLを使っ ていますが、ほとんどC++で書かれています。その長さは約2000行です。でも 肝心の音を出すエンジンはほんの60行です。この60行を使ってもらうウインド ウやボタンの為に他の1940行があることになります。もしTZBで今回使ったコン トロールをHTMLへ埋め込めるようになれば、30行程度のHTMLとスクリプトで 同等のアプリケーションを提供できるでしょう。それが私の意図するところ です。
ttp://kuroda.bglb.jp/htabox/wave.zipを更新しました 。
シークバーで移動した場合に停止する可能性を排除しました。低水準APIの
メリットの一つがこのシークです。任意なポイントへ自由に移動できます。
私が何か気づいていない事があるのかも知れませんが、DirectSoundは何故
かバッファ長単位でしか移動できません。つまり2秒のバッファで演奏を開
始した場合偶数秒への移動は問題ないのですが、奇数秒のデータをバッファ
先頭に入れて演奏すると破綻します。DirectSoundが低水準APIより安定して
いる理由はそういった先回りした処理があるからだと考えられます。
HTABOX3を完成させるにあたり、一つ何悩んでいたことが解決しました。SPY++ でHTMLウインドウを探ると分かるのですが、ドキュメントのスクロールバーは 通常のコントロールではありません。HTABOX3ではドキュメント上に各種コント ロールを乗せますが、このスクロールバーより前面に出てしまいます。これは 前述のスクロールバーがドキュメントの子でない以上Zオーダーの問題ではなく、 親の下に子はもぐりこめないという根源的な要因を生み出します。じゃあディ バイスコンテキストへ領域制限かけて重複を回避すればという発想はあったの ですが、頭悪いもので今まで成功しませんでした。これで本当に自由な位置、 レイアウトで各種コントロールをHTML上に配置することができ、HTMLの特徴で ある大きなページでのスクロールを阻害することもありません。
今回TZBを書いて気が付いたのですが、アプリケーションは3つの局面に分けて 考えると設計しやすい気がします。一つは「取り説」のような静的局面。もう 一つは「設定」のようなファイル入出力をメインとした局面、最後に本来の機 能を操作するための局面です。TZBはまさしくその3ページをすばやく切り替え ることができるわけですので極めて直感的な操作を促せると同時に、設計しや すいというメリットもあります。
TZBrowserについて、 ウインドウ名は アクティブなタブのタイトル - TZ Browser としたほうが良いのではないかなと思いました。 コンセプトのシンプルに反するようであれば別に現状のままでも良いかと思いますが
おっしゃるとおりだと思います。TZ Browserはあくまで裏方ですので冒頭の タブに存在するページタイトルとか、タイトルを設定する関数とか、何らか の手段を提供すべきだと思います。大変有益なご指摘ありがとうございます。
44.1Kのデータをウインドウズ標準のPCMドライバで48Kや96Kにコンバートし ながら再生するとどうなるのかという避けては通れない課題を検証してみま した。結果は「音が悪くなる」でした。弦楽器なんかは明らかに付帯音がま とわりついて、聴くに耐えない状態となりました。いかんせんハード依存な 部分がありますからこの開発機ではという注釈が付きますが、元々無いデー タを補間してもいい結果が得られないというのはありそうな話です。
ttp://kuroda.bglb.jp/htabox/wave.zipを更新しました 。
11Kから96Kまでモードを選べるレコーダーも実装しました。このプログラム
は沢山の事を教えてくれました。HTABOXもTZBもある程度大きくなったソース
では根本に関るようなな実験や検証をやる勇気が無くなってしまうものですか
ら、喉に刺さった棘のような想いがあったのですが、それを解消できたと思い
ます。この再生、録音ソフトはあえて低水準APIを使っています。結果的にTZB
に搭載されなかった低水準APIへのレクイエムの意味もあります。ぜひ各種モー
ドで録音して、その音色の違いを比較してください。
もういじるのはやめにして、このプレイヤーで音楽を聴いてますが、思った よりも安定しているので自分でも驚いています。いつも作っていると忘れる 事なのですが、作成途中のアプリケーションは99%途中で強制終了させられて 書き換えられる運命なのですが、それを繰り返すことでコンピューター自体 にストレスが蓄積するということは十分考えられることです。ですから私は 低水準APIを過小評価してしまったのかも知れません。
このプレイヤーに動作を文字通りプログラミングできるエディタを付けよう と考えています。いわゆる開発言語によるプログラミングでは無しにPlay とかStopとかWaitとかの単純な命令を前面にアピールして、コンピューター の動作を事前に予約する楽しさ、便利さから本格的なプログラミングへの 導入ができればと考えています。ここをご覧になっている方々はすでにプ ログラミングの楽しさを知っているわけですが、そういう人って全体の1% にも満たないんじゃないかと感じています。
ttp://kuroda.bglb.jp/htabox/wave.zipを更新しました 。
テキストエディタウインドウを追加しました。このエディタ上のパスが連続
再生の対象となります。ウインドウ上の右クリックで表示されるメニューか
ら先頭行、カーソル位置からの再生を選択できます。また、多くの場合、WAV
ファイルは長い名前でしかも奥まった位置にある場合が多いことからこのメ
ニューから複数選択可能なファイルダイアログ、フォルダダイアログを表示
し、選択されたWAVファイルパスを一斉にエディタへ送り込む事ができます。
エディタで作成した再生リストは同じく右クリックのメニューから保存、呼
び出しが可能です。これで、何かをしながらBGMを流す用途にも使えます。
>>132 のMSDNが意図することがおぼろげながら理解できました。waveOutProcを定義
した(つまりwaveOutOpenを実行した)スレッドと関連の無いスレッドへコー
ルバック関数内からSendMessageすると重篤なフリーズに陥ります。今回はま
さしくコールバックが演奏終了と判断した場合に、無関係な演奏リストウイン
ドウへ情報を伝える必要がありましたので、その事実を体験することができま
した。その場合PostMessageにしてトリガーだけを引き情報の伝達手段を別途
用意すべきというのがMSDNの言いたいことだろうと思います。
少ないビットレートの録音が逆にだめなことに気づきました。TZB環境では 低水準関数がヒープに確保した領域にアクセスできないという状態を経験し たのでまったく別の設計とし、96,48,44の16ビットステレオでの動作しか確 認していなかったものですから足元をすくわれた感があります。これが機種 依存な動作でないとすれば録音時は96でサンプリングして任意なレートとチ ャンネルへダウンコンバートしてファイル保存するというのが賢いかも知れ ません。
今日はVC++のリソース管理について勉強する日になりました。私の書き方だと 環境が割り振ってくるリソースIDがすごく邪魔なのですが、Visual Studioを 改めて見てみると文字列IDに置き換えても問題が無いことに今日気づきました。 つまり、取り説HTMLがリソース格納される時数値IDの場合src="img/101"とか 後日編集するときに混乱が必至な書き方しかできないわけですが、文字列表現 IDならsrc="img/hoge.bmp"と普通に書けるわけです。で、これを環境からいち いち文字列IDに変更するよりも直接リソーススクリプトを編集して画像をどん どん足せるというじつに当たり前な事を今日まで知りませんでした。これでヘ ルプドキュメントの作業効率が格段にアップすることになりました。
TZB環境のデバッグについて深く考えていないことに気づきました。alert() があれば十分という上級者でなければ、やはりエラーの原因となった部分の 変数値を確認できるべきでしょうから、対策を考えています。今考えている ことはHTABOXの逆をやろうということです。wscript.exeを子プロセス起動 してHTMLスクリプトエンジンの代行をさせることができないかを検証しなけ ればなりません。多分この場合のオブジェクトはプロセス境界を突破できる 気がします。
プレイヤーはVistaで録音時にいやな固まり方をすることを確認しました。 結局DirectSound?になる可能性もありますが、対策を講じてみます。
いろいろやると動いたり、同じ条件でも動かなかったりと、言ってみれば 最悪な状態ですね。頭の悪い私にはとても要因を特定できそうにありません。 再生の方はいたって元気なので切り捨てるのは実にもったいない気もします が、ここは潔く撤退してDirectSoundエンジンに切り替える決断をしました。 一旦バイナリの公開を中止します。
Vistaでの再生、録音動作を確認しました。Vistaは最終テストでしか触らない ものですから、録音側ディバイスが見つからなくて一度泣き、テスト機のSN比 があまりに悪いことにもう一度泣きました。Vistaは各アプリケーション毎の ボリュームを管理しようとしているようですね。
ttp://kuroda.bglb.jp/htabox/p3a01.zip P3-A01をリリースしました。スレッド的には異質な存在ですが、音楽好きな
方なら、お役に立てるソフトになったのではないかと思います。一応シェア
という形ですが、公開されているバイナリになんら機能制限はございません。
動作させてお気づきの点がございましたら、Helpに記載したアドレスまで
ご連絡いただければ迅速に対応させていただきます。
TZBのデバッグモード原型実験はなんとか成功したようです。wscript.exeでは なく、非表示mshta.exeをデバッグ時の仮想母艦とすることでdebugger;ステー トメントでの停止、IDE環境での変数参照を可能にできそうです。今だからこう いった事をコーディングできますが、すこし前の私なら無理だろうと諦めるほ ど内部でやっていることはテクニカルです。母艦mshta.exeは必ず別プロセス で動作することになる訳ですから。
TZBにしてもHTABOXにしても拡張の基礎は自プロセス内で全てをコントロー ルすることです。これ無しには従来どおりCOMの登録とActiveXObject呼び出 しでしかHTMLを拡張することはできません。従来型の拡張はDLLでしか許され ませんので、おのずと従属的なものになり制約が多いものとなります。 TZB、HTABOXはHTMLインスタンスを自プロセスに生成し、これを単なるWIN32 ウインドウとして扱います。これによりあらゆる拡張をAPIレベルのスピード で行うことができますが、スクリプトデバッガに対しては応答しません。 なぜHTABOXがJS、VBS起動になったのかを振り返れば、そうしないとデバッグ できないからという単純な理由です。
そういえばIE9はどうなっているんだろうと確認してみました。MSHTML.DLLを 眺めるかぎりではさほど大きな変化は無いようです。MSHTA.EXEも存在します。 ただ、そのサイズにびっくりしました。Vista32bit版のmshta.exeは僅か12kし かありません。これは歴代のIEのなかでも最小サイズだと思います。
TZBデバッグモードの動作機序が正しい選択だったことを確認できました。 別プロセスMSHTA.EXEがダイアログの生成要求を受けてから表示されるまで 一瞬のタイムラグがありますが、例え個人で使用するツールといえども、不 具合を潰す作業は永遠と続くと思われますので、現実にはこのデバッグモー ドがメインの動作環境になろうかと思います。ただし今回フックDLLは書きた くないのでHTML上の右クリックによるハイパーリンク動作だけはリリースモ ードでしか機能しないという仕様になりそうです。
デバッグ動作であるか否かを明確にする意味でもフックDLLがあった方がいい ように思いはじめました。つまりTZBrowser.exeの傍らにDebug.dllが存在す ればデバッグ動作であり、無ければリリース動作というルールにすれば間違 ってデバッグモードのアプリケーションを配布することの防止にもつながる でしょうし、書いてみることにします。フックDLLを起点としたCOM呼び返し というのは今まで書いたことが無いのですが理論的には問題ないと考えます。
実際にやってみるとフックDLL中からのディスパッチ呼び出しというのは実現 が難しいのかも知れません。相手側プロセスのインスタンスと通信させようと しても蹴られるように見えます。今回実現したいことは単にどこが右クリック されたかだけですので、おとなしく共有セグメントとイベントハンドルで対処 するしかないように思われます。
どうも納得がゆかなくてDLLのコードを何度も書き換えているのですが、MSDN どおりだとダメでその逆をやると成功します。過去の経験から言ってこういう 状態は「危うい」ですね。自分の環境でだけ動く可能性が高まる気がします。 もうひと粘りしてみますが、デバッグモードではファイルドロップと右クリッ ク無しというのも選択肢のひとつかも、と思い始めています。
デバッグとリリースで機能が違うというのも美しくないのですが、結構根の 深い原因があると思われますので、課題として認識したいと思います。まぁ ファイルドロップというのはアナーキーな手法ですし、ハイパーリンクの右 クリックも提供するアプリケーションのナビゲート手法として使うことは無 いでしょうから括弧書きがついた機能にしたいと思います。それより実行時 アイコンとタイトルの設定関数を装備してとっとと仕上げたいと思います。
最終的なデバッグ仕様を決定しました。TZB.EXEは実行時自身のディレクトリ にDEBUG.HTAの存在を検査します。存在した場合確認のメッセージボックスを 表示してデバッグモードで動作します。全てのタブ内HTMLは内部的に前述の 非表示HTAの子として通常に生成されますのでMSEやVisualStudioがデバッガ として登録してあればエラーの発生で自動的に起動します。DEBUG.HTAは空の ファイルを想定していますが、何か記述してデバッグ動作をカスタマイズして も面白いかも知れません。
致命的な説明不足を犯していることに気づきました。このデバッグモードは TZBのEXE内部へHTMLをリソース格納した場合のデバッグをサポートするもの ですから、必要とされるのはまだ先の話でした。通常に引数で与えたHTMLは 当然の事ながら普通にデバッグできます。格納してあるヘルプ内でわざとエ ラーを発生させた時に、デバッガが起動しないのでその対策を講じたのです が、いつの間にやら通常デバッグだと思い込んでいました。そろそろ私の頭 も限界なのかも知れません。
P3のノウハウをTZBにフィードバックして調整を行っています。自動録音停止 には、最低秒数引数が追加されます。TZBの場合はあくまでもプログラミング の材料ですので、自動停止後の作成ファイル名はご自身で管理していただきま す。あと音圧ウインドウを縦横に選択できる引数も追加する予定です。
http://kuroda.bglb.jp/htabox/tzb.zip を更新しました。ダウンロードURLが変更になりました。TZBrowserはTZB.exe
で配布される予定です。添付Sound.htmの最上部のボタンがタイトルとアイコン
の変更関数デモです。SetIconは第一引数location, 第二引数BMP、第三引数マス
ク(BGR)です。このBMPは各種色深度に対応していますが、最終的にWindow付属の
Paintで読んで保存すると確実にWindow純正のBMPとなるようです。
ttp://kuroda.bglb.jp/htabox/tzb.zip を更新しました。録音自動停止最低秒数設定が可能となりました。
TZBでタブコントロールとHTMLアプリケーションの可能性を勉強して1ヶ月ほど
になります。HTABOX3は3分割可変ウインドウという書いてる側もややこしいし、
きっと使う側もそうだろうという状態に陥っていたのですが、スマートな解決
策を見出せたと思います。私は極めて横着な人間ですから、ヘルプが別窓だと
いうだけで見る気がしないんです。かといって同じ窓でもエディタの邪魔にな
る訳ですから、この可変サイズウインドウでのタブコントロールは私にとって
今後全てのアプリケーションの雛形になる素敵なプレゼントでした。
TZBはちょっとドキュメントをまじめに書けば終了します。頭の中はHTABOX3 に切り替わってきました。現状のプロトでは各コモンコントロールがメイン ウインドウに固着してしまっているので、例えばTreeやListを複数表現した くてもできません。P3を書いていてそれを解決する抽象化イメージが浮かび ました。食うや食わずの状態ですが、こうしてどこに痛みを感じるわけでも なく前に進むモジュールを考えられることに感謝しています。
今日もいつの間にかあたりが明るくなっていました。HTMLウインドウ上の 各種コントロールをCOMコンポーネントとして任意な数配置できるシステム の抽象部分を書き上げました。そんなこと無理だろうと思っていたのですが このシステムではHTMLウインドウとコントロールがウインドウメッセージで 連携します。そのコントロールが何であるかに関らず、指定されたエレメン ト位置を推測してスクロールに追従します。勿論スクロールバーの表示を阻 害することもありません。HTABOX3ではこのシステムの威力をお見せできると 思います。
見た目は驚愕なんですが肝心のSeekバーで移動できてませんね。ちょっと修正 が必要なようです。
LevelやSeekの表示要求を二重に許していたりする細かな修正点がいくつかあ ります。P3を書く以前でTZBの開発は停止していましたので、今になって眺め るとこなれていない部分が散見されます。小規模な手術を行ってクラス相互 の依存関係を修正します。
ttp://kuroda.bglb.jp/htabox/tzb.zip を更新しました。現状で把握できている部分のバグフィクスが完了しました。
コントロールの追加関数は固有のオプションが無い場合2つの引数を取ります。
MusicBuffer.ShowSeek(DocHwnd, 'SEEK2');
TZB上のHTMLスクリプトにはFraHwndとDocHwnd変数が自動的に追加されます。
これはダイアログのフレームHWNDとドキュメントHWNDです。スクリプトに
HWND型はありませんので実際にはVT_I4(4バイト整数)です。何らかのコン
トロールをドキュメントウインドウへ配置する場合必ずこれを第1引数として
渡すことになります。第2引数はウインドウ上の位置を決定するHTMLエレメン
トID文字列です。現在はこのエレメントが不動であると想定していますので、
DHTML手法でこの基準エレメントを動かしてもコントロールは初期位置に表示
されます。
半年くらい.NETやWIN32の基礎的な部分を掘り下げる作業になってしまいまし たが、ある程度の大きさのプログラムは一旦設計したらその基礎は動かしがた いものになります。やっと書きあがったと思ったら、隣にもっと素敵な書き方 があったという時ほど心が折れる瞬間はありません。とても散発的なデモを ご覧いただくことしかできていなかったことを深くお詫びしますが、研究は 完了しました。先を追えばきりが無いのですが、私が知りたかったことは全部 知ることができました。
リアルな世界での私の知人がこれを見ているわけも無いのですが、何年か後 の検索エンジンにこの文字列がヒットすることもあるかも知れません。 すべてをなげうって研究に没頭するなど、いい大人のすることではないと自身 でも分かってはいるのですが、この世に私という個性が生まれたことへ最大現 の感謝を表明するには、私という個性が許す限りの理想を実現することしかな いと考えています。「考えている」よりもそう思わなければ次に呼吸する気力 さえ沸かないと表現すべきでしょうか。少々疲れました。
205 :
デフォルトの名無しさん :2011/05/15(日) 00:42:09.04
お疲れさまです。
ttp://kuroda.bglb.jp/htabox/tzb.zip を更新しました。Sound.htm冒頭のボタンはリッチエディットコントロールを
HTML中に埋め込むデモです。つまりこのコントロールは別ウインドウでも表示
できるし、埋め込みもできるというコードで構成され、しかもCOMとしてスク
リプトと通信するわけです。言葉にすると複雑ですが、パターンとして確立
していますのでコードの方はいったってシンプルです。
結局何かをうやむやにできない性分なので、別プロセスHTAの子ダイアログ群 のメッセージフックDLL、それに規格を合わせた本体側の変更を行っています 今のところ、コントロールがスクロールバーの前に出ることだけは解決でき ません。別プロセスの子ダイアログで更にその上のドキュメントウインドウ でスクロールバー自体はオーナー描画という悪条件ですし、あくまでデバッ グ目的の環境ですからこれについてはさすがに目をつむろうかと思います。
同時にソースコード隠蔽実験も行いました。今のところ暗号器と復号器を 渡して解析をかけられることに対する耐性は無い程度の暗号化ですが、個 人として使う分には誰かがEXEを覗き込んでも暗号文しかないわけですから 実用に耐えるだろうという程度の仕上がりにはなりました。こうやって突き 詰めて行くと、いっそのことTZBをHTABOX3に改名しようという発想も生まれ てきます。
少なくとも今回のフックDLLの成功でHTABOXのデバッグもwscript.exeを使用 せず、別プロセスで起動したHTAの挙動を支配することで行うことができると 考えます。つまりCOMDLL登録しなくてもいいわけです。特に私自身は開発途 中の複数バージョンHTABOXを抱えてしまいますので、果たしてどのバージョ ンがCOM登録されているのか混乱する局面があって、それ無しにデバックでき れば大いなる進歩になるんじゃないかと思います。
DLLの記述を終了しました。頭がDLLに切り替われば「あぁそうだった」と思い 出すのですが、AプロセスがHookをセットした結果のハンドルは共有セグメント に置いて固着させないとBプロセスでは未定義なんでしたね。当初に挙動が不審 だったのは、単純ミスだったようです。結果として0xff個までの別プロセスウ インドウを個別に管理してTZBのタブへ埋め込むフックDLLが完成しました。
HTMLダイアログのスクリプトグローバルスコープにalert()と書けばダイアロ グ本体が表示される前にalertが表示される訳ですが、多くの場合その後ダイ アログ本体は表示されません。これがIEのバグなのか仕様なのか知れませんが、 てっきり私のプログラムが原因なんじゃないかと無駄な時間を費やしてしまい ました。親でwindow.showModelessDialog("test.htm");としてtest.htmのスク リプトを<script>alert("test");</script>にするとこれを検証できます。
いろいろ書き進んでゆくうちにより上位にある抽象的なイメージに到達しまし た。例えばリッチエディットを例にとればWscript環境からはスタンドアロン のエディタウインドウとして生成でき、HTML中からなら基準エレメントを指定 してその位置に追従する、ディスパッチでラップされたコントロールを作れば 使う側がTZBであれHTABOXであれ、貴方のスクリプトであれ流用できる訳です。
非常に当たり前な結論ですし、昔からそういう考えが無かったわけではあり ませんが、その為に解決しなければならない課題というのは山のようにあっ て、私などが到底達成できる目標ではないと考えていましたが、いつのまに かその為の機序をすべて見通せる位置に立っていました。分かってしまえば 目の前にコードはあまりに短く、何年か前にこのくらい書けなかったのかと いう悔恨の念にさいなまれますが、生きてここに到達できたことを素直に喜 びたいと思います。
TZB環境におけるリストビューコントロールの実験を完了しました。TZBのスレ ッド構造はHTABOXの反省の上に設計されましたのでリストビュー上のイベント (WM_NOTIFY)をHTML側スクリプトへ反映されることに何ら問題は生じません でした。本当にWindows上のアプリケーションの書き方自体が変わることにな るかも知れません。
TZBへリストビューとツリービューの実装を行いました。TZBの場合HTMLは最 終的にWS_POPUPの権利を失うことでタブコントロールに治まりますからシス テムメニュー、ツールバー、ステータスバーが実装されることはありません。 また、ウインドウのサイズが可変な状態を想定するコンセプトから左ページ ャーメニューも実装する予定はありません。この辺が自身のウインドウを完 全にコントロールしようとするHTABOX系とTZBの明確な相違点になります。
フックDLLが完成したことでHTABOXは複数のHTAを表示することが可能となりま す。また、既に実行中のHTMLウインドウを持つアプリケーションの制御を完全 に奪ってカスタマイズすることが可能となります。例えば丸いウインドウを持 つInternet Explorerを作り出すことができるわけです。ただそこまで行くと 元となるのIEを作った側の権利を侵害することにならないのかという別の問題 が発生するでしょうけど。
今日はListViewとTreeViewのコールバック仕様について結論を出しました。 従来の選択エレメントへのclick呼び出しと同時に親となるエレメントへ selected属性を動的に追加し、選択されたエレメントインスタンスを当該 属性の値へセットすることとしました。結果的に個々のエレメントにonclick を書かず、親へ転送されたonclickでthis.selected.innerText等を参照して、 選択されたエレメントを識別できるものです。今日はこの事にすごく悩みま したが、納得できる結論に達したと考えています。
親にWM_SIZEが発行された場合のみ各コントロールが自身の基準エレメント位 置を再確認するロジックを組み込み、フックDLLで問題となっていたコントロ ールとスクロールバーのZオーダー問題を解決しました。内部的にはHTML埋め 込みコントロールクラスを作成し、このクラスを継承するコントロールは自動 的に埋め込み全般のロジックが付加されるようにしました。これだけ抽象化し てもオーバーヘッドがほとんど生じないというC++の威力をまざまざと見せ付 けられた感があります。
そろそろ低層のことを考えるのはやめにしたいと考え始めました。少々無理 筋なことでも執拗にチャレンジすればなんとか打開策は見出せるものですが、 やや現実の社会とはかけ離れたことを考え続けた結果、実社会への適応とい う能力が極端に低下してしまいました。もっと平たい言い方をすれば私は変 人から狂人へ変化してしまったのではないかと感じています。
せめてこの小さな箱の中で起こっていることの「虚構」と「真実」を見極め たいと勉強を続けてきました。コンピューターを動かすというとこをもっと 平易に、もっと高速に、もっと柔軟にできるのではないか。商業主義を背景 とし、単にハイスペックなハードを要求するだけのWindows系の流れに一石を 投じることはできないのか。
自分が知りたい事にある程度結論めいた回答が得られた時に、食うや食わず の現状と、そこ至った経緯を省みようとするのですが、あまりに長い間プロ グラムを動かすというただ一点に集中しすぎた結果、もはやストリーが繋が らなくなっています。ただ自分に都合のいい事柄を拾い集めて自己の擁護の ために順序良く並べているにすぎない気がします。
222 :
デフォルトの名無しさん :2011/05/20(金) 20:11:12.88
とりあえず、夜10時には寝ること。朝6時には起きること。1日1時間、散歩すること。 庭の草取りをすること。 毎日少しずつでも太陽を浴びて汗を流さないと人間の体は壊れます。 そんなあたりまえのことを1週間も続けていると、体は元に戻っていこうとしますから。 大丈夫です。
>>222 ありがとう。明日、近所の田植えを手伝ってきます。私にはそういうことが
必要なんだと思います。
田植えの全日程を終了しました。全くスレ違いな話題ですが一言言わせて下さ い。日本と言うシステムは既に終わっています。水田には当年とって50才にな る私より若い方は見かけません。wikipediaで地方自治体の人口構成を見てくだ さい。この場合、政令指定都市以外ならどこでも同じです。大学入学年齢で人口 が激減し、卒業後に戻る人口はごく僅かです。水田を這いつくばって、水稲栽培 に励むなど、今の若者には死んでもやりたくない事の一つなのでしょう。結果日 本という国は終わりを迎えました。勿論、世界で必要とされる人材は日本という 枠を超えて評価されますから、プログランミングは国際的な評価を得る近道です。 私がなぜメニュー等の文字列に日本語使わないのか?逆に私はこう質問したい 「なぜ70億の中の1億しか読めない文字列を使用する必要があるのか?」少なく とも私はその事にかかる労力に見合う成果は期待できないと判断しています。 正直、一日でも早く日本が国際的に正しく評価され、結果として財政破綻し国防 に従事する人間以外の公務員、特別公務員(議員等)は無給のボランティアと なることを切に祈っています。このまま事なかれ主義を続ければ国として再起す る可能性さえ失われるのではないと危惧しています。
Rich Edit にもう一工夫加えたいと考えています。現状のRich Edit系コード は実に誰でも書きそうな物でしかなく満足できません。Rich EditにOLE埋め込 みで編集を促すような状態を作ることはMSDNのとおりなのですが、HTMLのパー ス結果をエディタ上に矛盾の無い形で出現させる事ができるのではないと考え ています。結果としてHTMLが表示可能なオブジェクトはすべてRich Editに表示 可能となります。具体的には特定の段落が矩形を形成しその中にHTMLウインド ウが存在するものです。画像等を表示するための静的描画と、そこにあるボタ ン等がインタラクティブな動的描画の双方を提供したいと考えています。
Rich Editへパース済みHTMLを埋め込む手法の基礎実験は終了しました。勿論 もっとも単純なのはDCへの強制書き込みですが、それでは現在当該位置が表示 されているのかを常に監視しなければならないコストがかかります。今回はあ くまで規格どおりのOLE埋め込みを偽装し、いざ描画する段になると通常のHTM Lアイコン状態では無しにパースされた画像やテーブルを表示しようという意図 ですので、結構トリッキーなロジックとなります。まだ克服しなければならな い課題は残っていますが、この技術だけでも一つの商品になるのではないかと 考えています。
Rich EditへのHTML埋め込み手法を完成させました。結果的に静的な表示は 無しにして、インタラクティブな表示に一本化しました。考えてみるとIEの HTMLエンジンはターゲットURLに画像ファイルを指定した場合自動的に<img> タグを持つシンプルなHTMLを生成しますので、画像等の表示用に特別な手段 を用意する必要が無い事に気づきました。結果的にHTMLエンジンが表示可能 なものは全てRich Editへ挿入することができます。したがって動画を挿入 しても何ら問題は生じません。
通常OLEというと正に埋め込みで、当該箇所をダブルクリックすると登録済み アプリケーションが別窓で起動する訳ですが、単純にエディタ上に任意な大き さの矩形を予約する目的でOLEを捉え、後はそこを好きに使わせてもらうとい う発想は、テキストを主体でなければならないドキュメント(例えばソース コード)へ画像や動画といった形でのコメント挿入を可能にします。
ttp://kuroda.bglb.jp/htabox/tzb.zip を更新しました。添付ole.htmをTZBで開くとRich EditコントロールがHTML
上に表示されます。コントロール下部にあるボタンにより通常OLE埋め込み、
HTMLパース状態埋め込みの動作を確認できます。尚、HTMLのサイズは自動的
に判定しますが、HTMLダイアログ評価しますので、評価時におけるbodyの
marginは0pxなことに注意してください。任意なマージンが必要な場合は明
示的に宣言する必要があります。
TZBの取り説は実行可能でなければなりません。HTABOXも同じ手法を採用した いと考えています。そこで憂鬱な問題が発生してしまいます。WORDでは実行 可能スクリプトを内封したドキュメントが書けないのです。そこでFrontPage とスクリプトで自動目次生成、使用BMPの自動リソース格納を実現するシステ ムを書いています。一人の人間が組織と伍して製品を生産するということは 物理的な製品では不可能なことです。しかし、ことコンピューター上の事柄 はそのアルゴリズムさえ明確ならすべて自動化できます。たった一人の人間 が世界を相手に戦える唯一フェアなビジネスフィールドがソフトウェアであ ると信じていますし、誰かがそれを証明しなければ、未来永劫プログラミン グとは「下請けの過酷な労働」という地位から向上しないだろうと思ってい ます。
今日はフレーム構成のHTMLページへのコントロール埋め込みについて検証し ていました。TZBのヘルプ自体がフレームページなので、その場で埋め込み を実行して見せたかったのですが、位置演算に費やすコストが高くて美しい 仕上がりになりませんでした。子フレームの場合、フレームの位置、フレー ム内BODYのスクロール位置を常に問い合わせることは避けようの無い事です。 もしこれを採用した場合、非フレームの場合にも当該処理が足を引っ張るこ とになりますので、フレーム構成ページへのコントロール埋め込みは実装し ない判断をしました。今後もっと素敵な解決策が見つかるまでの課題とさせ ていただきます。
TZB用ドキュメントを書いています。私は動けば先を書き進めてしまうので 使う側の目線で全てを見直すことは重要な作業です。当然、手直しが必要な 部分も出てきます。ただ、この段階で何かを切り捨てることはあれ、付け加 えることは極力避けるようにしています。ただでさえ仕事が遅いのに、根幹 を書き換えるようでは無限ループに陥るからです。
明日TZBを正式にリリースする踏ん切りがつきました。 要は「全力でソフトウェアの勉強をして食えるようになるのか?」 というごく単純な実験を皆さんはご覧になっていることになります。 で、食えない場合はどうなるのか?まだ全てを諦める気にはなりませんので 食べる為にあらゆる手段を考慮しなければなりません。勿論、この分野の研 究に割ける時間は激減するでしょうが、私が息をしている限り同じ主張を継 続してゆきたいとは思っています。 私がここに居て、これをご覧になっている方が幾人かいて、私の書くつたな いアプリケーションに興味を持っていただけていることに感謝します。TZBは そんな方々の期待を裏切らない仕上がりになることをお約束します。
最終的にドキュメントを仕上げる段階でFrontPageにはアウトラインプロセッ サが無く、Wordではスクリプトを書けないというジレンマを克服するために 自前でアウトラインプロセッサを書いています。<h1>〜<h6>がツリー表示さ れて、ドラッグすることでドキュメント全体の構造を変更できるものです。 部分的に文章を書く私にとって無くてはならないものが全体の構造を俯瞰で きるアウトラインプロセッサです。
Windows8はHTML5とJavaScriptでのアプリケーション開発を前面に押し出す 戦略のようです。正にわが意を得たりなわけですが、既に複数HTMLインス タンスの集積化、複数プロセスHTMLインスタンスの集積化、HTMLウインドウ へのネイティブウインドウ埋め込みと連動、独自スクリプトパースによる コードの隠蔽等「HTML+JScript」が注目されればHTABOXやTZBが持つアドバ ンテージにより多くの方が気づいてくれるのではないかと期待しています。
1週間ほど柿の芽を選るバイトに汗を流していました。何かを考える暇も なく手を動かし続けると心が純化されてゆく気がします。プログラミング のことはどうでもいいと思えるほど良く眠れます。もし私が「天才」と呼 ばれる部類の人間ならこんな状況でも後世に残る提言ができるのかも知れ ませんが、私は書いて躓く事でしか前に進めない「凡人」以下な人間です から、ある程度「精神的不健康」というリスクを負わなければならないと いうことも感じています。
アウトラインプロセッサを書きながら「表現するとは何か?」というような 問題を考えてしまいます。私の考えを自由に閲覧可能にできれば各人のスト ーリーに沿い最短距離で理解する事ができるでしょうが、いかんせん一旦静 的な文字列にしなければならず、結果的に特定の仮想読者に向けたドキュメ ントにならざるを得ません。仮想読者の範囲を広げればドキュメントは冗長 なものになりますし、範囲を狭めれば多くの方にとってちんぷんかんぷんな ものになります。もし、全ての要素がカオスな状態で存在し、読者の閲覧パ ターンで構造化されるようなアルゴリズムが確立できればノーベル賞もので しょう。
238 :
忍法帖【Lv=16,xxxPT】 :2011/06/23(木) 13:29:33.85
作者さん、その後の状況はどんなもんなんでしょう?
ご心配いただいて申し訳ありません。TZBとHTABOX3用ヘルプHTML作成ツール を書きながらヘルプ表示方式にも若干の改良を加えておりました。まだこな れていない部分もあるのですが、このHTML用アウトラインプロセッサは汎用 な動作が可能ですので、公開して使っていただける状態にします。
ttp://kuroda.bglb.jp/htabox/outline.zip を公開します。このzipファイ
ルはoutline.exeとtest.htmで構成されています。outline.exeへtest.htmを
ドロップし、HtmlViewタブでtest.htmの冒頭を眺めると操作の説明を見るこ
とができます。要は<Hn>タグを構造化された見出しと認識し、構造を表示し
たツリービューの内のドラッグと、右クリックポップアップメニューで見出
し構造を変更するものです。ただし、まだ動作実績が不足しているので使用
する場合は、原版HTMLを確実に保存し、そのコピーを対象に使用してくださ
い。
このアウトラインプロセッサはFrontPageやMsWordで作成されたHTMLの構造を 変更することを想定して設計していますが、エディタで直接HTMLを編集する ことも可能です。アウトラインを正しく認識するために静的文字列、HTMLコ メント、JavaScript中コメントを認識する必要がありますので、エディタ上 では若干の色をつけています。それ以外のエディタ機能はほとんど素の状態 なのですが、複数行を選択してのTAB、shift + TABには対応しています。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。アウトラインツリーはデフォルトで全展開状態としました。
エディタは<p>及び<p></p>間の<br>を認識し、innerTextを一行80バイトに
自動整形する機能を追加しました。FrontPage、MsWord、ScriptEditor
、VisualStudioでHTMLを作成する場合、それぞれ余計な整形やタグ生成を
したがるためにHTMLレベルで文章を練ることが出来ません。それらに無い
アウトラインプロセッサ機能と、長いinnerTextの自動整形機能を持った
HTMLエディタを書いてしまおうというのが今回の目的でした。
またC:直下にtest.xml吐いてますよ
自動整形は文字列編集状態での文字入力で頻繁に呼び出され、<p>タグ内にあ るか?<br>は存在するか?全体文字列から改行の削除、80バイト整形後の改 行追加、カーソルの復元という作業を行います。WIN32で記述すれば全くスト レスを感じない速度を実現できますが、間接的な手法では実現しにくい分野 だと思われます。これできちっとした論理構造であらゆるドキュメントを書 く準備が整いました。
アウトラインプロセッサのエディタ部にVMLコード生成機能を付加してはどう かと考え、改めてVMLの仕様に目を通しました。それ自体はさして難しいこと では無いのですが、仕様として正しいVMLを出力してもFrontPageやMsWordで 再編集した場合に表示されないという壁があるため断念しました。FrontPage 等は極めて独自な手法でVMLを管理していますし、スクラッチで書いたVMLコ ードも強制的に自身の規則で書き換えます。書き換え後に表示できればまだ いいのですが、書き換えた挙句表示できないという罠が待っていましたので あっさり引き下がりました。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ASCII文字連続時の改行抑制に伴いバッファ長を限定するこ
とが危険なことから逐次_bstr_tへの一文字追加へアルゴリズムを変更しまし
た。また、ITextRangeにバグを発見しましたので対策コードを付加しました。
当該zipには従来のtest.htmに加えtest2.htmが添付されています。これはTZB
等のヘルプファイルを想定した画像とVMLの右側配置に関する資料です。内容
は極めて初歩的なものですが、参考にしていただける部分があるかも知れませ
ん。
HTABOXと言う発想は従来のアプリケーションをHTML + JScript or VBScript で実現しようという発想な訳ですから、開発の簡便さを知らなければ外見は 見慣れたアプリケーションになります。そういう意味では別に新しいもので は無い事になります。最も象徴的な現象は「アプリケーション」と「取り説」 を必ず別ファイルで用意しなければならないだろうという事です。
それに対してTZBという発想は、HTMドキュメントウインドウ部のみへの拡張 に限定することでウインドウの水平、垂直スクロールを可能なまま維持しま すから、縦横に大きいウインドウでもユーザーは通常のWEBページを見る感覚 で閲覧、実行することができます。最も象徴的な現象は「実行できる取り説」 を作成できる事です。つまり「アプリケーション」と「取り説」が一体となっ た新たなアプリケーションの姿を提示することになります。
アウトラインプロセッサは現在ヘルプファイル作成という目的の為に存在し ますが、将来はTZBアプリケーション開発用エディタという位置づけにできれ ばと考えています。まもなくリリーするTZBのヘルプページがそうなりますが、 ページ内のh1〜h6を構造化したツリーはTZB上の全てのページで利用可能とな ります。どんなに長大なページでもユーザーはツリーのクリックで目的箇所 へ移動できますから、他の部分にどんなに長い説明文があろうが気にしない でしょう。そこにあるボタンをクリックすることで、当該ページ若しくはTAB に追加されたページに表示される実行結果を見るという展開になります。
つまりHTMLアプリケーションを「従来型アプリケーションの模倣」というレ ベルから「HTMLアプリケーションでなければ実現しにくい」というレベルへ 進化させるのがTZBの目的だと考えています。現状のTZBはある程度の拡張の 結果「企業秘密」と認識されるコードを含む状態となってしまいましたが、 前にお話したように、そういった部分を排除、若しくはLIB化してソースを 公開し、複数の叡智でこの発想を推し進めることも想定しています。
253 :
忍法帖【Lv=18,xxxPT】 :2011/06/27(月) 12:24:00.30
USA!TZB!TZB!TZB!
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。本文にクォートされた文字列がある場合に改行を抑制する
ことにしました。これでいかなる状況でも<p></p>間の\r\nがHTMLの表示へ
影響を及ぼすことは無いと考えます。現時点でこの本文整形はデフォルトに
機能しますが、リリース時には実行時に選択できるオプションという位置づ
けになろうかと思います。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。このままではスパイスが足らない気がしてツリー画像の色順
と、HTML側見出しの背景色グラデーションを加えてみました。話の流れからす
るとグラデーションはIE固有の機能を利用していると思われるかも知れません
が、Foxでも動作するものとしています。任意な数のDIVを動的に外周へ生成す
ることでグラデーションを実現します。詳細は添付HTMLファイルをご覧くださ
い。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ツリー上でのドラッグ、右クリックで表示されるダイアログ
とメニューを詳細にして、考えうる全ての見出し編集動作に対応しました。
ソースの色分けは原則として編集中の行内で判断しています。これはブロック
型のコメントの開始などで文章終端までのサーチが行われては動作が散漫とな
るからです。編集中に文章全体を再評価して厳格な色分けを行うキー操作は
とりあえず「CTRL + TAB」としています。現バージョンではこの再パースに
よって文章中の全<p></p>間文字列は自動的に整形されます。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。タブでの切り替えウインドウに「ヘルプ」が追加されまし
た。このヘルプで使用しているツリーがTZBで利用可能となるメニュー用の
ツリービューです。このアウトラインプロセッサではアウトライン用ツリー
が常に表示されますから、やや狭苦しい感がありますがご容赦ください。
TZBの場合、このヘルプウインドウもTZBオブジェクトを利用できますから、
解説と実行を両立したヘルプページが作れるわけです。
RichEditについてもだいぶ実践コードを書きましたので概要を理解すること はできたと思います。私の本業はエディタではなくInternet Explorerコア 解析なのですが、OLEと見せかけてHTMLインスタンスをエディタへ貼り付け る事には成功していますので、通常のエディタ屋さんでは不可能な事を簡単 に実現できます。例えば文章を操作するHTAをマクロとして作成し、そのHTA 自体が当該文章上に見えるという状態です。また、HTMLを介して.NETコード により文章を操作することについても何ら障壁はありません。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。実験的な意味合いは薄れましたので、Pタグ整形はメニュー
又はツールバーから選択可能な機能とし、一行長と改行規則をダイアログか
ら設定可能としました。自動整形<->長い一行の動作を非常に軽量に行えます
ので、本文編集時はHTML評価を気にせず単純な整形を用い、HTML評価時に長
い一行とするというのが賢い使い方になるでしょうか。ちなみにHtmlViewは
ファイルの上書き保存を促しますので、そういう使い方なら常に長い一行で
保存されていることになります。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。見出しのドラッグと挿入でNextSiblingを指定すると対象
の子を肩代わりして所有してしまうバグを修正しました。例によって書きか
けですが、Helpタブも有効です。今日はTZBのデバッグモードでツリーメニ
ューを動作させるコードで一苦労しました。動いてみると別プロセスと協調
するデバッグモードの方がGUI的にはやや軽量だったりします。メッセージ
キューが分散されることにより、結果として軽量に動作するというところで
しょうか。
エディタ部のショートカットキーなんかを考え始めるときりが無いので、ア プリケーション側はCOMインスタンスとしてエディタとドキュメントを提供し ユーザーがスクリプトで自由に定義できる方向で考えています。ちなみに現状 でこっそり存在するキーはSHIFT+ENTERで<br>、CTRL+ENTERで<p></p>、 CTRL+TABで全体の再評価となっています。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。マクロ編集、実行機能を追加しました。これに伴いメニュー
やツールバーが変更されましたが、ソース用とマクロ用の2組が存在すると
考えていただければ理解が早いと思います。ただし、アウトライン編集機能は
ソースのみで、実行機能はマクロのみというルールになっています。添付
macro.htmをマクロはソース側文章を自動で制御するサンプルです。マクロと
して読み込んで実行してください。
現状の仕様ではマクロ側HTMLのdialogArgumentsにソース側のITextDocument2 実体が渡されています。ですからTZBのように新たなタブを生成するような機 能は提供されていません。この場合はあくまでも文章の編集が目的ですので、 いたずらに多機能を追求すべきではないと考えています。 MSDNのITextDocument2に関する解説では正規表現が利用可能となっています が、私の環境では利用できたためしがありません。しかし、文字列をJScript で認識できるこのマクロ手法を使えば、使い慣れた正規表現関数で自在に文章 をコントロールできることになります。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。マクロHTMLのdialogArgumentsをタブインスタンスへ変更し
ました。このインスタンスはLengthプロパティーとGet、Setメソッドを提供
します。マクロから先頭エディタのドキュメントインスタンスを取得する場合
var TAB = dialogArguments;
var TextDocument = TAB.Get(0);
となります。詳しくは添付macro.htmのソースをご覧ください。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。細部の煮詰めを行いました。例えば見出しのRenameでは従
前の文字列がダイアログのテキストボックスに入力された状態としました。
ふと、プログラムとはかくも残酷なものかと感じました。随分前に会社で後
輩社員が仕事でマクロを使ったら先輩社員が反則だと怒ったことが論議を巻
き起こしているという記事がありました。曲りなりにもプログラムを書く立
場から見れば「反則」というのはばかげた発想で「じゃぁ紙と鉛筆以外は全
部反則?」と逆に問いかけたくなります。
でも先輩社員の真意はもっと深い意味を持っています。一つは書ける人間に 対する畏敬と危惧が入り混じった感情です。場合によっては後輩社員が通常 は一人が一年かかる事務処理をたった一日で終了させたかも知れません。 第二に、もしその効果が前述のように劇的なものであった場合、書けない人 間の雇用機会が確実に失われる事です。アルゴリズムの定まっている情報処 理はすべてプログラミングできますが、そのことがこういった負の効果を生 み出す事もありえます。
このアウトラインエディタを書く進めるうちにTZBとHTABOXは融合できるとい う直感を得ました。事実アウトラインエディタのマクロ実行ウインドウが現 状のダイアログベースだけではなくHTAベースでも可能とすれば、エディタ機 能の付いたHTABOXとなります。HTMLアプリケーションを従来型ではなくコンテ ンツ型を主体としたものと捉えれば、その全体構造を俯瞰しながら編集できる アウトライナー的機能は是非装備すべきだと痛感しています。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。自動整形ルールを見直しました。
<p></p>間にホワイトスペースが連続する場合一個の\x20に置き換えられると
いうのが各ブラウザの仕様のようです。ASCII直後の\r\nはこのホワイトスペ
ースとして扱われ、全角文字直後の\r\nはホワイトスペースとみなさないと
いう前提のアルゴリズムに変更しました。ただし、オプションで単純バイト
換算での改行を許していますので、手順によっては余計な\x20が追加されか
ねないことに注意が必要です。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。従来はプロセスが分散することはデメリットしか生じない
と考えていたのですが、多数のコントロールがメッセージで駆動している場
合、分散させることでやや軽量になる傾向を感じることから、マクロの別プ
ロセスHTA実行を積極的に活用しようと思います。正直IE9にはmshta.exeが付
属しないのではないか?と考えていたのですが、ちゃんと付属していた事も
要因の一つです。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ソース及びマクロのエディタ上でポップアップメニューを
表示することにしました。内容は、"Cut","Copy","Paste","Clear","Undo",
"Select All","Find Text", "Replace Text"です。これでオーソドックスな
編集動作には十分対応できるものと考えます。もし正規表現検索置き換えが
必要だとしたら、マクロでHTAを書いてください。書きなれたHTML+スクリプ
トでエディタマクロが書けるメリットを最大限に活用してください。
今日はリッチエディット上のIMGタグを実際の画像として表示する部分につい て、最適な手法を検証していました。結局GDI+でファイルを認識し、互換DC にビットマップを保持し、描画が要求されたら提供するという手法を採用し ました。エディタ上の右クリックメニューでIMGタグ直後に画像イメージを 表示するか否かを切り替える仕様を想定しています。
JScriptソース隠蔽についてできるだけ過酷な条件でテストを繰り返していま す。現状での推測は、完全にアルゴリズムを隠蔽したければ、たとえソースが スクリプトな状態でも、外部DLLに置けるような記述でなければならないだろう ということです。具体的には暗黙のwindowとかdocumentという記述を行わず、 関数内で参照が必要な場合は明示的に引数としてもらう必要があるんじゃない かと言うことです。で、そこまで気を使うんだったら速度的に有利なC++の直接 コーディングによるCOMオブジェクトでもいいんじゃないかと感じます。
いろいろ試しているうちに、当然ながら普通にHTMLのスクリプトスコープで コードをパースすれば、あらゆる状況下で期待通りの動作をすること痛感し ました。これを受けてカジュアルな隠蔽という発想があってもいいんじゃな いかと考えています。手法としてはファイルの一時生成が最も単純ですが、 あまりに芸が無い手法なので既存バイナリのリソースデータを動的に変化さ せるという手法になりそうです。
話は前後してしまうのですが、「完全な隠蔽」はJScriptコードをネイティ ブコンパイルする手法で実現したいと考えています。これは出来上がった ファイルがバイナリに見えるだけではなく本当にC++コンパイラが吐き出す ネイティブコードでなければなりません。手法はいたって単純でJScript文 法に出現するオブジェクトをC++クラスでエミュレートし、目的JScriptソー スをVisual StudioのWIN32DLLプロジェクトに取り込むと自動的にCOMDLLが 生成されるというものです。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。実際にフリーハンドでダイアグラムを作成できるHTMLが添付
されています。現状ではこのHTMLの結果を保存する機能は抑制されています。
このデモは「カジュアル隠蔽」を実践している例でもあります。マウス移動
等のシステム系イベントハンドラ駆動というのはスレッド管理という観点から、
最も過酷な状況となります。ここでは安定を重視して単にパースしながらソー
スを隠すことを試みています。
添付ダイアグラム.htmは全スクリプトがBASE64風の文字列として記録されて います。このエンコードはエディタ上で領域を選択し、特定のキーを組み合 わせて押すと、選択領域全体がエンコードされるルールとなります。同じく デコードも可能としますが、その場合著作者以外のデコードを許さない工夫 が必要になるはずです。最も単純で破られにくい方法として、ソースコード 中の特定規則コメント全体がデコード時に示されたキー文字列と完全に一致 しなければならないというものを想定しています。この場合キー長は無限に 長いものとすることが可能です。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ダイアグラムをXML形式で保存呼び出しできます。文章編集
とは今のところ関連していませんが、カオスな状態での各項目を列挙し、それ
ぞれの関連を確認しながら、最終的にツリー構造を作成するツールとして利用
できるだけの機能は有していると考えます。尚、添付ダイアグラム.htmはマク
ロではありませんので単にoutline.exeへドロップしHtmlViewで動作させてく
ださい。
zipにsample.xmlを追加しました。VMLという機能は従来全く陽の当たらない 部分だったのですが、WEBページでは無しにアプリケーションウインドウのグ ラフィックツールと位置づけると、WIN32APIで書いたら目も当てられないよ うな仕事を鼻歌交じりにこなすことができます。しかも基本的にベクトル処理 ですから大きさに関り無く軽量です。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ダイアグラム表示の場合は要素タイトル編集の延長として
本文も編集できる流れが自然かもしれないということで実装しました。これ
以前の保存XMLとは仕様が異なりましたので、従前のXMLと互換性はありませ
ん。混沌とした考えを混沌のまま記録し、客観的な観点から再編を繰り替え
すとこが出来ます。「アイディア エディタ」みたいな名前がふさわしいと
思います。
このダイアグラムはツリービューでは表現できないものを柔軟に表現できる 可能性を秘めています。ツリー(樹状構造)は親子の結合という言わば強い 結びつき以外の関係を許しませんが、ここではもっと弱い結びつきを同時に 表現できます。例えば強いラインが文章構造やページのリンク構造とするな ら、弱い結びつきは、引用や参照と例えることができます。この文章がどこ でアンカー参照されているかという情報を同時に表現できるわけです。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。ダイアグラムエディタはStruct Designタブに組み込まれま
した。エディタからHtml Viewに切り替えた場合ソースにエラーがあった場合
HTMLの生成を停止しエディタのハングを抑止しました。文字位置、行位置を
ステータスバーに表示しました。UNICODE単位、BYTE単位で表示しますが、
これは単にVisual Studioの表示形式をそのまま採用しています。
私はHTML+JScriptがアプリケーションの主役になるためには、より高速に動 作させるためのバイナリ拡張とソース隠蔽オプションが不可欠だと考えてい ます。隠蔽のロジックについてはある程度の見極めができているんですが、 いざ自分で書いてエンコード->デバッグ->どこがエラーか当然不明->デコード ->実行->エラー起きないというめんどくささに嫌気がさしたもんですから、 単一エディタ上でコーディング、エンコード、デコード、デバッグが行える 環境を書いてしまおうというのもこのアウトラインエディタの目的です。 これはTZBよりもHTABOXで必要になる機能だろうと考えます。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。Struct Designタブ内の機能を完成させました。まだZオーダ
ーの部分に未解決な問題が存在しますが、全く自由に論理の構造を変更する
ことが可能で、各ノードの位置情報を維持したXMLと単純<Hn>にみなしたHTML
へ出力できます。また、カスケード、縦ツリー、横ツリーへ整列する機能も
追加しました。
自分としてはこのStruct Designタブ内におけるVMLによるGUI形成がとても 気に入っています。さずがに500MHzという年代物で動作させるとややもたつ く感が否めませんが、操作のレスポンスは.NET上でのコントロールを上回る のではないかと感じています。全く画像ファイルを用意することなくグラフ ィカルなボタン等を生成できることは、開発時のポータビリティーを向上さ せる意味において大変有益なことです。
アウトラインエディタは「エディタ付きTZB」な訳ですが、マクロは別ウイン ドウでHTA動作します。このマクロHTAウインドウは複数生成されることにも 対応するために別プロセスで実行されます。つまり裸な状態ですから、エラ ーが発生すれば、通常のデバッガが起動されるはずです。つまり従来デバッグ を目的にHTABOX.EXEをCOMEXEとして設計したり、起点をWScriptにしたりして いましたが、その必要が無くなることを意味しています。勿論リリースモード でEXE格納されたHTAソースはインプロセスで実行させますので攻撃者がデバッ ガで停止を試みても応じないというルールにできると考えます。
つまり「アウトラインエディタ」の余計な機能を削除しマクロ環境へHTABOX が有する拡張機能をディスパッチインスタンスとして提供すればそのまま 「HTABOX3エディタ」とすることができます。HTABOX3エディタの最大の目玉 は任意なスクリプトブロックをエディタ上で範囲指定し、その場でエンコー ドできることになるでしょう。このエンコードはカジュアルなものですから、 未エンコード時と全く同じ動作が保障されます。将来は範囲指定されたソー スがプリミティブなJScriptコードであった場合Visual Studio環境と連動し てネイティブコンパイルされることになるでしょうが、その実現にはかなり の時間を要すると考えています。
私の立場からすれば、はじめからHTABOX用ソース、TZB用ソース、....... を複数管理しようとは思っていないわけで、同一なプロジェクトが生成する 外観の違いをそれそれの呼称で呼ぶという状態が理想です。その外観の違い は、同一EXEが実行対象と認識するHTMLファイルで演出されてゆくということ になります。ですからTZBとHTABOX3のバイナリを比較するとリソース部分しか 違わないという事になると思います。で、TZBやHTABOX用に迷路や救急統計を 書いても違うのはリソース部分だけということになります。例えばベースと なるネイティブコード部に修正の必要が生じても単に格納し直すだけで更新 は完了することになります。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。GUIの配置を見直しツールバーは各エディタに存在するもの
としました。また、無駄な記述を排除したのでやや動作が軽量になりました。
内輪ネタですが、このアウトラインエディタは私にとってはTZB及びHTABOX用
開発エディタですので、フックDLLを配置した起動でデバッグを受け入れるこ
ととした点が最も重要な変更箇所となりました。
ユーザー定義型のエンコード規則について考えてみました。基本的に単純な 一段BASE64動作としてこの変換規則をユーザーがキーとして設定できるとい うルールにしてみようかと思います。通常のBASE64は 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' という並びなわけですが、この順番を任意な並びに変更してエンコードと デコードを行うものです。無論変更された並びはEXE内にキーとして極めて 難読な形で保存しなければなりません。
並びかえるといってもこの64文字をすべて定義する必要はなく、重複の無い 形でこの64文字中の任意な文字列が与えられた場合、一定の規則で64文字を 並び替えるというルールがスマートだと考えています。気の短い人は[A]と いうキーだけでエンコード、デコードを行えますが、誰かが試しに[A]でデ コードを試みる可能性は高いですから、もっと長いキーを使いましょうと いう展開になります。
従来のHTABOXの場合はランダムビットスクランブルを多段で行って更に変形 BASE64を多段で行うというものだったのですが、今のところエンコードによ るソース隠蔽はあくまでカジュアル(お気軽)なものと位置付けていますか ら「素人目には見えない」でよろしいんじゃないかと考えています。
スクリプトのエンコード、デコードを繰り返す時に長大なスクリプトをいち いち範囲指定するのが面倒なものですからSHIFT+CTRL+Sでカーソル位置から </script>直前までを選択、SHIFT+CTRL+Cでカーソル位置から*/までを選択 という機能を追加したら作業が夢のように簡単になりました。でもこういっ た部分は個人の好みに左右されますから、マクロ階層とは別にショートカッ トキー階層を用意してカスタマイズできるようにすべきと考えています。
C/C++のプログラミングで最も根源的で重要な課題は、従前に宣言された型 しか有効ではないと言うことです。静的にリンクされますので当然と言えば 当然なのですが、これを回避する方法の一つがIDispatchのような基底クラ スの導入です。「こんな関数ありますか?」「このIDですよ」という手間を 設けることによって、クラスの記述位置を意識しないコーディングが可能で す。
でも今日、もっと高速にそれを実現する手法が用意されていることに気づき ました。HWND又はスレッド間のメッセージ通信です。HWND又はスレッドIDが 確定していればそのクラスがどこに記述されていようがトリガーを引くこと ができますし、COMオブジェクト間のやりとりが複数回のメッセージで構成 されることを考えれば、よりシンプルで高速な手法なわけです。とっても 今更な発見なんですが、気づいていないと余計な継承構造を導入して自爆す る原因になりかねません。
私にとっての「大統一理論」とも言うべき母艦EXEの構築を行っています。 HTABOX3、TZB、OutLine、PCMプレイヤーを搭載されたHTMLファイルの違い だけで実現できるという、明確な枠組みが存在しますから、そんなに悩む ことは無いのですが、細かく書きすぎている部分をばっさり捨てて、全体 の構造を再度見直すという作業は、自分が理想とする物への勇気を試され ている感があります。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。デバッグ用DLLが添付されていますので、起動するとデバッ
グモードで動作するかを問い合わせるダイアログが表示されます。エディタ
で何らかのHTAを記述しHTML Viewした時に文法又は実行時エラーが発生する
と通常通り登録されたデバッガが起動するはずです。このデバッグモードで
のHTMLページは全て別プロセスMSHTA.EXEが生成したダイアログウインドウ
ですから、普段どおりにデバッガが起動するわけです。このEXEはOutLineと
いうよりTZBの原版という位置づけになっています。タブスタイルが選択でき
、タブ上に追加された×ボタンでページを削除できます。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。Struct Designタブで個々の要素にビットマップ情報を持た
せることが可能となりました。WIN32で各種コントロールを設計しHTML中のス
クリプトから利用する手法の最終チェックの意味でposition:absoluteに追従
する走り書きコントロールを実装してみました。また、従来HTML中のエレメン
トを基準に何らかの拡張を行う場合はID必須としていましたが、今回の最終
チェックの過程で、単なるエレメントとして渡されても対応できるようにし
ました。TZB、HTABOXでの各種コントロールは極めて単純なスクリプトで利用
可能となります。
全てを統合した環境の仕様が完成しました。実行HTMLへ提要されるディスパ ッチ中にTZB名前空間があり、TZB系の機能はそこで提供されます。従来はあ らゆる機能をEXE側へ追加することで、最終的に万能なディスパッチを形成し ようという方向性でしたが、本体EXEはシンプルで汎用なものとし、リソース スクリプトを切り替えることによって変幻自在なEXEが生成されてゆくという 手法が、横着な私にぴったりだと考えています。私は常に同じWIN32プロジェ クトを開くのですが、目的アプリケーション用のリソースへ切り替えてコンパ イルを行う訳です。根幹の部分でバグフィクスが行われれば、すべてのアプリ ケーションのバグフィクスも完了したことになります。
今回はWindows上のHOOKを徹底的に解析していた時期があったのですが、二つ のプロセスにまたがったC++クラスインスタンスの維持という課題をクリアす ると従来のCによる原始的なHOOKでは記述しにくい動作を記述することができ ます。手っ取り早い表現を用いればもう被HOOKアプリケーションは誰かが書い たものではなく、私が書いたかのように動作をカスタマイズすることができま す。しかも私の知る限りWindows上でHOOKを拒否するすべは存在しませんから、 IEだろうがFOXだろうがC++で書かれていようがJavaで書かれていようが、あら ゆるアプリケーションにちょっかいを出せると考えています。
通常本体アプリケーションの拡張はいわるゆ「プラグイン」で行われるわけ ですが、その場合あくまでも従属的で制約の多い立場でしか動作できません。 それに対しHOOKは本体アプリケーションがシステムと交信する情報を奪った り、摩り替えたりできますし、HWNDを相手側実行プロセス空間で握ることが できますから、相手を逆に従属させることができます。
やっとHTABOX300というプロジェクトを揺ぎ無い信念で作成することができま した。この絶望の淵の中で新たな生命が誕生しました。毎回そう思うのです が、私の愚かさも、私の賢さも、このプロジェクトに凝縮されています。
新たなHTABOXはソースコードをEXE格納する際に3種類の実行モードを選択可 能にする予定です。フックDLLを添付し、実行環境でMSHTA.EXEを起動する完 全MSHTA.EXE動作、内部でMSHTA.EXEをエミューレートしMSHTA.EXEを必要と しない従来の動作、そして最も軽量に動作するだろうHTMLダイアログ動作で す。ソースエンコードはエディタ上で行えます。ただしフリーバージョンで は単なるBASE64エンコードとし、固有のエンコードが可能であることを示す 程度に留めます。アイコン、バージョン、外部リソースはEXE生成時にコント ロール可能とします。拡張機能ディスパッチ抜きに上記機能を搭載したα版 を早期にお見せしたいと考えています。
HTABOX With Editorではソースを編集して実行、ダメならまた編集して実 行という事を行える状態にしますが、HTAインスタンスはプロセス中に一個 でなければなりませんから、従来手法では実現できませんでした。今回は やや面倒でもフックDLL中にEXEと同等なWindowClassを置いてそれを実現し ます。ただし、空ダイアログによるディスパッチ提供を別プロセスから行っ た後の被フック環境では特定の操作を行った場合、自身documentへのアクセ スでも0x80004005が報告される事を確認しました。これはあくまでも限られ た状況下でしか発生しませんから全体のパフォーマンスを低下させるもので はありませんが、このフックによる別プロセス動作はあくまでもエディタ環 境からの起動に限定すべきという暗示にも受け取れます。したがってEXE格納 後のHTA起動はDLLやMSHTA.EXEの存在に依存しない従来型インプロセス起動と すべきというのが今日の結論です。
最後にいまだ触ったことの無いバージョンリソースについて調べてみました 。結論から言うとリソースとして扱うよりバイナリファイル中の目的文字列 置き換えで処理した方が柔軟性があるようです。土台、著作表示やバージョ ン表示を後から変更しようというのは、ややダークな話題になりますから、 一般に解説されている分野ではない気がします。
>>311 お疲れ様です。努力が結実したこと、嬉しく思います。
「受難は天に登るための階段だ」という古いことわざがあります。
困難を憎まず、うまく味方につけて下さい。
その才能の高まりが、正当に評価される日を信じて止まないです。
めっきり暑くなってきましたが、どうかお身体にはお気をつけ下さい。
>>315 ありがとうございます。未だ食うに至らず、枝豆を収穫するバイトでなんと
かサーバーを維持する通信費と電気代を維持するありさまですが、夢と闘志
だけは未だ衰えず、私が存在した意義を少しでも残せればと奮闘しておりま
す。どうしても手探りの分野では安定度という点がウィークポイントになり
がちですが、現在HTABOXの原版EXEで実際にテストアプリケーションを開発す
る試験を繰り返しております。
今日は、あれこれ試しながらHTABOXでのアドバンテージとしてHTMLイベント をより高速に伝達して描画に反映させることはできないのかという課題に取 り組んでいました。最初の発想としてはHTMLウインドウの上にレイヤー階層 を置いて、イベントをキャッチすればいいのではないかと考えたのですが、 レイヤーはディスクトップを親としたPOPUPでなければならずHTMLウインドウ と連携させた場合むしろ散漫な動作を生み出すという結果でした。
で、ためしにJScriptで記述してある部分をVBScriptにしてみると案の定速度 は向上します。原理的にはパース後のVBScriptはC++によるCOM操作と同等な 速度で動作するはずです。それに対しJScriptはその柔軟性故にIDispatchEx を前提とした動作となりますので、最も高速であるべき配列操作においてさえ Arrayディスパッチに対してGetDispIDとInvokeExを繰り返す規格から逃れるこ とはできません。
将来、動作環境に.NETが必ず期待できるとなれば、立ち上がりこそ時間がか かるもののJScriptアセンブリとHTMLを融合させることでVBScriptに近い処理 速度を達成できるはずですが、現状においてHTMLアプリケーションを開発し、 そのコードをJavaやC++へ移植する予定が無いならば、VBScriptで記述する方 がいいと結論付けます。JScriptに生のSAFEARRAYを扱う機能を追加すること はやぶさかではありませんがVBScriptという道具が実在する訳ですから上手 に使い分けるというアプローチが正しいと思います。
HTABOXのHTML実行速度実験をやりながら、Mazeのマウス座標判定アルゴリズ
ムを見直し、JavaScriptでのオブジェクト参照を極力配列参照に置き換えて
処理を軽量にしました。
http://kuroda.bglb.jp/maze/mokuji.htm このWEB版はFoxでの動作も含まれますからあくまで素のJavaScriptです。外
観を形成する画像も一新しましたので、遊んで、コードを眺めて、コードを
書き換えて、楽しんでください。
機械という奴は血も涙もないマウス座標判定をしますので、今回は現在座標 と従前判定座標との間に飛ばされたと思われるブロックが一つ存在した場合 に、擬似的に飛ばされた座標でも判定を行うようにしました。したがって角 を曲がる場合、ショートカットしても素通りされたブロックが1つなら通常ど おり経路が継続します。
>>319 JSは参照渡しをサポートしてないから
使いたくても使えないAPIがたまに出てくる
でもJSの柔軟性は捨てがたい
そういう意味でもVBSとの使い分けは必要になるね
今日はHTABOX、TZB、....という複数のプロジェクトをどう配置してソースを 共有すべきかについて勉強し、結論を出しました。通常はライブラリとして 奥まったディレクトリに共有ソースを置くのでしょうが、私のように再イン ストールを衣類の洗濯のような感覚で行う人間はうっかり置き忘れる可能性が 出てしまいます。そこで親にはソースやヘッダだけを置いてプロジェクトを作 らず、複数の子ディレクトリに存在するプロジェクトからそれを参照するとい う方式にすると、大変管理しやすいものになるようです。
JavaScriptがJavaScriptであるかぎり高速化を謳ったところで、たかが知れ ているという事実を私はある意味素敵な事だと感じています。多くの人がそ の速度に不満を持ちながらもクライアント側WEBアプリケーションにおける 事実上のスタンダード言語として使用されている訳ですが、ターゲットをIE に限定できるHTMLアプリケーションの場合、その実行速度を劇的に改善でき る可能性を秘めています。
VC++コンパイラはExpress Editionに限りますが無償で提供されていますから 適切なヘッダファイルさえ設計できればJavaScriptソースに若干の制約を加え るだけでネイティブコンパイル可能だと予測しています。ここで言うネイティ ブはあくまでもC++側のCOM呼び出しに置き換えるという意味ですが、素のJava Scriptとは異次元な速度を実現できるはずです。
枝豆のバイトが本格稼動したので、ソースを書く時間は少なくなりました。 朝5時半から畑で収穫を行い午後5時まで脱穀や選別に汗を流しています。こ ういう生活をするたびに思うのですが、余暇にプログラミングを行ういわゆ る「サンデープログラマー」には越えられない壁が存在すると思います。 結局世界に類を見ないチャレンジングな事を実現するためには「死線を越え る」くらい「不退転な覚悟」が必要です。一仕事終わった後にそんな気が起 こるわけがありません。ですから私は4年間とても幸せな時をすごさせてもら ったんだとあらためて感じるのです。
HTABOXがWSH起動になった背景はデバッグをスムーズに行うためだったわけで すが、HTMLウインドウの表示、非表示をコントロールできるというメリット を生み出しました。現在は別プロセスMSHTA.EXEをフックで服従させてHTABOX 互換動作を可能としてますからわざわざWSH起動しなくてもデバッグできるの ですが、WindowsXP以降のマニフェスト機構を利用してレジストリ未登録COM をWScript.exeに認識させれば従来は不可能だったトリックを実現できますの で、勉強してみたいと考えています。
上記分野については具体的なサンプルを探すことにあまり苦労しないようで す。私の知る限りwscript.exeはsystem32に必ず存在しますので、コピーして 自ディレクトリに持って来れば例え疑似餌でも喰らい付くという展開です。 HTML中のスクリプトパースは従来独自の内部スクリプトエンジンで行ってい ますが、これはスクリプトスコープにHTMLインスタンスさえ出現させることが できれば何でもいいんです。したがってHTMLスクリプトスコープでWSH.Sleep とかを呼ぶことに全く問題は無いと予想します。また、将来XPの存在を意識し なくて済むようになれば、HTML中のスクリプトエンジンを.NETエンジンに置き 換える予定です。JScriptの場合Fast-なら従来互換が保障されますから必要に 応じ.NETライブラリを使えるという新たなステージを提供することができます。
マニフェストによる未登録COMで使えるのはCOMDLLのみでLocalServer32のEXE はプロセス境界によってインスタンス化できないというのがsocial.msdnでの 結論になっているようです。ですから手法としてはダミーDLLを介して異プロ セス間でのCOMインスタンス共有という事が必要になりそうです。マジックを 披露するためには必ずネタが必要で、それはいつもマジシャンの袖の中に隠さ れているということでしょうか。複数の手段が候補にあがりますので絞り込む のにすこし時間が必要かも知れません。
意外な事に、wscript.exeは移動すると起動しないようですね。昔はどこへ 持って行っても起動できたと思ったのですが、5.6と5.7との相違ということ でしょうか?やはり正攻法はwscript.exeの非公開関数攻略なんでしょうが、 今後の課題ということにして、HTABOXは通常のHTMLファイルでの動作を基本 とし、表示前、表示後の動作をコントロールしたい上級者向けに内部スクリ プトエンジンからの起動、当該動作をデバッグするためのCOM登録という流れ にしようと思います。
330を訂正します。動かないように見えたのはマニフェストが不完全だという 理由でした。
ただ、wscript.exeは実在ソースファイルが無いと起動できないでしょうね。 たとえそれがeval一行だとしてもhoge.jsという実在が条件となるならプロ グラムのファイル構成としては美しくないと言わざるを得ません。せっかく TypeLib駆動のEXECOMサーバーを開発していましたので、マニフェストによる 未登録COMがらみは先送りという結論は変化しません。
話題は寄り道しますが通称「ウイルス作成罪」について私見を述べます。 ソフトウェアが製造物責任法の範疇に含まれなかった事は、プログラムとは 何たるかを踏まえた正しい見識と感じていました。今度は使用者が「意図し ない動作」と判断しただけで作った人は刑事罰という法律のようです。
私のようにあらぬ嫌疑をかけられても正々堂々説明しようという覚悟の人間な ら問題は無いのですが、検挙されたという報道だけで社会的に致命的なダメー ジを負う人間はプログラムを発表できないという展開になるわけです。 ここで問題になるのは「意図的」か「バグ」かですが、司法の世界にバイナリ が読める人間はいないでしょうから「疑わしきは罰する」になりかねないと 感じます。
いまの菅直人の拉致に関連する人物が絡む団体への政治資金問題も一切無視するのが日本のメインストリームのマスコミです。 かつては人権擁護法案の危険性も完全無視したのが日本のメインストリームのマスコミです。 ウィルス法の危険性についても、そこから派生する問題意識を訴えるような番組なんて見たことないです。 作者さんが、時の政権や公安ににらまれるような政治運動に絡むようなことがないように祈るだけです。
人間の価値観を突き詰めると「食べる為に生きる」のか「生きるために食べる」 のかというところへ行き着く気がします。「自分の懐が痛むかどうか」が全て の発想の原点でなければならないとしたら、私はこの世界とは相容れない存在 なのかも知れません。
HTABOXのWSH起動デバッグに対応すべく全公開ディスパッチをタイプライブ ラリ対応モードへ変更する作業を行っています。今のところCOM登録して外 部スクリプトから内部ディスパッチを使うアプリケーションはHTABOXだけ なのですが、メインソースコードは全アプリケーションが共有して使用しま すから、潜在的に全てのアプリケーションは自身をEXEサーバーとしてレジ ストリ登録可能で、そのためのボタンが有るか無いかの違いということにな りそうです。
枝豆相手のバイトですから、成長の具合でお休みが生じたりします。今日は DirectDrawをHTABOXに搭載する仕様を決定し、簡単なゲームでもお見せでき ればという課題で勉強しています。DirectDrawについてもオリジナルな提言 をしたいポイントがありまして、システムの解像度とカラーディプスを奪っ た状態でのウインドウ表示をメインにしたいと思います。単なるウインドウ 表示ではGDIが足を引っ張りますし、全画面表示ではメニュー等のコントロ ールが使えないので双方のいいところだけを使おうという展開です。
http://kuroda.bglb.jp/htabox/directdraw7.zip をDirectDrawエンジンのコンセプトとして公開します。ウインドウとしてメニ
ュー、タスクバーを表示しながら、解像度自体を変更しています。また、タス
ク切り替え(ALT+TAB)が生じた場合GDIディバイスにVRAMのスナップショット
を表示しています。まだ改良の余地はあるのですが、私の提案するDirectDraw
ウインドウの方向性はご理解いただけると思います。
色深度については軽量さと発色のバランス、また、もはや256色モードでは動 作しないディバイスも存在することから65536色モードを基本とする設計とし ています。使用する画像はTrueColorでかまいませんが、内部で自動的に減色 処理を行います。ただし、COMとしていかにデザインすべきかが煮詰まってい ませんのでHTABOXへの実装は今回のリリースで行わない可能性が高いと考えま す。
久しぶりに休みだったので、サブの開発環境作成に時間を割きました。 PV700MHzという低スペックなノートなのですが、開発環境というものは意識 して低スペックにしないと、CPUパワーに依存したルーズなコードを放置して しまいますので...という貧乏人特有の言い訳を用意しています。VS2005以降 は低スペックマシンだと重くて使えませんからVS2003を持っている幸せを噛み 締めつつ、そのインストールの面倒さに閉口する一日でした。
元気出せ日本
収穫すべき枝豆も残り僅かとなったようです。4時で起床し20時には横になる という生活はとても健康的なのですが、頭の中はリセットぎみで、次に何を 書くべきだったのかソースコードを熟読しないと思い出せないでしょう。 良い方向にとらえれば、過去の無駄なしがらみに気づく機会になるでしょうが。
コードのことを考えない時間が長くなればなるほど「もう書けないかも」と いう不安に襲われます。年齢を重ねると何日もの間ひとつの問題へ向けて思 考とコーディングを繰り返す気力も失せてしまうのではないかという不安で す。このブランクを「災い転じて福」となすように過去のしがらみを断ち切 った開発環境の構築を行っています。
具体的には.NETのJSコンパイラを活用した自分用ツールの開発手法について 煮詰めています。従来はHTAまたはWScript.exe用JSでしたので厳密な文法チ ェック無しに実行時デバッグですべてを修正していた訳ですが、.NETのJSコ ンパイラを導入すればよりシンプルなコードで、概ねのことは自作COM無しに 処理することができます。.NETの欠点はアセンブリがキャッシュされるまで のタイムラグですが、あくまでも「自分用ツール」なのでその点は無視でき ます。
.NETのJSコンパイラを使って幾日か経過しましたが、規模の小さな実験用 データでは発生しないトラブルが実用的な規模だと発生してしまうことに 気づきました。具体的には数百キロバイト程度の文字列に対して連続した 正規表現操作を行うとVS2003のデバッグ環境がハングするというものです。 fast-の互換コードでも、fast+で.NETの正規表現クラスを使っても同じ症 状が出ます。まぁやってみなければ判らない事でしたので、時間が無駄に なったとは思いませんが、かなり気が滅入りました。逆に言えばWScriptや HTAでのJScriptがいかに枯れて堅牢なものであるかを再認識した次第です。
最近、皆さんが動かせるものを公開していないので粗品をプレゼントします。
ttp://kuroda.bglb.jp/jscript/clipboard.zip これはWSH等へクリップボードへの読み書きを提供する軽量なWIN32.EXEです。
.NETだとクリップボードクラスがあるのですが、WSHには無いということで、
皆さんどうしているのかな?っと検索したら、回りくどい手法のオンパレード
でしたから、標準入出力経由で当該機能を実現するEXEを作りました。
使い方は添付のtest.jsをご覧ください。現状で対応している形式はCF_TEXT
のみですが、これだけコンパクトなEXEならDLLと同等なレスポンスで動作す
ると思われます。
横着な私にとって、複数のHTMLページのリンク構造を管理するのは最も避けた い仕事ですから、長大な単一ドキュメントから複数HTMLページを生成してサイ トへ仕上げる仕事はFrontPageにやってもらうのですが、FrontPageのVBAが曲者 でして、リンク構造が深いと再帰動作でお亡くなりになる傾向があります。 また、単一ページへの操作は成功しても連続したページを高速に操作すると 毎回違った破綻の仕方を見せてくれます。 そこでWSHによる外部操作と内部のDcumentオブジェクトに頼らずエディタの HWNDへ直接WM_COPYやWM_PASTEを送信する手法で目的を達成しました。その 時必要になったのが上記Clipboard.exeという展開です。
2週間ほど身辺のガラクタ等を整理し、プログラミングとは無関係な時間を 過ごしました。当初は3日で終わるつもりだったのですが、いっそのこと 従来の仕事を全く客観視できるほど、距離をおいてみたいという気持ちに なりました。
Windows2003Serverのセットアップを行っています。ところでASP.NETとは何 なの?をまったく知らなかったものですから、単純なサンプルを表示させ、 ブラウザ側のソースを見て驚愕しました。考え方として最終的にサーバーが レスポンスするHTML+ScriptはEXEのバイナリコードみたいな存在で、それが どんなに入り組んでいても開発者はソースだけ見ていなさいという発想なん ですね。これを積極的に活用するつもりは無いのですが、もしブラウザ側が エラーを報告した場合、EXEに例えればクラッシュしたメモリアドレスから ソース中のバグを推測するようなもどかしさが発生するんじゃないかと感じ ました。
IIS6.0のISAPIフィルタとASPで共有するCOMDLLという重箱の隅をつつくよう な分野のプログラミングをここ数日やっているのですが、データベース系の 操作を連続させるとエラーが出るという症状に悩んでいました。 IIS5.xとIIS6.0の最大の違いはスレッドタイプの違いだということは情報と して頭の中にはあったのですがSTA(シングルスレッドアパートメント)と MTA(マルチスレッドアパートメント)で実際に何をどう変化させるべきな のかについて勉強不足だったものですから解決に時間がかかりました。
IIS5.x以前のISAPIフィルタにとってカレントスレッドは通常のスレッドです から必要な時にSTA又はMTAの初期化動作が必要になります。初期化動作が必要 という事を裏返せば終了動作(CoUninitialize)も必要ということです。これは 面倒なことではなく初期化と終了の間に生成したCOMインスタンスは必ず破棄 されるという意味でむしろわかりやすいソースコードになると感じます。
IIS6.0のISAPIフィルタにとってカレントスレッドは既にMTA初期化されたスレ ッドです。したがって初期化せずCOMインスタンスを生成できます。この環境で COMインスタンスを生成する場合、COM側のMTA対応を前提としたコードでないと 2回目、3回目の呼び出しでエラーとなるようです。具体的には利用するインス タンスをクラススコープに置いて、各メソッドは当該インスタンスを参照する という書き方です。これを各メソッドの実行時に個別にインスタンス化しよう とするとエラーが発生するようです。これはC++のCOMDLLに限った事ではなく JScriptで書かれたASP中のオブジェクトでも同様と推察され、個々の呼び出し 時に new ActiveXObject するのではなしにできるだけグローバルなスコープ で new ActiveXObject し各メソッドで利用すべきだと考えられます。 もし、IIS5.xから移植したASPやCOMがIIS6.0以降で得体の知れないエラーとな る場合、原因の多くはこのスレッドタイプの違いによって生じていると考えら れます。
ISAPIフィルタDLLを開発する場合、どうしても実際に稼動している状態での 変数値を確認したくなるのですが、WWWサービス自体が特殊な保護プロセスで すから、大変面倒なことになります。また通常のIDE環境デバッグでは動作を 一旦停止するため、タイミングによってはエラーを再現できない可能性が高ま ります。今回はISAPIフィルタ側からのWM_SETTEXTで文字列情報を受信するEXE を書き、今まで疑問だったISAPIフィルタの仕様を確認することができました。 IISを根本からカスタマイズするにはWWWサービスから呼ばれないと動作しない ASPやASPXでは限界がありますが、組み込みDLLを導入すれば高速で堅牢なもの となります。時間がありましたらIIS周辺のISAPIやCOMについてのドキュメント を作成して公開したいと考えております。
>>355 至極当然な話として受け止めました。書いていることを見せたくない派の私
でも、万が一人を雇うことになれば、私にとって可読性の悪いコードを書い
てもらいたくはないと考えるでしょう。私が予見する未来は、アプリケー
ションはもっと具体的な局面を想定したコンパクトなツールに分解されて行き、
オンライン上でそれらを組み合わせることで目的が達成される環境です。
何が言いたいかというと、複数のスタッフが協力しあう大規模なアプリケーシ
ョンは淘汰され、個人単位で管理可能なクラウドパーツが主役になるだろうと
いう気がします。そいういう環境ができて初めて「プログラマーの汗」が真に
報われることになるだろうと考えています。
で「ビルド可能な難読コード」というテーマの場合、私ならVisual Studioの マクロでビルド可能な程度のエンコードを行うでしょう。実際にC++ソースコ ード中に静的文字列としてスクリプトコードを埋め込まなければならない局面 用にそういうマクロをいくつか書いています。復元したい時にはその範囲を 選択してDecodeマクロを実行するだけですから最も堅牢で確実な手法だと考え ています。
しばらく自分用のツールを書いているのですが、そいうことをしながら混沌 とした自分の考えを具体的な形に描き始めています。TZBを世に送り出そうと して躊躇したのは「何か芯が足らない」「何をやりたいのかはっきりしない」 という感じがしたからです。今日やっと自分がやりたかった事を明確に表現 するイメージが浮かびました。
TZB形式で5つのエディタを編集可能とします。この5つとは 「HTML/HTA」「JScript」「VBScript」「JS.NET」「VB.NET」です。 このエディタ上のコードはHTABOX固有の拡張機能を利用できると同時に、 相互をCOMインスタンスとして呼び出し可能とします。そしてこの5つを 単独のEXEへ格納できるというものにすれば、私の仕事の集大成的なツール になるだろうと思います。アプリケーションとしてのトリガを引く言語を 限定しないことによって、より自由な発想のプログラミングが可能になる でしょう。
HTAで重い処理を行うと描画が追いつかないような状態になりますが、これは HTAに限ったことではなく、WIN32で書いたアプリケーションでも全く同じだ ということに今日まで気づきませんでした。要はメインスレッドのHWNDがス ムーズにメッセージを処理できるかに帰着するわけで、重くて時間のかかる 処理はスレッドを投げて実行しなければ、いかにも素人の書いたアプリケー ションという動作になるわけです。逆に言えばHTAやHTML環境のスクリプト でも上手にスレッドをコントロールすれば洗練された動作にできるだろうと 考えます。
ただし、COMという要素が絡むとスレッドを跨げるインスタンスとそうでない インスタンスが存在すると考えます。ディスパッチ系は基本的にシステムが 提供するマーシャリングでプロセスさえ跨ぐ柔軟性を見せますが、同一プロセ ス内でも参照が破綻するケースを体験しています。すべては私の勉強不足なの ですが、できるだけ洗練された環境を提供できるように分析を続けています。
従来はHTAウインドウ生成時にある程度クリティカルな状態となっていました。 これは生成の完了をdocument.readyStateで判断しようとしていたからです。 つまり生成途中のHTAインスタンスは、大忙しにもかかわらずreadyStateの GET要求を処理しなければならなかった訳ですから、環境によっては生成完了を 検出できませんでした。
今日は発想を変えて、HWNDに到達するメッセージの流れからドキュメントの 生成完了を判断するというアルゴリズムを採用して、大変良好な結果を得ま した。HTA生成時には何のストレスもかかりませんからごく普通に起動します。 また、ストレスが無いことによって非レジストリ登録ディスパッチを初期注入 するダイアログ手法もあらゆる環境で成功するという感触を得ています。後は これをディバッグ用別プロセスフック環境でテストすれば、新たなHTABOXのス レッドデザインが確立することになります。
HTML Application内のスクリプトからはスレッドの優先度設定ができません から、どこか窮屈な動作になるんですが、今回はあらゆる手を使ってそれを 克服する努力をしています。スレッドの分散はもとより、積極的に複数プロ セスを活用しようと思います。例えば.NET環境が存在する場合、自身のクロ ーンEXEを起動してmscorlib::_AppDomainPtrを取得し、汎用なDLLをバックグ ラウンドでキャッシュした後にプロセス越えで親プロセスへ渡すモジュール を実験しています。これが成功すれば.NET固有の初回タイムラグを撲滅する ことができます。
実験は成功したようです。効果のほどは実際にさまざまなコードを処理させ ないと判断できませんが少なくともデフォルトより遅くなることはないと思 われます。これでHTABOX3.00の基本的な仕様を固める情報が出そろいました。 HTABOX3.00は原点に立ち返って通常のHTMLと完全に上位互換な仕様とします。 つまり単一なHTMLにタグと複数のスクリプトがあり、IEやMSHTAで動いていた コードは絶対にそのままHTABOXでも実行できる状態とします。
HTABOXはHTML中のスクリプト言語にJS.NETとVB.NETを使用することができま す。ただし、現状での.NET系言語に対する考え方はJScriptとVBScriptを補助 するクラスを提供するもの考えていますので.NET系言語から直接documentや windowを操作するのではなしに、.NETクラスライブラリ機能やWIN32API機能を JScriptとVBScriptに提供するものになると思います。
.NETでの補助が可能となったことで、スクリプトへWIN32API機能を提供する オブジェクトの位置づけもより明確になります。.NETでできそうな事を用意 する必要はなくなるわけですから、音、描画、各種コモンコントロール等で ネイティブコードだから実現できる切れを発揮することに専念できると考え ます。
今回の実験でひとつ驚いたことがあります。COMの動作は結局メッセージのや り取りですから、別スレッドでCOMを生成し、本スレッドから呼び出す場合、 別スレッドの方はGetMessageで動作し続けなければなりません。さもなければ 呼び出し要求に応答できず、オブジェクトではないと判断されてしまいます。
ところが.NETの場合、別スレッドでコードをスクリプトエンジンでパースし、 インスタンス化する動作を行い、ループ待機することなくスレッドが終了し、 パースしたエンジン等が破棄されても動作可能に見えます。おそらく.NETシ ステムはインスタンス化されたCOM(アセンブリ)をシステム領域にストアし アプリケーションのメッセージループとは切り離された状態で効率的に動作 させようとしているようです。これも実際にコードを走らせないとわかりま せんが、うまく使えば通常のHTAならWM_PAINTにさえ応答できないような重い 動作の連続を平然とこなすことも可能だと考えられます。
現状では.NETのGUI系との整合を考慮していません。たとえば.NETのファイル ダイアログを表示することはできますが、2回目の表示で後ろへ表示されたり します。ですから、フォルダ、ファイルについてのコモンダイアログは従来 どおりWIN32APIで提供する予定です。気軽にHTAへ.NETコードが書けるという 観点からもう一度.NETクラスライブラリを眺めてみると「宝の山」に見える かも知れません。
今回の研究中にリッチエディットを使った拡張コンソールも出来上がりまし た。プログラムの性質にはボタン等の静的コントロールで繰り返し同じ動作 を行うものと、ウイザードのようにストーリーがあって一連の動作を行うも のの2種類があると考えます。後者の場合、画面が変移するよりも経過が見え るコンソール型GUIの方が適しています。また、自分用ツールの場合はパラメ ーターを限定するコントロールより、コマンド入力による指示の方が柔軟な 動作を実現できます。自由な色とフォントが使え、画像、HTMLを配置でき、 ハイパーリンクによるクリック動作ができるDOS窓がこの拡張コンソールです。 これはCOMDLLにしてさまざまな言語から使えるものにしようと考えています。
私はC++でヘッダファイルを作るのが嫌いです。というよりヘッダだろうが 何だろうが複数のソースファイルでものを管理するのが嫌いです。相互の 参照でエラーが発生した場合、大変わかりにくいバグになるからです。個人 がプロジェクトを管理する最大のメリットは全てをひとつのcppファイルで 完結させる事が可能なことだとさえ感じています。
ですから私の中での理想は、あらゆるEXEやDLLを単一cppファイルから生成 することなんですが、そのためには各アプリケーションの差異をリソースの 違いで表現できればいいんじゃないか?というある意味妄想めいた考えに固 執していました。つまりリソースであるHTMLがHTABOX手法でアプリケーション を表現し、出現させるというものです。ですからHTABOXは私にとって単にHTA として実行するものではなくC++環境でのアプリケーション管理手法でした。
しかし、実際には全機能を最終的にCOMの状態まで引き上げるには大変な労力 が生じる訳で、結局「ああではない、こうではない」とプロジェクト毎にcpp ファイルを作っては、物置に放り出すという事を繰り返す羽目になっていまし た。何かを書きながら「それっていつか書いたよね」と物置をかき回す日々に なりがちでした。で、頭の悪い私は今やっと気づきました「プリコンパイル」 ですべてを切り分ければいいと。
HTABOXコア3.00はmain.cppを参照するEXEプロジェクトと、同一cppを参照する DLLプロジェクトがあり、#defineで切り分けています。これが大変ラクチンで 気に入っていたのですが、これを複数のEXEに応用すれば...という恐ろしく基 本的な事に気づいて「あぁ、全てが解決した」という安堵感というか脱力感と いうか自分の馬鹿さ加減への怒りというか大変複雑な感情がこみ上げてしばし 呆然としてしまいました。本当に私的にはこれで全てが解決しました。単に #if defined(hoge) 〜 #endifで複数のWinMainを切り分て単一cppを常に編集す るという単純な発想で、何らかの修正があらゆるアプリケーションへ即座に適用 される状態を作り出せるし、もう物置をかき回しに行く必要は無いわけです。
377 :
片山博文MZ ◆0lBZNi.Q7evd :2011/12/03(土) 17:18:42.15
がんばれ、がんばれ、hi・de・bo・u
ありがとうございます。3.00では全てを見直しました。特にHTAやHTML側の実 行コンテキストを尊重した設計としておりますので、全体にスムースな動き になります。そのために裏方では高速な文字列クラス、Invoke速度の向上等、 今までの全てを投入したものになります。また、3.00の目玉として「動かせる ヘルプ」を実現すべく、その部分を書いています。もう5年近くこのことばか り考えてきましたので、良くも悪くも「私のすべて」を出し切ったものにした いと考えています。
今日は朝一番でHTMLダイアログのハング状態を見せ付けられたものですから、 神様のおぼしめしどおりにモーダル、モードレスのHTMLダイアログについて 徹底的に再考しました。結果的にダイアログのフレームはWIN32で形成しクラ イアント領域にHTMLを表示する方式としました。非表示状態のHTMLを先行して インスタンス化し、取り込むことで従来より切れのいい出現状態とする事が できたようです。
HTABOX3.00でのソースエンコードシステムについて暫定的ですが仕様を決定 しました。今回のコンセプトとしてHTML側のコンテキストからトリガを引く ことから、各スクリプトブロック冒頭に待機関数が置かれるものとします。 これにより、当該スクリプトブロックでは拡張ディスパッチの生成タイミン グを気にすることが無いコードを記述することができます。 HTABOX3.00は引数無しで起動された場合エディタとして機能し、任意なHTML ファイルを編集できます。エンコードは単に対象スクリプトブロック全体を 選択し、シュートカットキーを押すことで行われます。待機関数コードは自 動的にスクリプト冒頭に追加されます。
現時点で挿入する予定の関数は下記のようになります。 <script language="jscript" id="JS001"> function Parse() { if(typeof(WIN32) == "undefined") window.setTimeout("Parse()", 1, "JScript"); else WIN32.Parse(document.getElementById("JS001")); } Parse(); /* エンコードされたスクリプトコード */ </script> <script language="vbscript" id="VB001"> Function Parse() If TypeName(WIN32) = "Empty" Then Call window.setTimeout("Call Parse()", 1, "vbscript") Else Call WIN32.Parse(document.getElementById("VB001")) End If End Function Call Parse() ' 'エンコードされたスクリプトコード ' </script>
3.00のWIN32ディスパッチは従来よりスムースに追加されるため実際に上記 関数を置き、はたして何ループ待機を実行したのかを調べると私の環境では 常に0回と報告されるのですが、万が一にもWIN32が未初期化な状態ですと、 エラーダイアログを拝むことになりますので、保険のようなものと考えてい ます。
ttp://kuroda.bglb.jp/htabox/htabox300.zipを更新しました 。
HTABOXコア3.00は引数無しで起動されると、TZB形式のウインドウを表示し
ツリー付のヘルプページとシンプルなHTMLエディタをタブで切り替えること
ができます。エディタで添付test.htmを開き、スクリプトブロックのエンコ
ード、デコード、編集中コードのHTA実行を行うことができます。エンコード
した場合スクリプトは内部ActiveScriptエンジンでパースされますので、VB
のMsgBoxは使えないことに留意してください。久しぶりだったので私はこの
事実を思い出すまで、何処かで踏み外しているんじゃないかと焦ってしまい
ました。
私が開発の対象としている分野のユーザーインターフェースを考えた場合、 対話的に操作とその操作による結果を表示するためにテキストエディタは不 可欠な要素と考えています。EXE格納動作はボタンやリストの選択ではなしに エディタ上に出現するハイパーリンクをクリックしてもらい、そのレスポンス をエディタ上に表示しながら、EXEを生成するということを考えています。 ただし、このRichEditというコントロールはバージョン間の差異があるので 私の環境で動くものが、他で動くのかという不安が付きまといます。今回は MSDNが正しいとすれば2.00をインスタンス化するコードなのですが、動きが 変だという方は、ここでもかまいませんし、デモのヘルプに記載されたメル アドでも結構ですから、環境をお知らせいただけると大変助かります。
インプロセスHTAやHTMLDialog生成の場合通常のプライマリースレッドとは 別系統のスレッドが生成され、相互にCOMを利用しあう場合ややこしい問題 が生じていました。今回の最大の改良点はここにあって、EXE側は何も押し つけず、全てをHTML側の要求に答える形にしようという設計にしています。 でも素のHTMLがHTABOXに何らかの要求を出すことはありえないわけですから、 HTML側スレッドに侵入してHTML側コンテキストのメッセージを監視し、特定 のタイミングで要求を出すということになります。
この発想にたどり着く過程に別プロセスMSHTA.EXEインスタンスへHTABOXイン スタンスを滑り込ませることはできないのか?という実験がありました。結果 的にこれは可能で、相手側コンテキストでトリガさえ引いてもらえれば、相手 側メモリ空間に送り込んだいかなるC++クラスでも自前EXEのそれと同等に動作 させることができるというものでした。まぁCPUは単にアドレスをなぞっている だけですから当然と言えば当然なのですが。
もう何年前になるのか忘れましたが、旧HTABOXを書き始めた頃どうして○○ はできないのか?それを可能にするために何が必要なのか?私にはその答え にたどり着く権利さえ無いのか?という焦りとも絶望感ともつかない複雑な 心境になりましたが、全てはWindowsがどうやってプログラムを動かしている のかにあるわけで、その一端を理解できた今、諦めずに良かったと深いため息 をついています。
応答せよ
無事に年は越せたのでしょうか。
作者タンだいじょうーび?
test
ご心配かけてすいません。CGIが置いてあるサーバーが変化したんですね。 てっきりもう書き込めないと判断していました。今月中にはサーバーを 刷新してメッセージボードとブログを設置し、いつでもご意見を伺える ようにしたいと思います。
昨年の暮れからもう一度全部を見直して自分なりのMSHTML.DLL体系を構築 していました。従来はOLEという観点からHTMLフレームとDcumentの関係を 分析するということはしていなかったのですが、徹底的にその部分を解析 してHTAとしてHTMLを生成した場合の特性や、独自IDocHostUIHandlerの注 入手法等について多くの収穫がありました。従来はHTML生成後にHWNDを捕 捉しての操作でしたから、今になって思えば「窮屈なこと」を必死にやっ ていた感がいなめません。
結論としてあらゆるHTML系ウインドウの内部コンテキストでスレッドを生成 し、まったく無理のない状態で既定の動作を拡張できることが判明しました。 ちなみにHTAの独自機能は通常のHTMLにHTA名前空間のバイナリビヘイビアを 定義することで実現されているように見えます。バイナリビヘイビア手法は 今後切り捨てられる可能性もありますので、あくまでMSHTML.DLL全般を捕ら えた中で、現状で最も便利なウインドウであるHTAの利用手法を提案してゆけ ればと考えています。
また、今回での研究で大きな収穫のひとつにHTABOXコア内で動作するHTML中 に、レジストリ非登録なActiveXオブジェクトを<OBJECT>タグで生成可能と なることが挙げられます。恐らくセキュリティー関連の理由でTDCにキルビット が適用されていますから、その代替としてCSVとXMLを認識する独自オブジェクト を開発しました。これで、こころおきなくデータバインドを利用することが できるはずです。また、HTML中にネイティブなWIN32ウインドウを出現させる 場合にも軽量なActiveXオブジェクトを用意し、そのHWNDプロパティーへ希望 のHWNDをセットしてもらうとう明快な手法を採用したいと考えています。
あと、HTMLアプリケーションに限らず、HTMLページの外観はもっとリッチに なってもいいんじゃないかという提案をしてゆきたいと考えています。従来 は文字コードとフォントデータは別だった訳ですが、これだけ通信インフラ が整備され、マシンのパフォーマンスも向上したのですから、特定のサイズ でフォントイメージをEXE内部にリソースとして保持し、独自のプロトコル によって高速に各文字のイメージを再現する手法を確立しました。 勿論、フォントのデザインには所有権がありますから、あくまで各製作者が 自分のマシンにあるフォントを使ってドキュメントを公開する場合の手助け という位置づけになりますけれど、文章のコピーを阻害したいが、全面が一 枚の画像では不自由といったケースで喜ばれるのではないかと思います。
ぜんぜん話題は変わるのですが「数学者列伝」で検索すると大変興味深い 動画を見ることができます。私は無学な人間ですから、数学にはうといの ですが、とても印象的なのは「数学者は学会でのほめ言葉(多分に外交的) を反芻しながら孤独な戦いを続ける」旨の言葉でした。私が相手にしている のは神様が書かれた宇宙ではなく、たかが人間が書いたモジュールの振る舞 いなのですが、それでも数年に渡って「はたして役に立つのか」さえ不確実 な事象を考え続ける持久力、最終的にエレガントな解に到達しなければ治ま らない心の渇望という点で、数学とプログラミングには共通項が多いと感じ ました。
また、「天才が生まれるには国家の品格が必要」という言葉もわが国におい ては、痛烈な皮肉に思えます。もはや私は「大本営発表」と何ら変わらない メディアを信じず、「単なる保身」を目的とした政治劇にあきれ返るばかり です。結局のところ自らを投げ打っても後世のために何かを残したいという 志の集積が「国家の品格」を形作ってきたとすれば、もはやこの国に品格な ど存在しないかのようです。
話をプログラミングに戻すと、モジュールの低層に存在するHWND操作に代表 されるよなAPI呼び出し階層と、HTML中のスクリプトが認識するオートメー ションとしてのCOM階層を単に組み合わせようとすると、実行コンテキスト において混乱を生じる恐れがあります。この混乱は明らかなエラーとして 停止する(ある意味良質)ものから、表立ってエラーではないが実行を阻害 するものまでを生み出します。でも、実際の生成過程がそうであるように HWND階層->OLE階層->オートメーション階層という概念を持って動作を設計 すれば、得たいの知れない事柄など発生せず、見てのとおりなプログラミン グができるとうのが私の到達した結論でした。
すこしばかり多くの事を見すぎて、はたして実現したいことは何だったのか を見失いがちになります。サイトのコンセプトは「3Days Programming」に しようかと思います。構想1日、コーディング1日、ドキュメントに1日の計3 日でアプリケーションをリリース可能な環境という意味です。ベースとなる のはHTA完全互換の実行EXEです。このEXEはHTMLコード未格納な状態でHTML エディタとして機能し、自身が格納するコードを編集できます。もしエンコ ードでソース隠蔽したければソースを範囲指定してショートカットキーを操 作するだけで誰にもソースを見られることはありません。.NETエンジンは通 常のスクリプトのようにシームレスな.NETクラスライブラリ呼び出しを実現 します。また、CLRランタイムの取得と.NETコードのパースはシャドウプロセ スによって高速に行われます。.NET系アセンブリのチャームポイントはプロ セス境界を意識しないですむことですからそれを最大限に利用します。
アプリケーションメニューを除くネイティブコントロールは<OBJECT>タグで 宣言されます。非登録なActiveXを登録済みであるかのように見せるには WindowsXP以降のmanifestを使ったトリックが必要ですから、実行環境から Windows2000は除外されます。このトリックは今までの常識を覆すものとなり ます。実行EXEが自身のDllGetClassObjectをシステムに要求することで単一 ファイルがEXEでありDLLでもある状態を作り出します。つまりDLLファイルさ え存在しないのに非登録なActiveXを利用できるのです。
まもなく新サーバーを公開しますが、WSS3.0を利用することにしました。 SharePoint系は1.0の頃から横目で眺めてはいたのですが、改めて確認して みると2.0で「既定FrontPage Server Extensionsが存在すると動作しない」 つまり、サーバー自体が企業内イントラネット環境であることを半強制する のに対し、3.0は柔軟に共存でき、80番以外のポートにも素直に治まること からメッセージボードやブログとして利用可能と判断しています。
非力なサーバーと頭の悪い私にとって「総てをASP.NETで動的に生成」しよう とするWSS3,0は「重い」「面倒」「訳分かんない」の3重苦なのですが、発想 を変えて、大企業が用意してくれた無料CGI集だと思えばかなり素敵な存在だ と思います。要は内部の細かな動作をプログラミングしようとせず、万が一 何らかのカスタマイズが必要な場合はISAPIフィルタでサーバーレスポンスを 加工すればいいという発想です。
C++プログラミングにしてもSharePointの分析にしても、最も重要な要素は 知識とか、テクニックとは別の次元に存在すると感じます。いずれも本来の システムを破壊しかねない。若しくは破壊するまでチャレンジを繰り返す 場合があります。したがっていかに短時間に実験パーテーションを復元でき るかが重要なポイントです。環境の再インストールとアップデートに半日が 必要なのであれば躊躇する試みも、数分で復元可能であれば試してみようと いう気になるからです。コンピューターについて何か他人が知りえない情報 を得たいと考えた場合の最強兵器は、当該HD以外からブート可能なバックア ップアプリケーションかも知れません。
あとWIN32的には表示していないHWNDのDCを画像として保存することは無理 だと思うのですが、MSHTMLのレンダリングエンジンとOLE手法によってあら ゆるHTMLは表示することなく画像ファイルとして保存可能であることがわか りました。これを利用して、自前のリッチなフォントを使ったHTMLイメージ を瞬時に単一画像HTMLに変換し、ハイパーリンク座標を当該画像に対するク リッカブルマップ情報として付加することで一見普通のHTMLページなんだけ ど実は単一画像という状態を作ることに成功しています。またこのテクニッ クはロボットがWEBを自動巡航して各ページのスナップショットを収集する目 的にも活用できるだろうと考えています。
IIS、SQL、ASP、ISAPI、そしてCOM。本番に向けてサーバーの最終調整を行 っていますが、C++ソース一本で解決するスタンドアロンアプリケーション とは違い、多岐にわたる原因とその解決手法を考えなければならない事に 若干閉口してしまいます。考え方としては、できるだけCOMに機能を集約し、 他環境から随時呼び出すことで、動作管理の一元化を目指すのですが、それ でも個々の設定をその理由も含めてきちんとドキュメント化しないと後日 ひどい目にあいそうです。
なかなか興味深いニュースを目にしました。 オウケイウェイヴ(OKWave)は2012年3月30日、個人の持つ知識やスキルを登 録して個人間で売買できるサイト「Abilie(アビリエ)」を正式公開した。 問題点は何らかのノウハウが拡散するわけですから、購入者がそのノウハウ をさらにや安い価格で商品化できてしまう部分でしょうが、アプリケーショ ンという硬い存在ではなく、スキルという柔らかい状態の情報を販売しよう いう発想はあってしかるべきだと感じました。単に広報媒体として利用する 目的でも有効だろうと思います。
情報を発信しても利益が生まれないということは、情報自体が枯渇すること になります。例えばMSDNの重要な部分は「日本語化」されていません。あれ だけの情報を日本語化して、誤植やバグがないかを検証するには莫大なコス トがかかることでしょう。それを実施して費用を回収できるか?というシュ ミレートをして否だから「日本語化」されていないわけです。
IISとFrontPageサイトの自動操作に管理スクリプトを書いているのですが、 その環境に今日は悩みました。従来は.NET1.1のJSC.EXEのデバッグコンパイル で実験しながらWSHで実行するのですが、WSS3.0の関係で.NETが結果的に3.5 まで上昇してしまうとなぜかストールしやすくなり使えません。HTAは.NETと 無関係ですからいつもどおり動きますが、MSE7上でブレークポイントを設置 できないという欠点があります。結論は自作COMでGetObjectを可能にしたHTM ファイルが最強ということなのですが、その結論を得るのにほぼ一日費やして しまいました。
管理スクリプトを書き終えました。新たなサーバーではドキュメントをWORDで 管理します。書きあがったDOCを仮想プリンターで印刷すると、等倍なPNGファ イルが生成され、クリッカブルマップ処理したHTMLが生成されます。生成され たHTML群はその見出し階層からFrontPageサイトへ自動展開されます。したがっ て、ページサイズはWORDのページ設定の大きさに必ず固定され、自由にフォント や段組レイアウトを使うことができます。すべては画像化されていますので、 異種ブラウザ間の差異を一切に気にする必要はありません。ポストスクリプト インタープリターだけ他人様が書いたモジュールですから製品化するためには その問題をどう解決するかが課題ですが、手前味噌ながら、この仮想プリンタ ーは静的HTMLの書き方を根底から変革する可能性を秘めていると思います。
サーバー切り替えに伴い、実働機から必要なファイルをコピーする作業を行 いました。一年半ほどの稼動でしたが、その間にもいくつかのソフトウェア 的変更がありましたので、ちょっとした考古学状態になりました。当時はい やというほど心に焼き付いている変更動機もすっかり忘れ去っていることに 今更ながら驚きます。また、たいした広報活動もしていないので当然ですが、 一番頻繁に利用されているQuickでさえ日に数件程度しか格納動作が行われ ていませんでした。日本だけならそんなにへこみませんが、かりそめにも 世界ですから、かなりへこみます。
この冬に徹底的に基礎部分を研究しましたので、どんなにストレスのかかった 環境でも安定動作するHTMLアプリケーションベースをお見せできるという喜び と、どうせどんなに優れたものを提供したって、無駄だろうという絶望感が せめぎ合うのです。ただ、はっきりしていることは 「諦めたら、私を支えてくださった方々を裏切ることになる」 ということです。私の夢を聞いてくださった方々に、その夢のひとかけらでも 実現するさまを見ていただくことが、私という人間の存在理由だと心に刻むのです。
救急医療情報処理等の既存サービスを乗せるプラットホームとしてまだ3.00 が成熟していない関係上、幻となっていた2.50を昨日、今日と見直していま した。3.00の開発過程で得たスレッド進入テクニックで一切HWNDを検索する ことなく既存HTMLインスタンスをコントロール可能としました。また、GUI 系追加ディスパッチをHWND側コンテキストとすることで、ブロック問題を解 決しました。2.x系のチャームポイントはHTML生成前にWSHでその準備ができ ることです。私の説明不足が原因でこれは複雑なものと受け取られているか も知れませんが、バグがHTML側なのか、提供ディスパッチ側なのかの特定、 また、両者のタイミングを調整する必要が生じた場合などに、明確な表現が できるメリットを強く感じました。
3.00では通常、WebBrowserのように重いコンポーネントでしか実現しにくかっ た細かな動作の制御を軽量な既成コンポーネントであるHTAやHTMLダイアログ に適用することができます。例えばセキュリティーゾーンやスクリプト実行の 可否、スクロールの可否やテーマ認識の可否等、多岐に渡るカスタマイズが 可能となります。これらはHTML表示前に設定される必要があるわけで、そうい った意味でも、JSから関数呼び出しでHTMLウインドウを生成する機能は3.00 でも有効とする予定です。ただし、目的が上記のように生成オプションコン トロールですから、2.x系のようにレジストリ登録してデバッグ可能とはしな い予定です。3.00はあくまでHTMLとして通常にデバッグでき、隠蔽部分に 原因がある場合は、エディタ上で即座にデコードし、デバッグを再実行する というコンセプトにしたいと考えています。
毎度の事ながら予定が10日も遅れてしまいました。「成功する人はたった一つ のことしかしない」という格言を知ってはいるのですが、ことHTMLがらみの アプリケーション開発環境となると、ひとつの課題に対して非常に多くのアプ ローチが存在し、得意な分野だけで推し進めると、他のアプローチなら単純な ことに気づかない可能性があるものですから、つい可能な限りの実験を行って しまいます。でも、これで2.x系の落としどころは決定しました。マニフェスト による自己参照形式も導入してみたのですが、自身がEXEのアウトプロセスサー バーである関係上、安定させるには設計の見直しが必要なようです。2.xを改良 して3.00もどきを作っても意味がないので、windows2000でも動作可という存在 として位置づけようと思います。とりあえず2.5規格でサーバー側を整備し徐々 に3.00へ移行する予定です。
C/C++でなければ書きにくい分野というのは、他の言語に比べマシンに近い 階層での動作な訳です。また、そのマシンに近い階層と高級な言語との橋渡 しとしてCOMサーバーを作成したりするわけですが、ケースによっては非常に デバッグしにくいものとなります。例えばブレークポイントを置くことさえ 許されないような状況です。そういった状況を経験すると、どんなに複雑で も、F9で赤くした行にブレークしてくれるだけで半分もらったような気にな ります。
そこで痛感するのですが、何かを実現するために、まず開発補助のツールを 書かなければならないような奥まった分野でのコードや情報というものが 実に少ないということです。勿論「職業」として領域になりますから飯の種 をそう易々とは見せられないという事なんでしょが、実行サンプルが陳列 されていて、実行結果を確認した後にそのソースコードを有料で購入できる システムを作れないかなぁーっと思ったりします。
これまでの経緯を自分の頭を整理する意味も込めて書くことにします。 HTMLアプリケーションのアプリケーション作成効率は、素晴らしい可能性を秘めている。これを利用すれば、 個人がソフトハウスと伍して戦える強力な武器となる。結果的に個々のアプリケーションの価格を押し下げ るだろうし、従来は出来合いのアプリケーションを操作する側でしかなかった人間も、自らの経験と知識を アプリケーション化して発表可能となる。ここでのキーワードは「集団」から「個」への移行である。 または、多くの機能を満載した汎用性から、特定の目的に特化されたコンパクトさへの移行でもある。
HTABOXコアの出発点は自プロセスで実行するHTMLのスクリプトインスタンスにオリジナルなディスパッチを挿 入することにより、レジストリ登録無しにHTML機能を拡張しようとする試みである。例えば、ネイティブな WIN32形式メニューを単純なテーブル定義で生成可能とした。HTMLアプリケーション手法の弱点はソースコード が暴露されることだと考える。どんなに心血を注いだコードでも、厳密な意味で「それは私が書きました」 と主張できる要素は存在しない。従って、公開するということは実質的に知的財産を放棄するに等しい。
HTABOXコアは独自ににスクリプトエンジンを持っている。もしスクリプトコードを事前に取得できればHTML生 成時にHTMLとスクリプトを分離した管理ができる。これによりスクリプトソースをHTML空間から隠蔽すること が可能である。ただし、初期1.x系では、非隠蔽実行と隠蔽実行との環境差が存在し、万が一隠蔽実行中にエラ ーが発生すると、当然の事ながらデバッガはソースを追跡できず、実際の開発に使用できない問題が存在した。
2.x系の最大の課題は隠蔽とデバッグという相反する要素の折り合いをつける事だった。発想として非隠蔽と 隠蔽間の環境差をできるだけ小さくすること。これを実現するためには、別プロセスでのHTML実行を内部実行 に近づける必要があるため、HTABOXコアはアウトプロセスサーバーとしてディスパッチを提供する機能を持つ ことになった。また、HTMLをWSHから生成可能とすることで問題の切り分けを容易にした。結果的にWSHを起点 とすることにより、フレームの一部がサーバー上に存在する場合の混乱を完全にコントロールできる副産物を 得ることになった。
2.x系でその拡張手法を模索した。例えばネイティブなコモンコントロールを追加する場合に採るべき手法 といった部類のことである。また、そうしたストレスのかかる状態にしたばあい、HTMLの生成そのものがストー ルする可能性を持つことも問題であった。2.x系の技術的基盤はHWNDのWIN32操作であるため、EnumWindow系の 使用を避けては通れない。また、アウトプロセスサーバーである関係上ディスパッチの生成コンテキストと 実行コンテキストの管理に難しさが付きまとう。この問題は、根本的に解決されるべきであるし、根本が変更 される予定であればその拡張手法について模索することは意味がない状態となった。
3.00の基盤となる技術を確立するのに1年を要した。結果的に3.00は総てのHTMLインスタンスをOLE的に管理する。 また、独自のエディタ環境でエンコード、デコードを行い実行することにより、非隠蔽、隠蔽時の環境差は まったく存在しないに等しい状態となった。3.00は原点に回帰してレジストリへの非登録で総てを可能とする 設計がなされている。これにはマニフェストによる参照モジュール指定が必要であり、実行環境はXP以降となる。 今日まで数日間、2.50へ3.00で得たノウハウを適用する作業に追われていた。つまり、ある程度OLE的にし、こな れていない部分を書き直した。また、コモンコートロール等の拡張規格を3.00と同一にできることも確認した。
3.00はエディタや独自のヘルプ表示エンジンを持つ。フォントイメージをリソースとして保持することも可能 なので場合によっては数メガのサイズとなる場合もある。これはクローンEXEを生成する上でマイナスな要素と なる。したがって、クローンの原版となる「コア」と3.00自体を別ファイルとする可能性がある。欲をいうな れば、軽量でコンパクトである2.x系コアと3.x系コアが選択できる状態を実現したい。
HTABOXコア2.50のMSHTA.EXEフックデモを用意しました。
ttp://kuroda.bglb.jp/htabox/hookdemo.zip 添付HTABOXAPP.exeを起動してレジストリに登録後、demo.htaを単独起動する
と、ActiveXObject生成されたWIN32を通じてMSHTA.EXEインスタンスをフック
し、メニュー、ポップアップメニュー、ファイルドロップが有効なHTAとなり
ます。フックには相手に送りつけるDLLが必須ですので添付HtaHook.dllは必ず
HTABOXAPP.exeと同一位置になければならないことに注意してください。
2.50ではHTABOXの引数として実行するHTAでも自動的なWIN32の追加は行わず、
ActiveXObjectでの取得とします。つまり拡張機能を使用した開発にレジスト
リ登録は必須となります。ただし、Quick等でEXE形式にした場合はマニフェスト
による自己参照で、登録無しにActiveXObjectが成功するルールとしました。
ですから開発はwindows2000環境でもできますが、配布対象は2.xバージョンでも
XP以降となることをご了承ください。
この2.50でのQuickはマニフェストで自身のパスをCOMサーバーとして定義し ますが、美しく埋め込みマニフェストとした場合、マニフェストという存在 の性格上、単純に上書きしての変更は不可能と認識しています。したがって、 ファイルコピー後にバイナリデータとしてマニフェスト記述位置を認識し、 既存データ長を一切変更しないで内容だけを置き換える操作が必要になるよ うです。当然、クローン先で長い名前が使われる可能性があるわけですから 原版となるコアではマニフェストが破綻しない位置にスペーサーとしてコメ ントを準備し、それに備える必要があるという点がややテクニカルでした。
2.50には3.00開発で得たテクニックを適用していますから、documentはきれ いに取れているがwindow取得を拒否されるとか、document.readyStateの連続 参照でエラーが発生するというような、予測不能で稀に発生する可能性のある 課題を根源的に排除しています。すべてはHTMLインスタンスの側に立ってスレ ッドの設計や管理ができるかにかかっています。もしコンテキスト的に隔絶 されたインスタンスでの通信が必要な場合はPost系のメッセージをトリガと して相互の連携を模索するといった発想が無いと、たった一つの無理強いで 全体を破綻に追いやりかねません。この部分がCOMプログラミングの難しさで あり、醍醐味でもあると感じています。
MSHTMLについて言えることは、IE5.5時点での技術的拡張が基盤となっていて、 その頃はまだ、Microsoft社にも自分たちがコンピューターの未来を切り開く という自負があり、C++インターフェースを使った解説が存在しました。でも その後、多くのエネルギーを.NET方向に費やした結果そういった基底の情報が MSDNから割愛されているように感じます。つまりやや古い情報を持っている人 間だけが自在にMSHTMLを操れるということです。
「どんな天才でも月の石を持ってくる事は出来ない」という言葉が印象的で す。つまり月へ行くロケットという乗り物が存在しない限り才能や閃きでは 実現できない事があるわけです。私がこの数年研究してきた分野へ当てはめ るなら、「COMによる分析や操作無しにMSHTMLをカスタマイズすることはで きない」ということになるでしょうか。私自身旧HTABOXに着手した頃はスク リプトと名前付きパイプ程度で総ては実現できるのではないかという幻想を 抱いていたわけですが、やはりロケットは必要だったという結論です。
HTABOXコア2.50をベースにしたEXE生成ツールHTABOX Quick2.50を公開します。
ttp://kuroda.bglb.jp/htabox/quick.zip HTABOX Quick2.50はvar WIN32 = new ActiveXObject("HTABOX.Application");
を自身のDllGetClassObject呼び出しにすり替えます。したがって格納前と
格納後での環境差を吸収する目的の#defineを使用する必要がありません。
また、ソースコード隠蔽時はHTMLの文字コードを認識する必要があり、従来
はANSI限定でしたが、自動判定機能を追加しました。デモ用HTMLはshift-jisと
utf-8の2種類が存在します。尚ヘルプ等は未だバージョンアップに伴う変更
を反映していないことをご了承ください。
レジストリ登録&フックだと単に拡張子htaやhtmをクリックするだけで拡張 機能が有効となりますから、なかなか快適です。EXE化後はマニフェストで 自家発電というロジックもとくに不安な要素もなく機能しているようです。 しいて難点を挙げればEXE化後だと「管理権限実行」が必要になることですが、 まぁそれは小さな代償だろうと思っています。この成功によって新たな柱と して追加される予定のTZB(複数HTAの集約実行環境)の基本設計がおのずと 決まりました。頭の悪い私でも同じ分野の事を実験し続けていると、頭の中 で複数の手法の組み合わせパターンをシュミレートし、メリットとデメリット をある程度予測できるようになったようです。
TZBは開発用のベースEXEで必要なHTMLを複数表示している状態を単一EXE化し 配布EXEとできる構想を持っています。タブに表示されるHTMLウインドウは最 軽量コンポーネントであるドキュメントの直接インプレースアクティベートに なるでしょう。また、HTABOX2.x、3.x、そしてTZBは同じ規格のDLLを配置する ことにより、ツールバーやツリービューを追加できる方式となるでしょう。
何か2.50系だと↓こんな事言われます --------------------------- エラー --------------------------- DateTime = 2012/04/12 2:41:41 File = .\main.cpp Line = 759 Description = InvokeEx : userAgent Error = この操作を完了するのに十分な記憶域がありません。 --------------------------- OK ---------------------------
>>434 貴重な情報をありがとうございます。早急に原因を調査しますが、OS等の
環境を教えていただけると、より迅速に解決できると思います。ご面倒お
かけしますが、よろしくお願いします。
>>435 OSはXPSP3ですがXPが入った他のPCだと出なかったりして再現条件はいまひとつ不明です
最後の2,3日はwindows2003上で動作させながらの公開となりましたが、改めて XP上でQuickを動かしてみるとまた別の意味のエラーが表示されました。 userAgentはメニューを生成する相手が自身EXEかMSHTAかを認識するために 行っている判断ですが、HookDemoをXPで動作させた場合は再現できません でした。この場合のIEは7です。
こちらのフックデモだとエラーが出ないことを確認しました HTABOX Quick2.50も対応していただけると有難いです demo-sjis.exeの場合 --------------------------- エラー --------------------------- DateTime = 2012/04/13 2:00:31 File = .\main.cpp Line = 753 Description = InvokeEx : userAgent Error = この操作を完了するのに十分な記憶域がありません。 --------------------------- OK ---------------------------
メニュー形成について改めて検証してみると、当然documentに問い合わせて MUNUやPOPUといったIDのエレメントを探しますので、window.onload以降の 呼び出しでなければ機能しないようです。自作HTAの場合も var WIN32 = new ActiveXObject("HTABOX.Application"); function window.onload(){WIN32.BuildMenu(document);} という配慮は必須になります。
demo-utf8.exeの場合 --------------------------- エラー --------------------------- DateTime = 2012/04/13 2:00:31 File = .\main.cpp Line = 746 Description = GetDispID : readyState Error = アクセスが拒否されました。 --------------------------- OK ---------------------------
demo-utf8.exeの場合(続き) --------------------------- エラー --------------------------- DateTime = 2012/04/13 2:00:31 File = .\main.cpp Line = 753 Description = InvokeEx : readyState Error = アクセスが拒否されました。 --------------------------- OK --------------------------- --------------------------- エラー --------------------------- DateTime = 2012/04/13 2:00:31 File = .\main.cpp Line = 753 Description = InvokeEx : userAgent Error = この操作を完了するのに十分な記憶域がありません。 --------------------------- OK ---------------------------
demo-utf8.exeについては同様のエラーをXP上で確認しました。 とりあえずuserAgentを使わないコアによるzipに総て差し替えました。 demo-utf8.exeの生成後、実行時のエラーについてこれから対応します。
迅速な対応有難うございます。 userAgent絡みのエラーが出ないことをdemo-sjis.exeとdemo-utf8.exeで確認しました。
readyStateは鬼門なので、少々コストが高くてもIConnectionPointを採用 していたのですが、IConnectionPointが必要かを判断する時にreadyStateを 問い合わせるという単純ミスをしていました。これは何か別の方法を見出す 必要がありますので、何分というオーダーでは解決できないと思います。 3.00ではHTAを生成初期から掌握して必ずcompleteが発生するのですが、2.50 ではあくまで既成品のHTAインスタンスを横取りすることから、避けて通れな い問題なのです。
readyState対策済みのQuickを用意しました。
ttp://kuroda.bglb.jp/htabox/quick.zip HTABOXコア自体は、まったく生成状態に依存せず、HTML側コンテキストなりに
自然な動作を行う設計なのですが、Quickで一時生成ファイルを削除するタイ
ミングのためにこの操作が必要でした。一時生成ファイル消去な状態で意地悪
く極めて大きな画像を表示させた場合消去の方が早くなる可能性も否定はでき
ませんが、ドキュメントHWNDのWM_PAINTをもって完了と認識する方式に変更し
ました。
サーバーを更新しましたら、2.50が持つ拡張関数についての詳細な説明を ご覧いただけるようにします。2.50は.NETをパースできます。ただし、3.00 では、自身のクローンインスタンスでランタイムを高速に初期化する技術を 適用しますが、2.50はシンプルさを重視して、そういった裏技なしにしようか と考えています。
Quickにドロップされたファイル中にicoが含まれていたらグループアイコン としてチェックできる拡張を予定していますが、バージョンリソースは検証 してみると、マニフェストと同様に単純にUpdateできないリソースだと認識 しています。したがって、書き換えを可能にするためには事前に十分な領域 を持ったダミーリソースを確保し、バイナリ置き換えを実施するしかありま せん。実はバージョン情報全体は非常に多くの情報を記録できる規格なもの ですから、取捨選択の難しさから先送りにしています。そこで単にEXEを右 クリックした場合のプロパティー表示に限定するならば、一定長文字列以下 という規則を作って対応できるかも知れません。
それからQuickが存在することで、誤解を招く恐れがありますから改めて書き ますが、2.50も本来のEXE生成はQuick.exeやMaze.exeがそうであるように一時 ファイルを必要としない形式です。最も手っ取り早い選択肢としてはQuickの EXE生成オプションにres://として実行を追加できればいいのですが、2.50の スクリプト隠蔽方式を3.00で採用する「格納時エンコード」に変更する必要が あるので、迷ってしまいます。完全な製品としてのEXE生成は3.00で...という 展開もありかも知れません。
今日はTabular Data Control機能を2.50に組み込みます。このActiveXはDLL の形で提供し、開発環境中ではレジストリ登録されたコアEXEの傍らに置かれ、 配布EXEな場合は当該EXEの傍らに置くだけでレジストリへ登録されているか のように利用できます。実際にregsvr32で登録できる機能を追加するかどうか については悩むのですが、GUIDというシステムがどうも好きになれません。 数字に肌触りを感じてしまう体質なものですから、ランダムに生成された数 の羅列を突き付けられると、拒絶反応を起こします。かといって自分が好きな 数字を列記しては既存のGUIDと衝突する可能性が生まれるからです。
「そうします」と書いて自分を追い込んでから、実際には考え始めるのが常 なのですが、やっと構想がまとまりました。外部HTA実行時にはきちんと GUIDがレジストリ登録されていないとやはり手がでません。ただし、レジス トリにはDLLのパスではなく、EXE側のパスを登録し、EXEのDllGetClassObject へ自身以外のCLSID要求を検出した場合、隣接DLLのDllGetClassObjectを間接 的に呼び出すという方式が最も柔軟だと考えます。
また、レジストリ登録されているEXEは、常にクローンが要求に備えて登録 済みDLLに対応するGUID定義をコメントアウトしたマニフェストに保存する 必要があります。つまり「レジストリ登録」ボタンが押された時に実行中の 自身EXEファイルを書き換えるわけです。現実には実行中の自身を書き換え るのは不可能ですから、チェインして自身の一時クローンに作業を依頼し 終了後に呼び出してもらう形になります。かなり面倒なコーディングになり ますが、できるだけ早くお見せできるように努力してみます。
当初はプロセス実体であるEXEが全DLLを中継する形式でなければならないと 仮定したのですが、実際に試してみると単にDLLを指し示す(説明する)だ けで機能するようです。コア本体でレジストリ登録をおこなうと隣接DLLを 列挙して通常にレジストリ登録し、登録時に取得したタイプライブラリ情 報をコメントアウトした形式のマニフェストへ記録します。この本体がク ローン要求によりコピーされる時、コピー先EXE名への小変更が行われた後 にコメント記号が削除されます。結果的にコピー先EXEにDLLを添付すれば、 まったくレジストリに触らないクリーンなCOM生成環境となります。
当初、全DLL中継をやろうとした最大の要因は、万が一DLLを添付し忘れた場合 「アプリケーションの構成が...」という不親切なエラーダイアログがでるこ とを回避することだったのですが、windows2003では前述のとおりであるもの XPのsp3では実際にDLLへの呼び出しが発生するまでエラーは発生しないという 事が判明しました。つまりEXEの起動すら許されない事態ではなく親切な説明 を表示する余地があるということです。vista以降ではまだ動作させていませ んがXPと同様な改善がなされているものと推測されます。その全前提に基づ いて、前述のような機序により非登録実行を実現しました。現状ではQuick で生成されたEXEが展開するHTML中なら非登録の<OBJECT>が利用できること を確認できるでしょう。デモでお見せする<OBJECT>はXMLとCSVを高速に テーブル表示し、ソートも可能なデータバインディングオブジェクトにな ります。
以前からActiveXObject生成と<OBJECT>タグ生成の違いは何なのだろうと疑問 だったのですが、両者が宣言された場合の内部動作を解析するとActiveXObject はあくまでもオートメーション(ディスパッチ系)であり、<OBJECT>タグは 生のインターフェース型を扱えるという違いがあるようです。データバイン ディングはディスパッチではなく専用のインターフェースを通じて提供され ますから従来のTDCの場合も<OBJECT>タグでなければならかったというのが 真相だと思います。
データバインドデモが一応動きましたので公開します。
http://kuroda.bglb.jp/htabox/databind.zip 今回はHTABOXAPP.exeとDBIND.dllによるレジストリ登録後の実行と
Quick格納後exeとDBIND.dllによる非登録実行を検証するためちょっと
ファイル数が多くなっています。添付TEXTに説明がありますのでご覧ください。
通常データバインドはすでにファイルとなっているデータを対象としますが、
XMLも扱えるこのオブジェクトの場合、動的に生成されたデータも極めて
短いコードで処理することができます。是非サンプルHTAのソースもご覧ください。
尚、データバインド機能を提供するDBIND.dllにはregsvr32に応答するコード は搭載していません。単体での使用ではなくHTABOX系プラグインとして使用 する事を想定しています。本家TDCがキルビットされていますので単体での ご要望もあるかと存じますが、その場合個々にご相談の上提供させていただく ことにしたいと思います。
もうとっくに時間切れな状況なのですが、それでも物を作る側に立つと自分が 納得できないものを人様にお勧めするわけにはゆきませんので、2週間遅れて しまいました。今回のマニフェスト規格についても十分な時間をかけて多方面 から検証したいところではあるのですが、走り出しながらの修正になりそうで す。せめてもう2年早く、ここに到達していたらと悔やまれてしかたありません。
DataBind.exeがDBIND.dllなしだと接続を要求するのが薄気味悪いのですが
「接続の要求」はまったく身に覚えがないのですが、マニフェスト参照先が 実在しない場合、OSがネット経由でもそれを探しに行くサービスがあるんで しょうか?環境を教えていただけると、当方でもその現象を再現できるかと 思います。
当該DLLが実在しなかった場合、当方の2003、XPでは単にスクリプトのエラー で停止します。デバッガが有効ですから「デバッグを実行しますか?」とい うダイアログが表示される状態になります。当初は参照先が無いとシステムに きつく怒られて起動できないと思っていたのですが、無くても起動できてしま う事に驚きましたが、今度は逆に無い場合自前で警告を発しなければならない という示唆かも知れません。必要なDLLがなければどこかの局面ではエラーな 訳ですから、起動に自身マニフェストを取得し、参照先DLLが実在することを 確認する動作を追加したいと思います。
今回のデモは<OBJECT>を使いますので、環境によってはたとえば「フラッシュ」 の実行でオブジェクトが動作できなかった場合のように、自動的に探しにゆく 動作をIEのバージョンが上になると行うというのは、ありそうなストーリー だと思います。いずれにせよDLL実在確認は必須な動作ですので直ぐに追加します。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。HTABOXAPP.exeまたはそれを原版とした全てのexeは起動初期
に自身が参照すべきファイルを列挙し、その実在を確認する動作を追加しまし
た。HTABOXAPP.exeでレジストリ登録、DLLも登録を行った後、DLLを隠して再
起動すると動作を確認できます。まったく動かないと、その先にある特定の動
作だけが欲しい場合に厳しすぎる対応となりますので、デフォルトは停止で、
強行するオプションも選択可能としました。大変貴重な情報をありがとうござ
いました。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。登録削除時にDLLを列挙してDLL情報を取得するというミス
がありましたので、マニフェストを見て登録と認識しているDLLのレジストリ
登録が実際になされていれば、当該DLLが実在しなくてもレジストリとマニフ
ェストから削除という動作にしました。DLLの登録は各DLLで確認をとりながら
、登録削除は一斉に行い、必要なDLLは再度登録してもらうという流れです。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。デモ用HTAをUTF-16からUTF-8に変更しました。どうして
隠蔽モードだとHTMLが空になるのかで半日悩みましたが、単に私がサポート
していないという落ちでした。ちなみに3.00はHTMLをバイナリとして扱いま
すから、この手の問題とは無関係なのですが、2.50の隠蔽ではストリーム中
の\0で解釈を停止する仕様となっています。
やはりdllなしで強行するとorigin-codecs.microsoft.comに接続しようとしますね それはそうとこれでVB6ランタイムやMS officeに含まれているMscomctl.ocxを登録できれば リストビューとかのコントロールが使えるんでしょうか
HTABOXAPP.exeは現在の仕様だと拡張子DLLを発見した場合そのタイプライブ ラリを解析して、全COCLASSとその直下インターフェースをマニフェストに 定義しますから、他人様が書いたものでも同様なことを可能にはできます。 ただし、呼び出し側が可変する場合はあくまで通常にレジストリ登録した 方が使いやすいでしょうし、HTABOXで生成されたEXEに添付する場合は当該 DLL等のライセンスという課題をクリアしなければならないと考えます。
まだ、本格的にマニフェストを操作して日がたたないものですから、どんな 拡張の可能性があるのか未知数なのですが、いろいろなアイディアをいただ ければ、可能な限り盛り込んでゆきたいと考えております。誰かが欲しいと 感じる機能は必ずもっとたくさんの誰かが必要としている機能なんだと思い ますし、そういったことの積み重ねでしか愛されるものは生まれないと思って います。
下記URLは当環境におけるC:\WINDOWS\system32\MSCOMCTL.OCXの解析結果です。
ttp://kuroda.bglb.jp/htabox/MSComctlLib.txt これを見る限りは外部依存も無いようですので、単体の取り込みでプライベー
トな利用が可能だと考えられます。それでは、ものはついでですからOCXも
存在すれば取り込めるような拡張を今後したいと思います。今回はボツになっ
たのですが、全DLLへの要求を単一EXEに集約してそこから再配分するという
技術も確立しています。たとえばHTMLからの要求を一旦受けて、DLLが存在
しそうな場所を検索してインスタンスを返すという手法です。埋め込みマニ
フェストにしてもレジストリにしても、動的な使い方には不向きな規格です
から、そういった部分を埋める提案ができればと考えています。
今までリソース格納系の関数は解説しなかったのですが、原版の状態でDLL情報 を取り込み、そのクローンを生成して、マニフェストのコメントを外しプライベ ート環境で実行するWSHの例を示します。最新のHTABOXAPP.exeで動作確認済みです。 var WIN32 = new ActiveXObject("HTABOX.Application"); var FSO = new ActiveXObject("Scripting.FileSystemObject"); var OwnPath = WIN32.OwnPath; //登録されているHTABOXAPP.EXEのパスを取得 var DestPath = "c:\\hoge.exe"; //クローン先パスを決定し変数格納 var ScriptPath = "c:\\start.js"; //クローン先が引数無しで起動した場合のJS FSO.CopyFile(OwnPath, DestPath, true);//クローンの生成 WIN32.DispResource.SetManifest(DestPath, FSO.GetFileName(DestPath));//マニフェストコメントの削除と基準EXE名の変更 WIN32.DispResource.SetResourceFromFile(DestPath, "SYSJS", "", ScriptPath, "");//クローン先の起動JS格納 WIN32.MsgBox("END"); //上記スクリプトで生成されたc:\\hoge.exeは原版HTABOXAPPが取り込んでいたDLLを非登録な状態でnew ActiveXObjectできる //start.jsの例 DBAIND.dll情報格納済みで、生成hoge.exeの脇にDBAIND.dllが存在すれば下記スクリプトは成功する /* var DBind = new ActiveXObject("HTABOXCOM.CDataBind"); DBind.About(); */
今度は起動JSからHTAを生成し非登録COMを使うサンプルです。用意すべきファイ ルから先に説明した方が解りやすいですよね。 //start.jsの例 var WIN32 = new ActiveXObject("HTABOX.Application"); var HTA = WIN32.CreateHtaWindow("res://" + WIN32.GetScriptPath() + "/HTM/START.HTM"); WIN32.WiteForWindow(HTA.FraHwnd); //start.htmの例 <html> <head> <title>START HTM</title> </style> </head> <body> <input type="button" value="test" onclick="test()"> <script language="jscript"> function test() { var DBind = new ActiveXObject("HTABOXCOM.CDataBind"); DBind.About(); } </script> </body> </html>
生成スクリプトは前の例にHTMLファイルのリソース追加が加わっただけです。 var WIN32 = new ActiveXObject("HTABOX.Application"); var FSO = new ActiveXObject("Scripting.FileSystemObject"); var OwnPath = WIN32.OwnPath; //登録されているHTABOXAPP.EXEのパスを取得 var DestPath = "c:\\hoge.exe"; //クローン先パスを決定 var ScriptPath = "c:\\start.js"; //クローン先が引数無しで起動した場合のJSを用意 var HtmlPath = "c:\\start.htm"; //start.jsが呼ぶHTMLを用意 FSO.CopyFile(OwnPath, DestPath, true);//クローンの生成 WIN32.DispResource.SetManifest(DestPath, FSO.GetFileName(DestPath));//マニフェストコメントの削除と基準EXE名の変更 WIN32.DispResource.SetResourceFromFile(DestPath, "SYSJS", "", ScriptPath, "");//クローン先の起動JS格納 WIN32.DispResource.SetResourceFromFile(DestPath, "HTM", "START.HTM", HtmlPath, "");//起動JSから表示されるHTML WIN32.MsgBox("END"); HTMLを格納する時リソースタイプをHTMLとしたくなりますが、これはRT_HTML として予約されており、unicodeでバイトアライメントを考慮したHTML専用で あることに注意してください。ここではそれを避けた3文字のHTMとしてユーザ ー定義型リソースとしています。
2つめの例で起動JSがHTAを生成するURLはEXE内部ですからres://ですが、 この一行を //var HTA = WIN32.CreateHtaWindow("res://" + WIN32.GetScriptPath() + "/HTM/START.HTM"); var HTA = WIN32.CreateHtaWindow("c:\\START.HTM"); としただけで、EXE格納しない当該JSの実行結果も同じものになります。つま り「普通にデバッグできて、そのままEXEへ放りこめる」と「放りこんだら使用 COMは登録せずに利用可能」を実現するための工夫ということを理解していただ けると思います。
3.00ではこういった一連の処理をウイザードで行う予定です。ここをご覧に なっている方々はHTABOXがどう推移してきたかをご存じですから、スクリプ トでの格納をなるほどと思うかも知れませんが、一般の方にとっては「面倒」 以外の何物でもないでしょう。でも私はこの2.50方式が大変気に入っています。 この威力を理解していただける方の為にも2.x規格を継続して成長させてゆこう と考えています。
472:「全DLLへの要求を単一EXEに集約」によって実は画期的なことが実現でき ます。サーバー、クライアント間のCOM共有がDCOMですが、セキュリティー という観点からは大穴を開けることになりますから、それを回避しながら実 現するために大変面倒な手続きが必要になります。しかし、サーバーのCOM を利用したい。同期する必要は無いからDLLだけ使いたい。たとえば既存の MSCOMCTL.OCXようなバイナリをHTTP経由で暗号化送受信し、動的に実体化さ せ提供するということが可能です。この場合実ファイルを一時生成さえせず、 メモリ中にマッピングさせることさえ可能なのではないかと推察されます。
この発想を発展させると、EXEはマニフェスト管理と通信のプラットホームに 過ぎず、実体はサーバー上のDLL群であるというアプリケーションスタイルに なります。通常クラウドシステムと言うとブラウザ経由でサーバーの演算結果 を返すという、きわめて強力なサーバーが無ければ実現できないものを指しま すが、クライアントのパワーを最大限に利用しながら、あくまでもサーバーが 統括権限を失わないシステムが構築できると感じています。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。HTABOXAPP.exeのレジストリ登録動作中に自身のマニフェスト
を書き換える際に、COMサーバーとして利用中(誰かが握っている)場合書き込
みを断念していますが、その表示を行っていなかったので追加しました。2つ
同時に起動させ、レジストリ登録を行いDLL列挙すれば動作を確認できます。
また、WIN32.WaitForWindowにスペルを修正しました。
単なるスペルの修正ですが、コピーしてすぐ動作可能なように474:475の 内容を再掲します。 //start.jsの例 var WIN32 = new ActiveXObject("HTABOX.Application"); var HTA = WIN32.CreateHtaWindow("res://" + WIN32.GetScriptPath() + "/HTM/START.HTM"); WIN32.WaitForWindow(HTA.FraHwnd); //start.htmの例 <html> <head> <title>START HTM</title> </style> </head> <body> <input type="button" value="test" onclick="test()"> <script language="jscript"> function test() { var DBind = new ActiveXObject("HTABOXCOM.CDataBind"); DBind.About(); } </script> </body> </html>
//c:\hoge.exeを生成し、用意されたc:\start.jsとc:\start.htmを格納するWSHスクリプト var WIN32 = new ActiveXObject("HTABOX.Application"); var FSO = new ActiveXObject("Scripting.FileSystemObject"); var OwnPath = WIN32.OwnPath; //登録されているHTABOXAPP.EXEのパスを取得 var DestPath = "c:\\hoge.exe"; //クローン先パスを決定 var ScriptPath = "c:\\start.js"; //クローン先が引数無しで起動した場合のJSを用意 var HtmlPath = "c:\\start.htm"; //start.jsが呼ぶHTMLを用意 FSO.CopyFile(OwnPath, DestPath, true);//クローンの生成 WIN32.DispResource.SetManifest(DestPath, FSO.GetFileName(DestPath));//マニフェストコメントの削除と基準EXE名の変更 WIN32.DispResource.SetResourceFromFile(DestPath, "SYSJS", "", ScriptPath, "");//クローン先の起動JS格納 WIN32.DispResource.SetResourceFromFile(DestPath, "HTM", "START.HTM", HtmlPath, "");//起動JSから表示されるHTML WIN32.MsgBox("END");
データバインドオブジェクトのCSV解析部分を書いています。本家のように 項目デリミタと行デリミタを指定可能です。現状の仕様では先頭行は項目名 として認識され、ソートが要求された場合はその先頭行内容を列挙し、一致 する項目名を発見した列を基準にソートを行います。ソートの引数には "text" 又は "number" を指定することで文字列評価か数値評価かを指定 できます。完成したらデータバインドデモでXML動作とCSV形式の両方を比較 できるようにしたいと思います。それからサンプルHTML中に削除し忘れた </style>タグが存在しますが、単なる消し忘れですから深く意味を考えな いでください。
改めてデータバインド手法を眺めると、速度ではなくテーブル生成のスムーズ さを優先させていることが解ります。データプロバイダ(提供側)をHTMLから のデータ要求に瞬時に全応答可能な状態としても、ボトルネックはテーブルの 描画速度ですから、最終的な構築速度は向上しません。数万セル程度存在した 場合は、ややじれったい事になります。データプロバイダが全TEBLEタグを生成 して返すことは可能ですが、今度はその描画が完了するまで無応答に見えてし まうことでしょう。
速度が高速でないとすればどんなメリットがあるのか?ですが、これは明確 です。XMLとXSLとJScriptでもある程度データバインド風なことはできますが、 90秒以上CPU稼働率が上昇し続けると「このスクリプトを停止しますか?」と いうダイアログが表示されるはずです。データバインドの場合、その心配は ありませんし、JScript手法よりは数段高速です。今回は軽量な埋め込み型 ActiveXの処女作としてデータバインドを選択しましたが、表示領域を持った ActiveXとして以前見ていただいたWIN32のリストコントロールを使った高速 データテーブルも予定しています。
ついでにこの90秒問題については3.00で画期的な解決策を提示します。HTML 中スクリプトの場合setTimeoutで呼び出し関数を予約し、グローバルスコー プから再突入することでスタックを開放できますが、ばかばかしいほど書き にくく、読みにくいコードとなります。また、WSHでは私の知る限りレジス トリを書き換えるコードを書かない限り、この問題への解決策は存在しませ ん。
90秒問題を解決するもうひとつの方法が存在します。それはモーダルダイアロ グでスレッドを一旦モーダルループとすることです。「スクリプトを停止」 というダイアログの後、また一定時間動作できるのは前述ダイアログがモーダ ルであるからに他なりません。ならば、非表示な空のモーダルダイアログを 用意し、長時間過酷な状況が予想される場合にループ中から呼ぶことで絶対に 90秒問題を発生させないことが可能です。このダイアログはWIN32のダイアロ グテンプレートによる0pxウインドウですから数ミリ秒程度の時間リソースし か消費しません。またこのダイアログには、現在のCPU稼働率を検出し、目的 稼働率を上回っている場合、それに応じた時間スレッドを待機させる自動機 能を持つ予定です。「スクリプトじゃアプリケーションは書けない」と考える 最大の要因がこの90秒問題だと認識していますので、3.00は完全にその問題 を解決した環境となります。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。XMLとCSVでデータバインドを行う事ができます。DBIND.dll
には新たにCSV処理関数が追加されましたので、従前のDLLを削除することを
お勧めします。新しい方は96kですが、古い方はちょっと小さいはずです。
テストしながら私自身が古い方へ呼び出しをかけて2回ほどがっかりしてしま
いました。特にQuickで生成した先のexeに隣り合っているDLLは要注意です。
データバインドDLL内部での処理は結局XMLで統一しています。当初一連データ 領域にCSV形式文字列を並べ、超高速アクセスを行っていたのですが、485:に 書いたように意味がありませんでしたので、ソート、XPath検索、要素の移動 や入れ替えといった事が容易に実現できるXMLとしています。CSV各項目文字列 は#cdata-sectionに格納されますから使っていけない文字はありませんが、 CDATAの終了記号である]]>という3文字が連続した場合の動作は未定義です。
データバインドオブジェクトにWidth、Heightを設定可能にして、テーブル 生成状況を表示するプログレスバーにしたいと思います。やはり大規模なデ ータになると、生成完了を待たずにソートしたくなったりしますから。必要 無ければサイズ0pxとすればいいわけですし。あと、本家TDCはResetでスムー ズに再構築されたと思ったのですが、私のやつはデータプロバイダを更新す ることで再構築を促しています。ここももっといい手がありそうです。この 2点について結論が出たら、しばらくは営業活動に専念することになると思 います。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。DBIND.dllは92kになりました。従前の各ファイルは混乱を
避けるために削除をお勧めします。プログレスバーのデモですから、ある程度
の大きさであるサンプルXMLファイルとCSVファイルを追加しました。デモHTA
の説明部分をそのまま転載します。
1.適当なファイルを選択する(親ディレクトリを基準にファイルを再帰列挙するので大規模な場合は注意)
2.MakeXML()又はMakeCSV()を実行する。途中経過は表示しないが、終了でalert('END')している。
3.SetXML()又はSetCSV()を実行する。データが表示され、項目名をクリックすればソートが実行される。
4.操作系のボタンは混乱を避けるために非表示となる。新たなデータを処理する場合は再起動すること。
※サンプルData.xmlとData.csvのいずれかをファイルを選択すればMake系関数は即座に完了する。
ただし、Data.xmlを指定してCSV動作、又はData.csvを指定してXML動作の結果は未定義なことに注意。
※プログレスバーの色はBarColor属性で変更可能。ただし、WIN32APIの悪しき風習でBGRなことに注意。
プログレスバーについては直接HTMLのDCへ描画していますので、テーマが適用 可能なコントロールではありません。そのかわり、色を自由に指定可能としま した。ソート時の再構築問題はちょっとだけ考えましたが、プログレス表示が 存在すれば、これはこれでいいんじゃないかという理由で手をつけていません。
この埋め込みActiveXは完全にスクラッチで書いています。私はなんとかテン プレートライブラリというものを一切使いません。理由は単純です。HTMLへの 埋め込みに限らずDLLの本番環境での変数確認というのはデバッガを使いにくい です。それでも何らかのシグナルが欲しい場合、Beep(1000, 100);のようなコー ドを埋め込みます。もし、QueryInterfaceでそれを行いたい時、ATLのような 出来合いのライブラリだと、「奥まったところに隠されてる若しくはマクロで 処理されている」という壁が存在してしまいます。STLにしてもATLにしても ソースをそのまま流用する権利を有する「参考ソース」だと捉えれば、C++ プログラミングはとっても見通しの良いものになります。
ttp://kuroda.bglb.jp/htabox/databind.zip を更新しました。今回は2.50の.NETパースエンジンを3.00互換仕様に変更しま
した。今まで気がつかなかったのですが、.NET3.5ではシステム系クラスが多く
生成されることから、生成クラスを後方から列挙し、インスタンス化が成功す
るクラスをHTMLスコープへ追加することとしました。ちょっと脈略が無いので
すが、データバインドデモにこの.NETパースエンジンデモも含まれます。
2.50のWIN32.DispResource.SetResourceFromFile関数、最終引数はEXE格納時 及び内部パース時のユーザー固有キーです。このキーが設定されたEXEの場合 起動側JS又はVBSが堅牢に隠蔽されるというルールにしたいと考えています。 「2.50は原則としてHTML中のスクリプトを隠蔽しない」とすると設計的にとて もすっきりするからです。QuickがHTML中のソースを隠蔽できるのはあくまで 一時ファイルを生成する途中に操作ができるからです。3.00ではNETも含めて 全てのスクリプトコードを堅牢に隠蔽できます。
従来EXEやDLLは一つのマスターからのコピーですから、クラックされ易かった と考えます。EXEやDLLが顧客固有のバイナリであれば、たとえクラックされて も、その発生源を追跡できるからです。最終的にWEB経由のフォーム入力結果 をトリガにしてC++コンパイラがオリジナルEXEやDLLを生成するというのが、 私の実現したい事のひとつです。2.50ではその技術についての検証も行う予定 です。
話はまったくプログラムとは関係無いのですが、最近思うことを書かせてく ださい。私たち人間のレベルでは観測することができない構造でこの宇宙は 構成されているのだと仮定します。これはかなり高い確率で当たりだと思い ます。もし、今より真実に近づける時がくれば、水平線の向こうが滝になっ ていると信じていた過去を笑うように、ビッグバンとか膨張宇宙を信じてい る現在を笑う時がくるかも知れません。
では、私たちをこの狭い視野と、多くの場合利己的な動機しか持てない存在 たらしめている要因は何でしょうか。それは「脳」なのではないかと思いま す。それが物理法則に支配された結果としてそうなのか、はたまた何らかの 意思でそうプログラミングされているのかは判りませんが、私たちはこの 狭い視野の中で試されている存在な気がしてなりません。そして、脳の呪縛 から解き放たれてやっと真実を理解できるのでないかと思うのです。
すべては仮定ですが、実際に普通の人には見えないはずのものが見える人も いるわけですし、あながち間違ってはいないと思います。空間とか、一方向 に進む時間とかは、そう仕向けられている幻想で、実際にはすべてが同時に 実在しているとしたら...。つまり、私はいつかこうやってキーをタイプして いる自分を懐かしく眺める事ができるのではないか。逆に言えば、今私に興味 を持つ存在が私の周りにいてもおかしくないのではないかと思います。
そう考えた時に、私が思うことはただひとつ「誠実に生きよう」ということ です。自分が何をすべきかを真剣に検討し、それに向かって手を抜かず努力 すること。たとえどのような境遇にいたとしても誠実でありたいという私 なりの宇宙観、宗教観を恥ずかしながら、ここに書かせてもらいました。
データバインドはデモを見てのとおり<td>内に<span>か<div>でも置いて単に datafld='hoge'を宣言すると、何万行だろうが自動生成してくれる、かなり 横着な規格です。この世の摂理として「楽」イコール「細かい制御は無理」 からは逃れられませんから、スクリプトから見た場合、特定のデータが出現 した場合に当該セルをどうにかしたいという要求はテーブル構築が終了した 後になるでしょう。ですから構築終了時にスクリプトからコールバック関数 をもらっていたらそれを呼ぶという工夫は必要だと考えています。
ただ、HTMLから呼ばれている側のISimpleDataConverterには毎回エレメント のポインターが報告されてきます。このタイミングで「もし○○なら」を 判断しエレメントを操作すれば、ほとんど今と同じ処理速度で当該エレメン トに対て、変更を加えることができます。じゃあどんな事をしたら素敵なの かについて全くアイディアが浮かびません。もし何か「こうだったら」と いう要望があれば、なんでもいいですので書き込んでください。
デモンストレーションファイルを整理し、総合的なものとしました。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip このデモにはグループアイコン及び<hta:application icon=""に対応した
アイコン設定手法が含まれます。また、従前は引数無しのシステム領域へ
起動スクリプトを格納していましたが、それでは格納後に引数を利用できな
いことから、JSNT及びVBNTという領域を用意し格納することに変更しました。
当環境での動作確認はしておりますが、お気づきの点がございましたらお気軽
にご連絡ください。ドキュメントに記載のメール宛てでも結構です。
いつかお約束したアイコン等も全て格納した単一EXE生成をやっとご覧にいれ ることができてほっとしております。これに時間がかかった原因は個々の技術 的な問題ではなく、HTAやHTMLの生成と取得に不安をぬぐい去れなかったから に他なりません。そんなものをお勧めできるわけがないのです。3.00用に開発 したHTML手法は、今まで何千回と起動していますが、当環境においては一度た りともストールしていません。ぜひオリジナルEXEを作成し活用してください。
最も最初に抱いた気持ちを思い出しました。HTMLApplicationはこんなにも 便利なのに心ない一部の人間によって悪用され、拡張子HTAは危険なものと いう観念が定着していました。私自身あまり信頼していない友人からHTAや WSHのファイルを受け取ったとしても、内容を確認せず実行したりはしない でしょう。残念ながら「素人が書いた悪戯」と疑うことは重要です。
HTABOXはそれをEXEにしてしまいます。書く側にとってはHTAであり、WSHなの ですが、受け取る側にとればEXEを生成するスキルと責任のある人間が作った と受け止めるでしょう。つまり、これを使った瞬間から今までとは違った責任 や、自覚を持っていただきたいのです。正々堂々とそれは私が書きましたと 言えないものをEXE化しないでください。HTAがなぜ忌み嫌われる存在となった かを、もう一度かみしめてみる必要があります。
もうひとつ説明を忘れていました。コモンダイアログ系をWIN32とは別にHTML 側コンテキストで用意しています。HTML中のスクリプトを起点とした場合、 WIN32側のコンテキストではHTMLウインドウが再描画されませんので、こちら を使ってください。スクリプト中にDAIALOGという名前空間が追加されています。 DIALOG.MsgBox("メッセージ"); var Path = DIALOG.BrowseFolder("フォルダを選択", "c:\\"); var Path = DIALOG.GetOpenFileName("EXEを選択", "exe(*.exe)\\0*.exe\\0", "c:\\", "hoge.exe", 0); var Path = DIALOG.GetSaveFileName("EXEへ保存", "exe(*.exe)\\0*.exe\\0", "c:\\", "hoge.exe", 0); 尚、EXE生成デモのHTAにそれぞれの呼び出し例を追加しました。
従来は低水準関数でディスパッチを生成していたのですが、関数一覧を出力 するときは、タイプライブラリがあった方がいいですね。helpstringに簡単 な引数の説明を付ければ、たいした解説もなくコーディングできるわけです から。ちなみにデータバインドはディスパッチ系の直線継承ではなく、生イ ンターフェース必須ですからタイプライブラリで生成されています。あと、 3.00をにらんで、HTABOX2.Applicationとするべきか考えています。
HTMLコンテキストのダイアログディスパッチをIDL生成してタイプライブラリ 解析すると下記のような文字列が得られます。 FUNC BrowseFolder(BSTR as title, BSTR as dir) return BSTR//BrowseFolder FUNC GetOpenFile(BSTR as title, BSTR as filter, BSTR as dir, BSTR as def, I4 as flg) return BSTR//GetFileName For Open FUNC GetSaveFile(BSTR as title, BSTR as filter, BSTR as dir, BSTR as def, I4 as flg) return BSTR//GetFileName For Save FUNC MsgBox(VARIANT as v) return VOID//MessageBox これがイテリセンスに表示されるわけですから、やはり親切だと思います。ただ、 以前の関数名「GetOpenFileName」はIDL手法だと予約済み名との衝突判定をする らしく、動作しないのでしばらく悩んでしまいました。
やってみて初めて気付いたのですが、IDL生成のディスパッチは呼び出しコン テキストにシビアだという結論に達しました。関数の内容ではなく、呼び出し 自体が許されないケースに遭遇しました。さてその要因は?という時間はあり ませんから、しばらくは低水準手法で行きます。逆に言えば、他の人がやらな い手法でアプローチしていたからこそ、安定動作していたのかも知れません。
IDLの存在目的はあくまでも、オリジナルなインターフェース型を定義して、 型に固有なプロキシ/スタブを自動生成することなのでしょう。勿論基底に IUnknownやIDispatchが存在したとしても表層に現れる型は必ずオリジナル なものにならざるを得ないわけです。ならば、マーシャリング機構に当該 型に対する十分な説明が必要になるでしょう。したがってIDispatchExの親 へIDL生成されたIDispatcを動的に追加し、親が子をPROPERTYGETされた状況 を想定すると、オリジナルな型であることが裏目に出て正しくマーシャリン グされないという想像をしています。無論、IDL生成された子が単独でレジス トリ登録され、単独でインスタンス化された場合は約束通りに動くはずです が、何かの機能を使うたびにnew ActiveXObjectが必要な構造になるとしたら それは、私が目指しているものとは明らかに違うものということになります。
私の知る限り、HTMLやWSHのスクリプトコードで子インスタンスの取得が行わ れた場合IDispatchとIDispatchEx以外の型に対する問い合わせが発生すること はありません。もし、スクリプトに型を教えることができれば話は別です。 C++クラスインスタンスとインターフェースのVTLからメソッドを呼ぶ言語拡 張がなされれば、柔軟に型へ対応できるでしょうが、その中継自体がリソース を消費するでしょうし、結果的に遅いC++もどきにしかならないでしょう。
どうせそういったモジュールが必要となるので、通常の静的なタイプライブラ リ情報によらず、生成中ディスパッチのTypeInfo情報から関数情報を列挙して XML化するモジュールを書いています。これで何ができるかというと、HTABOX APP.exeのレジストリ登録画面で、その時点でHTABOXが装備している関数情報 を一覧表示することができます。今回データバインド機能も有しましたので、 各項目でソートして簡単な分析を行うこともできるでしょう。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。引数無しでHTABOXAPP.exeが起動した場合、レジストリ登録
画面になりますが、そこでメニューの「ヘルプ」から関数一覧を表示すること
が可能です。また表示内容をXMLとして保存することもできます。TypeLibの
helpstringに代わる存在として、CPPソースの当該関数宣言位置を自動検索し、
一行分のソースをヘルプとするシステムとしました。まだ有効なコメントは
ありませんが、随時追加しこの一行を見ただけで関数の機能を理解できるよう
に整備してゆきます。
人間、追いつめられると知恵も出てくるもんで、CPPソースコードをそのまま 関数のhelpstringにしようというアイディアはよく思いついたものだと感じ ています。自分用に詳細なコメントを書けば、それがそのまま利用する方々 にとっても有効なコメントとなるわですから、まさに一石二鳥です。関数を 追加するときは、その時々の要求があるわけですから、総合的にこうデザイ ンしようという意思はなかったのですが、こうして一覧してみると、数が増 える前にこうすこし系統立てた分類をすべきかもと思います。 ちなみに。一覧にはクラス名が存在しますが、関数は全てWIN32の子として 直接記述することができます。About()という動作確認用関数以外は衝突して いる名前は無いはずですが、もし同じ名前があった場合はクラス名を明示し た呼び出しにより、正確に呼び出されます。低水準関数で生成したディスパ ッチの特徴として、引数の省略はできません。数値ならゼロ、文字列なら"" を指定する必要があります。
4月にはサーバーを乗り換えて営業活動に入るつもりが20日も経ってしまいま した。でも、この20日の仕事には大変満足しています。いくつかの課題をクリ アしましたが、いままで混沌とした状態で存在した知識やモジュールが、強い 磁力で一斉に極性がそろうかのように整然と結合しました。それも、ここで いただいたアドバイスのおかげです。私のように未熟な人間の書いたプログラ ムに興味を持っていただけることに心から感謝いたします。飛んで行ってお礼 申し上げたいのですが、それも叶わない状況なことをご容赦ください。
低水準関数で生成され、動作中のディスパッチ情報からタイプライブラリを 説明用に生成するということは可能だと思います。ただ、これをインテリセン スへ反映させるためには、通常レジストリでタイプライブラリ位置を明確にす る必要があるため、その結果、昨日体験したIDL生成固有のデメリットが生じ るようであれば現実的ではないということになります。それを検証してみたい と思います。
なんとかタイプライブラリ生成のメカニズムは掴めましたので、本番コード でインテリセンスが機能するか、機能した状態で動作に不具合が生じないか をテストする段階に到達できました。もし、低水準で生成されたディスパッ チのインテリセンスを有効とできれば、私にとって夢のまた夢だったことを 実現できることになります。
このスレと関係があるかはわかりませんが、こんなものがあったら便利だと思うんですが。 HTAのようなものというか、WSHにHtmlエリアが付いたものというか・・・ 上半分または左半分のエリアにボタンやチェックボックスなどのフォームをhtmlで配置できて簡単なユーザー対話が出来る。 下半分はまんまコンソール画面でふつーにexecやWScript.Echoみたいな VbscriptやJScriptのCscriptをいじってる感じ表示できる。 なんとも中途半端だけど、いろいろ試したいサンデープログラマーが興味持ちそうなツール。 こんなものはもうあるんですかね?
>>521 世間は広いですから、そういったアイディアのものは存在するかも知れませ
んが、対話型のコンソールというものを私も再評価しています。実は従来の
コンソールの概念を打ち破った「リッチエディット」によるコンソールを
開発しています。このコンソールは通常のコマンド入力、や出力表示が可能
で、フォントや色もコマンドから指定できます。また、HTML風タグコマンド
を入力すると、ハイパーリンクコマンドをマウスクリックできたり、HTMLペ
ージを矩形表示できます。3.00用に準備したテクニックなのですが、リッチ
エディットは通常のコンソールより数段高速な描画が行えますので大変将来
性を感じているテクニックです。
単なるEXE生成ウイザードの対話用ではもったいない気がしておりましたので、 その先のインタープリタを指定できる拡張コンソールとして発表してゆきたい と思います。それから、思い出したのですがこのコンソールはリッチエディッ トですから、当然コマンド入力、出力結果をそのままTXTファイル又はRTFとし て保存できます。最初にこれに取りかかった動機が、コンソールではコピペさ え面倒で、そのままファイル保存なんてできるわけがない事に業を煮やした事 からでした。近日中にデモをご覧に入れたいと思います。素敵なアイディアを ありがとうございました。
作者さん、早速の反応ありがとうございます。 HTABOXコアやHTML+Javascriptを利用したアプリケーションの時代には、 HTMLやスクリプト、正規表現、文字列の操作、関数、クラスなどというのものを、 コンソール画面で実験結果をprintしていく操作のシンプルさをベースとしたインターフェース+ちょっとしたボタンなどで 簡単に試行錯誤が出来る環境があったらいいと思うんですね。とくに日本の子供たちを対象に。 そういったツールでシンプルなものが今あればいいのだけれど、いろいろ調べる限りではそういったものは見当たらない。 コンソールと一体となったウィンドウの中の限られたエリアへのHTMLのフォーム表示に限るだけで、 出来ることはHTABOXに比べたら大幅に制限されるけれども、覚えることは大幅に少なくてすむような 実験環境が作れると思います。 作者さんのビジネスに、そういった教育分野への影響力拡大と解説本みたいな流れがプラスされた面白いんじゃないでしょうかね。 まずはクラスまでは作れないレベルのちょっとしたスクリプトをいじれる大人たちや学校の先生も含めた人々の実験ツールの定番になれば HTABOXのビジネスにもよい影響を与えると思うんですが。
まさしく私がこのコンソールに対して抱く構想は「入門者」がコマンドや 簡単な関数をパースして、その実行結果を即座に見れることにあります。 function Test(a, b){return(a + b);} をパースして次にコマンドTest(1,2);を入力すれば結果が表示されるという ような、最初の感動を与えることができれば、プログラミングに興味を持つ 子供たちも増えるんじゃないかと考えています。
文字列での対話というと外観的にはどれも同じようなものになりますが、例え ばHTMLだとGUIが窮屈すぎる場合がありますよね。選択の可能性が分岐するよ うなパターンで、すべてのボタンを用意するのは書く方も、扱う方も大変なわ けです。ウイザードのように、選択しながら一方向に流れる処理の場合、今ま での選択ログがコンソール上に残っていたほうがいいですし、その対話結果を TXTとして保存して、次回はそのログを読み込んでMAKEファイルとして使う。と いうような事も直感的に理解できると思います。
実際にはこんなスクリプトを内部で動かす予定です。 var ret = Pause("実行しますか?<link>はい</link>又は<link>いいえ</link>を選択"); if(ret == "はい") { Println("実行中です"); } else { Println("終了しました"); }
通常の表示文字列中に簡単なタグを採用しますここでの<link>はマウスで クリックできる青いボールドの文字になります。Pauseはいずれかがクリック されるまで制御を返さず、クリックされた場合選択された文字列を返します。 と、同時に今までクリック可能だった文字を通常文字に戻します。リッチエデ ィットはデフォルトの状態でも、マウスイベントとハイパーリンクが扱えます から、こういったものを作るのには大変向いているコントロールです。
タイプライブラリはお蔵入りになりそうです。ソフトウェア的(タイプインフォ 規則的)には完全だと思うのですが、レジストリに嫌われます。まったく同じ要 素のIDL生成TLBと比較すると、微妙にバイナリが違います。昔書かれた本家の サンプルコードも同じく嫌われることから、IDL生成にアドバンテージを持たせ るたに何らかの仕様変更が行われているように思います。その要因も目星は付 くのですが「そこまでしてやることか!」ともうひとりの自分が叫ぶので、 ソースはディスクの片隅で眠りにつく予定です。発想を変えて本体EXEの機能 を縮小させ、DLLへ移動すればインテリセンスの課題はエレガントに解決できる でしょう。3.00へ向けた課題とします。
開発機を本番サーバー用にリセットしました。今回のインテリセンス実験で リジストリを操作し続けましたので、気分一新というところです。頭を切り 替えて、正しい日本語を思い出しながらドキュメント作成にとりかかります。 不思議なもので、プログラミングは午前五時に神様が微笑むジンクスがあっ て夜通し取り組むのですが、「言葉」を紡ぐ方の脳はきちんと人間らしい リズムで生活しないと活性化しないのです。今夜から早寝早起きをこころ がけます。
枕元に500MHzという化石のようなノートがあるんですが、EXE生成デモで生成 されたEXEはJSからCreateHtaWindowしHWNDの存在を監視しますが、この終了 待機ループで余計なメッセージを拾い、マウスがまたたく状態になりやすい ですね。ここは早急に改善したいと思います。逆に格納前の方が安定してい ることから、自身プロセス内でのみ発生する要因だと思われます。
>>526 そのへんも実はチェックしたんだけれども、イメージはだいぶ違います。
コンソールと言いすぎたのが誤解を与えちゃったかな。
エディタ部分でスクリプトを書いてCscriptで実行する環境にGUIを少しつけた感じ。
作者さんのOutline.exeやTBZ、HTA、Cscriptみたいなものがごちゃごちゃに混ざったイメージ。
それはHTAなのかもしれないけど、縦2分割の半分または横2分割の半分というように
GUIの部分をおおざっぱな型で決め付けてしまって設定を簡易化しておいて使い続けてもらえば、
そこからHTML型のアプリケーションを覚えていくのも楽になるのではないかと思ったんですね。
その代わりできることは限られるし、見た目もスマートではないけれど、
中の動きが見える状態で使えて、そこそこのUIは持っていて、ある程度は楽ができる道具みたいな感じです。
これは作者さんのアプリと報酬についての考えとは違うかもしれないけれど、
素人や子供たちが、そのスクリプトを1週間使ったあとで、頭からスクリプトの内容を忘れたあとでも、
らくに改良できる状態に戻るにはどうしたらよいのかということの提案でもあります。
てきとーに描いてみたイメージ
http://up3.viploader.net/pc/src/vlpc011168.jpg >>528 わかりやすいツールができるのを期待してます
>>533 何よりもその情熱に感動しました。イメージとしてはTZBの部品としてコンソ
ールウインドウ、HTMLウインドウ、を置けて、場合によっては2つがセットに
なっていてHTML側のログがコンソールに出力されたり、逆にコンソール側のコ
ードがHTMLに反映されたりする機構のように感じました。これはそういうイメ
ージの実現を可能とする受け皿としてのメタツールを提供するのが正解になる
かと思います。
子供のころ「電子ブロック」というおもちゃが欲しくて欲しくてたまらなか ったのですが、結構高い値段で欲しいと口に出すことさえなく我慢していた のを今でも鮮明に覚えています。TZBでソフトウェア的な電子ブロックを作る という明確な目標ができました。TZB用に完成されたツールページ、半完成だ がカスタマイズできるページ、連動するページセット、等の部品を用意して それを組み合わせることでオリジナルなアプリケーションができてゆくという 電子ブロックのソフトウェア版を作れたら子供たちに夢を与えられるでしょう。
まず、TZBへ開発モードと実行モードを定義可能にします。開発モードでは 通常セキュリティーのWebBrowserやHTA系のウインドウ、WIN32で作成された コントロールウインドウをドロップしてタブに追加することができます。 それぞれのウインドウは規格として公開する情報が決められています。つま り電子ブロックのそれどれの電極のようなものです。HtML系ウインドウ、や コンソールウインドウは空、つまり実行時にページや実行コードを選択する ことも可能なら、あらかじめ決まったページやコードを実行することも可能 にします。実行モードでは使いながら混乱することを避けるため、タブへの ウインドウ追加をある程度制限するというようなルールが思い浮かびます。 確かに、これだけ広範囲に渡ってのプログラミングができる変態プログラマー は私だけかも知れません。
あぁ、TZBは大枠と各ブロックの素材(連絡用の枝規格)をある程度定めて あとは、どんどん皆さんからブロックを作ってもらうとうのが賢いかもしれ ませんね。もちろんWIN32がらみで面倒という場合は私が書きますし、優れた ブロックはちょっと値段がついていたりすれば、書く意欲にもつながるで しょう。連絡用の規格については速度重視なのか、柔軟性重視なのかで悩み ますが、相互を操作可能とすればDispatchExが最も有力でしょうか。HTML系 の場合はwindowまたはdocumentはDispatchExですし、スクリプトエンジンは JS、VBともグローバルスコープをDispatchExとして取得可能です。.NETの場 合、JScriptエンジンのグローバルスコープはDispatchExですが、それ以外 はDispatchです。WIN32コントロール等は内部にスクリプトエンジンを持たせ そのDispatchExを通信インターフェースとして使うとすればいいでしょう。 大げさな表現をすれば「小さなオペレーティングシステム」の中でページ が連携できる仕組みで、私はAPIレベルでの関数や、メッセージ通信の規格 だけを提供し、あとはお任せするというのが賢い選択ですね。
前の書きこみを書きながらWIN32だけちょっと「不安」だったのですが、 今回、2.50で埋め込み<object>をレジストリフリーで利用する実験が成功 していますから、その延長線上で考えるとすべてがすっきり治まります。 つまりWIN32コントロールはHTMLに必ず乗るというルールです。全面をリッチ エディットにしたければ、<object>のwidthとheightをスクリプトで引っ張る 若しくは、width = "-1" height="-1"でウインドウサイズに自動追従すると すれば、頭の中でははぼ完成しました。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。ヘルプからの関数一覧でSTDCALL等の余計な文字列を抑制し
見やすいものとしました。また、関数ヘルプ文字列は別セルに表示します。
WaitForWindow系関数動作を見直しました。内部では待機側スレッドIDをHWND
に報告し、HWND側はWM_DESTROY時確実に当該スレッドIDへWM_NULLをPOSTして
HWND存在判断用にメッセージループを回すこととしました。EXE生成デモで
表示されたHTAが閉じられるとき、確実に「終了」ダイアログが表示される
ことでこの動作を確認できます。また、EXE生成デモで生成EXEがDLLをチェック
する動作は規格どおりですが、チェックしない原版EXEを作成する方法について
の説明を"XE生成デモ.txt"に追加しました。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。クローン作成関数を追加しました。
WIN32.CopyExe(SourExePath, DestExePath);
クローン作製時、原版にDLL参照情報があった場合継承するか確認ダイアログが
表示されます。したがってEXE生成デモでは「いいえ」を選択することで単独
実行EXEが生成されます。この変更に伴いQuick内の生成JSも変更されました。
まだ、ドキュメントの整備は整っていませんが、このバイナリをもって
「HTABOXコア2.50」を呼称します。今後の改善が行われた場合マイナーバージョン
を上昇させることで識別します。
走り出してから後悔することはよくあるもので、やはり低スペックなPCで連 続起動という過酷な状況にしたときに、何らかのメッセージをサブクラス化 の途中で取りこぼす、又はコンテキストの違いで処理していないケースがあ るので、HTAのメッセージループを別プロセスMSHTAと同じくHOOKに切りえる 作業をしています。もちろん同一プロセス内HOOKですからDLL添付無しでも 動作します。この作業のついでに別プロセスMSHTAにもフォルダダイアログと ファイルダイアログを提供するかも知れません。
今までdocument.Script (scriptsではない)を取得してHWNDをPUTしようとし ていたのですが、単にそうされるとdocumentが機嫌を損ねるというのが原因 のようです。このScriptは結局windowと同じアドレスのインターフェースポ インターを返すのですが、名前からしてこっちが主役だろうと勝手に決めつ けていました。生成EXEはHTABOX自身をマニフェスト参照してHTMLスコープ からWIN32を取得しますので、何かを焦って追加する必要は全くなくなった んですが、過去を引きずっている部分がありましたのでもうすこし手直しす る予定です。
原因は前述の部分ではありませんでした。3.00でもほぼ同じ経過をたどる部分 があるので、徹底的に部分的書き換えを行いながら原因を絞ったところ、たい した意味もないだろうと思っていたAPI関数の呼び出しの引数が実は大変重要な 意味を持っていたという要因でした。一度持ってしまった観念、思い込みという ものを振り払うことの大変さを身にしみて感じました。
いろいろな部分で症状が出にくくなったりするものですから、いままで適当 だった部分が目について書きなおしたのですが、やっぱりたまに出る。出る 条件は「終了」MsgBoxがSYSTEMMODALで表示された直後、マウスが安定しない 状態だと発生しやすい。結果WM_NCHITTESTが連続で来る。改めて一番ありそう な原因はGUIスレッド問題。開始時プライマリースレッドはウインドウを持た ないのでGUIスレッドと認識されていない。HTMLウインドウがサブスレッドで 開始される。単にそれが終了すれば問題ないが、終了時にプライマリスレッド からSYSTEMMODALを要求され、システムがちょっと困る。そのお釣りが次回の 起動に影響を及ぼす。本当は無駄なHWNDは生成したくないのですが、HWNDの無 いGUIスレッド宣言は今回のケースでは意味を持たないようなので0pxのPOPUP を初期に作成しておくと全く症状は出ないようです。まぁ何度も「出ない」 と思って、結局再調査してますから、もう少し過酷な条件下でもテストを繰り 返します。
結果は良好です。ウインドを作るというと、よく目にするWIN32でHelloWorld を書かなければいけないわけではなく、今回の要求を満たすコードはこれだけです。 WNDCLASSEX wex = {sizeof(WNDCLASSEX), 0, DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)GetStockObject(NULL_BRUSH), NULL, TEXT("GuiWin"), NULL}; RegisterClassEx(&wex); CreateWindowEx(0, TEXT("GuiWin"), TEXT(""), WS_POPUP|WS_VISIBLE,0,0,0,0, NULL,NULL,NULL,NULL); HWNDインスタンスさえ保持しませんが、プライマリスレッドが消滅すれば自動 消滅するはずです。なぜ、表示しないのにカーソルとブラシを指定するのかに ついては経験側です。これを指定しないと生成時にシステムが考え込む時間を 発生させてしまうからです。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。連続起動でマウスがまたたくケースがあることへ対応しま
した。MSHTAで実行中HTAのフックでメニューに加えフォルダ、ファイルのダ
イアログを提供しました。フックの起点となる関数はBuildMenu(document);
です。メニューテーブルを宣言しなければダイアログだけ利用できます。
デモにフックデモを追加しました。ファイルダイアログのフィルタ文字列等
についてはデモHTAのソースをご覧になればすぐ理解できると思います。
今回のバージョンは2.50のまま、訂正しての公開とさせていただきます。
今日のように根幹の部分にある問題に立ち向かうとき「だめかも」という不 安に独り立ち向かうことになります。もしだめだったら全部が無に帰する可 能性を持つ緊迫した状態です。2.50のソースは現在300k程ですが、その一行 一行を自分とは別の人格になって精査するような作業になります。そういっ た事を数年続けていると、気付かないうちに心にダメージを負ってしまうの かも知れません。そしてその自問のはけ口がこの場所なのかも知れません。
「つまんない事やってるね」って言われたら、気の弱い私ですから挫折して いたかもしれませんが、自分なりに出すべき材料を全部並べることができる 状態になれたのはこの場所も含めて私の周りにいる方々の心配りのおかげで す。夢を語るのは簡単なことですが、それを実現することは容易ではありま せん。プログラミングに関して言えば、すんなり動くコードは何ももたらし ません。どんな世界でも同じでしょうが、だめならなぜだめなのかを積み重 ねてゆくことしか前進への道はありません。 今までは自分の書いたものが動くところを正直見たくありませんでした。自分 が思い描くイメージとは程遠いものだったからです。ここにきてやっと自分が 書いたものに愛着を持って接することができます。よくも悪くもこれが私とい う人間のすべてです。
さぁ、今度は使う側の立場に立ってドキュメントを書かなければなりません。 このままでは、ひとりでよがっている得体の知れないプログラムに見えるで しょうからね。理想はヘルプ内のコードをそのまま実行して結果を見れるこ とですが、2.50でそれが実現できるかどうかちょっと考えなければなりませ ん。3.00の場合、はじめからそれを意識した構造となっています。
プログラミングはクリエイティブな作業だと思っています。そしてもっと アーティスティックな扱いを受けるべきではないかととも考えています。 書かない(書けない)多くの人間にとってアプリケーションとは無機質な 生成物でしかありません。使う側にとればそれを作成した人間が死んでも 次の人間が即座にそれを引き継いで、自分がその利便性を失うことが無い ことを願うでしょう。
それは、アプリケーションとして当然の要求なわけですが。私はその上に 「芸術」に昇華する領域があってもいいんじゃないかと感じています。 ブラームスの交響曲やショパンの夜想曲やルノワールの絵のように、それは とうてい余人ではなし得ない領域に到達していて、アプリケーション名では なく、それを作った芸術性に対する敬意が先行するような状態です。そいった ことを実現する先駆者がいない限り、どんなに書いても名前など表に出ず 「あんたの代わりはいくらでもいますから」という環境で仕様にしたがった コードを書かなければならないプログラマーなんぞに憧れる子供たちなど 現れるはずもありません。
2.50用に3.00のヘルプエンジンを簡素化したものを書いています。どうせです からこれをWIN32.CreateHelpWindow(url);としてWSHから呼べるようにしたいと 思います。この関数ではurlで指定されたHTMLの見出しを<Hn>で階層認識し、 左ツリービューに表示します。ツリービューをクリックすることにより当該 見出し位置へ右HTMLはスクロールします。もうひとつ関数を追加します。 WIN32.RunHelpHtml(str, path);この関数はHELPとして表示されているHTML中 で使います。HELP中のサンプルHTMLは<>のようにエンコードされている はずですが、この関数はそれをデコードし、第2引数パスへ\xff\xfeを付加した UTF-16として出力し、HTABOXAPPのクローンを起動して実行します。 これはヘルプ目的ですが、ちょっとしたツールを長いHTML中の<pre>タグ内等に 複数記述し、それぞれの</pre>の直前にボタンを置けば実行できます。 <input type="button" value="実行" onclick="WIN32.RunHelpHtml(this.parentElement.innerText, path);"> 元のHELP用HTMLをメモ帳で管理すると頭こんがらがると思いますが、通常の HTMLエディタならデザインモードでタグを打てば<に変換しますし、改行 ではなくSHIFT + 改行なら単一の<pre>内にコードを記述することもそんなに 困難ではないようです。
2.50デモの現行版をXPで試すと、 アイコンあり、タイトルなし、ウインドウサイズが0×0pxのタスクボタンがまず出現、 そのあと実際のタスクボタンが表示されて二重になるのですが
確認してみます。ご迷惑をおかけします。
おっしゃるとおりですね。GUIスレッド対策のウインドウがタスクに認識され ていることを確認しました。対応策を練ります。ねぼけまなこで最終テストを 行ったものですから、タスクバーを見落としていたようです。大変助かりまし た。今後ともよろしくお願いします。
WS_EX_TOOLWINDOWを拡張スタイルへ追加することで、タスクに認識されない ウインドウとできるようですので、現在行っているヘルプエンジンの搭載と 同時に改善してバージョン2.51をする予定です。現在ヘルプエンジンは最終 テストを終え、デモの体裁を整えているところです。
CreateHelpWindowで生成されるウインドウはT字型で区切られるの3パネルと しました。水平バー、垂直バーは軽量に移動可能です。HTABOXAPP.exeを引数 無しで起動した場合もこれが表示されます。レジストリ登録系のボタンは 上部のパネルに置かれ、下の左右はツリーとドキュメントになります。 したがってCreateHelpWindow(url, url);になりますが、上は使わないという 選択の余地があるように第一引数は空文字でもいいことにします。上下だけ を使いたいという要望もあるかも知れませんので第2引数空もありですが、 下側パネルだけ垂直バーが左端にあるというのが美しくないので今のところ は推奨しません。
完成かなっと思ってほかのウインドウを重ねて再描画性能を見ると、不合格 です。2.5系はできるだけ従来手法を残した存在にしたいとという感傷が若干 あったのですが、単発ウインドウではなく、複合ウインドウ中にドキュメント を自由にレイアウトしようとすると、どうしてもHWNDは多重な構造になります し、その多重な状態に既製品HTMLコンポーネントを乗せてもメッセージの伝達 性や反応速度がよろしくない状態となります。しかたがないのでこのヘルプエ ンジンに使うHTMLコントロールを3.00用に開発した最新兵器に乗せ換える作業 を行っています。結局今日も、ない頭であれこれ悩みながら朝になりそうです。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。上記URLは250ですが、251を呼称します。ご指摘いただいた
ダミーウインドウがタスクへ追加されることを修正しました。ヘルプ作成用
関数を2つ追加しました。デモが存在しますが概要は
WIN32.CreateHelpWindow(title, path1, top, path2, left);
引数はタイトル、上部HTMLファイルパス、上部初期高さ、右HTMLファイルパス、左初期幅です。
そこで表示されるHTML中から使うと便利な関数が
WIN32.RunHelpHtml(str, path);
引数はファイル出力するコード、一時生成パスです。
(ファイルはBSTRのままunicodeで保存されます)
やってみるまで気付かなかったんですがinnerHTMLだと &とlt;なのでHTML
評価する前に復元が必要かと思っていたのですが、innerTextだと<になって
いることを知りませんでした。ヘルプエンジン用HTMLコンポーネントはWIN32
をnew ActiveXでする必要がありません。スクリプトが解釈されるずっと前
からwindow.externalで待っています。3.00ではすべてこの形式に統一され
ます。またHTMLコントロールで設定可能な項目はあらゆるものがすべて設定
可能です。たとえばデフォルトでテーマを有効にとか、HTAウインドウの右
にいつもある垂直バーもどきを消したりできます。なんかまだ抜けてるとこ
ろがあるかも知れませんが、すこし眠いのでとりあえずアップしました。
あぁ、ヘルプデモのHTMLではまだ、ActiveX取得しています。これは呼び出し JSがHWND終了を待つループとwindow.externalとの相性がまだ悪いためです。 ちなみに同じことをやっているHTABOXAPPのヘルプページでは、ウインドウの 終了まで普通にメッセージループが回っていますのでexternalから取得して います。
TZBの場合はタブで横並び、この場合はTバーで区切られているのですが、そ の場合お互いにwindowとかdocumentを相手に見せたほうがいいのか、はたま た、共通の上位オブジェクトとしてスクリプトエンジンを置いた方がいいの か決めかねています。ご意見を気長にお待ちしています。
例によって枕元のXPでヘルプデモを実行すると、ウインドウを閉じるタイミン グで「Unknown」ですね。最終段階で大手術になったものですから、こなれて いない部分があるようです。すこしだけ原因について検証しますが、場合に よっては、この機能を持つ関数を公開するのは3.00以降となるかも知れません。
3.00では複数のHTMLウインドウを別スレッドで同時進行させた構築を行って います。そして、ヘルプのように大規模なページの場合、プロセス内での メッセージ飽和を回避するためにクローンプロセスも駆使しています。です から多くのHTMLウインドウ生成関数は呼出し後直ぐに制御を返します。その ことを忘れていて、結果的にIsWindowVisible判断ループは直ぐにbreakして いたというのが原因でした。なんとか対応できそうな気がします。
HTABOXAPP.exeはCOMサーバーと、スタンドアロン実行の2つのモードで動作 しているわけですが、COMとして呼び出された場合のコンテキストとスタン ドアロンでは内部動作のコンテキストは異なります。Monikerが必要とする スレッド環境をWSH側が提供できていないことのように見えます。最も間違 いのない解決策はCreateHelpWindowで受け取った引数情報を利用してスタン ドアロン環境へ切り替えることだと判断しました。呼び出す側としては何の 変更もないのですが、内部では単に"自身.exe arg1 arg2 arg3 arg4 arg5" のコマンドを実行するという方法です。2.50系と3.00系ではスレッディング モデルの違いが存在するということを概念では理解していましたが、実際に 体験することができたことは収穫でした。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました2.51修正版です。ヘルプエンジン呼び出しを内部でEXEC的処理
とすることで、WSHから呼び出した場合のスレッド問題を解決しました。レジ
ストリ未登録な状態でデータバインドが呼ばれた場合、未インストールでも
typeofはobjectを返すことから何もしないCheck();関数を追加しました。
tryブロックでData.Check();を行い例外が発生した場合、未インストールと
判断できます。DLL系も小変更されていますので、従前のバイナリは削除する
ことをお勧めします。
もし、モジュール間の伝達情報が静的なものであればCreateProcessほど安定 した呼び出しはありません。なにせシステムはその実行専用に環境を整備し、 ほかプロセスから保護してくれるわけですから。ただ、情報は主に引数で受 け取ることとなるので、正規表現ライブラリをきちんと整備していないと、 引数判断部分を書いているだけでやる気が失せるものです。今回の収穫は、 引数チェック機構としてだけCOMを使うということです。関数呼び出しの引数 は実際には"HELP_MODE\tTITLE\tURL1\tTOP\tURL2\tLEFT"という文字の引数に 変換されCreateProcess時に使用されます。実に私らしい横着な手法ですが、 確実にコンテキストのしがらみをフラッシュしたい場合、実に強力な武器とな ります。
ヘルプ用ウィンドウの機序と構造が頭にあるうちに、もう少し軽量にする 方向の改良を行っています。3.00では必要でも2.50には邪魔な機能がある からです。既製HTMLウインドウはHWNDが最低でも2重、WebBrowserに至っ てはそれだけで3重で更に親が必要なのですが、今回の改良でドキュメント を直接ネイティブHWNDへ乗せます。これがすめば表示するHTMLの規模にも よりますが、通常のネイティブウインドウ並みのレスポンスが実現できる はずです。
改めて
>>533 さんの画像を拝見すると。なかなか示唆に富んだ内容ですね。
HTABOXの場合JS,VBS、HTA、HTMLを実際にHTABOX環境で実行するには引数とし
てHTABOXAPP.exeへ与えるか、格納EXEを生成する訳ですが、3.00用に用意して
いたエディタを2.50に搭載して、「File」->「Open」で編集中のスクリプト
とHTMLをそのまま実行できる機能を追加してみます。だんだん2.50が限りなく
3.00に近づいてしまっている気がするのですが(笑い)。2.50用にコードを見
直すことで、バグフィックスにもなるでしょうし。まだ533さんのイメージには
程遠いでしょうが、[WSH][HTABOX]と[MSHTA][HTABOX]を選択可能にした実行エデ
ィタとする予定です。
あぁ、面白いことを思いつきました。DirectSound系を今後どう提供しようか と考えてたら、埋め込みActiveXをHTAで書ける状態になっていることに気付き ました。<object>埋め込みは通常のHTML中スクリプトでできないことをやるの が仕事ですから、まったくスクリプトでは意味がありませんが、母艦DLLに DirectSound系関数を用意して、それを利用しながらGUIを形成するHTAを書い てもらい。(たとえば再生と停止ボタン)それをHTABOXにDLL化してもらえば 母艦DLLと当該DLLをセットにして「私が作った埋め込みActiveX」ですと言える 状態になるわけです。IE以外のブラウザが<object>をどう扱うのかは調べたこと がありませんが、うまくゆくとWindows系OS上ならFoxやOpera内でも動作できる 可能性があります。<object>を介することによってHTMLアプリケーション手法は ほかのブラウザ内でも動作する夢の環境へと変貌するわけです。
今書いているエディタ中のスクリプトで実行する時、エディタに存在する TextDocumentインスタンスをスクリプトへ渡すことができれば、533さんの イメージに少し近づけるかも知れません。つまり実行スクリプト中に TextDocument.Add("追加しました"); が存在すると、編集中スクリプトへフィードバックされるわけです。これは エディタの編集マクロ代わりにも使えるわけですから2重に便利でしょう。 スクリプトの実行自体は別プロセスで行われる予定ですから、プロセスを超 えて正しくインスタンスを渡せるかどうかが鍵になりますが。
570は単純に解決しました。呼び出された側で書きコードを実行すれば呼び出 し側エディタに文字が使いされます。 //最後のWindowsがエディタであると想定 var Wins = new ActiveXObject("Shell.Application").Windows(); var Editer = Wins.item(Wins.Count - 1); var TextDoc = Editer.TextDocument; WSH.Echo(TextDoc.Selection.Text); TextDoc.Selection.Text = TextDoc.Selection.Text + "\r\n" + "Hello"; つまりエディタをDispatchでラップし、ShellWindowsへ追加しただけですが、 これが最も単純で確実な手法だと考えます。これで自身ソースコードを書きか えるスクリプトを書けます。また、最初に実行側エディタを起動し次に出力側 エディタを起動して実行すれば、結果は後の方に出力されますから混乱しない ことになります。
エディタはほぼ完成しました。このエディタに3.00デモでお見せしたワンタッ チエンコードを有効とすれば、なんとなく3.00がいらないんじゃないかと思え てしまうので、本体の機能拡張はこの辺で終わりにしたいと思います。その他 のコモンコントロールとかDirectX系の拡張は基本的に埋め込みActiveX用DLL で行われます。そしてそのDLLはそのまま次期3.00で利用可能です。
エディタの動作確認がとれたので、開発用自作Invoke関数から、TOMインター フェースへの書き換え作業を行っています。これが結構面倒な作業なんです。 たとえば多くても1秒に1回程度の呼び出しなら、スクリプトのように名前で DISIDを取ってからのInvokeでなんら差し支えないのですが、このエディタは 入力の文字とカレント行を逐次確認する処理をしていますので、生インター フェースへの呼び出しとしたいのです。結果的にDLLバージョン依存が出たら また自作Invokeに戻すことも視野に入れて作業を行っています。多分、機能が 少ない分だけ、極めてレスポンスの鋭いエディタになると思われます。
なぜ開発時にインターフェースが記述されているヘッダファイルや#importを 使わないかという理由ですが、簡単に言えば得体のしれないエラーを回避する ためです。教科書どおりな構成ならめったに起こらないのでしょうが、考えう るあらゆる可能性をテストするために、多くのインターフェースを同時にイン スタンス化したりすると、当然のごとく名前衝突が起こります。そして、この 衝突が要因にも関わらず、その原因を掴みかねて最善の手法を見逃す事にもな りかねません。開発時に速度は必要ありませんから、私は生インターフェース を一切使いません。すべてスクリプトのようにGetIDsOfNamesとInvokeで処理 します。そしてリリース段階で速度が重要な場合のみ今回のような作業を行い ます。
なんとか作業を終えました。エディタという分野は非常に奥が深くて、私は ほんのさわり程度しか書いていないと思うのですが、やっぱり一番悩むのが Shift+tabで複数行のインデントを削除する動作です。たとえばABCという行 があってTabでインデントされています。A行は中間から、BCはすべてが選択さ れた状態でのShift+tabをどう扱うか、どう扱ったら操作側の意図に沿うのか。 もし、スペースとタブが混じった状態のインデントだったらどうするのか等 考えたらきりがありません。私は横着ですからそんな時はソースを書いている Visual Studioがどう振る舞うのかを参考に同一動作としました。
エディタ搭載の2.51を公開します。まだ、エディタのコードページ認識が甘く
ANSI(shift-jis)に固定されていますので、正規リリースとは呼べません。
ttp://kuroda.bglb.jp/htabox/EditTest.zip レジストリ登録の画面に「エディタ起動」ボタンがあります。添付jsをこの
エディタで開き、WSCRIPT.exeで実行すると。スクリプト側がエディタの終端
へ書きこみを行います。
WIN32.CreateEditWindow(title, path);//第2引数は通常空文字、コードページANSIのみ
見かけ上はCOM呼び出しですが、ヘルプエンジンと同様に内部では別プロセス
を生成しています。今のところこれはあくまで「付加機能」と考えています。
どうもリッチエディットのコードページ解釈ルールが理解できていません。
その辺がクリアされれば、前面に押し出されるべき機能だと考えます。
私にとってリッチエディット、TextDocumentインターフェースはMSHTMLに次ぐ 大きな柱の一つですが、ネイティブなメッセージ処理と密接な関係にあるもの ですから、問題点が不明瞭になっていました。今回シンプルなクラスとして再 構築する過程で、間違っていた点や、スムーズさに欠ける部分を確認すること ができました。 とりあえず動くというだけで外観はまるでCSS抜きのHTMLの様相ですが、単に GUI操作でHTABOXを利用できるということには大きな意味があると思います。 今後も改良を続けて参りますので、お気づきの点がございましたらお気軽に ご指摘ください。
そういえばヘルプエンジンを書く前の1週間くらいはTypeLibとTypeInfoだけ 勉強していたのですが、このエディタでインテリセンス表示することはそう 難しくないように思えます。3.00ではレジストリという言葉さえ出てこない 状態を目指しますが、その場合ネックになるのが、インテリセンス問題だと 予測します。独自エディタが親オブジェクトの子を記述するための「.」を 認識したら、その子要素を列挙して当該位置へリスト表示するという機能を 軽量に実現できれば大きなな前進となるでしょう。
エディタデモでスクリプト側がTextDocumentでGETしているオブジェクトの
内容はITextDocumentで検索すれば公式な情報を入手できますが、短時間に
全体像を把握する目的でTypeLib解析データをアップしました。WORDのVBAを
書いたことのある方はなんとなく雰囲気が似ていますので、すらすら面白い
ことが書けるんじゃないかと思います。
ttp://kuroda.bglb.jp/htabox/tom.txt
コードページの認識について検証しています。これはエディタコントロール に原因があるわけではなく、IMultiLanguage2::DetectInputCodepageの問題 なのですが、リッチエディットは一旦ファイルにアクセスするとストリーム を形成し、指定コードページで内容を上書きする特性があることから、ファイ ルを開いて文字化けが見えた時点ではもう手遅れで、元ファイルも文字化け します。アルゴリズムとしての対応は後になると思われます。0xff0xfeが付 いているUTF-16は必ず1200と認識しますし、WSHもUTF-8のソースは受付ませ んが、UTF-16は実行できることから、プラットフォーム的解決策として非HT MLスクリプトは全部UTF-16で統一というのも考えています。
IMultiLanguage2::DetectInputCodepageはその辺のコードページ判定とは 違い、複数のコードページのパーセンテージ情報まで返します。この構造 体は引数として渡されますが、どうせ1個しか取得しないからとケチると S_OKを返すものの結果は予期せぬものとなるというのが主な原因でした。 DetectEncodingInfo Info[5] = {0,0,0,0,0}; int Count = 5; Lang2->DetectInputCodepage(MLDETECTCP_NONE, GetOEMCP(), Buf, &len, Info, &Count); のようにあらかじめ十分な数を与えればInfo[0]はパーセンテージこそ低 いものの、こちらが期待したコードページになるようです。ここで100%な コードページを採用すると、誤った判断となるところもポイントなようで す。
で、こんどはリッチエディット側の問題なのですが、原版ファイルを指定コ ードページで開き、編集するとリッチエディットは自動的にファイルへ内容 をフィードバックしています。この時のシステムデフォルトのコードページ が使われるため、開いたコードページを記憶しているアプリケーションで保 存しないかぎり予期せぬコードページで上書きされた状態となるのが真相の ようです。
エディットの動作は原版を開いた後にテンポラリーファイルへ移行し 通常はこのテンポラリーへ結果を自動保存。ユーザーからの保存指示があ った場合にのみ、原版パスへ当初のコードページで書きこむ動作をしなさ いという暗示なんでしょうね。これで、もやもやがある程度解消できました。
HTABOXのように何かを実行するというのは、誤った動作さえしなければ、ア トクサレの無い分野だと思うのですが、エディタというのはそれより責任が 重い分野だと思います。自分で作成していてのテストでさえ、編集中のファ イルコードページが変更されてしまったりするとブチ切れそうになりますが、 これが他人様の大切なファイルだったりした場合はそんな動作は絶対に許さ れないなわけで、どうしても慎重にならざるを得ません。
エディタは必要によりiniファイルを生成し、セッティングを保存できるよう にしました。現在設定可能なのは、フォント、文字数上限です。フォントは デフォルトでSYSTEM既定としています。文字数上限はデフォルト1Mで、軽量 さが要求される場合は64k、1M以上のサイズが必要な場合は16Mに変更可能で す。この文字数上限はiniファイルに記録され次回起動時に有効となります。 まもなく最終チェックを行って、リリースします。
しばらくリッチエディットの事も考えなくなると思うので、これの上に生きた HTMLのコントロールを美しく載せることができるかを、ちょっとだけ試して います。美しくなくてもいいのなら、HWNDとDCで構成されているウインドウ ですから何とでもなりますが、美しく埋め込まれた状態を実現したことが ありません。直感としてはちょっと無理筋な気はしているのですが。
前から気にはなっていたのですが「RichEdit50W」はOLE的に従前の不具合を 修正したバージョンのように思います。いままでそれ以前のバージョンでの 縦スクロール時に埋め込みオブジェクトに対して正しく情報が伝達されない 事に悩み続けていたのですが、50Wだとなんの苦もなく動くように見えます。 マニフェスト関連の動機でXP以降という方針を決定したことですし、50Wで テストを継続します。
リッチエディットに生きたHTMLを出現させると何ができるのかについては、 あまりに画期的なので私の想像の範囲を超えています。エディタ側に簡単な コマンド、例えば<html src="htt://hoge" width="480" height="320">を解 釈する能力を与えただけで、編集中文章にHTMLが出現します。もちろんクリ ックしてスクリプトが動くHTMLページです。で、ページは大きな一文字と認 識されていますから、必要なくなったらBSキーで削除することができます。 これを自身を書きかえるスクリプトと組み合わせると、かなり柔軟で面白い ことができると思われますが、後は皆さんにお任せします。このHTMLを表示 する機能は実装して、もしばらくは公表しないと思います。多分説明をされ た側が混乱してしまうでしょう。ここをご覧の皆さんだけが知っている機能 というのもなかなか素敵ではありませんか。
そのエディタって行番号表示はあるの?
>>589 いまのところRow、Col表示だけですが、将来は行番号にブックマークを付け
てジャンプできるようにする予定です。その実証コードは実験済みです。
最終的なテストの結果リッチエディットへのHTML埋め込みは、まだこなれて
いないと結論づけました。文章中に複数のHTML要求があると、システムは非
同期にそれをこなそうとしますが、場合によってはハングします。単体エデ
ィタの機能としては使えるかもしれませんが、HTABOXから起動することを前
提としていますので、もうしばらく先になります。それでは、その機能を削
除して取り急ぎエディタのリリースを急ぎます。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました2.51のままエディタを正式に追加しました。エディタは引数
無しでHTABOXAPP.exeを起動したウインドウのボタンから利用できます。まだ
モージュールとしての実績が乏しいですから、是非大切なソースは別名を作
成して編集、実行してください。誤動作で元ファイルを傷つけないようファ
イル名先頭にアンダーバーを付加したファイルを作成し、当該ファイルを保持
しています。SaveまたはSave Asの場合、保持していたテンポラリを対象にコ
ピーしています。リッチエディットバージョンは従前に戻しました。50Wだと
コメント識別等が機能しませんでした。原因が判明し次第リッチエディット
バージョンは50Wへ変更される予定です。
未踏破だと思われる事を実現する為にはまさに、一難去ってまた一難です。 当然多くの方が試みるでしょうし、実現が難しいとすれば、それ相応の理由 が存在するはずです。いつも一つの課題をクリアすると、待っていたかのよ うに次の課題が頭をもたげるものですから、そういう展開にはなれっこにな りました。正直言って50Wですんなり動いたときにわき出た感情は「やった」 ではなく「気味が悪い」でした。そのための代償を感じさせる成功というと ころでしょうか。この2.3日もいろいろありましたが、やはり痛感するのは 「書いて動かさないことには何もわからない」ということです。
そういえばヘルプウインドウを最小化してタスクへいれ、再表示すると上 パネルが大きさを主張しなくなる事に気付きましたが、ちょっとへとへと ですので一度休んでから直します。きちんと従前の表示割合を記憶して、 全体のサイズが変わっても、その割合を維持する予定です。
50WのTOM経由テキスト改行コードはCRのみだというのが要因でした。これは 地道に痛い変更です。全体文字列ならEM_GETTEXTEXメッセージで改行コード を指定できそうですが、TOMでRangeからGetTextする場合には今のことろCR のみを受け入れるしかないように感じます。まぁ20Aの頃からそういう仕様 になっていたようで、無頓着だった私の責任ではあるのですが、50W導入に 向けてCRLFに依存している部分を全部洗いだす必要があります。ひょっと して昨日のハングが文字列処理を起因とするものだったりするととても幸せ なのですが。
50Wへの対応が終わりました。HTML埋め込みがストールしているように見えた のはエディタ内に生成されたHTMLのwindow.externalに与えたWIN32インスタ ンスがが早期Releaseされるためrefカウント判断で終了していたものと判明 しました。本当はスタンドアロンEXEとして動作していますから、少々refが 違っても...とも書けるのですが、COMサーバー動作とコードを完全に共有す るのが2.x系の美学ですので、その辺が解決したらデモをお見せしたいと考え ています。
デモを書きながら気付きましたが、フォント設定は設定時に存在する領域に は有効ですが、新たな行で\がバックスラッシュになりますね。 EM_SETCHARFORMAT等をきっちり実行して正しく動作するように改善します。
あれっと思ってサーバ上の非50W版を見たら上記問題は起きていないんですね。 通常は難解な事ほど嬉しいと思ってしまう体質なんですが、50Wに関しては 下位互換くらい確保しろよっと文句のひとつも言いたくなります。
それでは驚愕の埋め込みHTMLとリッチエディットの連動デモです。
ttp://kuroda.bglb.jp/htabox/insert.zip デモのHTABOXAPP.exeを起動し、添付Insert.htmをエディタで開いてください。
内容は下記のとおりです。
<html>
<head><title>Insert HTML DEMO</title></head>
<body bgcolor="buttonface">
<textarea id="TAREA"rows="10" cols ="40"></textarea>
<input type="button" value="Add Text" onclick="Add(TAREA.innerText)">
<script type="text/JScript">
var WIN32 = window.external;
var TextDoc = WIN32.TextDocument;
var Range = TextDoc.Range(0, 0);
function Add(str)
{
Range.Move(6, 1); Range.Text = "\r\n<!--" + str + "-->\r\n"; alert(str + "を終端へ追加しました");
}
</script>
</body>
</html>
<!--右クリックのメニューから[Reset Bgcolor]を選択すると下記コメントが評価されHTMLが表示される-->
<!-- <html src="./Insert.htm" width="320" height="240"> -->
エディタ中に忽然とHTMLページが出現し、そのテキストエリアへ文字を入力 してボタンを押すと、エディタ終端へ無害なコメント形式で文字列が追加 されます。まぁ役に立つか立たないかは別にしてこれほど奇異な状態を目に する機会はそうないと思います。本来このHTMLページは大きな一文字として 削除できるのですが、その部分を書いていないので、文章上は削除されても 画面上はHTMLページが表示され続ける仕様であることに注意してください。 エディタの<html src="...">で生成されたHTMLへはwindow.externalでWIN32 が渡されています。またWIN32には、TextDocumentインスタンスが追加され ていますから、エディタ側を操作できます。
2.50でいろいろなものを見ていただきましたが、根底にある考え方は単純です。 何かに、他の何かを埋め込むというだけです。私は当初これをWIN32的に解決 しようとしていました。確かにネイティブウインドウとHTMLウインドウの立場 が逆転しようが、それぞれHWNDですから埋め込むことは可能でした。ただし その関係は疎遠であるため、常に子は親の状態を、または子は親の状態を監視 する必要に迫られます。これは内部でCOMが忙しく動作するような場合、結果的 にメッセージの流れをひっ迫させ、散漫な動作や予期せぬストールにつながって しまいます。またCOMを共有した場合そのコンテキストを適切に管理する観点 からも不利です。
そこでOLE手法の実験を繰り返しました。そして当初、実現すべき目的を極め てシンプルなものに限定しました。「親は子を自動的に移動させる」又は、 「親は子へ位置を指示する」さえ実現できれば、後はWIN32手法でなんでも解 決できるという考え方です。結果的にHTMLへネイティブを埋め込む時の手法は <object>タグ、ネイティブへHTMLを埋め込むための手法はインプレースアクテ ィベートに落ち着きました。
実験を行いながら、デバッガで動きを追跡すれば、おのずとスレッドやコン テキストへの理解は深まります。強引に持ってきたインスタンスを参照させ ると何が起こるのか、起こらないのか。要求されたインターフェースを返さ なかったら何が起こるのか、起こらないのか。こういった数行の変更による 数多くの情報収集ができたのは、すべてをスクラッチで書いていたからだと 思います。
最後に、私にとってネイティブ、HTMLと同じくらい重要なカテゴリーと位置 づけているリッチエディットへのHTML埋め込みを実践したわけです。その逆 にHTMLへの埋め込みはネイティブウインドウと同一な扱いです。これですべ てのパターンを統一された原理、理論、コードで実現できました。あとはこ れを活用するだけですが、私の頭はもうとっくに柔軟性が欠けていますから、 これとこれを組み合わせるとこんなことがきそうというアイディアがありま したら、気兼ねなく書きこんでください。可能な限り実現させます。
コンソール型の対話アプリケーションには、固定されたGUIになってしまう HTMLアプリケーションには無い柔軟性を感じます。ただし(Y/N)のキー入 力だけというのもこれまた単調すぎます。必要な局面ではチェックボックス やドロップダウンリストも使いたい。それを実現するのが今回のデモの真意 です。本来はGUIを持たないスクリプトからCreateConsoleWindow();を実行 して返されたインスタンスへParse("<html src='hoge'>");でコンソールの 流れの中にGUIを織り込むためのものと考えています。HTMLを表示できると いうことはHTMLとして評価できるものは何でも表示できるということです。 すでに、コンソールへ動画も追加できていることになります。
昨日のデモを改良しています。埋め込みHTMLはアクティブでない場合も実 ウインドウとしてエディタ上に存在していますが、非アクティブな場合は 単にスナップショットをビットマップ転送するようにします。これにより エディタの再描画時の負荷が軽減されますし、文章上での削除がそのまま HTML存在の削除に見えるはずです。50Wについて総括すれば、TOM経由で文 字列を取得した場合のCRLFがCRである点を除けば、公式ドキュメントどお りな事をすればきちんと動作するという印象です。実際にCRへ置き換えな ければならなかった個所は僅か3個所でした。考えてみればRangeを行拡張 してどうたら、という書き方をTOMでは行いますから、コメント文字列評価 時くらいしか改行コードに依存していませんでした。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.51のまま、エディタにタブインデント設定を
追加しました。予想はしていたのですが、TrueFontがらみで文字の実際の横
幅を取得するのにかなり難儀してしまいました。結局一般的な手法ではなく
実際にエディタへ半角スペースを表示させ、Selectionのサイズから横幅を
取得し、今度は\tに置き換えて、両者の横幅が一致するまでEM_SETTABSTOPS
指定量を増加させるというアルゴリズムを採用しました。エレガントではな
い手法ですが、いかなるフォントでも機能することは明白です。
2.51については不具合が発見されない限りバイナリの更新を一旦停止し、ヘ
ルプドキュメント作成を行います。エディタの仕上がりが予想より良かったの
で、解説ではHTABOXへ引数としてファイルを渡すよりも、エディタで開いて実
行する手法を推奨動作にしようと考えています。
エディタへのHTML埋め込み動作については結局変更しませんでした。HTMLを POPUPにして、MDI子にしたら...とかさまざまなバリエーションは試行しまし たが、どう利用するかが明確でない段階で、利用手法を限定するような記述 をすべきではないと判断しました。アプリケーションにとって最も重要なのは 基礎となるモジュールなものですから、これといって派手な機能をデモできた わけではありませんでしたが、ヘルプを完成させ、各方面への広報活動を開始 したら、DLLでコモンコトロール系やDirectX系の機能を追加してゆきます。
行番号表示に乱れがあるので修正しています。ついでですから、行番号表示 とブックマークジャンプも追加する予定です。Visual Studioのブックマーク はCTRL + k を2回なのですが、もうちょっと直観的な操作で設定できた方が いいように思えます。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.51のままエディタに行番号、ブックマーク機能
を付加しました。だた、微妙に不本意な部分がありますので継続して書きます。
ブックマークはCTRL+ K(トグルでON/OFF)
前方検索 CTRL + P
後方検索 CTRL + N
なぜか同じコントロールなのに、行番号と本体にずれが生じる点と、マウス
によるカーソル移動に反応しにくい点が、課題です。大規模なソースにな
るとブックマーク無しではとてもメンテナンスできませんので、是非活用し
てください。
ちょっと、どっちつかずな部分がありましたので、一旦ファイルの公開を 停止します。当初、順次行番号を生成して軽量にしたかったのですが、 ページエンドへの移動やマウススクロールではいきなり終端へゆくわけです からもう一工夫必要でした。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。さっきどこ直したんだっけ?を探すのに時間がかかるとい
う末期状態ですから、すこし気分をリフレッシュしないとますます変なこと
を書きそうです。意外と、並列に存在するリッチエディット間にもコンテキ
スト問題が潜んでいて、この20時間ほどは久々の消耗戦となりました。ヘルプ
を書きながらも、不具合を放置するわけにもゆかず、ついでに手を出したブッ
クマークは超難問で、へとへとです。
開発機では気付かなかったのですが、例の500MHzノートでは「重すぎる」 印象を持ちましたので、なぜかWM_PAINTごとに行っている、表示中ソース のスキャンを廃止して、軽量化したいと思います。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。従来は、場合によっては複数起動中の当該エディタから
ブックマークを含む領域がペーストされたら...というような考えすぎな
部分がありましたので、単に自身エディタ上のブックマーク宣言、解除
にしか関心をもたないように軽量化しました。マウスでカーソルを決定
した場合、若干行番号と本文がずれますが、そこを編集するためにキー
操作が行われると適正な表示となりますので、これは現時点では「仕様」
ということでご容赦ください。
50Wへの変更でそうなったのか、複数行インデント操作が正しく機能していな いことに気付きました。修正を行います。このエディタはHTABOXとは何か?を 知る窓口と位置付けていますので、完全なものでなければなりません。
1ヵ月かかってしまいましたが、例えば「拡張子を表示してください」とか 「引数として実行してください」とか、解っていればそれ以外に表現のしよ うが無いことをあえて噛み砕いて説明することの困難さを痛感していました ので、エディタで単にファイルを開き、内容を確認して単に実行という機能 は必須と考えていました。これはこれで、ツリーによるアウトライン操作、 VMLによるまったく自由な構造操作、必要によっては画像、HTML、動画等も プレビュー表示できる多機能なエディタとして独立した製品にして行けたら と考えています。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.52を呼称します。
CreateHelpWindowk関数にで生成されるウインドウはアルファレンダリング
によりフェードインするものとしました。これはヘルプ専用ですので速度
は要求されませんし、HTML構築時の楽屋裏がちらりと見えることを嫌った
対応です。2.5系の仕様は固まったと判断し、2.52としました。正規リリース
版バイナリと認識しています。ヘルプがまだでご迷惑をおかけしますが、
早急に整備いたします。
ヘルプは<PRE>中にサンプルHTMLを書きやすいFrontPageで書くのですが、 文章の全体構造を俯瞰することが困難ですから、50Wに対応したアウトライン エディタをこっそりと2.52へ実装中です。これもHTABOXの機能として説明 するのは受け取る側が混乱するでしょうから、実装はされているが公開さ れない機能になる予定です。もちろんここをご覧の皆さんにはその起動 方法をお知らせする予定です。
アウトライン処理のコードを改めて眺めると、まったくエレガントでないこと に幻滅してしまいました。もし、すべてのドキュメントが整形XMLであったなら アウトライン処理は極めて単純なものになります。しかし実際にはXMLエディタ で書かない限り、現実世界のHTML表現を完全な整形XMLに変換するのは難しいと 思います。そこに単純な正規表現コンバーターを導入して、相互の変換を単純 化しようと思います。やっと思ったことをC++で具現化できるようになりました ので、逃げずに取り組みたいと思います。
従来アウトライン処理は、見出しの文字位置、移動範囲文字数、移動先文字 位置等、をXMLノード集合の属性として記憶し操作していたのですが、煩雑 なので、単にCDATAに担当範囲HTMLを格納し、移動や階層変更が生じた場合 担当範囲HTML中に埋め込まれた管理コマンドを正規表現コンバーターが認識 し、処理するという発想にしたところ、見てのとおりのソースコードとなる ようです。つまり「<h3>hoge</h3>#本来はh2です#」という文字列から出力 時にh3をh2に置き換え、##間のコマンドは削除するアイディアです。
対症療法的な記述が積み重なった部分というのは、冷却期間を置いてから 見ると、めまいと、吐き気の原因になります。その事に真っ向から立ち向 かって解決しない限り、ただ漠然と「あの分野は嫌い」になりかねません。 今では私のプログラミングの中核をなすモジュール群もかつてはめまいの原 因だったものばかりです。でもしつこいようですが、一度書いて、動かし。 それが納得できず、いらだつというプロセス無しに次のステージには進めま せん。「楽しくないなら書かない」も一つの生き方でしょうが、走り切る 喜びは、走る苦しみを知る人間にしか訪れないと思います。
かなり悩んだんですが、結論から言うとリッチエディットの20A、50Wは素の 20とはTOM経由の動作がかなり異なります。20A、50Wでカーソル周辺の文字列 をRangeで正確に取得することは困難です。20Aのメリットは見いだせていませ んが、50WについてはOLE埋め込みコンテナとしてかなりの改良が加えられてい ます。その変更時に、基本的なRange操作の部分が意図的か、単なるバグかは 解りませんが結果的に犠牲になったと推察されます。やや面倒ですが、目的に 応じて動的に生成するバージョンをコントロールする必要があるようです。
http://kuroda.bglb.jp/htabox/outline.zip を用意しました。細かなテストは実際に使いながらになりますが、公開します。
バイナリは全く通常リリースのHTABOXAPP.exeと同じになりますが、起動引数
を与えることによりアウトラインエディタとして動作します。引数は添付bat
ファイルのとおりです。サンプルHTMLも添付しましたので、開き、ツリーの
更新を行って、ツリー上のドラッグや右クリックでアウトライン操作が行えま
す。
アウトライン専用ツールバーの内容はツールチップに表示されるとおりです。
自動整形はHTML中の<p><li>内を対象とします。<p>生成はCTRL+SHIFT+Pで<li>
の場合はPをLにしたキーです。SHIFT+Enterは<br>生成です。また、このエディ
タはHELPファイルを作成する目的で存在しますから、ツールバーの実行ボタン
はヘルプウインドウを生成して編集中HTMLをプレビューする動作となります。
このアウトラインエディタは操作対象を問い合わせるためにダイアログが 頻繁に表示されますが、ここで使っているダイアログはダイアログテンプ レートで生成されたネイティブウインドウ上へHTMLドキュメントを埋め込 んだものです。既成のHTMLダイアログはやや重いものですから、その生成 過程がちらりと見えたりしますが、このダイアログは軽量ですからそうい った事はありません。昔WIN32を触った当初に「完全に動的なダイアログ」 という夢を描いたものですが、これが動的なダイアログに対する私なりの 回答です。
従来のHTMLアプリケーションはMSHTAを使うか、HTMLダイアログを使うか程度 の選択肢しか存在しませんでした。前述のダイアログが示唆することは、まっ たく新たに、使用目的に沿ったHTMLアプリケーション用ウインドウを設計する できる事を意味します。3.00ではもはやMSHTA互換という言葉は出ますが、HTA という表現は意味がありません。すべてはHTMLアプリケーションであり、目的 沿ったウインドウを生成時に指定できる状態となるのです。
実際にアウトラインエディタの一時整形を使うと、期待した</p>が無い場合 動作が変ですね。とりあえず<p>以降に</p>以外のタグが出現したら離脱し、 CTRL+SHIFT+Pもペーストと被っていますからCTRL+SHIFT+ENTERに変更して テストしています。現在のヘルプが完成するまでには動作しながら細かな仕様 変更がありますから、ご了承ください。
631に書いたように3.00は従来のHTABOX(HTA用の箱)というイメージから 柔軟なHTMLアプリケーションベースへの変身を予定しています。現在は3.00 として開発されていますが、リリース時には全く別のアプリケーションとして 発表した方が混乱を招かないかもしれません。HTMLを書いて、それを表示する ウインドウのウインドウスタイルや、セキュリティー設定等、MSHTMLで可能な 要素は全て選択でき、動作の結果が良好ならそのままEXEにできるというツール になります。アプリケーションの書き方自体を変革する能力を3.00は持ちます。
ttp://kuroda.bglb.jp/htabox/outline.zip を更新しました。エディタ用ヘルプ、アウトライン用ヘルプを実際にアウト
ラインエディタで書いて、小規模ですが最終テストとしました。メニュー
のヘルプからエディタの、ツールバーからアウトラインのヘルプをご覧に
なれます。まだ、編集途中で落ちたことはありませんが、転ばぬ先の杖で
テンポラリの定期更新を追加しようと考えています。
とても基本的な事ですが、HTMLの表示テキスト中の改行コード等は単発だろ うが、連続だろうが半角スペースに変換されて表示されます。つまり、<p> から</p>までは長い一行でなければなりません。ヘルプのように長い段落の 場合、はたして最後に</p>が正しく存在するのかを確認するだけで嫌気がさ すのです。アウトラインエディタはデフォだと80バイトで一括整形し、編集 終了時に一括で長い一行へ変換できます。正直言ってこの機能なしに長大な HTMLを書く気にはなれないという理由で存在しています。
そういえばどうしてアンドゥバッファが無いんだろうと再確認したら、私が 愛用してしたリッチエディットは1.0系だった事が判明しました。それで謎が 解けまして、50Wは規格通りコントロールできることも判明しました。勘違い、 それも非常に足元の部分で躓いていましたので50Wにあらぬ濡れ衣を着せた ことをお詫びしなければなりません。もし、XP以前のコンピューターがあった らワードパッドにWORDで作成したクリップアート付きドキュメントをコピぺし てみてください。次にXP以降のワードパッドで同じことをやってください。 これが50W以降の威力です。
なんで私が混乱したか判明しました。MS側では必須と考えているafxwin.hに #define _RICHEDIT_VER 0x0210 が存在し、同じ文字列でのCreateWindowEx でありながら、リッチエディットのバージョンを切り替えているようです。 多分私はこのヘッダファイルを使わないので、同じコードでも1.0のまま だったようです。アウトラインを50WにするとIME確定時に整形で次行へカ ーソルが移動した場合にカーソルをコントロールできないという点が引っ 掛かりますので、せめて20WにしてCTRL+Zは有効な状態で妥協しようと思い ます。
アウトラインのツールバー背景が一旦最小化すると抜けてしまう状態を認識 しています。かなりネストした構造なので、親の色をButtonFaceとするよう な対応が考えられます。あと、改行や、タブがビットマップで記号表示され れば申し分ないのですが、今のところそこまで手が回りません。道具もでき ましたので、日本語を書くほうに専念します。
アウトラインエディタを見慣れた後に素のエディタを見るとあまりに寂しい ので、ツリーを持つエディタを新設しました。//で始まる一行コメントを 弓括弧の階層で認識し、ツリー表示するものです。適切にコメントが付加 されていれば、高速にソースコードを読み解くことができます。ソースコ ード観賞用エディタというところでしょうか。音楽家が演奏よりも楽譜で 音楽を鑑賞するように、プログラマーはソースコードでアプリケーショ ンを鑑賞することができると思います。もちろんそのためには鑑賞に堪え うるリズミカルで美しいコードを書かなければなりません。コードページ 認識にまだ問題がありましたので、そこを改良してから公開します。
エディタ環境を整えた事で、私の苦手分野であるに日本語での解りやすい説明 という分野が克服できた気がします。ソースであれば善し悪しは動作で明確な のですが、言葉に関しては「書いては消し」を繰り返しては結局形にならず、 なぜが、ソースの方をいじくりまわすという展開だったように思います。 すべてのヘルプ情報はツリーの付いた見やすいものに統一することにしました。 つまり、ヘルプウインドウをプロセス内で軽量に生成可能としました。アプリケ ーションの動作が変というご指摘をいただき大変助かっておりましたが、今後は 「ヘルプのここがわかりにくい」というご指摘もいただければ尚、助かります。 できる限り「作る側のエゴ」を捨てて取り説に臨んではいるのですが、捨てきれ ない部分があるかと思いますので、よろしくお願いいたします。午前中には改良 されたエディタ部を完全なヘルプとともにお見せできると思います。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.52のまま、CreateEditWindw2関数が追加され
、引数なし起動画面上のボタンで表示するエディタは同関数が生成したもの
となりました。エディタ系はCreateEditWindwで生成された既定クラスを拡張
してTバーウインドウへ格納し、追加された機能をツールバーで表現するという
規格を定めました。したがって基本的なエディタヘルプはメニューに存在し、
拡張機能ヘルプはツールバー上のヘルプボタンに存在します。
実際にアウトラインエディタで簡単なヘルプを2つ完成させたわけですが、 自身の書いたソフトに感動したのは実に久しぶりです。それ用にできてい る訳ですから、当たり前といえばそれまでなのですが、いままで面倒だと感 じていた作業をすいすいこなせます。結果的に心に余裕が生じますので、内 容もより客観的に評価できます。このペースで一気に全ヘルプを完成させま す。
エディタという観点から、開発手法全体をどう変革できるかを考えた場合に 真っ先に頭を過ぎるのが「ネイティブAPI」と「Javaクラス」の結合環境で す。.NETにしてもJavaにしてもHWMDやメッセージを直接操作している訳では ありませんので、厚手の手袋をして細かい作業をしなければならないような もどかしさが存在します。かつてのMSJVMはそういう意味で「理想的」だった のですが、ライセンスの問題で消滅してしまいました。エディタの状態で コンパイル前のソースを加工できれば、あらゆることが可能に思えます。
いろいろファイルのコードページ取得に関して試してはいるのですが、サン プルファイルさえ文字化けするケースがありますね。これは当初の計画どお り、化けるよりは処理をユーザーに投げた方が正解だと判断します。開く、 又は、保存は全て2系統あって自動と手動が選択できようにします。
コントロールパネル表示のステータスバーが気になります GUIを作るHTMLでも使えるんでしょうか
ステータスバーは普通、一番外側のウインドウが内にあるウインドウをステ ータスの幅分小さく表示する必要がありますから、既製品のHTMLウインドウへ 独自ステータスバーを追加する場合は、その特性を追加することになろうかと 思います。HTABOXAPP.exeのウインドウはネイティブなんですが、HTAウインド ウへ追加できるかちょっと考えてみます。
ネイティブにドキュメントが基底のCreateHelpWindowの場合は単純に可能です が、多分、既存のHTAウインドウの事だと思うので、多方面から検討してみま した。OLE的には既存HTAのフレームとドキュメントの結合は通常より堅牢で すから割って入ってもメリットは見いだせません。フレーム、及びドキュメン トのHWND操作ではOLE的に決定されているドキュメントの大きさを美しい状態 でコントロールすることができません。最も安定するのはHTAのフレームを子 とするネイティブHWNDを生成して3重構造とした場合です。この場合、外側の HWND同士が必要なメッセージを送りあう必要が生じますが、そのメッセージ を選別する作業が面倒なだけで、技術的にはなんら問題ありませんでした。 この件に関してはもっといいアイディアが浮かぶかも知れませんので、継続 した課題として捉えたいと思います。
確かにステータスバーも一度見慣れると無いことが寂しく感じられますし、 HTMLダイアログで代行した場合、要りもしない地球儀画像が入るはずでした ので、CreateHtaWindow2、CreateDlgWindow2として3重構造ウインドウを実装 したいと思います。ただし、これはMSHTAが生成するものとは本質的に異なり ますから、同一コードをMSHTAに食わせてHOOKということは原理的に不可能 ですし、当面HTA:Applicationによるウインドウ操作がアイコンのセット程度 に限定されることもご容赦ください。
ステータスバーの宣言は一行のテーブルとし、 <table id="STATUS"><tr> <td width="100px"></td> <td width="200px"></td> <td width="*"></td> </tr></table> 書き込みは、WIN32.PutStatus("hoge", n);みたいなルールを考えています。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。CreateHtaWindow2、CreateDlgWindow2を追加しました。
WSHでなくともCreateHtaWindow2、CreateDlgWindow2であることを明確にする
方法として、HTML系ファイルの拡張子末尾に2が付いた場合HTABOXはネイティブ
ウインドウを生成してHTMLウインドウをラップします。ただ、拡張子が独自
だと、他のエディタで編集しにくいことから、この辺はご意見をいただきたい
ところです。
レジストリ登録後、デモファイル群中のStatus.htm2をエディタで開き、必ず
Run HTABOXで実行してください。2分割されたステータス領域に文字を追加する
デモです。
デモで使用しているHTMLを掲載します。ダイアログの場合、複数同時もあり得 ることから、PutStatus関数はdocumentを引数に取ることとしました。 <html> <hta:application icon="INFO.ICO"></hta:application> <head><title>STATUS DEMO</title></head> <body bgcolor="buttonface"> <table id="MENU" style="display:none"> <tr><td>終了</td></tr> <tr><td onclick="window.close();">終了</td></tr> </table> <table id="STATUS"><tr><td width="200"></td><td width="*"></td></td></tr></table> <input id="T1" type="text"> <input type="button" value="Add Text" onclick="WIN32.PutStatus(document, T1.value, 0)"> <input id="T2" type="text"> <input type="button" value="Add Text" onclick="WIN32.PutStatus(document, T2.value, 1)"> <script type="text/JScript"> var WIN32 =new ActiveXObject("HTABOX.Application"); //メニューの構築はdocument構築以降でなければならない function window.onload() { WIN32.BuildMenu(document); } </script> </body> </html>
前から思っていたのですが、HTAとサイズグリップは相性が悪いですね、 自分のステータスでない場合にも嫌がらせをしてきますので一旦グリップ 無に変更します。
グリップ無だと安定しますので、そういう症状の出ないダイアログには気の 毒ですが、グリップ無で統一したいと思います。今までHTAのフレームウイン ドウのPOPUP権限をはく奪したことは無かったのですが、素直にWS_CHILDへ 降格してくれるのには驚きました。3.00になれば、HTAでなければという機能 は存在しなくなるのですが、一つのモニュメントとして意味のあるチャレンジ だったと思います。649さんに感謝いたします。
例によって枕元のPCで確認したらRunでエラーでした。早急に対策を行い ますのでしばらくお待ちください。一旦ファイルの公開を停止します。
昨日は新たなベースウインドウを作ったわけですが、自分でもこのての拡張 がこんなにすんなりできてしまうとは思っていませんでした。神様がすこし だけ私にご褒美をくれたんだと思います。ネイティブ内にHTMLドキュメント を埋め込むことは、極めて安定的に実現できていたのですが、HTMLフレーム を埋め込むことはしていなかったのです。このCreateHtaWindow2は生成時に ちょっとちらつきます。HTAは経験的に構築時SW_HIDEではストールすると 判断しているからすが、対策が無いわけではありません。表示されていれば いいのであって、それがスクリーン上ある必要はないことを突き、一時的に はるかかなたへ飛ばせばいいのです。でも、しばらくはどのくらいちらつく のかというデータ収集が必要ですから、現状のままになります。
機序が頭にあるうちに、このHTAフレーム降格手法をMSHTA.exe生成の既存イ ンスタンスへも拡張してみます。これが成功すれば、特別な拡張子で識別す る必要もなく、実行HTML中にid="STATUS"が存在すればCreate2系と判断する ことが可能ですし、場合によってはデフォルトでCreate2系を実行という選 択肢も生まれます。
突拍子もない話ですが、多分コンピューターの中身を知らない多くの方は大き な誤解をしていると思います。それは「いつかコンピューターは人間に近づい てくれて、アドレスやメモリイメージを考えなくてもプログラミングできるよう になるんじゃないか」という幻想です。事実はまったく逆です。アドレスやメモ リイメージを考慮しないということは考慮してくれるデバイスに依存するという ことですから「散漫で融通の利かない」ライブラリの中でしか仕事ができないこ とになります。もしろコンピューターは複雑化し根気の無い人間には理解不能 なものになりつつあります。もし本気でプログラミングを学習したいと考えるな ら、早いにこしたことはありません。もうすぐ狼になりたくても羊でいること を強要される時代が来ると感じます。
別プロセスHTAのフックによるステータスバー拡張はなんの問題も無く可能 でした。久しぶりにフックDLLのコードを眺めて、ずるいことを思いつきま した。考えてみればフックコールバックルーチンというのはアンフックする ために必要なのであって、相手プログラム終了まで付き合う気なら単なる サブクラスでいいわけです。ただしこのサブクラス実行のワンステップだけ フックした相手コンテキストでの実行でなければなりません。何が素敵にな るかというと、HWNDのメッセージプロシージャは本体EXEコードのコピペで いいことになります。
もうひとつ、思いついたんですが。HTMLアプリケーションで普遍的な存在と はドキュメントなわけで、その外郭に存在するウインドウは後で変更されて もいいわけです。今回のケースではSTATUSがドキュメント中で要求されそう だからウインドウを一枚足しているわですが、あらゆるケースでこれは有効 です。例えばCreateなのかCreate2なのかをユーザーは意識せずHTABOX側が動 的に対応するわけです。当たり前な展開ではあるのですが、なんとエレガント な発想でしょうか!!。
663は実践すると成功しませんでした。「HWNDのコンテキストはフックDLL 内の方が厳格である。」ということのようです。要はできるだけ個別な コードを書かずに楽をしようと思いましたが、フックはフック、サブクラス はサブクラスと分けないとコンテキスト問題固有の「得体の知れない」エラ ー停止にはまり込む懸念があります。
最終的にCreate2系を廃止し、通常Createでステータスが要求された時点で 動的にウインドウ構成を変更する方式を採用しました。MSHTA.exe生成後の フック動作についても同様です。したがって、HTABOXAPP.exeがレジストリ 登録されていれば、単にhtaを突っつくだけでステータスは表示されます。 今日は一日DLLをいじるはめになりましたが、最初の着想を若干手直しした パターンが唯一の正解コードで、それ以外のパターンはことごとくコンテキ スト問題でどこか変という流れでした。今日中には新たなステータスバーデ モをご覧いただけると思います。
少し疲れて気分が落ち込みました。コンピューターのディスプレイにこんな 四角形が表示されたところで、世の中1mmも変化する訳がないという気がしま す。今回は目標とするコンセプトをほとんど達成できました。説明の質は別 問題として、これを見ても誰も何とも思わない世の中ならば私は何を支えに 生きてゆけばいいのでしょうか。書けもしない似非評論家達に鉄槌を。
昨日は通常のHTMLでは表現できないウインドウ上の固定要素、つまりスクロー ルしても移動しない付加領域の追加を動的にこなすことができた訳ですから、 同じ手法でツールバーを追加してみたいと思います。以前デモでご覧いただい た、単純に画像がボタンになる形式を想定しています。ツールバー自体をHTML で表現可能にするのも一考ですが、それではHTML間の連絡が複雑化しますし、 フレーム分割してツールバーもどきを作るのとなんら変わらないことになり ますので、ここでは単純さと軽量さを目的としたものにしたいと思います。
以前にもツールバーをHTMLウインドウへ追加する試みは行っていたのですが、 解決できない問題が存在しました。それは画像ファイルのパス問題です。 私は、画像は柔軟にURLで指定できなければならないと考えましたが、そのた めには非表示のまま、指定URL上の画像データをビットマップハンドルへ変換 できるか?という壁が存在するわけです。HTTPプロトコルレベルなコーディン グを行えばいいわけですが、それではローカルな実在ファイルと統一された扱 いができません。最近になってそれが非表示HTMLドキュメントとモニカの連携 で実現できることに気付いたのです。この手法は非常に強力で、あらゆるHTML をバックグラウンドで画像化することが可能です。今回はその手法でツールバ ーとして指定されたテーブル全体の画像を非表示生成し各TD座標のDCからビッ トマップを生成しようとしています。
小ネタ exe生成の場合HTAタグでicon="start.exe"とか自分自身を指定しておくと、 アイコンリソースの置換にも追従するのでちょっと便利かも 当然exe自体をリネームされるとアイコンを見失うけどリネームはマニフェスト絡みで独自の警告が出ますし
>>671 アイコンにicoじゃなくexeやdllを指定する発想はありませんでした。
大変勉強になりました。ツールーバーデモで遊んでください。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。フックデモのToolStatus.htaはツールバーを含んだデモに
なります。レジストリ登録後なら単にhtaをクリックしても機能しますし、
当然HTABOXでも実行可能です。同一位置にあるtoolbar.htmは画像を定義する
ためのhtmです。これはツールバー生成時に参照されますが、表示はされませ
ん。
画像定義を別htmlにすることについては悩んだのですが、今後ツリービュー 等でどうしてもイメージリストを管理しなければならず、いっそ画像管理 htmlという位置づけで別ファイルとする選択をしました。本体のTOOLBAR テーブルは単にonclick="hoge()"定義ですので見てのとおりですが、画像 定義のルールについて説明します。 <html> <head><title></title></head> <body leftmargin="0" topmargin="0"> <table id="TOOLBAR" border="0" cellpadding="0" cellspacing="0" width="320" height="32" Mask="0x0"> <tr> <td title="タイトル0"><img src="img/tool0.bmp"></td> <td title="タイトル1"><img src="img/tool1.bmp"></td> <td title="タイトル2"><img src="img/tool2.bmp"></td> <td title="タイトル3"><img src="img/tool3.bmp"></td> <td title="タイトル4"><img src="img/tool4.bmp"></td> <td title="タイトル5"><img src="img/tool5.bmp"></td> <td title="タイトル6"><img src="img/tool6.bmp"></td> <td title="タイトル7"><img src="img/tool7.bmp"></td> <td title="タイトル8"><img src="img/tool8.bmp"></td> <td title="タイトル9"><img src="img/tool9.bmp"></td> </tr></table> </body> </html>
HTABOXは本体HTMLにid="TOOLBAR"を発見すると、同一フォルダでtoolbar.htm
を探します。発見すると非表示なまま評価し全体を一枚の画像として保持しま
す。この時全てのマージン、ボーダーは0pxでなければならないことに注意して
ください。特にbodyはデフォでマージンが存在しますから明示的にゼロを指定
しなければなりません。id="TOOLBAR"のテーブルにはwidth,heightが存在しな
ければなりません。ツールバーの場合この幅をセル数で割って個々の画像幅
としています。Maskは16進文字列の透過色です。できる限り純色が望ましく
可能であれば純黒か純白をお勧めします。省略時は黒が採用されます。
ツールバーは画像なのでツールチップによる説明は必須です。タイトル属性
の文字列は当該ボタン上にマウスがホバーすると表示されます。画像URLは
http://でもかまいません 。HTABOXは単にHTMLページの表示結果として画像を
取得するからです。
画像切り出し時に、論理的スクリーン上位置と、実際の位置に若干の差異 があったため、補正していますが、これは私の環境に依存しているかも知れ ません。もし時間があったら横に30個くらいのボタンを定義して最後のボタ ンも正しく表示できるか確認してください。もし、端が切れるようなら画像 が本来より左なのか右なのかも教えてください。お願いします。
エディタでHTMLを表示し、Run HTABOXを実行すると、高い確率でRunされた したインスタンスがWIN32を握って離さず、タスクマネージャーのプロセス 一覧で残留していることを認識しています。実害は生じませんが、当然修正 すべき点ですので、できるだけ早く対応します。実はこのRun状態で5つプロ セスが起動しています。4つはきれいに終了するのですが、1つ残る場合があ るようです。しゃくな事にRun MSHTAでは発生しないようです。
ToolStatus.htaを試すと確かに30個目以降のツールバーボタンが右側の表示、 31個目以降は加えて左側の表示も欠けますね あと終了時に必ず↓のエラーが出ます --------------------------- mshta.exe - アプリケーション エラー --------------------------- "0x01ee3d32" の命令が "0x7e63b190" のメモリを参照しました。メモリが "read" になることはできませんでした。 プログラムを終了するには [OK] をクリックしてください --------------------------- OK ---------------------------
>>677 大変手間のかかることを検証していただきありがとうございました。
mshtaの終了時エラーは環境、特にIEのバージョン情報を教えていただけると
こちらで再現した上で対策を講じられるかと思います。尚、終了時の動作を
見なおしてみます。
ツールバーの画像定義については環境が異なると最悪まったく表示されない ことも想定していましたが、情報をいただいて一安心しました。これについ ては、定義の方法自体にもっと素敵な方法が無いのかTableではなく他のタグ でもずれが生じるのか、という観点で再検討してみます。肝心な時に人並な 睡眠時間をとってしまいました。
改めて全体のコードを見直すと、特に開始処理、終了処理に手抜きが散見で きます。どうしても開発時は早く結果が見たいものですから、自身の環境で 動けば、後回しにしようとおもい、そのまま忘れるというパターンでしょうか。 ステータスのサイズグリップについては単に初期化していなかっただけで普通 に利用できそうな気配です。
サイズブリップは一見正常そうで、実はHITTESTでハングすることがあるよう です。以前のデモではドキュメント中に他のエレメントをどかす領域を作って もらってネイティブなコントロールを追加していましたが、これからはOBJECT タグでの追加になります。じゃあ外側のステータスやツールバーは?という 事に気づいて、今回のコーディングとなりました。特にフックで固められるは 、ウインドウを降格させられるは、余計なものは追加されるはで、MSHTAの身 になると大変気の毒なのですが、極めてアクロバティックな内容にも関わらず 起動時のストールが一切発生しない事には自分自身驚いています。
EXE生成デモも早期終了していますね。今日は全体を総合的に再点検して、混 雑ぎみのロジックを整理したいと思います。第一CreateHtaWindowの返却値を 保持することは必須条件ではなくなった訳ですから、単にExec的にウインドウ を生成し、起動スクリプトは終了できる余地が無ければならないと思います。 正直2.5系のソース量は3.00を完全に超えました。不用意にクラスを追加すると コンパイラでさえ解釈に苦慮する傾向があります。このまま化け物になる前に きちんと手を打たなければなりません。
EXE形式COMサーバーにとっての生命線は参照カウント管理に尽きます。従来 は唯一な存在であるDispMotherインスタンスを各子供達が握ることで、親は 間接的に子の解放を知るという方式だったのですが、実際にコーディングす ると、子が親経由で兄弟の持つメソッドを利用する必要というのは生じませ んでした。ならば、通常のアグリゲート手法で子への参照を親が集約管理し たほうがいいのではないか?というのが今日のテーマです。通常のコーディ ングが整形外科手術だとすれば、これは心臓外科手術ですが避けては通れな い課題だと思います。
ざっと親と子の参照関係をチェックすると、2.0初期に必要だった無駄な参照 を維持している部分や、サンプルHTMLをエディタから起動することで、WSH経 由での動作との間に私の勘違いが発生していることに気付きました。HTMLが 引数として渡された場合はそのHWND終了がEXE自体を終了させなければなりま せんが、WSHから起動された場合はCOM動作ですから、HWNDの終了では何もせず WSHがWIN32をリリースした時点でEXEが終了しなければなりません。この辺を きっちり押さえながら全体を見直しています。
BuildMenu関数は呼び出し元のウインドウへメニューを追加したりしているの ですが、呼び出しコンテキストこそHTML側であるもの、操作は別プロセスの EXEサーバー内なわけです。今まで表面化しませんでしたが、ステータスバー 追加の時点で被フックMSHTAがかなりぐずったわけはそこにあると思います。 その経験をもとにツールバー生成は、BuildMenu関数内で判断だけをし、呼び 出し元へ作業を依頼する方式としていました。これらを切り分けて動作させる と、最後に書いたツールバーだけが予測通りの参照カウントを生成し、従前の モジュールを付加すると、不正なものになるという結果が出ました。 プロセス残留は、本体->エディタ->Run HTABOXでしか発生しないのですが、 「HTABOXって何?」を手っ取り早く知っていただく重要な機能ですので、 完全な状態を目指したいと思います。
久しぶりに数時間、途中でテストできないコードをただ祈りながら書きました。 結果は良好です。HTML系ウインドウにユーティリティークラスを追加し、 HWNDへのメッセージコンテキストで全拡張機能を追加することに変更しました。 これを被フックHTA側コードへも追加し、終了時のクリーンナップを見直して 最終テストに臨みたいと思います。今回の変更は大きかったのでバージョン 2.54を呼称する予定です。
本編はとっくに完成していますが、デモのメッセージボックス関数だけが なぜか、引数不一致エラーなので引っ掛かっています。DISPIDを変えても 名前を変えても順番を変えてもと、あり得ないエラーなのですが、隣接メ ソッドは正常動作するというこの怪奇現象から抜け出せません。
現状のあらゆる要素を総合的に判断して、デフォルトで3重構造のHWND構成 とする判断をし、全体の調整を行っています。やはりHTMLインスタンスの HWND系の操作は自律的に行った方がいいという理由からです。従来コモン ダイアログをDIALOG名前空間で提供していましたが、これをUTILに改名し ステータスバーへの文字出力メソッドもここに置くことになります。短期 間で非常に大きな構造転換となりますが、書き換える事を恐れだした時こそ、 ソースが自分に敵対し始める時だと感じています。
今日は一日領域の解放とは何か?を突きつめて考えさせられた日でした。 確保したメモリ領域の解放を丁寧に記述すべきかという論争があるそうですが、 これは論争の題材にはならない事象です。なぜなら解放を記述する理由は明白 だからです。システム領域のハンドル等はその限りではありませんが、プロセ ス固有の領域に確保されたメモリはおのずと解放されます。この時どれが先に 解放されるかはスコープが階層化されていない限りくじ引きとなります。Aの上 にBがBの上にCが乗っている場合は通常C,B,Aの順に解放が行われなければ終了 時にお釣りをもらうようなメモリアクセスエラーとなりますから、明確に解放 を記述しなければなりません。
では、HTMLインスタンスの確実な終了タイミングを知るにはどうすればいい でしょうか?が今日の本題でした。普通はコネクションポイントと発想する でしょうが、これは活きている間のイベントを拾うものであって、本当に 相手が消滅したタイミングを知る為のものではありません。ここではCPUステ ップ単位での正確さ必要ですから、イベントのようにもっさりしたものでは 目的を達成できないのです。
私が最後に到達した方法は、実に単純でした。HTMLスクリプトインスタンス へ何らかのディスパッチを追加する。このディスパッチは利用価値があるも のでもいいし、単に寿命を知るための空なものでもいい。このディスパッチ のrefがゼロになりdelete thisされる時、最も正確にHTMLインスタンスの終 焉を検出できる。イベントもHWNDメッセージもこの正確さにはかなわない。 なんのことはないコロンブスの卵的お話ですが、これによって私が抱えてい た諸問題は一気に解決したと思われます。
COMにとって自身の開放判断はrefにより決定されます。HTABOXのようにEXE 形式のCOMサーバーの場合、クライアントプロセスからの呼び出しは基底で メッセージ通信に変換されていると推察されます。クライアントがWIN32を 保持しながら、完全なReleaseを行う前に、WM_QUITでメッセージループを 閉じてしまえば、クライアントは終了しても、サーバーは路頭に迷うわけ です。WIN32を握っているのはスクリプトであって見かけ上のドキュメント や、OLE的オブジェクトとは微妙に寿命が異なりますから、その消滅を正確 に知る方法を確立しないと、その場限りな結果となってしまいます。
そういえば解放の話で思い出したのですが、XPより後のOS上ではCOM呼び出し は中間でソフトウェア的ドライバが介在するようですから、利用元プロセス 情報を取得できません。利用元が正しくHTABOXを開放すればいいのですが、 そうでない場合残留します。残念なことにWSHは終了時のクリーンアップが 甘いと思われますので、最終行にWIN32.Quit();が無いとHTABOXは残留します。 もしWSH上のエラーで最終行に到達できなかった場合HTABOXは残留しますが 、いまのところこれを回避する方法はエラーの無いソースを書くということ だけです。ちなみにHTABOXへ引数として与えた場合、EXE生成用起動JSな場合 は終了時クリーンナップは自動的に行われます。ただし、エラー停止な場合 はそのかぎりではありません。2.54最終テストが終了しました。まもなく公開 します。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.54を呼称します。全域にわたってにメモリ
管理を見直しました。メニュー、ポップアップメニュー、ステータスバー、
ツールバーの作成コンテキストを変更しました。従来コモンダイアログを
提供していたDIALOG名前空間はUTILに改名され、PutStatus(str, index);
が、追加されました。UTILインスタンスは各ドキュメント毎に提供される
ため、document引数は不要となりました。UTILインスタンスはWIN32の仲間
では無いので、関数一覧には表示されませんが、ヘルプドキュメントにその
説明を記載する予定です。今回の改訂を顕著に表現するのが、フックデモ
のHTAです。
HTAウインドウは、別プロセスでHOOKな場合WIN32.BuildMenu(document);が 呼ばれた後、HTABOX内での実行では開始当初から3重ウインドウとなります。 外郭ウインドウが本来のHWNDを包む時に取得する情報はアイコンとタイトル だけです。ウインドウスタイルについて細かな制御を行いたい場合はonload 以降にWIN32.SetWindowLong(FraHwnd, -16 /*GWL_STYLE*/, hoge);等を実行 してください。HTABOXはウインドウに対する操作を可能とする低水準関数を 提供しています。
2.5で実現できたことは、旧HTABOXを書いていた頃の私にとっては夢のまた夢 だった技術ばかりです。あれからもう7,8年はたっていますし、着想してから は10年以上経っているかも知れません。そのために習得しなければならなかっ た技術を振り返ると、たとえアドバイスやサンプルが存在したとしても3年は かかるボリュームだろうと思います。いつかネット上でスクールを開けたら と思っています。本気で書きたい人だけが本当の事を学べるスクールです。
昨日は非常につらく厳しい時間を過ごしましたが、それだけに解決した時の 喜びはたとえようの無いものでした。なんでも気付いてしまった後になると 「当たり前すぎる」事なのですが、気付かなければ一生気付かないわけです し、気付けない事でそのプログラマーの実力が決まってしまう怖さがありま す。全ての可能性を実験したら天文学的数字のパターンになるような場合で も、直観を信じ、祈りながら書くしかありません。ただ、昨日の発見の功労 者はBeepです。要所要所に音階の違うBeepを忍ばせ、コードを変化させなが らそのメロディーを聴きます。耳というのは目と違ってミリ秒単位を確実に 聞き分けられますから大変有効な確認手法となります。
2.54のソースを一つのファイルにすれば540Kのサイズでした、行数約15000、 元来、本当に細かな事は書かない横着者ですので、エディタモジュールなど は既製品を流用してもこの量になりますから、趣味で取り組んで成功するボ リュームではありません。前職を続けながらでは、半端なものを書いて自重 で潰れるのは必至だったでしょう。貧しく、無能と人にさげすまされようが、 私は今、人生で最も「幸せ」なんだと実感しています。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。スクリプトエディタのドキュメントツリーを空な文書の
まま更新するとエラー停止する部分を修正しました。今までいろんなプロ
グラムを書いてきましたが、「バグが待ち遠しい」と感じたのは初めてで
す。レジストリ操作の時に負荷をかけるのは避けるべきですが、それ以外
の動作で他の何かに迷惑をかけることはおきませんので、いろんな意地悪
をしてみてください。
WSHからBrowseForFolderすると、必ずしも最前面に表示されません。いつも これを見ると「所詮スクリプト」と小馬鹿にされている気がします。そこで 、HTABOX内のBrowseForFolderはダイアログHWNDをコールバックで受け取っ ていますから、SetWindowPosでHWND_TOPMOSTすることにしました。また、 MessageBoxも最終引数まで受けるようにしましたのでMB_SYSTEMMODALを指定 すれば、常に最前面で操作できます。これらの変更を行ってサンプルスクリ プトをお見せする予定です。
var MB_YESNO = 0x04; var IDYES = 0x06; var IDNO = 0x07; var MB_SYSTEMMODAL = 0x1000; var WSS = new ActiveXObject("WScript.Shell"); var HTA = new ActiveXObject("HTABOX.Application"); var FSO = new ActiveXObject("Scripting.FileSystemObject"); var SourList = new Array(); function EnumSour(Folder) { for(var e = new Enumerator(Folder.Files); !e.atEnd(); e.moveNext()){var File = e.item();if(File.Path.search(/\.cpp$/i) != -1) SourList.push(File.Path);} //日本語混じりのフォルダは独自にソースを保存しているので除外している for(var e = new Enumerator(Folder.SubFolders); !e.atEnd(); e.moveNext()){var Item = e.item(); if(Item.Path.search(/[\u0100-\uffff]/) == -1) arguments.callee(Item);} } function Main() { if(HTA.MessageBox(0, "C++バックアップ", "", MB_YESNO|MB_SYSTEMMODAL) == IDYES) { var Sour = HTA.BrowseForFolder(0, "Select Search Folder?", WSS.CurrentDirectory); if(FSO.FolderExists(Sour)) { EnumSour(FSO.GetFolder(Sour)); var Dest = HTA.BrowseForFolder(0, "Select Destination Folder?", Sour); if(FSO.FolderExists(Dest)) { for(var c = 0; c < SourList.length; c++){FSO.CopyFile(SourList[c], Dest + SourList[c].replace(/^.+?(\\[^\\]+)$/,"$1"), true);HTA.MessageBox(0, SourList[c], "", MB_SYSTEMMODAL);} } } } } Main(); HTA.Quit();
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。以下の関数に変更が加えられました。
BrowseForFolder(long hwnd, BSTR title, BSTR root);
GetOpenFileName(long hwnd, BSTR title, BSTR filter, BSTR root, BSTR def, long flg);
GetSaveFileName(long hwnd, BSTR title, BSTR filter, BSTR root, BSTR def, long flg);
は必ず最前面に表示するよう変更しました。
MessageBox(long h, BSTR s, BSTR t, long f);
が新設されました。
サンプルJSはディレクトリ以下を再帰的に列挙し拡張子cppファイルを指定
ディレクトリへコピーしようとするものです。いつの間にかこのサーバーの
CGIは投稿改行数にうるさくなったので読みにくい状態となっていますが、
きちんと整形すれば見てのとおりの単純なスクリプトです。最終行のQuitが無い
とWSHはHTABOXを解放せず、HTABOXAPP.exeが残留することに注意してください。
尚、紛らわしいかもしれませんがHTML中スクリプトではHTMLコンテキストと 完全に同期した下記関数 UTIL.MessageBox(BSTR s, BSTR t, long f); UTIL.BrowseFolder(BSTR title, BSTR init) UTIL.GetOpenFileName(BSTR title, BSTR filter, BSTR dir, BSTR def, long flags); UTIL.GetSaveFileName(BSTR title, BSTR filter, BSTR dir, BSTR def, long flags); を使用しないと描画が正しく行われません。先頭HWNDは自動的に最外周HWNDと なり、識別のために若干名前が異なります。フックデモのHTA中はこれらの 関数を呼び出す例ともなっています。
と書き込むボタンを押して、やっぱり名前は統一すべきと判断して修正しまし た。現在アップされているバイナリは名前が統一されています。 MessageBox(long h, BSTR s, BSTR t, long f); BrowseForFolder(long hwnd, BSTR title, BSTR root); GetOpenFileName(long hwnd, BSTR title, BSTR filter, BSTR root, BSTR def, long flg); GetSaveFileName(long hwnd, BSTR title, BSTR filter, BSTR root, BSTR def, long flg); HTML中ではUTIL名前空間に同一な名前の関数が存在し、第一引数は自動的に 設定されますので、存在しません。と説明した方が絶対に解りやすいですよね。
考えてみると、この小さな箱の中にも、プログラミングに足を踏み込むと格 差とか、差別みたいなルールが存在します。スクリプトやHTAからコンピュー ターを見ている人間は所詮HTAだからと、その格差を甘んじて受け入れている 部分があるのではないでしょうか。でも、私はどんな入り口だろうと自分の コンピューターの動作を思いのままにする権利は尊重されるべきだし、その ための効果的ブリッジが存在すべきだと思っています。BrowseForFolderを 最前面に出すことはかなり面倒なことをやればスクリプトだけでも可能かも 知れません。でもそんなパズルゲームはお終いにして、誰かがHWNDを直接 操作するCOMを書けばいいというのが私の発想です。
Vista + IE9でテストを行いました。HTABOX本体の再描画とデータバインドDLL の認識に修正すべき点があるようです。特に後者はUACがらみでレジストリへ 登録すべき情報が不足しているかも知れませんので、情報収集が必要です。
Vistaで動作させて初めて知ったのですが、WSH用JSとかHTAを単にクリック しても、管理権限実行では無いのでオリジナルCOMのnew ActiveXObjectは 蹴られるんですね。ところが、HTABOXは管理権限起動していますから、その 引数だったり、エディタからの起動なら全く問題なく動作する。また、動的 マニフェストも完全に機能しています。 ここでもし、「COMDLLは、お金を払って登録していなければ実行させない」と いうロジックなのだとしたら、HTABOXは事実上それを無効化し、自由にオリジ ナルなCOMDLLを使える環境ということになります。ただ、もっと情報収集しな いとはっきりしたことは言えませんが。
ツールバービットマップマスクと、HTMLスクリプトが握ったWIN32の解放に もVista固有の対策が必要なようです。最悪、訳のわからないメモリエラー でお亡くなりになることも想定していましたので、この程度の対策はよし としなければならないでしょう。
IE9がWIN32を握って離さない事に対してもWIN32側の積極的Quitで対応する のが最も適切だと考えられます。そこで、HTML側がエラーで停止した場合の 検出問題も兼ねてWIN32.Init(document);でdocumentをもらうアイディアを 持っています。ドキュメントをもらえばそのHWNDは自明ですから、WIN32側 は定期的に当該HWNDの実在を検査し、実在しなければ停止と判断して自己 消滅することができます。
IE8のXPで試したらツールバー画像の透過色の部分がテーマに追従していないような感じです
>>711 IE9でもその症状を確認しています。内部でDDB->DIB変換を行っていま
すが、この時32bitのビットマップが作成されると、アルファレンダリングが
有効な環境では色情報4バイト目が透過度と判断されることが要因です。24bit
に統一するか、4バイト目を操作するかを比較検討しています。ただ、画像の
僅かなズレはやはり機種依存する部分でしたので、そこの検討にも時間がかか
ってしまっています。必ず解決させますので、ご期待ください。
現状ではまったく表示しないまま、画像定義HTMLが表示された場合の画像情 報を取得していますが、この魔法のような手法にも現状ではやや難点があっ て、ディスプレイドライバ毎の微妙な差異が発生してしまいます。その部分 の解決を先送りして、はるかかなたのスクリーン座標、又は生成中ウインド ウの裏で実際に表示すれば、必ず正しい大きさで取得できるのではないかと 考えますので、それを検証したいと思います。
結果的に非表示なままエレガントに解決することができました。アルファ 問題はDIB返還後のRGB情報をサーチし、指定マスクと同一だった場合当該 4バイト目に0x00を設定する方式としました。マスクに純色が望ましいと 考えるのはDDB->DIB変換を内部で行っているからです。今までの経験から たとえTrueColor設定でもWindowsは描画を高速におこなう目的でウインドウ 内の使用色を減色していると思われます。したがって中間色を指定された場 合DIB返還後にRGB値を正しく再現できない可能性が生じるのです。
これでVista以降、IE9に完全対応したHTABOXをお見せできます。今回の変更 で画像定義HTMLのBODYマージンはデフォルトのままでもいいことになりました。 画像座標も論理値と一致することから、何百個ボタンがあろうが、整然と処理 するはずです。逆に何百個もボタンがある状況のほうが、スクリーン上に存在 しないものを取得している魔法のメリットが活かされるかも知れません。
Vista以降では管理権限無しにMSHTA.exeを起動する形(単にhtaをクリック)で、 HTML内のnew ActiveXObject("HTABOX.Application");が評価された場合失敗 しますが、これはこれでいいんじゃないかと思います。HTABOXの引数として 実行するか、エディタで開いて実行すればいいわけですから、素のHTAや素の WSHで利用可能とするために、上納金を納めてまで安全とマークする必要は 無いと今のところ考えています。
逆に、HTABOXは管理権限でMSHTA.exeやWSCRIPT.exeを起動するランチャーと 捉えてもらうことの方に重点を置いた方が多くの方に使ってもらえるはずです。 これも本来はターゲットexeの傍らにマニフェストを置けば済む話なのですが、 私自身そういってマニフェストを置いて、後で後悔するはめにならないかと 躊躇しますから、HTABOXのチャームポイントとして利用すべきと考えます。
今回の修正の大きな変更はWIN32.Init(document);の追加です。これはHTML スクリプト中でnew ActiveXObject("HTABOX.Application");を行った直後に 必須な関数と考えてください。Init呼び出しを受けたHTABOXは引数ドキュメ ントが存在するプロセスハンドルを保持し、その終了を検出するとrefの数 にかかわらず、自身を終了させます。保持しているのがプロセスハンドルで あることに注目してください。したがってWSHからCreateHtaWindowが行われ た場合、WSH中のエラーでwscript.exeがストールしても対応できることにな ります。
Vista+IE9で動作しているHTABOXを眺めて、「これを書いたのが私以外の誰か でなくてよかった」とつくづく思います。私は極めて負けず嫌いな性格ですか ら、勝てる勝負しかしません。たとえその分野に興味があったとしても「とて も太刀打ちできない」と感じたら、そんな興味は最初から無かったことにして 次へ向かいます。とても了見の狭い話に聞こえるでしょうが、この世に1つし かいらないものを、もう一つ作る為に無駄な時間を費やしたくないのです。
自分のハードルは自分で設定するしかありませんが、「それなら書けそう」 と思えるものを世に出して飯が食えるほど世の中は甘くないとすれば、「どう なっているのか想像もできない」くらいのものを書かなければならないだろう と思ってきました。この5年間私に休日という概念はありませんでした。常に 前へ、常にその先へ、人が成しえなかった領域へ、その過程で世界中の洗練 されたコードに助けられました。そして日本にもそういったサイトは存在し、 彼か彼女の書いたコードは多くのインスピレーションを私にもたらしました。 何かを成し遂げた時こそ、つくづく人間というものは、独りでは何もできや しないと感じます。本当に私に関わっていただいたすべての方々に感謝して います。
ツールバー画像の座標や透過色のテーマ追従を確認できました ただ何回かに一回、マウスカーソルがdefault→progress→default→……と ひっきりなしに切り替わり続けることがあります 同じ1.73GHzでもXP+IE6よりXP+IE8の方が発生しやすい模様です
>>723 情報ありがとうございます。GUIスレッド問題だと思いますが、一旦
対応して、当方では症状が出ていなかったのですが、まだ対策が甘いのかも
知れません。表示までの手順、表示モードが複数あるものですから、出現を
確認した手順を教えていただけると助かります。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。ツールバーが表示しきれない場合にページャーコントロール
が表示されるようにしました。尚、HTAフック環境ではなぜか100px早くページ
ャーが出現しますが、今のところ「仕様」であるということにします。
>>723 若干対策を強化したバイナリに変更しました。今までの経験から数秒で解決
できる事とは思えないのですが、現在アップされているEXEを試してみてくだ
さい。
IE8環境を実験用に構築し、GUI問題の発生しやすい500MHzで繰り返しあらゆる パターンを試していますが、いまだ再現できていません。このダミーウインドウ が原因で、アクティブウインドウの切り替わりが美しくない状態となりますので 原理的に別の対策を行った方がいいかも知れません。
これを確実に防止する方法は実に簡単なんです。多分それをやると「うざい」 と言われるんでしょうが、スプラッシュウインドウを出せばいいんです。 「HTABOX CORE ....」とうかいうウインドウが開始当初に一定時間表示され れば絶対に起きない問題です。もしそれが最も確実だとしたらそうするかも 知れません。ソフトハウスさんへ納入する場合はそこをユーザーさんのロゴ に変えればいいという発想です。
728 :
723 :2012/05/15(火) 20:49:46.44
一番発生しやすかったのはXP+IE8環境で、
EXE生成デモで作ったアプリケーションを多重起動して次々にそのウインドウを閉じていった時ですね
最新のバイナリを試すのは個人的な事情でちょっと後になりそうです
>>727 0×0pxのスプラッシュウインドウでも防止策として有効なんでしょうか?
>>728 わざわざありがとうございます。もっといい解決策を思いつきました。本家
MSHTA.exeと同じくメインスレッドでHTAインスタンスを生成してみようと思
います。従来はメインスレッドで生成後の処理をこなす必要があったのです
が、考えてみると今は何もしていないことに気付きました。
GUIスレッドと認識されるためにはuser32.dllをコールすれば足りるはずです
が、現状の0pxでウインドウとしての振る舞いが不十分ならスプラッシュとい
う選択肢も考えてなければならないという展開です。少なくともアクティブ
ウインドウの引き継ぎが0pxでは円滑に行えないことは明白です。
確かにご指摘の操作で症状を確認できました。「終了しました」メッセージ ボックスからのアクティブ引き継ぎ動作時に発生するのは、依然と同じ機序 です。まずは抜本的なスレッドデザイン変更からとりかかります。あと、 EXE化後にウインドウ生成時とメニュー生成時のちらつきが気になりますので 場合によってはonloadでメニュー生成せず、スクリプト冒頭で予約してウイ ンドウはメニュー生成以降に表示されるというような実験も試みたいと思い ます。
HTAをプライマリスレッド生成すれば、当たり前ですが本家と同様にごく自然 に動作します。余計なダミーウインドウも生成しないので、アクティブウイン ドウの受け渡しもごく自然です。これを採用したいと思います。ただし、WSH からCreateHtaWindowを呼ぶ意味は希薄になります。もしHTMLウインドウを 生成し、そのドキュメントをWSHから操作したければ、CreateDlgWindowを使う ことになります。CreateHtaWindowは値を返さないだけでなく、自身のプロセス をきれいに終了させようとするようです。まぁこれが本来の姿なのですが。
デモには含まれませんでしたがCreateDlgWindowでもツールバーやステータス バーはHTAと同様に表示されます。外見上の違いはBODYのデフォルトマージン が0pxであるだけです。ただアイコンの設定能力がありませんので、以前に 作って置いた関数を実装して設定可能にしたいと思います。
ただ、COM経由だと問題がのこりますね。おそらくコンテキスト問題でHWND を自在に操作できない。3.00では当初からHTAウインドウはモーダルダイア ログと同等の扱いで動作をブロックするという設計にしていますが、レジス トリ登録してのCOMサーバーにはならなくていいという前提でのデザインです ので、2.5のうまみを維持しながらここを解決するためにはもうすこし考慮 時間が必要なようです。
冷静になって動きを追跡すると、まずCOMサーバー動作でダミーウインドウを 生成していないという凡ミスが最大の要因でした。さらにHTMLウインドウ終 了時にGUIスレッドと認識されているダミーウインドウへ確実にActiveを渡す と別プロセスへのActive移譲も通常通り行われるようです。したがってHITTEST 先を発見できずにマウスが点滅状態になることも発生しないと思われます。 結果的に0pxのCreateWindowExだけでもGUIスレッドとしては有効であるという 教訓を得ることができました。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。HTML系ウインドウが表示される直前にメインスレッドで
ネイティブな非表示ウインドウを生成し、HTML終了時にアクティブを譲り
受ける動作としました。これにより、複数のインスタンスを生成し、ラン
ダムに終了させてもアクティブなウインドウが必ず存在する状態になった
と思われます。結果的にマウスのちらつきが発生しないことを手元の環境
では確認しました。私独りでは年々経っても気付かないようなミスだった
かも知れません。大変ありがとうございました。
GUIスレッド問題を私なりにまとめてみると、プライマリスレッドで生成され たGUIスレッドはSetActiveWindowをしなくてもシステムがActive、非Active が管理される。これがもっとも望ましい状況。別スレッドからウインドウを 生成した場合、SetActiveWindowが必要になる場合がある。つまりプロセスと 親密な関係には無いウインドウと認識されている。したがって非アクティブ になる前にプライマリで作成しておいたGUIスレッドをアクティブとしないと システムが混乱する。
そこで私は全てをプライマリスレッドで生成するように書き換えた。これは 本来あるべき姿だったが、EXE形式COMサーバーとして呼び出された場合、EXE 内スレッドのコンテキストと呼び出し側コンテキストとの差異により結果とし てウインドウへの操作は100%の失敗ではないものの、コンテキストの一致が 条件である場合は失敗する。したがって、スタンドアロン動作の状態から、 別スレッド生成とすれば、GUIスレッドに対する手当は必要になるものの、 COMサーバー動作時にまったく同一のモジュールを使用することができる。
3.00では全てのHTMLウインドウ生成にその動作当初から関与する設計として いますが、2.5の場合、3.00手法に欠点が見つかった場合の保険として従来 手法の延長線上に置くというスタンスで取り組んでいます。これで2.5が一 段落し、3.00へ手が移った時「そんな事もできなかったっけ」がいくつか 出現すると思うのですが、その場合3.00が2.5側へ歩み寄ることになるだろ うと思います。EXEのCOMサーバーであるべきかというのが一番のポイントに はなるのですが、いままで「得体の知れない問題」と捉えていた事が一つ づつ明確になるにつれ、COMサーバーとしてのメリットを活かした設計に魅 力を感じつつあります。
本格的にちらつき問題に取り組み始めました。今日中には結論を出したいと 思います。勿論、生成後にフックしたMSHTA.exe由来のHTAがメニュー構築で ちらつくのは、ごく当たり前ですからフォローする気にはなりませんが、HTA BOX由来な場合はさまざまなアプローチで表示前のHWNDを操作できますから、 ドキュメント構築まではアルファを落としてメニューの構築如何に関わらず ドキュメントの完全な構築を待ってアルファを上昇させる手法が最も美しい と考えています。
このアルファ操作については、難儀する予感がしていて、先送りしてきたと いうのが真相なのですが、意外とあっさり実現できました。Vista+IE9でも まったく問題ない手順を確立することができました。メニュー関数呼び出し が必須ならもう何も書く必要も無いくらいなのですが、もし、メニューを 必要としていなかった場合にも対応すべくロジックを考えなければなりませ ん。
この場合へたに仕組みを考えるより、呼び出し規則を考え直した方がいいと いう結論に達しました。WIN32.Init(document);が呼ばれた場合、ドキュメント の構築を待って、自動的にメニュー等の各コントロールは生成されます。つまり WIN32.BuildMenuは廃止され自動化されます。こうすればメニュー等の生成要素 の如何に関わらず、HTABOX側はアルファ上昇のタイミングを取れることになりま す。
今までガタピシいってから表示されていたのが、ぬぅーと出てきますから 思わず笑ってしまいます。まだまだ、稚拙であることは否めませんが、こ れでプログラムを書く立場のプロフェッショナルにも見せられるクォリテ ィーに達したと判断します。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。CreateHtaWindow、CreateDlgWindowは初期アルファ0x01で
メニュー構築完了後に0xffまで上昇しWS_EX_LAYEREDを破棄します。
WIN32.BuildMenu()が廃止され、スクリプト冒頭での初期化WIN32.Init(document);
が必須なものとなりました。この関数はドキュメント構築状況を検査し、
構築完了と判断した場合メニュー処理を行います。
また、ウインドウ側はメニュー処理動作後に表示されます。もしこの初期化
関数を呼び出していないと判断された場合(10秒でタイムアウト)ダイアログ
にタイムアウトでの表示である旨の表示が行われます。
ウインドウの初期アルファレンダリングは原理的にフックしたHTAには適用
されません。Run HTABOXでの実行、EXE化しての実行で有効なことに注意して
ください。
これで、しばらくの間新たな機能が追加されることはありません。もちろん 修正すべき点は、即座に対応しますので、なんなりと書き込んでください。 ヘルプドキュメントの完成が遅れていることをお詫びいたします。
EXE生成デモでまたタスクボタンが二重になるようです
ご指摘のとおりです。ただ今回のは前回と原因が異なるはずなので、0.5秒 とはいかないようです。できるだけ早く修正します。
今まで一番地味だと思っていたEXE生成のstart.jsなんですが、手軽にぬぅー を見れるのでつい実行してしまいます。このstart.jsが表示するHTM/start.hta でもWIN32.Init(document);していますから、WSHプロセスの終了を検出して HTABOXは終了します。ですから以前のstart.jsにあったWIN32.Quit();は削除 されています。
ソースの履歴を見ると2.50を触り始めたのが4月6日でしたから、2,3日で終わる はずの非公式修正が1カ月と10日の全面改訂になってしまいました。3.00開発で 基礎的な情報集積がありましたので、4,5日触れば現状の基盤の上でどこまで 可能かはめどがつきました。いろいろチャレンジもしましたけれどその中で、 きちんと公開するというプレッシャーをかけた状態でエディタを書きあげた ことが最も大きな収穫だったと思います。エディタで開いて実行、3.00の場 合はエディタで開いてEXE化が私のイメージですので、無くてはならない要素 ですし、そこがバギーでは全体の機能がどうたらという前にそっぽを向かれ ますから、かなりの時間をそこにつぎ込みました。
現状の2.5を総括すると、私の観点からは「出来すぎ」に思えます。前に進む ことを止めはしませんが、「3.00って本当に必要なの?」という気持ちが湧き 起こってしまいます。昨日は根本のスレッドモデルを変更して情報収集しまし たが、改めて局面ごとに自分がした選択を顧みると、それ以外の順序でそれは 実行できない、それ以外のタイミングでそれは取得できないというようなタイ トロープを渡りきっている事に気付きました。旧HTABOXから脈々と続いてきた 既存HTA環境に対しての鬱積を完全に晴らす完成度だと自負しています。
3.00が目指すところはもは更にその上の高みです。HTMLはアプリケーション 開発をどこまで効率化できるのか。言語間の壁を取り払いCOMという共通プラ ットホーム上でいかに連携させるか。組織としての開発ではない環境で、組織 と伍して戦える製品を生み出せるパフォーマンスをいかに提供できるか。その 時、ネットワークやサーバーはどう組み込まれるべきなのか。贅沢は言いませ ん。私がそのことを考え続ける時間さえあれば、必ずその具体例をお見せでき るでしょう。ただし、その時間があるかどうかはこの2.5が世間にどう評価され るかで決まってしまうでしょう。
>>753 コア2.40のエンコーダと
ブラウザ上で作動するWYSWYGなHTMLエディタと
作成したアプリケーションの部品を公開して有料または無料で配布できるオンラインストアを
足して割らないようなIDEを妄想しました
>>755 ソフトウェアの最大の特徴は「原材料コスト」がかからない事です。つまり
いかなる「妄想」も実現可能なのです。みなさんのご意見を実現するのが私
の存在理由だと思います。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。行番号表示を改善しました。詳しく説明すると長くなります
が、ほとんど改行だけで一行だけ長い文書を表示し、その長い行の末端だけが
見える状態まで右へ水平スクロールし、マウスホイール、又はスクロールバー
で垂直スクロールした場合にも、正しく行番号は追従します。
DC上の微妙なオフセットは表示されている文字でなければ比較できませんの
で、従来は表示先頭行だけ検査していましたが、表示先頭行に表示領域文字
が無い場合、表示中の行を列挙して位置取得可能な文字を発見したら、オフ
セットを判定することにしました。
エディタに関しては、はっきりいって「ズブの素人」ですから、こんなんじゃ つかえねーよ的要素があったらこっそり教えてください。速攻で改善します。
行番号デフォルトは4桁9999ですが、この状態でHTABOX本体のソース15000行 を読み、スクロールを繰り返すとGDI的な乱れが生じるために、番号最大数を 明確にしました。3桁から6桁までを選択できますが、この設定は再起動後に有 効となります。もし、3桁の設定で1000行が出現しても番号側が描画を無視する ことで、描画が乱れる可能性も排除しています。
HTABOX2.5については現状の未エンコード状態でのリソース格納になんら量的 制限をかける予定はありませんが、EXEバージョン情報を変更する関数は将来 に渡って提供しないことにしました。商品として購入していただいた場合、 当該製品は個別にバージョン情報を設定してビルドされます。また、このバー ジョン情報領域にチェックサムを導入し、単純なバイナリ置き換えで改変された 場合、警告後にEXEの動作そのものを停止するロジックを考えています。
また、購入していただいた場合 SetResourceFromFile(BSTR dest, BSTR type, BSTR id, BSTR path, BSTR key); 等のリソース格納関数、最終引数がユーザー指定文字列と一致すれば、起動スク リプトはエンコード後に専用領域に格納され、エディタでも見えない状態にします。 また、エディタ上でHTML中のスクリプトを範囲指定し、ユーザー指定文字列をキー とした本格的エンコードで掩蔽します。これによりHTMLアプリケーションである ことのデメリットはほぼ消滅することになります。
バージョンリソース周りのロジックは完成しました。当初これを根こそぎ置き 変えようとし、非常に困難であることを知りましたので、それを逆手にとって 利用し、正規リリースの非クローンEXEであることを条件にエディタ上のエン コーダー、デコーダーは動作します。
前々から、悩んでいたのですが.NET系パース動作には3.00用に開発した別 プロセスを積極的に利用する方式を導入してみようと思います。HTMLでの .NET利用はどうしてもそのパースにかかる時間的コストとの戦いになるも のですから、武器として使えるものは何でも使おうと思います。結局こう して書いて見ると、3.00開発で実現しにくかった事を盛り込むものですか ら、既成HTML生成手法ではあるもののHTABOX4.00的様相を呈してきました。
#include <windows.h> class TestWin { static LRESULT CALLBACK OuterProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){return(((TestWin*)GetProp(hwnd, TEXT("CLASS")))->InnerProc(hwnd,uMsg,wParam,lParam));} public: HWND Hwnd; WNDPROC DefProc; TestWin(){WNDCLASSEX ex ={sizeof(WNDCLASSEX), 0, DefWindowProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),(HBRUSH)GetStockObject(WHITE_BRUSH), NULL, TEXT("TestWin"), NULL};RegisterClassEx(&ex);} void Make() { Hwnd = CreateWindowEx(0, TEXT("TestWin"), TEXT(""), WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); SetProp(Hwnd, TEXT("CLASS"), this); DefProc = (WNDPROC)(LONG_PTR)SetWindowLong(Hwnd, GWL_WNDPROC, (LONG)(LONG_PTR)OuterProc); } LRESULT CALLBACK InnerProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { if(uMsg == WM_DESTROY){SetWindowLong(Hwnd, GWL_WNDPROC, (LONG)(LONG_PTR)DefProc); RemoveProp(hwnd, TEXT("CLASS"));PostQuitMessage(0);} return(CallWindowProc(DefProc, hwnd, uMsg, wParam, lParam)); } }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG Msg; try { TestWin Win1; Win1.Make(); TestWin Win2; Win2.Make(); while(GetMessage(&Msg, NULL, 0, 0) != 0){TranslateMessage(&Msg);DispatchMessage(&Msg);} } catch(...){MessageBox(NULL, TEXT("Unkown Error"), TEXT(""), MB_SYSTEMMODAL); return(1);} return((int)Msg.wParam); }
このCGIの行数制限の中で、私が提唱するC++的WIN32プログラムが書けるか という興味が湧いて、投稿してみました。インデントが無くなるので読みに くくなりますが、これを実行するとWinMain内で2つのウインドウが生成され ます。これはTestWinの2つのインスタンスですが、全ての処理はクラスイン スタンスで行われる為に絶対衝突しません。これがC++でWIN32を書く最大の メリットです。staticなOuterProcはファイルスコープでは?という疑問は そのとおりですが、この場合のメッセージはWinMain内のループから順次送 られて来ますから同時呼び出しは発生しません。
なんでCの欠点をせっかくC++で改良したのに、いまだに拡張子だけcppで中身 はCなサンプルだけなんでしょね?これで頻繁に行われる処理をグローバル関 数にしてしまっただけで、衝突回避策が必要になってしまいますから、入門者 も嫌気がさしてしまうでしょう。こうしてクラススコープに引きずり込めば、 後はスクリプト同然な記述でプログラミングできるようになります。
#include <windows.h> class TestWin *TEST_WIN; class TestWin { static LRESULT CALLBACK OuterProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam){return(TEST_WIN->InnerProc(hwnd,uMsg,wParam,lParam));} public: HWND Hwnd; TestWin(){WNDCLASSEX ex ={sizeof(WNDCLASSEX), 0, OuterProc, 0, 0, NULL, NULL, LoadCursor(NULL, IDC_ARROW),(HBRUSH)GetStockObject(WHITE_BRUSH), NULL, TEXT("TestWin"), NULL};RegisterClassEx(&ex);} void Make() { TEST_WIN = this; Hwnd = CreateWindowEx(0, TEXT("TestWin"), TEXT(""), WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); } LRESULT CALLBACK InnerProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { if(uMsg == WM_DESTROY){PostQuitMessage(0);} return(DefWindowProc(hwnd, uMsg, wParam, lParam)); } }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG Msg; try { TestWin Win1; Win1.Make(); while(GetMessage(&Msg, NULL, 0, 0) != 0){TranslateMessage(&Msg);DispatchMessage(&Msg);} } catch(...){MessageBox(NULL, TEXT("Unkown Error"), TEXT(""), MB_SYSTEMMODAL); return(1);} return((int)Msg.wParam); }
ついでですから、こんどはメインウインドウのように1枚しかいらない場合の 記述です。2つの例のうち前者はリッチエディット等のコントロールを想定し て、SetPropでHWNDへthisを教え、GetPropで取得する、またサブクラス化の ためにSetWindowLongしていますが、後者の方は単にクラスへ引き込むだけ です。逆に後者はいろんな書き方ができてしまうのですが、スタイルを統一 するために前者と同じ書き方を踏襲した方がコードの融通がききます。
まぁかくいう私もその事に気付くのに2年くらいかかった気がしますし、今の サンプルに落ち着くまでさらに2年くらいかかっていると思います。今更C++ はとっても素敵といったところで、難解だという観念を払拭することは難しい のかも知れませんが、これこそ人類の成し得た最高の英知であるにも関わら ず、数年持つか不安な言語がもてはやされるのか不思議でなりません。
2.5の場合COM的な混乱を回避するためにエディタでサンプルを実行するだけで 複数プロセスが起動するわけですから、これを単純に2倍のプロセスとするのは やはり美しさに欠けるような気がします。考えてみれば、GUIスレッド対策で 仕事をしないHWNDがメインスレッドにあるわけですから、どれほど時間の短縮 につながるかは実行してみなければ解りませんが、そいつに.NETパースを担当 してもらうというのがエレガントな解決方法に思えます。
.NETパースのテストを開始する前にモードレスダイアログがたまに言う事を きかない場合があるので、試行錯誤しているうちに徹底分析モードになって しまいました。自分でもたまに首をかしげるようなものをひと様の前に出す わけにはゆきません。結論から言うとモードレスダイアログはHWND生成まで 触ってはいけません。土台別スレッドだからモードレスなのであって、呼び 出し側のネイティブなスレッドがアタッチした途端にいつ不安定になっても おかしくない状態となるようです。つまりダイアログ側スレッドへ侵入して 監視しなければならず、生成後にアタッチ可能である旨を呼び出し側へ伝達 しなければならないというのが真相のようです。現在はモードレスダイアロ グでのみこの対策が必要と判断していますが、例のreadyState病がなぜ発生 するのかを考えた場合、HTML構築に負荷がかかるとHTMLインスタンス全般に ついて同様な心配りが必要なのかも知れません。
WIN32.Init(document);によるメニュー自動認識と、遅延構築されるサーバー ASPを用いたフレームHTMLとは、相容れない要素があるので、 WIN32.Init(document, bool);第二引数が真ならメニュー自動構築と初期アルファ レンダリング、偽ならいずれも行わないという仕様へ変更する予定です。
今日は暗号化、復号化の仕様を決定しようと思います。考え方としてはアルゴリ ズム自体を多重なものとし、複数の要素から実行時のアルゴリズム自体を変化さ せることを考えています。もちろんそれをコントロールするメタアルゴリズムが 存在することになりますが、製品としてのHTABOXは個別にビルドされるメリット を利用して、特定のバイナリについてアルゴリズムが判明しても、別バイナリに は通用しないというルールを確立することが目的です。従来、プログラムは同一 のバイナリをコピーして配布されましたから、1つがクラックされれば全滅だった わけですが、ユーザーの要求を受けてサーバーが再ビルドし、オリジナルなもの とすればそうではなくなります。最初はそんなに注文があるわけではないでしょう からそれを手作業で行いますが、最終的にそれを自動化することを視野に入れた ロジックとしなければなりません。HTABOX全体を見渡しても個々のコーディングは どっかで誰かも書いているでしょうね的レベルですが、システムとして最終的に 目指す規模の大きさ、そして、それを実現するために必要な極めて広範囲な知識 という側面においてHTABOXと私は稀有な存在だろうと思います。
3.00もその予定ですが、エディタ上で気軽にエンコード、デコードを繰り返 せる訳ですから、何らかの規則性が見てとれる場合、それを手がかりに解読 される懸念があります。本家のエンコーダーはそのいい例で、コードを変化 させると前後のチェックサムも素直に変化しますから、難読化程度にしかな らない訳です。今日書いているエンコーダーは多段な暗号化の途中で、全く 再現性の無いノイズを加えることにより、同一コードを繰り返しエンコード しても、全く別なコードを出力します。木は森の中に隠せと言いますので、 元のコードに対してエンコード結果が大きいほど堅牢になりますが、処理速 度との兼ね合いがありますので、大きくても2倍程度に抑えられればと思って います。
文字列変換も突き詰めて様々なケースを考えると、奥が深くて手間取っていま す。大変マイナーな次元にも関わらず、一文字でも破たんすれば全部がだめ という分野ですので、完全なものを目指したいと思います。
なんとか落とし所を見つけることができました。「原材料コスト」がかから ない事から、「妥協する必要もない」に発展してしまうのが私の悪い癖です。 プロフェッショナルとして何かを生み出す場合は必ず「時間」という制限が 存在します。もし、無期限な制作活動ならそれは「趣味」でしかありません。 つまり「妥協」という要素が必ず必要になります。私は今まで「妥協」する なら沈黙した方がいいというものしか書けませんでした。今回初めて「妥協」 しても世に出したいものが書けたと感じています。
後は、隠蔽ソースの自動パース部分を実装すれば完成します。これは3.00で 使用しているモジュールがそのまま流用できるはずです。本体に僅かな変更 がありました。.NETランタイムはEXE単体、COM呼び出しのいずれでも起動時 に取得を試みます。これはメインスレッドから要求をPOSTされたサブスレッ ドが担当しますから、起動が待たされることはありませんが、以前よりやや 時間がかかるように感じるかも知れません。もし、環境によってこの取得動 作が負担となる場合には、この動作をスキップするオプションが必要かも知 れませんが、現状ではその必要は無いと判断しています。
エンコード、デコードルールについて決定しました。購入時にファイル情報 、著作権情報を指定してもらい、その文字列を元に認証ハッシュを生成して EXE内に埋め込みます。エンコード、デコード時はEXEがオリジナルであるこ と、両者が一致することを条件にエンコードルールを動的に設定します。 したがって、同一製品を購入した他ベンダーのエンコードソースをデコード することはできません。デコード動作自体は正常終了しますが、出力された 文字列は全く無意味なものとなります。
.NET系とエンコーダーとの連携も確認できて、やっと解説が書けます。解説 を書いてから、使う側の立場にたって小規模な変更を行うことはありますが、 解説の展開を書き変えなければならないほど、本体の仕様が変更されては大き なロスになりますので、説明する場合の言葉をつぶやきながら、一つ一つの 機能を紡いできたつもりです。製品版の価格は10kにする予定です。また、 あらゆる方面に案内を差し上げて、直接販売以外にも技術供与等の道を探っ て行こうと思います。もちろんMS本家にもメールする予定です。英語が怪しい という時点で却下されそうな気がしますが。
全体のコンセプトは「HTMLアプリケーション用のコンパクトななOS」です。 自分用のスクリプトにGUIを付加するもよし、その延長線上でEXE化して配布 するもよし、本格的にソース隠蔽してビジネスツールとして使うもよし、 大概のことはHTMLと何らかのスクリプトで十分、APIをコールするDLLが必要 なら、自作するか、さもなくばご注文いただければ廉価に作成します。 という展開です。書いて生きて行かねばなりませんので、少々生々しい話 にもなりますが、書く側に収益が生じなければ、書く人はいなくなり、その 結果、既存のライブラリをつなぎ合わせたような毒にも薬にもならないツール しか存在しなくなるのは目に見えています。
エディタの自動コードページ判定は、冒頭に連続するキャラクタが特異である 場合、誤認識を完全に排除することはできないと判断し、Open With、Save With を追加し、コードページを指定してのオープン、セーブを追加します。これに より、コードページ変換器としても機能します。今日中には2.55を公開します。 ここで公開される2.55は架空のユーザーに納入された状態を想定しエンコード、 デコード可能な製品バージョンとする予定です。ただしこれはヘルプが完全な ものとなった時点でフリーバージョンに置き換えられます。
行番号のGDI描画を導入したことによって、アウトラインエディタの動作時に DCをロストすることに気付きました。これは、プログラム側でドキュメントを 操作する場合Freezeカウントを上昇させ、当該カウントがゼロな場合のみGDI 描画を行うことで大変エレガントに解決できるようです。アウトラインエディタ はあくまで隠し機能ですが、ここの皆さんには快適に使っていただきたいと思い ます。
面倒な手作業を自動化するのが、ソフトウェアですから、アウトラインにも 私が面倒だと感じた部分への対策が追加されます。現状では半角スペースを で出力するCTRL+SHIFT+スペース、ファイルダイアログを開いて画像フ ァイルを選択し、編集中ファイルからの相対URLを演算して<img src="..."> を出力するCTRL+SHIFT+Iを実装しました。
言い方が混乱を招くかも知れませんが、エディタを開発するということはへた な言語を開発するよりずっと賢い方法です。もし、JScriptをソースコードレベ ルでC++へ翻訳できれば、ネイティブコンパイラができますが、全く何の追加 ルールも無しにそれは難しいでしょう。しかし、中間にエディタを介在させれ ば、その追加ルールをエディタが誘導したり、チェックすることが容易にでき ます。つまり静的な仕様ではなく、動的なアドバイスで結果的に言語間の差異 を吸収してしまうことができると感じます。例えばJavaクラスをネイティブモ ジュールへ変換することは不可能でも、Javaソースファイルをエディタ上でC++ コードへ翻訳し、コンパイルしてネイティブコードを生成することが可能なのは 誰しも想像できるでしょう。
エンコード機能を多くの方に試してもらいながら、製品版の購入を阻害しない 手法について、新たなルールを導入しようと思います。使って試すこともでき ないものを買えというのはやや理不尽ですからね。試用版アカウントという概 念でこれを解決できるような気がします。あんまり詳しい事を書くとネタばれ なので伏せますが、デコーダーが起動された時、それをエンコードしたユーザ ーが試用版アカウントだと判断された場合に、バイナリレベルで眺めても回避 できない手法で(回避した場合全体が動作しない)試用版である旨の表示がな されればいいのではないかと思います。
現在2.5デモの公開を一時停止しています。公開のつもりでアップし、動作テ ストしたところ、細かな仕様の変更がデモに反映されていない部分がありまし たので修正中です。モードレスダイアログで顕著だった「さわっちゃだめ」 状態はストレスをかけるとHTAにも当てはまるようです。逆にこれで処理も 統一でき、安定してHTMLウインドウを生成するには?という命題にきちんと 体系化した理論を持つことができました。
今眺めていて気付いたのですが、.NETのJSとVBを直接パースして実行する機 能は実装していません。.NET側からWSHやHTMLインスタンスを操作できること は、実証済みですが処理が面倒なわりにその手法がもたらすメリットが無い という理由です。クイッキーにHTMLを出現させてから、ユーザーが操作を行う 間に.NETをパースする現在の手法は素敵ですが、その逆をやった場合、どうし ても一呼吸置いてからウインドウが表示されるからです。今後、メリットが 明確になったら実装するかも知れません。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。バージョン2.55のまま、エンコードルールを実装しました。
エンコードはエディタ上でスクリプト中にカーソルがある場合CTRL+SHIFT+S
でスクリプトブロック全体を選択し、そのままEを押す、つまりCTRL+SHIFT+E
で可能です。デコードは同じ要領でCTRL+SHIFT+Dとなります。エンコードされ
たスクリプトのパースはWIN32が行いますのでその宣言ブロックはエンコード
できないことに注意してください。現在の仕様ではLANGUAGE属性必須として
いますので、WIN32宣言ブロックはtype="text/jscript"としてミスを防止して
います。起動スクリプトもエンコードしてのEXE生成デモが未だですが、仕様
が決まり次第公開する予定です。
今回の修正でエディタもやや軽くなったはずです。その恩恵が顕著に表れる のはアウトラインエディタです。従来は整形と長い一文字をボタン操作で変 更した場合も行番号等を再描画していましたが、これは単なる無駄でしたの で、変更が終了するまで余計な描画動作は行いません。従来はその操作で ツリーからのジャンプ位置を自動的に再取得していましたが、これも必要 に応じてリフレッシュボタンを操作する仕様に変更しました。
個人のツールとして使う場合、エンコードは全く必要の無い機能ですが、売れ るものを書けるか、書けないかの違いは大変大きいと思いますので、フリーな 状態から機能するようにしました。しかし、私自身が干上がってはHTABOXが終 わりますので、プロセス中の初回エンコード、デコード時にダイアログを表示 しています。同じスクリプトのエンコード、デコードを繰り返しても同じ文字 パターンとならない事を確認できます。同じ文字の長大な連続を処理しても、全 く予測不能なキャラクタへのランダム変換が行われていることも確認できます。
エンコード時の留意点はドキュメントに詳しく記述しますが、JScriptの typeofがfunctionである場合、基本的にGET要求を拒否します。これは通常 の関数記述では全く意識せずともいいことなのですが、クラス代わりにfunc tionを使った場合、クラスメンバーに対する値の取得はGETでなくMETHODで 実行されるようにしてください。つまり従来メンバ this.valの値を取得す る場合var v = Hoge.val;というGETですが、valを返す関数をメンバとして 書きvar v = Hoge.GetVal();とする必要があります。このルールはObject 上のfunctionにも適用され、階層が深い場合でも再帰列挙して設定してい ます。
前文を読み返してもっと重要な事を言い忘れていました。もちろん隠蔽目的 のfunctionですから、PUTは必ず拒否します。動的に要素を追加削除する必要 があるならば、隠蔽しないブロックで宣言してください。この隠蔽という話 になると、比較した場合、やや遅く、隠すことでさらにちょっぴり遅くなる JScriptに比べVBScriptがうらやましく思えます。
別の非力な環境で試すとだめな点が多々ありますので、一旦公開停止して 修正します。.NETをデフォで初期化する関係で、タイミングがずれる気が します。
期待通りに動かない時は神様が私に何かを教えてくれようとしているんだと 思うようにしています。そうとでも思わなければこんなつらいことを投げ出 さずに、続ける勇気は湧いてきません。今回の教訓は非力なPCに優しいSleep 時間とは?のような気配です。
何かをすれば、次から次へ問題が生じます。まぁプログラミングとは元来 そういうものなんでしょう。ただし、そういう問題があるということを検証 できる位置にいなければ問題の存在にさえ気付きません。問題の解決策が 明らかになれば、それを再現する最短コードみたいなものが書けますが、 そうでない場合は不可能です。なんか不可逆関数みたいな法則ですね。
ひと寝入りして再度眺めたらまったくだめですね。どうもスランプというか 、能力が無いというか、やり直しです。
8日前のソースを元に、その後追加されたモジュールを足しながら、動作を 確認しています。どこかで余計なことを書いているはずですが、それを探す よりは、健全なソースを元に段階的な追加を行い、問題が発生すれば、その 追加内容ですし、発生しなければ何らかの事故だと思われます。正直ソース が長くなったので、VC++のIDE上で関係ない文字列が出現している事がありま す。
もう老い先短い私から、この国の将来を担う方々へ、私の愚かな人生の中で これは皆さん認識していた方がいいと思う事をお話します。どんなに崇高な 理想もしくは、どんなにささやかな理想でもかまいません。それを完全に実 現できる空間はこの世には存在しません。お金、時間、人間関係、社会的評 価、あらゆるものがその足を引っ張るでしょう。けれど、最もその制約の少 ない分野が「プログラミング」です。常に真摯に理想を追い求めてください。 誰もそれを邪魔することはできず、やがて、誰しもがあなたのやり遂げた仕事 に感謝する日がくるでしょう。人生はお芝居で、いつか幕が引かれますが、 幕が下りて尚、鳴りやまない拍手ほど、役者冥利につきるものはないはずです。
昨夜は早く寝たのですが、寝る前に眺めていた2003MSDNにHTAとHTCで作った ワードパッドもどきというサンプルがあるので眺めていました。ツールバー はそんなに気にならないのですが、メニューについては、たとえプロが書い ても、DHTMLでは越えられないかったるさがあって、「勝った」と思ってしま いました。
エディタ上でエンコード、デコードを行うというアイディアは我ながらエレ ガントな発想だと思うのですが、これには歴史があります。私はC++中にHTML やスクリプトを書いて楽をする時があるのですが、書き換えられると致命的 なコードの場合、静的文字列として存在するとEXEをメモ帳で開き、長さを変 えない状態で書きかえられてしまう恐れがでます。また、静的文字列には長さ 制限がありますので、あまり長いスクリプトも書けません。そこでVC++のIDE 上でエンコードしてしまう発想に至ったわけです。
実際にやってみせますが、C++コード中に見せたく無い文字列があるとすると。 _bstr_t hoge = "これは見せたくない文字列です"; のクォートされた部分を単に範囲選択してマクロ処理します。 _bstr_t hoge = "FJ7bnFweHVHbXUVUGIbQAwQnpIQ1RsNnlgPXN1QEdqdUlW1BtJ11wd=="; これは瞬時に変換されますが、この手法では単にエンコードされた文字列を 処理してしまいますから、今度は実行時のC++側ソースにデコード関数を置き その引数としてエンコード文字列を与える形式に変更します。 _bstr_t hoge = Decode("FJ7bnFweHVHbXUVUGIbQAwQnpIQ1RsNnlgPXN1QEdqdUlW1BtJ11wd=="); これで、バイナリエディタで眺めても何をどう処理しているのか解らない状態 を維持しつつ楽ができるわけです。難点があるとすれば、書きたくもないのに エディタマクロとしてVB.NETを記述する必要があることだけです。
このようにベースがC++で部分的にHTMLリソースやスクリプトを利用したい場 合は、マクロでのデコーダーとC++上でのエンコーダー連携で解決できます。 その発想をベースがHTMLな場合にも発展させていったのが現在のHTABOXのエン コードルールなのです。これを静的に解読することは事実上不可能です。また、 動的に、CPUステップ毎に2Gメモリ空間を探し、文字列ポインターを得ようと 気の遠くなる努力をすれば、見えなくもないですが、今度はCPUステップを拡散 した状態での分割文字列処理とすれば、その試みさえくじくことができます。
HTABOXの場合、例えば「既存EXEへグループアイコンを送り込む」という動作 は、一つの関数に過ぎないわけですが、通常はその動作だけでアプリが一本 存在し得るほどの記述を要求されます。しかも全てはCOM呼び出しとして連携 し、たった一つの破たんも許されません。たまには、動作の向こう側にある コードに思いを馳せてくださいね。
なぜ書き重ねたら予期せぬ事になったのかの原因がつかめないまま、だったの で、動作は予測どおりとなったのですが、今後の事を考え、エベント周りの処 理を改善しています。多分多くのVC++プログラマーも聞いたことが無いステート メントだと思いますが[event_source(native)],[event_receiver(native)]を 送信側、受信側クラス宣言冒頭に置くとC++固有イベントを利用でき、大変スマ ートなコードとなります。発火側クラスのポインターさえ捕捉できれば受信側 クラスが増えようが、いなくなろうが全く問題ないフローにできるからです。 ただし、使いすぎると今回のように意味不明な事が起こるかも知れないと推察 しています。以前から発火側のクラス位置を単にコピペで移動すると何故かコ ンパイラが内部エラーを報告してくるので、それを黙らせる方法で移動したの ですが、その辺からちょっと不安定になった気がします。このイベント通知に 何が使われるのかは解析していませんが、何かが飛び交うことは明らかですし、 常に予測されたA,B間の情報通信なら単に相手側クラスアドレスへの関数呼び出 しとした方が、速度も面でも有利だろうと考えます。
ttp://kuroda.bglb.jp/htabox/htabox250demo.zip を更新しました。CreateDlgWindowでタスクが2重表示され、タイトルが表示
されない問題を修正しました。考えてみればVista以降では管理権限でMSHTAや
WSHを起動しないとエラーダイアログを拝むことになりますから、デモ全体を
基本的にHTABOXのエディタから実行する形式変更します。そして混乱を招かな
いように、MSHTA.exeでのHTA実行、WSCRIPT.exeでJS実行を未サポートな動作
と表現する予定です。開発時における全ての実行はHTABOXエディタで行い、
XP環境において、HTABOXインスタンスを生成するHTA、JS等を直接実行するこ
とは、あくまでそれを理解できる人の裏技として扱うものです。その為に若干
本体を修正しなければなりません。
WSH環境互換のために存在した関数を削除し、実行JSにはグローバル変数とし てScriptFullPathを提供します。これは格納されていた場合EXEのパスを返し ます。また、HTML起動ベースパスとしてScriptBaseUrlを同じく提供します。 引数実行時はfile://親ディレクトリパス、格納後はres://EXEパスですから、 var Url = ScriptBaseUrl + "/HTM/test.hta";の結果は両環境において正し く動作することになります。尚、上級者向けに#defineプリプロセッサ命令は そのまま存在します。素のWSH環境には#defineは存在しませんので結果的に 両環境を切り分けたソースコードとすることができます。
仕様が決定しました。WSHを考慮した場合の起動JS原型は以下のとおりです。 var WIN32 = new ActiveXObject("HTABOX.Application"); //WSH環境にはScriptBaseUrlが存在しないので生成、HTABOX内ではエラーなので#defineでコメントアウト //#define var // var ScriptBaseUrl = WSH.ScriptFullName.replace(/\\[^\\]+$/, ""); //#undef var var HTA = WIN32.CreateHtaWindow(ScriptBaseUrl + "/HTM/START.HTA"); WIN32.WaitForWindowVisible(HTA.FraHwnd); WIN32.MsgBox("END"); つまりWSH環境を考慮しなければ、極めてシンプルな記述となります。 var WIN32 = new ActiveXObject("HTABOX.Application"); var HTA = WIN32.CreateHtaWindow(ScriptBaseUrl + "/HTM/START.HTA"); WIN32.WaitForWindowVisible(HTA.FraHwnd); WIN32.MsgBox("END");
これからHELPで使用するリソースが大きくなりますので、クローン生成時に 従前のHTML、画像リソースは全て破棄されることにします。アウトラインエデ ィタ用ダイアログもこれに含まれます。アウトラインエディタはオリジナルEXE でのみ使用してください。通常エディタのコードページダイアログはリソース から外し、本体EXE側に置きましたので維持されます。
長大なファイルのスクロールでエディタ行番号描画が要因のDCロストがあった のですが、処理を見直すことで劇的に軽量で正確なものとできました。本文側 とのDCズレを検出した場合は関数呼び出し一発で正確な位置に納まります。今 回は文章と行番号ですが、これでどんなに複数のエディタが動いていてもpx単 位で正確に表示位置を同期することができます。エディタ上に生きたHTMLを出 現させる異色のエディタ屋さんとしても何か発表してみたいものです。
リソースの追加は簡単なのですが、どんなリソースがあるか解らない状態で 列挙をかけ、条件に一致した場合削除するという動作は結構トリッキーな罠 があってハマりました。どんな動作でも最初に正解コードは書けませんから、 エラーの変化を見ながら探りを入れるわけですが、こういったモジュールハ ンドルがらみな場合は、たとえ結果として正解コードに到達してもエラーと なります。そこに到達するまでにシステムが不安定となるからです。つまり 今のエラーがコード原因なのか、後遺症なのかの判断は、PCを再起動しなけ れば判明しません。ネイティブコードは高速ですが、システムへダメージを 与えることも簡単なので注意が必要です。
実現しなければならないモジュールは出そろいましたので、次回の公開はデモ ではなく、コントロールパネルウインドウからの、サンプル実行という形式に なります。ここまで書きすすめてみるとこれは実質的にHTABOX4.00ですね。
実際にエディタを使って、ドキュメントを書くと細かな不具合が目につき、 修正を加えています。自分で書いたエディタでも、それまでの編集が失わ れる状態になるとやりきれない気持ちになりますが、まして製品として買っ ていただこうというソフトにそういった手抜きは許されません。
リッチエディットをCOMとして扱うと、開いたファイルへ自動的に編集内容 を記録する機能が働くのですが、これは通常邪魔になります。大きく変更 を試みた後に、やっぱり前のほうがいいやっと思った時には既に取り返しが つかないからです。対策としては実ファイルのコピーをテンポラリとして 明示的な保存まで実ファイルには触らないとしなければなりません。ここで テンポラリを非表示属性としていたのですが、その処理が、キャッシュの関 係で時に失敗するようですから、通常属性に変更するものとします。
エディタも安定して作業は順調です。サンプル表示ボタンでエディタがソース を表示し、コメントとして概要を見ることができます。面倒な人は単に実行 ボタンを押せば何ができるのか見る事ができるという、思い描いていたとおり の流れになりました。このシステムの最大のメリットは私もユーザと同じ視点 でソースを編集すればいいという事です。これが何らかの形でEXEに埋め込まれ ていたりすると、大変面倒な修正作業になりますが、単にエディタで思いつく ままに入力し、実行結果が良ければOKというのは夢のような単純さです。
2.5にはヘルプウインドウも存在しますから、EXE化デモの表示HTMLとヘルプ HTMLを書けば、それだけで1本アプリが完成してしまいます。ネタさえあれ ば、一週間に1本、年間52本も十分現実的な数値だと思われます。しかも エンコーダーを使えば誰にも手の内を明かす必要はありません。
エディタで表示されるソースコード中に実行ボタンを表現する画像を入れる ために、半日を費やしてしましました。リッチエディット中に画像を入れる 手法は20Wも50Wも同じなのですが、挿入後の挙動に違いがありました。その 違いはHTABOX側のモジュールで吸収することができたようです。そこを書き ながら、従来居残ってしまっていたHTMLをDELやBSで削除するには?という 問題にも解答を得る事ができました。
結果的に20Wは使用せず、全てのエディタを50Wに統一する判断をしてコード の整理を行っています。50WはIME確定時の挙動に癖があるのですが、システム メッセージの発生機序を解析し、コード側でそれを調整することで解決できま した。いまさらですが、プログラムで文字列操作するとUndo無効なんですね。 ノーマルエディタでは色付けくらいしかしていませんが、Undo優先でなんら 操作しないモードも必要だと考えています。
50WはOLE的に正しい動作をしますから、一般的なネイティブHWNDを美しく埋め 込むことができます。ですからHTMLも画像もアプローチとしてはOLEなんですが 結果として親子としてのHWND関係を構築できます。で、これが何の役に立つか というと、「何でもあり」を実現してしまいます。子HWNDはメッセージ的に独 立した存在ですから、OLEの子という呪縛から解き放たれています。通常のウイ ンドウに可能な事は何でも可能な状態を作り出すことになりました。
HTABOXは起動時のコントロールウインドウから各種サンプルを直接編集し、 実行することができるようになりますが、「ヘルプを見るのは面倒だけど 、ソースコードも読めない」というケース(ほとんどそうだと思う)では ソースコード中にある程度画像を含める必要を感じてエディタの煮詰めを 行いましたが、完全に目的を達成できました。ファイル自体がRTFなら苦 は無いのですが、それでは実行できません。JSやHTMLのソース中に実行を 阻害しない形式でHTABOXのエディタで開いた場合のみ見える画像を実現し ています。
従来、なぜHTAが普及しなかったのかという問いへの回答が、私としてもはっ きり解らなかったのですが、MSDNにあるHTAのワードパッドもどきを見てその 理由をはっきり認識できました。ユーザーはアプリケーション本体の仕事が クイッキーであることは期待しません。当たり前に時間のかかる作業な場合も あるからです。しかし、メニューやツールバーを操作する場合、その描画がも っさりしているだけで、かなり引いてしまいます。これは偽物だと直感してし まうんです。今はどうか解りませんがJavaのSwingが出現した時、確かにウイン ドウは表示されているんだが、触った途端に幻滅したことを思い出しました。
起動直後のコントロールウインドウ上に置く簡易な説明とサンプルの形式を
決定しましたので公開します。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip 本当は数行の説明でポンと実行が理想ですが、実際にあれこれ考えてると混乱
を招かないた為に最低限このくらいの説明はひつようかな?と考えた結果です。
未だ未完成で恐縮ですが、エディタは機能強化されていますから、入れ替える
価値はあると思います。ただ、若干提供関数が変更されたので、従前のデモを
実行することはサポートしません。
単純なHelloのHTMLを実行するために、根幹の部分を書き換える必要がありま した。追加のオプションを付けての動作だけだったものですから、何も無い 状態でのテスト行われていませんでした。そうやって一つずつバグが消えて 行くのは嬉しいのですが、そんな単純なテストもなおざりにしていた自分へ 嫌気がさしました。画像定義htmlは多用途な画像を定義する予定なので、従 来のtoolbar.htmからimagelist.htmへ変更します。これで、全体の完成が遅 れれば、私が怠慢なだけで何の言い訳も許されない状況ができました。
こういった、説明の課題を象徴するごく短いコードの集積で全体を表現する 手法は、提供する側でも個々のケースを実行しながら説明を書けるので大変 有効な手法だと実感します。静的な取り説を書いて、そこに文字列としての サンプルコードがあって、本体側が改変された場合、当該サンプルが本当に 正しく動作するのかを確かめるのには大変手間がかかります。手間がかかる 事が目に見えていますから、本体側の改変が滞るのです。たとえばこういっ たサンプルを列挙実行するチェックプログラムを用意して、全部問題なかっ たのか、どのサンプルでエラーが発生したのかを瞬時に判別できればそうい ったジレンマから抜け出すことができると思います。
当初、全体ヘルプと、サンプルヘルプの役割分担という発想でいましたが、 説明が必要なすべての要素について、まずサンプルが存在し、そのサンプル コードがなぜそうなのかを説明するコメントが存在し、全体のヘルプは複数 のサンプル集合を単に俯瞰するという構造であれば、提供する側も、使う側 も大変理解しやすいものになると結論づけます。
2年以上前からHTABOX的提案が成功する為の最も重要なポイントはエディタで あると直感していました。ただしこれを根本の部分から書く時間は無いので、 既存のリッチエディットDLLをどこまで活用できるかという課題を常に持ち 続けていました。この3日間で50Wを完全攻略でき、前述のヘルプ構造という 最も重要な発想にたどり着けたことを神様に感謝したいと思います。
エディタで編集中の全DCをPNG形式で画像保存するモジュールを書いています。 印刷という手順を踏むとか、RTFで保存後に別アプリで開いて処理というのも ありでしょうが、総合的なヘルプに個々のサンプルを画像として埋め込むため には、ページで区切られていない一枚の画像がほしいので、少々ぎこちなくと もエディタ単体で実現する予定です。
アウトラインエディタは現在単一HTML中の見出しをツリー表示して操作する わけですが、これの本来の目的は複数のHTMLページリンク構造をアウトライン 感覚で移動することにあります。つまりフロントページでページツリーを移動 する感覚で複数のページをごっそり移動するものです。今回エディタ文字列の 画像出力にこだわっているのは、アウトラインエディタが複数のHTMLを構造出 力する時、個々のページを単一画像HTMLに変換したいという願望もからんでい ます。エディタは画像やHTMLを表示することができますし、自由なフォントで 文章を作れます。そのスナップショットを大きなPNGとして単一<img>で構成さ れるHTMLへ変換します。もはやブラウザ毎の特性なんかとは無関係な世界です。 また、見せたいけど、単純にコピペで再利用されるのはいやだというソースや 文章を公開するにも適しているでしょう。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。エディタに[File]->[Save Image]が追加されました。
保存ファイルはPNG形式のみです。たとえ別の拡張子で保存しても内容はPNG
ですから注意してください。画像生成時に内部でビットマップハンドルを生
成する必要がありますので、あまり大きな文章だとメモリが足らなくなるか
も知れません。サンプル用のコードを想定した設計ですので、300行程度なら
軽快に動作すると思います。また、DC読み取りは実際に表示されている部分
で行いますので、画像生成時にウインドウ上に何かあるとそのまま画像化され
ます。終了のメッセージまで触らないようにすべきです。
これで、一つのテーマについて一つのコメント付きサンプルを書けば、実行 もでき、総合的なヘルプにはその画像を置いて、クリックされた場合にエディ タで本物のソースを開くという構造にできます。とにかく私は同じテーマで 2回ものを書くのが大嫌いですから、この画像保存機能は私のドキュメントに 対する苦手意識を根底から変える画期的なものです。
画像出力が可能だと、画像用に一旦フォントを変更したくなるものですから、 やってみると、いつのまにかフォント等を変えると編集中の文章がいなくな ることに気付きました。当然修正を加えますが、万が一RichEdit50Wの仕様か ら再起動が必要な場合は、それに従いたいと思います。
前述の件はタブ幅演算ルーチンが制御を返さない事が原因でした。実際に半角 スペースを指定数出力してpx幅を取得し。実際に\tを出力してそのpx幅が取得 済み幅と同一になるまでEM_SETTABSTOPSで上昇という異常なまでの細部へのこ だわりが嫌われていました。調べてみると指定文字数の4倍で妥協するのが一般 常識なようです。
VC++の開発環境で、exeファイルはDebugかReleaseのサブディレクトリに生成 されるわけですが、サンプルファイル集合は一つしか置きたくありません。 しかも実際のリリース時にはexeから見てSAMPLEというサブディレクトリに 全てが存在するとなると、exeを起点とした場合指定されたURLを柔軟に解釈 する独自プロトコルが必要なので実装しました。内容は単純でsample://が 要求された場合、自身EXEが存在する基底ディレクトリパスを先頭に付加して ファイル実在を確認します。それが存在しない場合、要求URLに"../"を付加 して検索します。いずれかの検索がヒットした場合内容をバイナリストリーム としてHTMLインスタンスへ提供するというものです。
HTML中で例えばボタンが押されたら...の操作先はスクリプト的手法でいくら でも柔軟に変更できるわけですが、素のHTML上にタグとしてsrc="...."があ る場合、初期に評価されるsrcの参照先、又は内容をスクリプトから操作する ことはできないと考えます。なぜならスクリプトがインタラクティブになる 前の世界だからです。これをプロセス固有の独自プロトコルと定義すれば、 そのプロトコルに係る一切の処理をプログラム側で定義することができます。
画像化時に非表示とした情報をどう復元表示させるかで半日悩みました。 当初は情報を別配列に保持して復元だったのですが、文字通りHiddenの オンオフの方が安定動作するようです。ユーザーがそうするようにサン プルを開いて編集し、同名のPNGに書き出せば、自動的に総合ヘルプにも 結果が反映されます。サンプル集合を単一テキストとしてアウトライン 操作の対象にすべきかどうかという課題は残りますが、それは走り出し てからでも対応できる問題です。
エディタについて完全な調和を図ることができました。一度書いたドキュメ ントは、実行サンプルでもあり、統合されたヘルプに表示される画像でもあ り、サーバー上のWEBページでもあります。また、独自プロトコルで後続編集 を許可したファイルアクセスとできるため、エディタで編集し、画像化した ドキュメントを即座に統合されたヘルプ上で表示できます。夢を見ているの ではないかと思わせるくらい、完璧なドキュメント作成環境です。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。ドキュメントは未完成ですが、エディタを調整しました。
エディタツールバーにイメージ処理のオン、オフボタンが追加されました。
イメージ表示の仕様は<image src="hoge.png">です。srcは当然編集中ファイ
ルとの相対パスです。画像処理は全てGDI+ですから、どんな種類に対応し
ているのかはGDI+に訊いてください。大概のものは表示するはずです。
実際に使うと編集ファイルと、同名なpngで保存することが多いので、画像保存 時のデフォルトディレクトリ、デフォルトファイル名を生成するようにします。 また、画像保存時は自動的に編集中テキストも自動保存される仕様となります。
エディタで画像表示のままコピペしたりすると、動作が怪しいですね。 今のところ非公開機能ですので勘弁してください。そういう事をしなければ ヘルプドキュメントの作成には支障なく動作しています。総合ヘルプはHTML でなければこなせないのですが、従来はそこに実行スクリプトやHTMLを表示 するためにエンティティーを考慮したソースを置く必要があった訳です。つ まり本当に実行するものと、表示するものを作らなければならなかったので す。それを画像として表示し、編集と実行が必要ならエディタ起動というの は、多分見る方もすっきりしていて理解しやすいと感じています。
実際にヘルプやサンプルを書きすすめてゆくと、思わぬ欠点に気がついては コードを修正するという作業になっています。自分で決めた期限はあと24時 間なので、それを目標に完成を急ぎたいと思います。
サンプル実行後にエディタ上の画像描画が乱れる場合がある事への抜本的対 策を模索して半日以上を費やしてしまいました。最終的には大変エレガント な方法で解決することができました。問題を先送りすると、何が問題なのか を理解する頭が戻ってこないこと、ブレークポイントを置いてその問題を 再現するコードが失われることが怖いのです。
実行可能なヘルプシステムとしてのバグは出尽くしたと思います。予想通り 自分で決めた期限など、とうの昔に過ぎ去っているんですが、今回はプロが 見ても「私には書けない」という感想を持たせなければ意味がありませんの で、ちょっとしたほころびも許せません。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。作業途中ですが、エディタに小規模な変更が加わりヘルプ
の構造も小規模に見直しました。ヘルプを書きながら修正すべき関数仕様は
容赦なく変更することにしました。開発->EXE化という流れなら格納された
時点で実行環境は完結していますから、その後に関数仕様が変更されても、
勘弁していただく事にしないと過去の仕様が足を引っ張る事になりかねない
からです。
エディタ上の文字列修飾は当初、全て動的画像処理と考えたのですが、GDI的 手法で取得するフォントサイズはリッチエディット上のものとは微妙に異なる ことから、通常のリッチエディット手法によるフォント設定と混在する環境を 構築するのに時間を要してしまいました。この過程でGDIリソースの解放が甘 かった部分も改訂しました。 <rich:font size="10" color="0xffff00" bgcolor="0x0000FF" bold="true">hoge</rich:font> のようなフォント設定タグを解釈します。このタグは入れ子にできますが、 子は親の影響を受けない仕様とします。これでコメント中に重要事項を赤く 大きなフォントで表示するような事ができます。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。作業途中ですが、エディタに<rich:font>機能が追加されました。
従来の<image>は<rich:img>に変更されました。<rich:img size="**"></rich:img>
はinnerText文字列の画像を生成し影付きで表示しますが、size部は元サイズ
をを何パーセント拡大するかの数値です。100でそのまま、200で2倍です。
<rich:font>の場合は普通にポイントですので注意してください。
リッチエディットはハイパーリンクも処理できますから、
<rich:link src="
http://hoge ">リンクはこちら</rich:link>的なものも追加
予定です。この場合、画像出力時にクリッカブルリンク情報も生成します。
画像挿入、文字修飾、リンクができますからそのままHTMLページを一枚の画像
で構成できることになります。ワードをベースにそいういツールを開発したの
ですが、画像出力時に他人様の書いたポストスクリプトインタープリターが
必要なものですから公開を躊躇していました。これなら100%自家製モジュール
ですし、ページサイズも文章中に改ページマークを定義すれば柔軟に対応可能
ですから、コピペされるのが嫌な局面でのHTMLページ作成ツールとして公開
する予定です。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。作業途中ですが、文字列画像化はGDI+でPathを使えば正確
なサイズが取得できることから変更を加えました。<rich:img size="**">は
すべてpt値(ポイント)に統一されました。ヘルプをちらっと見ていただけれ
ば解りますが、「これが動的に生成された画像なのか?」と疑いたくなるほ
ど細部の描画にこだわってみました。影はすべてグラデーション処理されて
います。
GDI+の可能性というか限界というか欠点探しというか、そんなコードに半日 を費やしてしまいました。GDI+を利用すると隠しHWNDが生成されることから Post系の動作が主体となっている気がします。スレッドをあからさまにブロ ックしない代わりに、呼び出し側は動作が真に完了しているかを知りえない という印象を持ちました。例えばある程度複雑なポリゴンを生成させ、即座 にその座標配列を取得しようとすると「アクセス拒否」が発生します。これ はHTMLのreadyStateのように一旦そうなるとリカバーできない部類のエラー なようです。隠しHWNDスレッドへ侵入して...ということまではやる必要も ないので実験していませんが、あまりシビアな使い方を想定したライブラリ では無いというのが率直な感想です。
上記のような状態を作らないアルゴリズムを意識すればいいというのが正解 なようです。大規模なパスオブジェクトはあくまでも結果蓄積用として位置 させ、作業用パスオブジェクトでポイント座標の取得や再設定を行うとすれ ば、スマートな記述と安定した動作を両立できそうです。
外に向けてもっとHTABOXや作者さんの宣伝をしたほうがいいんじゃないですか?
ツイッタークライアントはまだしばらくはニーズがあると思うので
そこで作者さん自体の名前を広める作戦もありだと思います。
ツイッターAPIを操作する雛形は公開してくれてる方がいるので敷居はかなり低いですよ。
おじいさんおばあさん向けの機能を絞ったらくらくほんみたいなツイッタークライアントとか。
(テレビでよく聞くツイッターというのを投稿はしたくないけど、見てみたいニーズ向けとか。
#NHKや有名人など老人が見てそうな番組の検索条件のみで動いてお気に入りくらいしか操作出来ないクライアント)
たとえば作者さんがいま拘ってる文書の画像化という点でいえば、
ツイッターの文字に収まりきれない文章やあとで文の内容を検索されにくいほうがいい場合(ニーズはよくわかりませんがw)など用に
140字を超える文を画像化してうpと同時に投稿するようなクライアントはまだ存在していないと思います。
2ch投稿専門ツールでもそういったニーズはあるかもしれません。(ちょっとダークサイドのニーズかもしれませんがw)
既存のツールとスクリプトを使えば出来るんですけど、自分でそこまでやりたくない人が多数ですからね。
特定の層にはアピールできると思います。話半分ということで。
↓
WSHでTwitter API(OAuth)
http://d.aoikujira.com/blog/index.php?WSH%E3%81%A7Twitter%20API%28OAuth%29
おっしゃる通りで、外に向けた本格的な情報発信はこれからになります。 140文字を超える情報を画像でという発想は思いもつきませんでした。勉強 してみます。個人の強みは法人としてのスタンスではできない事も実現でき ることだと考えています。ですから、クリーンとかダーティーにはこだわら ず、不利益を被る人間さえいなければ何でもありだと考えています。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。なかなか先へ進みませんが、GDI+のグラデーション機能を
使った<rich:line width="nn" height="nn" color="0xnnnnnn"/>を追加しま
した。この辺の仕様は流動的ですが、innerTextを画像処理するタグが
<rich:textに変更されました。<rich:imgはsrcでファイルを指定する時のみ
になります。
アウトラインエディタの起動はバッチでは作業しにくいので起動方法がありま す。「なんちゃらーるキー」を押しながら「スクリプトエディタ」をクリック です。また、通常エディタでサンプルを書き換え、同名pngで保存すると、次回 起動時にはヘルプに反映されてるわけですが、同じキーを押しながらHTABOXの [Help]をクリックすると再起動するまでもなくヘルプをリロードします。 アウトラインエディタは単純な<Hn>だけではなく、<fieldset><legend>内に <Hn>があると...という動作をするのですが、これは現在編集中のヘルプ構造 に依存する部分ですので一般化されていません。アウトライン自体が非公開 機能ですのでご容赦ください。
今回GDI+をみっちり勉強してその便利さを実感しました。例えばGDIで角丸 を描き、グラデーションを作ろうと1pxシフトしならが描くとアンチエイリ アスされていませんから引っ掻き傷のような線がでますが、GDI+なら綺麗 です。ただ角丸を生成することにちょっと工夫が必要です。単に扇形と矩形 の組み合わせでは余計なポイントが生成されるのでグラデーションした場合 に予期せぬ結果となります。この辺はバイナリレベルでライブラリ化し、他 言語から利用できるようにディスパッチインターフェースを付加した製品と して発表できそうです。名前はGDIの各文字を一文字進めてHEJ+なんていうの にしようかと考えています。
GDI+の文字列描画を見慣れると素のHTML描画のギザギザが気になったので標準 装備のDLLを一つ追加することにしました。GDIP.dllです。ヘルプ中で文字列 を描画するために必要ですが、ヘルプを見るためにレジストリ登録が必要と いうのも理不尽ですから、初期のHTABOXAPP.exeはEXE化時と同様にサイドバイ サイドで周辺DLLを利用するものに変更します。自身がレジストリ登録された 場合には従来どおりマニフェストをコメントアウトしてシステム経由のCOM呼 び出しとなります。
HTML上の独自レンダリングは当初OLE的手法で書きました。動作や機序は大変 明白で軽量でしたが、多くの個所でそれが要求された場合HTMLがobjectタグ だらけになる事から、Element Behavior手法を採用することにし、全テスト を終了しました。これのチャームポイントは、たった1個のobjectタグ実体 をstyle="behavior:url(#HOGE)"というCSS定義で関連づける事です。OLE的 手法では自身やその周辺エレメントを特定するのに一苦労しますが、CSSの 場合は、MSHTML側が適用先を教えてくれます。動作実体は各エレメント毎に インスタンス化される仕組みなんですが、コンパクトなクラスの継承だけで 済みますから、多くの個所で要求されても負担にはならない工夫がなされて いるようです。
私自身、BehaviorというとHTCを使った回りくどいものをイメージしますが、 C++からこの規格を利用するとDHTMLのもっさり感を完全に克服できます。独 自レンダリングクラスはHitTestPointを持つからです。例えば私の迷路プロ グラムもHTML上である限りマウスがもっさりしている事からは逃れられない と思っていたのですが、これを使えば高速なレスポンスと描画を、HTMLなら ではのお気楽なGUI作成と融合できるわけです。わざわざDirectDraw用ウイン ドウを生成しなくとも、これだけで十分遊べるゲームが作れると思います。 つらい2日間でしたが、大きな収穫を得る事ができました。
MSHTMLにおけるBehaviorについて自分なりにまとめます。ビヘイビアという 言葉が嫌いなのでここでは単に「エレメント拡張」という語を使います。 誰しもグラフィカルなボタンを元となる画像ファイル無しに生成したいと考 えたことがあるんじゃないでしょうか。それを実現するのが「エレメント拡張」です。 方法は2つ、一つは<object id="hoge" ...>のidに対してstyle="behavior:url(#hoge)" を定義する。つまり既存エレメントに対して拡張機能を付加する方法。 もう一つは、冒頭で<html xmlns:NAME>を定義し<?IMPORT NAMESPACE="NAME" IMPLEMENTATION="#hoge" /> で名前空間と<object id="hoge" ...>を関連付けた後に<NAME:fuga></NAME:fuga> を宣言する。つまり独自エレメントを生成する方法。 C++プログラマーから見れば、いずれも単一<object>を用意すれば利用方法が 通知され、動的に軽量な目的クラスを生成して提供できるメリットがあります。 つまり「エレメント拡張」という範疇ならば、いかに多様なパターンが必要 だとしても、HTML上は単一の<object>タグだけで済むわけです。
さらにIE6以降では、後者の独自エレメント生成時、自身アプリケーションが MSHTMLをホストしていれば、名前空間定義、オブジェクト宣言、?IMPORTを 内部で処理することができます。したがってHTMLコード上には何の前置きも なく<HTABOX:Application id="WIN32"></HTABOX:Application>と書けます。 スクリプト中でWIN32を参照し、オブジェクトがIDispatch又はIDispatchExを 返せば、表示目的エレメントではなく、ディスパッチ拡張エレメントとしても 利用可能だと思われます。また、表示する場合、C++コードからDCではなく DirectDrawサーフェスを要求できるようです。この場合全画面モードではあり ませんから速度的なメリットは無いでしょうが、オーバーレイサーフェスを 使えばDGI系では実現できない表現を行える可能性があります。
あぁ前述は「GDI系」のタイプミスですね。 ですからHTABOX自体にエレメントを拡張する機能を持たせるのも一考ですが、 デバッグ時にMSHTA環境では宣言が必要にあること、本体EXEの肥大化を防止 すること、という観点からやはり別DLLとして機能を提供するべきと結論づけ ました。
「教えて」系の掲示板で高度な事を実現したいという要望に対し、珠玉のサン プルコードが提示されているにも関わらず、「そんなに面倒なら諦めます」と いう展開には正直、腹を抱えて笑ってしまいます。おそらく顧客や上司の要求 に対してどう対応するかを模索しているんだと思いますけれど、それにしても もっと気のきいた返答があるだろうにと思います。もし、自分が実現したい と思う事であれば、引き下がるはずがありませんし、それを実現するコードが 難解であればあるほど、自分の発想は高度で、ユニークで、常人の成しえない 領域であると誇りに思うべきです。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。作業途中ですが、GDIP.dllが添付され、HTABOXAPPのデフォ
はマニフェスト有効状態となりました。したがってエディタ経由でRun HTABOX
な場合はレジストリ登録無しに全機能を使えます。レジストリ解除が2つのモー
ドに分かれました。一つはレジストリ登録のみを解除し、マニフェスト有効な
スタンドアロン状態にするもの、もうひとつは解除とマニフェスト中のDLL情報
も削除するものです。単にHTLPを眺めると従来<Hn>タグで表現されていた見出し
が独自描画処理されている事を確認できます。はっきり言って「壮観」です。
HTML上のIE固有CSSフィルタは廃止方向にあるようですが、そこで使われてい る DirectX TransformをGDI+に融合することはできないかというテーマで24時 間を費やしました。執念深い私も数回諦めかけましたが、最終的には成功しま した。IEがCSSフィルタを提供しなくなっても、HTABOX上ではもっと簡単な方法 で同様なエフェクトを利用できることになります。また、このエフェクト機能 を盛り込んだ拡張GDI+ライブラリとしての製品も、より現実味を帯びました。
ヘルプを書いていて影の表現が気に入らないと思ってしまったら最後、とこ とんやってしまうので、慢性的な遅刻が発生して申し訳なく感じています。 大したレベルのものを作れるわけでは無いのですが、これなら一秒でも早く 人に見せたいと感じるラインというのが自分なりにあって、そこに達してい ないと、スパートできず、達する為には何が必要かを模索してしまいます。
IEのCSSフィルタ処理が場合によって通常の画像処理ソフトより高速なのは なぜだろうと思っていたのですが、フィルタを構成しているインターフェース 群にIDXTConvolutionが存在し、当該インターフェースを通じて高速に画素の たたみこみ演算(コンボリュート法)を実現しているからだと思われます。 表示要求時に動的な画像の生成が要求される場面ではこういった道具を使う ことで通常は相反する要素である「美しさ」と「速度」を両立できると考え ます。
グラフィック処理手続きで明らかにMSDNとは異なる手法でないと成功しない 部分があったので、IE9環境でテストしています。まったく問題なく表示する ことから、若干の仕様変更があったと思われます。最後に残っていたボタン もビヘイビア描画しました。C++によるイベント処理はMSDNが極めて不親切な 説明しかしておらず、理解に時間がかかってしまいましたが、なんとか克服 できたようです。
HTML拡張をディスパッチで行うのか、<OBJECT>で行うのか、ビヘイビアで行 うのかというようなことは、農作業でいえば土づくりか、それ以前の土地選 びみたいな段階の話ですから、最初に理解すべき部分なんですが、それらを 比較検討できるコードを書けるようになるようになるのに数年を要してしま ったというところでしょうか。自分の能力のなさに嫌気がさします。
ビヘイビア環境で独立性を優先した<OBJECT>をエミュレートできないか?と いう試みに2日ほど費やしてしまいました。結論はNOです。何かが自動的に 行われるということは、その分自由度が失われるという摂理からは逃れられ ないようです。たとえばFoxやChromeをIE中に出現させるような場合はOBJECT タグが適しています。 どんなに驚くような結果をもたらすモジュールでも、元をただせば見ての通 りなソースコードです。それを公開すれば、とてもいい人なんでしょうが、 その一行一行には、私の家族の安寧な生活が、かかっていますので公開でき ないことをお許しください。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。ヘルプ未完成ですが、ヘルプ冒頭と最後尾に可変サイズHWND
をHTML中に埋め込んだ場合のデモエレメントが存在します。内容は単なる
GRAY_BRUSHですが、本物のWS_THICKFRAMEを出現させていますので、DHTMLによ
る可変サイズエレメントとは一線を画すレスポンスになっていると思います。
この機能は<OBJECT>タグで実現されています。ですからウインドウイベントの
解析部を汎用なものにすれば、どんなブラウザ上でも動かせると思います。
TZBではHTMLアプリケーションをTABブラウザ的に扱う発想ですが、もう一歩 進んでHTMLアプリケーションOSを想定した場合、単なるタブでは構造化した 分類が表現できないため、各タスクの選択がしにくくなりますが、Treeと縦 長なページとサイズ変更できる実行領域という組み合わせならより直感的に タスクを移動可能なのではないかと思います。今回のリリースでこの可変エ レメントの出番はないのですが、今後中心的な存在になる可能性があります。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。ヘルプ未完成ですが、ヘルプ冒頭と最後尾にある可変サイズ
HWNDをタイトルバー付きに変更してみました。「取り説が必要なものは作るな」
というのは至極ごもっともな話ですが、作り手側からしてみるとなし得難い課題
でもあります。たとえば可変領域があって、それが見慣れたウインドウの外観で
れば、なんの説明もなくサイズを変更してもらえると思います。
>>877 情報ありがとうございます。背景色関係で機種依存してしまった部分
があったようです。その部分のコードを再検証したいと思います。
また、今まではすべて実行時に文字列を描画して動的画像生成を行ってきま
したが、変更の必要がないケースでは一度だけ動的生成を促してPNG保存し、
実行時はこのキャッシュファイルを表示する仕様に変更します。動機は単純
で、ヘルプのエディタ起動ボタンを動的描画した場合、まった同じ画像を複
数生成するために起動がもたつくというおまぬけな状態となるからです。
開発環境2003とXPではdxtrans.dllの仕様が異なるため、画素に高速なフィル タリングを行う目的で呼び出しを行った場合の挙動も異なる事が原因でした。 両者の違いをコードで吸収するより、必要な動作はDLLに頼らず実装する方向 で考えています。dxtrans.dll、dxtmsft.dllはおそらくハードに近い部分で 動作していますので大変扱いにくい対象ですが、逆に言えばAPI経由では不可 能な処理速度を実現できる可能性がありますので、その解析は継続した課題 にしたいと思います。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。未完成ですが、画像背景が黒く抜ける事への対策を行い、
XP上でヘルプ中の可変ウインドウを操作した場合にSetWindowRgnの解除が必
要な点を修正しました。877さん、ありがとうございました。それと、ヘルプ
上のエディタ起動ボタンは、マウス位置のウインドウが純白かで画像を切り
替えていますが、場合によっては0xffffff以外が使われる場合もあるようで
すので、もっとエレガントな判断方法を模索したいと思います。
ttp://kuroda.bglb.jp/htabox/htaboxapp.zip を更新しました。未完成ですが、ヘルプ中のエディタ起動ボタンについての
修正を行いVist+IE9環境での動作も確認しました。dxtrans.dll、dxtmsft.dll
はひと手間加えることで仕様の差を埋めて利用しています。これについての包
括的なサンプルが皆無であるところをみると、低水準(非ATL)で利用できて
いる事がひとつの武器になるはずです。まだ実測したわけではありませんが、
この手法はDirectXの基本的コマンドでVRAMを直接操作していると推定されま
すので、動的な画像データ加工手法としては事実上最速だろうと思われます。
例外はあるでしょうが、多くの場合プログラミングが得意な人間はデザインが 苦手で、その逆にデザインや色彩感覚に優れた人間はプログラミングが苦手な 傾向にあります。結果、とても洗練されたサイトの内容はたいしたことがなく、 見向きもされないようなサイトに驚くべきコードが書かれていたりします。 ただ、前者は後者を凌駕する可能性があります。なぜならデザインするプログ ラムが書けるからです。その逆にプログラムしてくれるデザインは不可能です から、後者が前者を凌駕することはあり得ません。
そう書いておいてそれじゃあ何ができるの?と自問してしまいました。例えば 既存の写真やイラストの特定の形状だけを抽出、加工する場合に不可欠な技術 は何か?多分それは減色処理だと直感します。でも漫然とDC上で減色を行って もシステムが生成するパレットの呪縛からは逃れられませんから、そこをどう 解決するのかを勉強していました。具体的には見掛け上のグレースケール表示 ではなく、真に黒から白までのパレットを持つ4bit、8bitの画像データを生成 する手順です。これも出来てしまうと単純なロジックなんですが、見掛けグレ イは山ほどサンプルがあるのに、きちんとパレットまで作ったサンプルをあま り見かけませんので、いつか解説付きで公開したいと思います。
ttp://kuroda.bglb.jp/htabox/image.zip に減色処理結果の画像を用意しました。興味のある方はご覧ください。目的は
若干姑息ですが、原版画像に独自エフェクトを施し「私が書きました」と主張
するためには何が必要か?になります。
001.pngは原版画像を表示したものです。
002.pngはシステムパレット状態で8bitに減色したものです。これはこれで面
白い効果かも知れませんが、システムパレット中で実際に使用されている色は
限定的かつ、予測不可能なものとなります。
003.pngはグレースケースパレットを用意した8bitに減色です。この画像を見る
だけでは、ありふれた見掛けグレースケールと変わりませんが8bitです。
004.pngはシステムパレット状態で4bitに減色したものです。これもこれで面
白い効果かも知れませんが、16個のパレットは有効に使われていません。
005.pngはグレースケースパレットを用意した4bit減色です。これは多くの方
が目にしたことのない状態だと思います。16個のパレットが機能していること
を確認できます。
006.pngは005.pngの色境界をコンボリュート法により抽象化したものです。
つまり、人間のタッチでは実現できない境界が存在しては「手で書きました」
と主張できないからです。これを推し進めて領域をパス化し、若干の変形と
パレットの再定義がなされれば、オリジナルをプログラムで生成できます。
画像処理において疑問に感じていた部分を実験検証しこの件に関しては一旦 終息させました。結果的に任意なRGBを256階調化、各階調ごとに領域認識、 自由に移動して再度コンポジット合成するというクラスを作成できました。 これを使えば、色収差自動修正プログラムができます。もはや裸眼で天体観測 する時代ではありませんから、優秀な色収差自動修正プログラムがあれば、 もはやアポクロマート系レンズに車が買えるようなお金を投資する必要が無く なります。
誰かがそう言ってくれればその一瞬ですべてが理解できる一言があります。 例えば「生成EXEの中に変数名や関数名は存在しない」と言ってくれれば ポインターについて何の悩みも生じないでしょう。同じことがGDI+について も言えます。「GDI+はデバイス非依存な画像データを処理するために存在 する」と誰かが言ってくれたらとても理解しやすいと思います。ですから DDBへの変換が頻発するような使い方が間違っているのであって、それを踏 まえたロジックを組めばとても優れた独自ライブラリを構築できます。
最終的に2色でどこまで表現できるかという事に興味があったものですから、
明暗をハッチブラシで表現してみました。モノクロームより更に抽象化され
ると、逆に想像力が発動するというか、自分なりのストーリーを作れそうな
気さえします。画像の情報量をして少ないわけですが、これを瞬時に生成
するのはかなりハイテクニックなことです。HTABOXでは.NETが記述できます
からGDI+自体は操作できるわけですが、フィルタ処理等のより具体的な機能
をHTABOXのサービス関数として将来は実装しようと思います。
ttp://kuroda.bglb.jp/htabox/image.zip
画像処理という分野はMSHTML関連のように「自分だけの隠し球」を持てない プリミティブな分野ですが、この分野にも衝撃を与えるものをという趣旨で 減色処理で出現した複数領域を個々のRGNとして認識管理するクラスを2日書 いていました。要は数的な爆発現象にどう対応するかなんですが、最終的に ピクセル領域情報を線形リスト管理することで、たとえ画像が莫大だとして も任意な切片で処理を確定できる柔軟性を実現できました。このモジュール は画像を解析し数千から数万のパーツに分解します。個々のパーツは最小矩 形単位でファイル保存もできますし、移動、貼り付けもできます。つまり複 数の元画像から自動的にパーツライブラリを生成し、それらを任意に組み合 わせて画像を生成するシステムが現実のものとなりました。それでは本業に 戻ってHTABOXの完成を急ぎます。
画像ファイル処理に特化したデモとなりますが、
ttp://kuroda.bglb.jp/htabox/htaboxapp.zipを更新しました 。将来は同等の
ウインドウをCreateImageWindow関数で生成可能とする予定です。取り説のい
らないGUIを目指しましたので、いじってもらえば機能は概ね理解していただ
けると思います。説明すべきポイントがあるとすれば、いかなる変更後も左
パネルの「原版へ戻す」ボタンでファイル再読み込みを行えることでしょうか。
領域認識技術やDirectX系フィルタは封印してオーソドックスな設計としてい
ますが、お気に入りの写真からオリジナルイラスト風画像を作成できます。
ただし、飯のタネと考えていますので640*480に制限させていただいているこ
とをご了承ください。
色階調制限や点描で使用している誤差拡散定数は既存のものでは満足できなか ったものですから、オリジナルなものです。仕上がり時にデジタルノイズを抑 制するためには、できるだけCPUが困りそうな数を定数とした方がいいようです。 つまり素数を使い割り切れない数の集合で構成します。 誤差拡散にしてもコンボリュートにしても、小数点以下の微細な演算の蓄積が 大変大きな差となって反映される様は数学の奥深さを感じさせます。
全体の動作を確認するためにスタンドアロンウインドウとなっていますが、 個々の機能はすべてHTABOXがスクリプトへ提供する関数で構成されることに なります。このウインドウに操作ログエディタを追加しどんなエフェクトが 行われたをソースコード化します。例えばhogeを開いて色を調整すれば var WIN32 = new ActiveXObject("HTABOX.Application"); var Img = WIN32.CreateImage(hoge);Img.ColorBalance(0.5, 0.5, 0.7);Img.Save(hoge2); のようなコードが自動生成され、このコードは単体スクリプトとして実行 可能になるという展開です。結果的にコードの小変更で大量の画像に対して 連続したエフェクトを行えます。多分音響に関しても同じ展開になると考えま す。再生録音を総合的に行うウインドウを生成することも可能なら、個々の機 能をスクリプトから実行することも可能というシステムこそ、類似製品との 決定的な差になるだろうと考えます。
今回改めて「究極のGUIとは」を純粋にWIN32で追及しました。なぜ取り説が 必要になるかといえば、何らかのパラメータを設定するダイアログと、メニ ューやツールバーとの関連を理解するためだと思うのです。ですから従来の ダイアログをタブで一覧表示してしまい、ダイアログの「OK」に代わるもの として「変更の確定」ボタンを置くという発想で書き進めました。ドキュメ ント側のタブ集合とダイアログ側のタブ集合をオブジェクトとしてエレガン トに管理するシステムデザインを確立できたと思います。思い起こせばHTML ウインドウに魅力を感じた最大の要因が「スクロールの自動管理」だったの ですが、今回真面目にWIN32をおさらいしてこの自動管理を簡潔にパッケージ 化できましたし、具象としての差異を一旦置いといて、基底クラス配列として タブ集合を管理できるC++の柔軟性を再認識しました。
非COMなGUI形成部分に対症療法的記述があったので見直しを行いました。 スクロールシステム、タブシステム、ウインドウ分割システムを二度と顧みる 必要が無いところまで煮詰めました。今は、アウトライン->個別エディタ-> 画像化->ヘルプ表示の仕様を煮詰めています。出発点のアウトラインはHTML ですが、各項目の正確な領域認識を目的に整形XMLであることを条件に加える 方向で検討しています。サンデープログラマなら何ヶ月もかかるだろう課題を 数日単位で処理していますが、それでも、もう蝉の声が大きく聞こえる季節に なってしまいました。
2日間ドキュメントのアウトライン操作とアウトライン用XMLの規格について コーディングしていました。素のHTMLからも移行できるように見出しが<Hn> であることは外したくないポイントなんですが、入れ子にできるエレメント では無いものですから、親子関係や、もしDIV等で修飾されていた場合どこ までを当該<Hn>の領域とみなすのかをDOMで表現する必要があったからです。 結果的に構造用XMLと領域用XMLを分離することで目的を達成できそうです。 正直、頭の方も衰えてきていますから、今のうちでないとこの入り組んだパ ズルは解けないだろうと直感します。C++の素敵なところは、ただ一度だけ理 解すれば、後はカプセル化できることです。
やっと文章管理、ソース管理、公開用画像生成を独りよがり仕様ではなくXML を基礎とした汎用なアルゴリズムにまとめることができました。結局、ドキュ メントにしてもプログラムにしても「何かを伝える」行為だと思います。で、 何れの場合も内容が高度であるほど、そのボリュームも増えてしまいます。 つまりボリュームを見ただけで受け取り側が萎えてしまう可能性が出ます。 そこをどう克服するのかというのが私の最も重要なテーマです。 恐らく世の中には優れた発想やその具現化が溢れているんじゃないかと思い ます。でも、多くの場合それは「独りよがり」に見えてしまいます。受け取 り側は前述の理由で萎えてしまい。提供側は基本的に「文字」ベースでそれ を説明しなければならないからです。この状態は新たな概念を導入しなけれ ば解決できません。
新たな概念という表現を使いましたが、簡単に言えば「実行できるヘルプ」 です。そして場合によってはそのヘルプの構造や内容をユーザーが編集でき る自由を導入します。ユーザーは多くの機能の中から自分が頻繁に利用する 項目をチョイスして自分なりの実行可能ヘルプを作り上げます。場合によっ てはそのチョイスや編集が「新たなアプリケーションの開発」になり得ると すれば(当該実行可能ヘルプを配布、販売できる)これは従来のアプリケー ション開発手法を刷新する新たな一歩になるだろうと直感します。
y153219.dynamic.ppp.asahi-net.or.jp test
そろそろこのスレッドも900ですが、HTABOX的には地味な作業の連続でこれと いったご報告もありませんからちょっとだけ私の思想信条について書かせて ください。私がなぜ、すべてをなげうってもフェアな世界を実現したいと考 えるに至ったのかというテーマです。
歴史にはうといものですから調べてみると、イラクがクウェートに侵攻したの は1990年の事だったようです。この時、イラクが侵攻してもアメリカは黙認す ると伝えながら、実際には過剰防衛な反撃が加えられました。まだ、インター ネットは普及していませんから、そういった情報はあっても半信半疑でした。
しかし、あの日、全世界にリアルタイムで戦争の原因となる事象が中継された 日から、世界中の人は気づいてしまいました。見え透いた情報操作が行われて ていること。何人の血が流れるかより、いくら儲かるが優先されることをです。
50にもなって青臭い事を...と嘲笑されるかも知れません。しかし、私はこの 世界がかくも「アンフェア」なものであることを子供たちや若者が知ってし まった事は取り返しのつかない損失だと考えます。もしこの愚かさが我々の DNAに由来するものであるなら、我々は最も卑しく下等な生物でしか在りませ ん。
せめてフェアな世界のために私ができることは何か?誰に雇われることなく 個人の発想と努力で、勝負できる世界。そのための正しい情報発信と汎用な ライブラリの提供。私をキーボードに向かわせるエネルギーはそういった怒 りや憤りなのです。私が動いても世界は1mmたりとも動かないのは承知の上で すが、私はそうせざるを得ないのです。
コンピューター、ソフトウェア、ネットワーク、これらの作り出す世界は、 マネーとコネクションに関わりなく力を発揮できる唯一の存在です。適切な アプリケーションやサーバーサイドシステムは一個の人間が巨大な企業に対 抗することをも可能にします。それを誰かが示さなければなりません。それ を誰かが示さないかぎり、プログラマーという存在は依然としてマネーとコ ネクションの支配から抜け出せません。
こと、コンピューター上の製品について企業などというレッテルは不要であり むしろ個人としてのプライドで製品の品質を管理すべきというのが私のポリシ ーです。それを可能にする開発環境、実行環境、サーバーサイドシステムを 提供するのがHTABOXの目標です。個人を起点として製品が生み出された場合、 陳腐なナショナリズムは意味を失います。どこの国に居住しようが製品の提供 に問題は生じないでしょう。私はそんな世界を実現したいのです。
この1ヵ月エディタのマイナーなバグを取りながら、私が最低限必要としてい る機能を規格化する作業を行っていました。テキスト形式のファイルはあらゆ る開発言語のソースコードであると同時に、気軽にアイディアや思いついたフ レーズを記録できる情報タンクでもあります。もし、どんな分野でも躊躇なく 書き込めるテキストファイルがあり、いつでも最小限の労力で、必要な部分を 再配置(アウトライン操作)し、プレゼンテーション用に画像出力できれば、 蓄積と思考と公開が一体となり、人間の能力自体を拡張しうるツールになるだ ろうと考えます。
通常テキストに何らかの追加された意味を持たせる場合、独自のファイル形 式を宣言しがちですが、私はあくまでもプレーンなテキスト中のタグ表記に よって機能を拡張することを選択しました。デフォルトフォント以外のフォ ントを使用する場合は<rich:font>〜</rich:font>を使うというような手法 です。また、行頭に存在する@からEまでの記号直後の文字列をタイトルと みなし、アウトライン操作、テキスト内でのハイパーリンク宣言が可能です。
私はこの拡張テキスト規格にRichTextPlusという名前を付けて提供しようと 考えています。プレーンなテキストが持つ汎用性を最大限に生かした総合的 なツールです。また、HTMLでの公開用に複数のプレーンテキストのタイトル 部分をより高次元でアウトライン操作可能なエディタも提供します。このエ ディタでHTMLプレビューした場合、画像表示されているタイトル部分を右ク リックすることで、即座にテキストレベルでの編集が可能となります。
HTABOXとは何か?を正しく理解してもらうために、そして、受け取り手がい かなる知識階層にいようとも戸惑わないために、私は何をどういう順序で説 明すべきか?という動機でスタートしたエディタ関連の技術は、HTABOX用コ ードの編集、実行環境にとどまらず、広範囲な情報管理ツールとして成長し 逆にHTABOXがエディタのマクロ実行エンジンとなるような予感もします。
今日はファイルダイアログの拡張子フィルタをユーザーが切り替えた場合に 入力済みファイルパスの拡張子部分を自動的に置き換えるという、実にマイ ナーな課題に取り組んでいました。こういった車輪を再発見せざるを得ない 分野というのはつい後回しになってしまいますが、この辺の作りこみが利用 者側をいかに大切にしているかの指標にもなりますので、手を抜けません。 納得できる記述に到達するまで一日を要しましたが、あらゆる呼び出しで表 示されたファイルダイアログはこの変更の恩恵を受けることができます。
今日はRichEditへのOLE埋め込み手法を全面的に見直しました。結果として 画像等のように埋め込まれているが選択する必要が無いもの。HTMLのように 選択して表示サイズを変更できるもの。が使用するクラスを明確に分離して 余計な記述を一掃しました。従来は選択されたくない領域に不可視なHWNDを 被せていたのですが、数が増えれば重くなるのは目に見えていましたから、 その方式を捨てて、マウスイベントが発生した場合に、選択されたくない埋 め込みオブジェクトが選択されているかをチェックする方式としました。 また、HTMLは横幅を指定しないとインライン要素が折り返せないわけですが、 編集中に最適な横幅を模索可能なように埋め込み矩形サイズがドラッグ可能 となりました。要求を満たしながら、ソースコードが短くなった時はすこし だけ幸せな気分になれます。
なぜプログラムは途中で投げ出されてしまうのか?の原因について考えてみ ました。根本的な要因は「似て非なるもの」を分散して書いてしまうことで す。ソースコードは誤りに気づき、改良される運命にあります。じゃあ直そう とソースコードへ向かった時に、該当する部分が分散してしまっていると、 それだけで嫌になります。まして、複数のビルドに跨ればなおさらです。 飯の種でもない限り「もうやーめた」になってしまうのも無理はありません。 対策はただ一つ「似て非なるもの」を書かないことです。2つ3つ書いて似 ていると思ったら共通部分を基底クラスにします。はじめからクラス継承構 造を思い描いた設計など教科書の中の話でしかありませんが、複数の具象の 共通点を基底としてまとめるという行為はこの問題を解決する効果的な方法 です。
アウトライン操作や、プレーンテキストにタグ規則を導入するような課題は 「文字列操作という力技」で「頭爆発しそうに面倒こと」を解決しなければ ならない割に、それ自体はそれほど目新しいものでもないという過酷な分野 です。多分こういった局面で短時間にスマートなコードが書ける人は本当の 意味で「頭がいい人」なんだろうと思います。プラットホームは異なれども う十年近くこの課題に向けて様々なものを書きましたが、エディタ自体をカ スタマイズできる状況になって、やっと納得できるコードにたどり着けた気 がします。整形XMLの場合はSAXによるストリームパース、プレーンテキスト の場合は高速な正規表現エンジンがこの課題を解決する鍵だと感じました。
テキストエディタを単体でも活用できる体系に仕上げる作業を終えました。 二段組の文章でもない限り、もうMSWORDを使うこともないだろうというと ころまで煮詰めました。これで劇的にヘルプを書くスピードが上がるはず です。結果的にテキスト中の@からEまでの記号を見出し階層を認識し、 テキストでもアウトライン操作を可能としました。部分的フォント設定、 箇条書きリスト、画像挿入、HTML挿入はすべてタグで定義し、エディタは プレーンテキスト表示モードとタグ解釈モードを随時切り替えられます。 HTMLはすべて動作している状態で埋め込まれ、スクリプトへ実行中のTOM インスタンスが渡されますから、埋め込まれたHTML中のボタンから文章を マクロ的に操作できます。この時JScriptの正規表現が活用できることは 大変大きなアドバンテージとなるはずです。 最大の特徴である編集中のスナップショット画像出力は各種形式に対応し、 見出しが存在する文章を開く場合、見出しをツリー表示して選択可能とす ることにより、一部分を編集状態として当該部分だけを画像出力すること も可能です。サンプル文章を兼ねる説明を添付してできるだけ早くお見せ したいと考えています。
なぜエディタにこだわるのかといえば、私は断片的なコードや文章を書いて どこに行ったか判らなくなる事があるからです。多くの場合苦労して見つけ てもたいした事は書いてないのですが、それでもいらだたしい時間を過ごす ことに変わりはありません。すべての事柄を生涯にわたって単一なテキスト ファイルに保存し、適宜取り出したり、再編して公開したりできるシステム がない限り、記憶力の衰退に伴って私のパフォーマンスは低下するだろうと 予測されます。 しかし私の脳を補完する存在として、過去に書いたソースコードを含む森羅 万象が記録されているテキストがあれば、少なくともパフォーマンスが低下 することはありません。たとえ僅かづつでも前へ進むことが約束されます。 コンピューターという存在が最も力を発揮する局面とはそいう使い方だと思 います。様々な情報やアイディアを常に閲覧できる状態にして、その混沌か ら新たな発想を生み出す触媒として、このエディタをデザインしました。
現在のソースコードは約800K、2万行くらいです。概ねHTABOXコアのMSHTML系、 とGDI+や分割ウインド系、エディタ、アウトライン系の3つが同じくらいのボ リュームで存在する感じです。最終的に音響系が加われば1M程度のものになる と思われます。それぞれの部分を書いているときは七転八倒しているのですが、 省みると、どれもありきたりなコードに思えます。やっと技術的な部分は納得 できるところにきましたので、3項演算子で(JP)?TEXT("日本語"):TEXT("English") 的な作業を開始しました。個人的には「File」以上に合理的な記述は無いと思 うのですが「ファイル」としなければこの国では見向きもされないんだろうと 諦めています。
リソースで固めて自由にメッセージ内容や言語を切り替え可能とかにしたほうがよくね?
>>917 おっしゃるとおり教科書的には文字列リソースのDLLを置き換えてになるんで
しょうが、どうも私はリソースのID管理というのが苦手です。全体が固まって
静的な状態となれば使う文字列も確定するでしょうが、まだそこに至っていない
ということなんでしょう。いつかもう付け足すことは無いと思えるようなもの
を書いてみたいものです。
よそ様のアウトライン機能付きエディタを眺めてみると、あぁなかなか考え て作られていると感心します。本来はHTABOX用実行エディタなんですが単体 としてもインパクトを持たせるために、DHTMLでアウトラインをダイアグラム 風にぐりぐり動かせて、各ノードを別スレッドのエディタで編集可能とする 作業をしています。昔デモでお見せしたときは100%DHTMLだったのですが、 今回はほぼC++ですので、十分に実用に耐える軽量さとなるはずです。
>>918 なら英語メッセージなんてまだ不要ってことじゃない?
>>920 英語が得意なわけではないんですけど、コードを書きながら静的な文字列を
定義するとき単純に「日本語変換」が面倒なのでついアルファベットで表現
したくなるという横着が原因ですので、つたない英語->日本語という作業が
必要になるという展開です。
もう一度WebBrowserの動作を確認するためにJScriptからWebBrowserを制御
可能なデモを公開します。マニフェストが参照しているのでDLLが添付され
ていますが、動作的にはHTABOXAPP.exeとconfig.jsだけで完結しています。
ttp://kuroda.bglb.jp/htabox/browser.zip テキストも添付しましたが、起動はEXE側でconfig.jsはEXE側が読んで実体
化させているところに注意してください。
添付されているconfig.jsの内容です。googleを赤く表示するデモとなっています。
//--------------------------------------------------------------------------------------------------
//このオブジェクトはWebBrowserEvents2の各要素と同名な関数が存在した場合にコールされます
var Listener = function()
{
//生成完了を取得しています。第1引数はWebBrowserです。
this.DocumentComplete = function(disp, url)
{
disp.Document.body.style.backgroundColor = "red";
}
};
//--------------------------------------------------------------------------------------------------
//EXE側は起動済みと想定しShell.ApplicationのWindows最終ディスパッチを取得します
var Windows = WScript.CreateObject("Shell.Application").Windows();
var Util = Windows.item(Windows.Count - 1);
//WebBrowserのセキュリティーレベルを設定します-1:低(何でもあり) 0:標準 1:高(スクリプト無効)
Util.Security = 0;
//UIFLAGを設定可能です。
Util.UiFlag = 0;
//WebBrowserの生成を指示し、インスタンスを保持します。
var Browser = Util.Browser;
//ナビゲート前にイベントリスナーを設定します。
Util.Listener = new Listener();
//WebBrowserをナビゲートします。
Browser.Navigate("
http://www.google.co.jp ");
//ウインドウの消滅を待機します。(イベントリスナーの消滅対策)
Util.WiteForWindow();
WSH.Echo("End");
投稿文字列制限に引っかかって一度に送信できませんでしたが。UIFLAGには 以下の定数を任意に設定可能です。 var DOCHOSTUIFLAG_DIALOG = 0x00000001; var DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x00000002; var DOCHOSTUIFLAG_NO3DBORDER = 0x00000004; var DOCHOSTUIFLAG_SCROLL_NO = 0x00000008; var DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x00000010; var DOCHOSTUIFLAG_OPENNEWWIN = 0x00000020; var DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x00000040; var DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x00000080; var DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x00000100; var DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x00000200; var DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x00000400; var DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x00000800; var DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x00001000; var DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x00002000; var DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x00004000; var DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x00010000; var DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x00020000; var DOCHOSTUIFLAG_THEME = 0x00040000; var DOCHOSTUIFLAG_NOTHEME = 0x00080000; var DOCHOSTUIFLAG_NOPICS = 0x00100000; var DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000;
で、普段はdocumentの直接埋め込みなんですが、なぜ今更WebBrowserを確認 したかというと、WebBrowserは、あくまで「コントロール」としてアレンジ されているので、サイズ変更等に伴うちらつきが少ないという事を検証した かったのです。なんでわざわざHWNDが一枚多いのか?という理由はここに あるのかも知れません。
WebBrowserでパースするHTML中に<HTA:Application/>を書いても多分通常は何 も起こりません。でもこの前置き無しにいきなり名前空間付きエレメントを有 効にする手法はすでに実際に運用しています。ならば、WebBrowserに限らず通 常ドキュメントで解釈されるHTML中で、自前の<HTA:Application/>を有効とす ることになんら技術的問題は生じません。例えば透過ウインドウ等の属性を追 加することも可能です。そういった手法での提案の方が受け入れやすいのかも 知れないという発想が頭をよぎります。
今回のデモで起動EXEはドキュメントを生成する前、つまりIOleClientSiteの 振る舞いが決定される前にスクリプトへ伺いを立てるという事を試しています。 特にUIFLAG系はHTMLがパースされる以前に決定される必要があるので、HTML中 のスクリプトからは手が出せないと推定します。考えてみるとこの方式ならデ バッグ時にもレジストリ登録は不要です。マニフェストさえ不要になります。 課題はただ一点、別プロセスMSHTA.exeがデバッグ対象HTAをパースする以前に 既定IOleClientSiteを偽装することが可能かどうかです。いままでごにょごに ょとやってきた事を組み合わせるとこれは可能だと思われます。そうなると あらゆる拡張にnew AvtiveXObjectや<OBJECT/>は不要で<HTABOX:Application/> 的なタグを宣言するだけで足りる状態となります。明日これを検証したいと 思います。
別プロセスMSHTA.exeへの埋め込みビヘイビア検証を終了しました。別プロセ スということで、相手側のご機嫌を伺いながらタイミングを待つという工夫が 必要でしたが、理論どおり動作するようです。あくまでもこれはHTABOXエディ タからデバッグ目的で編集中ソースを「MSHTA.EXEで実行」する時のものです。 HTABOXがMSHTAをフックしない状態で<HTABOX:Application>のあるソースをパ ースしても何も起こりません。
MSHTA.exeの既定IOleClientSite偽装が成功しましたので、大変自由度が高い 設計が可能となりました。ある程度縛りがあると、そうならざるを得ない的 単純さがあるのですが、なんでもありなものですから、HTMLコードを記述する 側に立って使いやすい仕様を決定したいと思います。 最も大きな点は<HTABOX:Application/>の属性としてメニューを定義すべきか、 <HTABOX:Menu/>という独立タグにすべきか、はたまた、タグ内に記述されたス クリプトコードで制御すべきかというような事を一晩考えたいと思います。
HTAは他の面では頑固なのですが、サイトの入れ替えはすんなりと受け入れます。 HTMLダイアログ系も含めた抽象化を模索しているのですが、ダイアログ系は意外 とサイトの入れ替えには頑固な面を見せます。もはや、引数でディスパッチを 与えるアドバンテージは意味がありませんから、潔くダイアログベースの拡張 ウインドウは切り捨てるかも知れません。もしHTAに引数ディスパッチを与えた いならCreateHtaWindowに引数を与え、HTML側に<HTABOX:Arguments/>を宣言して 参照してください。とした方がエレガントかも知れません。
HTMLダイアログ系でもサイト入れ替えは可能なのですが、内部で一旦引数を 保持し、再度windowへ追加する処理が必要だったりしてメリットがありませ ん。プロセス中に複数のトップレベルウインドウが必要な場合はWebBrowser ベースのウインドウを用意し、ダイアログ系へのカスタマイズは行わない方 向で考えたいと思います。また、HTABOXには軽量なWIN32ベースダイアログの 中身をHTMLで記述し、ウインドウサイズはBODY直下のTABLEへ自動追従すると いう関数が実装されていますので、素のHTMLダイアログを使う機会も無いだ ろうと思われます。
アプリケーションメニュー、ポップアップメニュー、ツールバー等使用頻度 が高いと予想される拡張機能は組み込みビヘイビアで処理することとし、そ の仕様を決定しました。従来は参照するテーブルのIDが固定されましたが、 任意のIDを柔軟に使用可能となります。単純なアプリケーションメニューの 例を示します。 <HTABOX:Menu src="APPMENU"/> <table id="APPMENU"> <tr><td>test</td></tr> <tr><td onclick="alert('test')">test</td></tr> </table>
情報収集のためにデータバインドをビヘイビアで実現できないかを試しまし たが、ビヘイビアであるが故に要求インターフェースはエレメントとしての 機能に関連するものに限定させるようです。したがってデータバインドプロ バイダは<OBJECT>でなければならず、HTABOXが待つ動的マニフェストシステ ムは依然として必要なようです。
プログラミングってレースみたいなものだと思うんです。参加する側にとっ て見ればいろんなカテゴリーがあってそれぞれにレギュレーションがあるわ けですが、スタンドで見ている観客はそんな内幕なんてどうでもよくて単に 速いかどうかで判断する。しかも、プログラミングのレースには無制限クラ スが存在するので特定のカテゴリーでベストを尽くしても評価されないとい う厳しい現実があります。HTABOXは単にHTMLアプリケーションという枠で有 効なだけでなく、ビギナーでもこの無差別クラスで勝利できるパーツとして 提供したいというのが、私の目標です。
ツールバーの見直しに結局一日を費やしてしまいました。別HTMLでの画像定義 は廃止し、イメージリストを本体HTMLで定義することとしました。下記はその サンプルです。 <HTABOX:ImageList id="IMAGELIST" width="32" height="32" mask="0x000000"> <HTABOX:Item src="img/tool0.bmp"/> <HTABOX:Item src="img/tool1.bmp"/> <HTABOX:Item src="img/tool2.bmp"/> <HTABOX:Item src="img/tool3.bmp"/> <HTABOX:Item src="img/tool4.bmp"/> </HTABOX:ImageList> <table id="TOOLTABLE" style="display:none"> <tr> <td onclick="alert('ToolBar 0')"></td> <td onclick="alert('ToolBar 1')"></td> <td onclick="alert('ToolBar 2')"></td> <td onclick="alert('ToolBar 3')"></td> <td onclick="alert('ToolBar 4')"></td> </tr> </table> <HTABOX:ToolBar image="IMAGELIST" src="TOOLTABLE"/>
ステータスバーは <HTABOX:Status id="STATUS"> <HTABOX:Item width="20"/> <HTABOX:Item width="*"/> </HTABOX:Status> として、スクリプトスコープからSTATUS.Print(index, string);にする予定 です。今回の組み込みビヘイビア化でHTABOX内部HTAと、フックMSHTA.exeは 全く同一なモジュールで構成されることになります。ちなみに何れの環境で も既定の<HTA:Application>動作は有効なはずです。
HTAタグのsingleinstanceも有効になりますか?
938 :
デフォルトの名無しさん :2012/09/30(日) 19:23:57.36
>>937 独自ビヘイビアをフル実装した状態でテストしたところ、<HTA:Application
自体と競合する部分があるようです。つまり両者を共存させるのではなく、
<HTABOX:Applicationが従来型HTAの属性をすべて網羅する方向の解決策になる
と考えられます。どうせですから従来不可能だったものを取り入れますので
どんどん要望をいただけると励みになります。
>>938 従来は楽屋のどたばたを隠す目的でレイヤーウインドウだったのですが、今回
ビヘイビアによって大変スムーズなウインドウ生成とすることができました。
レイヤーウインドウはやや重い動作となりますので、ご指摘のような状況が発生
しやすいのです。明日には刷新されたHTABOXをお見せできると思いますので、ご
期待ください。
何度かそういう状況にトライしていたのですが、本体EXE用cppに#if defined でDllMainを置き、完全な同一ソースでHTABOXとMSHTAをコントロールすること に成功しました。ビヘイビアによってHTABOXがEXE形式COMサーバーである必要 が無くなったことでソースは極めて単純な構造となります。私の中で両者の位 置づけは以下のストーリーでご理解いただけると思います。 1.MSHTA.EXEに不満があるので互換EXEを自作したい。 2.自作したらデバッガへ情報を提供するのが面倒。逆手に取って隠蔽方向へ。 3.やはりデバッグしにくい。しかたがないのでMSHTAを乗っ取ってデバッグ。 4.そういえば<HTA:Application/>タグ的手法の方が拡張しやすいのでは。 という展開です。いろいろありましたが、やれる事は全部やった感があります。 基本構造が見直された事で、リリースバージョンは3.00を予定しています。
<HTA:Application/>の上位互換として<HTABOX:Application/>が存在すれば もはや、HTAという規格は意味をなさなくなります。HTAのサイトへ924で記 述したUIFLAGを設定することも可能ですが、それよりはじめからWebBrowser ベースのウインドウでUIFLAGの設定と<HTABOX:Application/>の使用を行った 方が自然です。ただしデバッグ時だけMSHTA.exeの懐を借りるということに なるでしょう。
上記デモでボタンの横にあるグレイの矩形がどの記述で定義されているのか 不思議だと思うんですが、<HTABOX:hode/>で出現するエレメントは非表示で メニューや、ツールバーを生成する仕事をさせることもできれば、表示領域 を持って通常のエレメントのように振る舞い、独自イベントを定義すること も可能です。しかも<OBJECT/>とは比較にならないほど軽量です。例えば迷路 の個々のブロックを<OBJECT/>にしても直ぐに飽和するでしょうが、ビヘイビ アでブロックを表現すれば数千、数万ブロックあったとしてもネイティブな 手法のゲームと同じマウスレスポンスが得られると予想されます。
WebBrowserベースだとセキュリティー制約が付きまとうという事に気づきま した。あくまでも外界に向けたブラウザであってインターネットオプション と深く結びついた状態なのかも知れません。そういう意味ではドキュメント 直接埋め込みや、HTMLダイアログ系の方がHTMLアプリケーションのベースと しては適しているような気がします。HTA系はプロセスにつき1つですので 自由に生成できる手法をもう一つ確保できればと考えています。
>>942 のデモだとXP+IE6ではツールバーアイコンに画像が反映されないようです(XP+IE8では正常)
またXP+IE6・XP+IE8の両方でWindow.ResizeToすると、
HTABOXのウインドウ自体はリサイズされずtest.htmの中身のみがリサイズされます
>>945 貴重な情報をありがとうございます。ツールバー画像はlocation.pathnameで
相対パスを絶対に変換するタイミング等に問題があったようですので、修正
します。リサイズについては中身の方から要求があった場合を考えていません
でしたのでその部分を追加します。今後ともよろしくお願いします。
弱気な事をここに書くと解決するというジンクスが私にはあるのですが、 WebBrowser生成のHTMLアプリケーションベースも問題なく動作するところに こぎつけました。MSHTAでデバッグした時は発生しませんが、WebBrowser はWebBrowserEvents2を報告してくれる事がメリットですので、ウインドウ の変移を積極的に活用したアプリケーションへの道を開くと考えます。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。スクリプト由来のサイズ変更に対応しました。
location.pathnameの解釈タイミング、正規表現置き換えを見直しました。
location.pathnameは若干バージョンや環境で文字列が異なるはずですが、
先頭スラッシュがあれば削除、デリミタスラッシュを\\へ置き換え、%20が
あれば\x20へ置き換え、最終\\直後から終端を削除、画像パスを追加という
処理にしています。IE6は7以降とは異なる癖があったような気がしますが
表示されるでしょうか?。
HTABOXが提供する拡張機能は従来どおり使用できますが、参照の方法が変更 されます。<HTABOX:Application id="WIN32"/>としてスクリプトからID経由 で関数を呼び出すことになります。WIN32.Hoge();つまりHTABOX:Application は全体の属性定義用エレメントでありながら、ディスパッチも提供すること になります。これにより、いかなる状況下でも呼び出しプロセス内でWIN32は 生成されますから、マーシャリングにかかっていたコストも不要となります。
HTMLスクリプト由来のウインドウサイズ変更はHTAやHTMLダイアログ系なら 処理的には最外郭のウインドウへメッセージを中継すれば済むんですが、 WebBrowserの場合はあらかじめサイズを指定されたコントロールですから、 リサイズという概念が無いようです。IWebBrowser2には過去の遺産として Resizableプロパティーが存在しますが、IE7環境ではE_NOTIMPLを返します。 まぁ、一旦手のひらに乗れば何でもありですから、後付でwindow.ResizeTo 等を定義し、HWNDへのメッセージとすれば対応可能だと考えます。
埋め込みビヘイビアを有効としたダイアログも安定動作するようです。 これでHTA、WebBrowser、HTMLDialogで何の前置きも無くHTABOXタグを 使用することができます。今日はそのダイアログが表示されるデモをお見せ できるようにもうひとねばりしようと思います。いつのまにかこのスレッド も終わりに近づいています。書けなくなったら、このサーバーが許せば新た なスレッドを作りますので、目を通してやってください。
952 :
945 :2012/10/02(火) 20:02:03.84
XP+IE6及びXP+IE8でツールバーアイコンの画像とWindow.ResizeToの正常な動作を確認しました
ただ
>>945 の時点で気付いておくべきだったのですが、Window.MoveToが無視されてしまうようです
>>952 了解しました。現状では確かに無視していますのでスクリプトからの移動も
可能にしたいと思います。今、母艦HTAからのダイアログ起動というコンテキ
スト地獄でもがいていますので、それにかたが付きしだい対策をしたいと思
います。
コンテキストメニューとメニューバーについて提案です。 コンテキストメニューは階層構造が無い物の方が一般的ではないでしょうか? また、メニューにマウスオーバーのイベントを付け加えて頂けないでしょうか。 (メニューの説明をステータスバーで表示するため) そこまで重要でないので出来ればですが 宜しくお願い致します。
>>954 おっしゃるとおりです。双方のメニューについてご指摘の部分を改善します。
確かに機能を実装する作業は簡単ではありませんが、「こうだと便利」が実現
されていなければ、存在意義がありませんので、お気づきの点がありましたら
なんなりとご提案ください。
ダイアログの表示はおもったよりエレガントに解決できたのですが、インプロ セスHTA起動時に、メッセージ間の衝突が散見されましたので、その解決に時間 を要してしまいました。本来使って欲しくないものを解析して使うという関係上 情報などあるわけもなく、さまざまな状況下で変化するメッセージの流れを読み 解くしかないものですから、完全は存在しないのですが、改善はできたようです。 いっそ、親ウインドウはWebBrowserベース一本にすればそれまでなんですが、 今までの流れもあってインプロセスHTAが制御できなければ「負け」みたいな こだわりを持ってしまいます。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。ウインドウ全体の移動については、内容HTMLが動いた後に
追従させるとギクシャクすることからすでに実装されているSetWindowPosで
対応していただくことにしました。表示、非表示、Zオーダー等も設定可能
です。詳しくはMSDNとソースを合わせてご覧ください。
アプリケーションメニューでWM_MENUSELECTが発生した場合、項目indexを
window.onMenuSelect(i)を通じてHTML側へ報告するものとしました。
アプリケーションメニューはHTML中の表示エレメントではないものですから、
HTML的イベント処理を強引に導入すると逆に複雑化するという判断です。
サンプルでは以下の単純な関数を定義して当該インデックスのタイトル文字列
をステータスバー先頭セクションに表示しています。
function window.onMenuSelect(i)
{
STATUS.SetText(0,APPMENU.cells[i].title);
}
コンテキストメニューについては、ルート要素にもonclickを定義できるよう にしました。当然ですが動作を定義した要素は親にはなれません。また、この メニュー定義時にもtitleを付けて説明のポップアップが出せるようでしたら 追加したいと考えています。 ダイアログについては、まだ、スタイル指定文字列を受け取らないなど、仕様 が確定していない状態ですが、全く本体と同じ拡張が可能である事をご覧いた だけます。ダイアログは通常のHWND構造ですからMoveTo等はそのまま機能します。
ステータスバーにSBARS_SIZEGRIPがあると稀にヒットテストに失敗するよう なので外しました。これは以前からHTML系にステータスを追加した場合に生 じていた事なのですが、要因については見当がつきませんから、僅かに外観 は劣ることになりますが、無くても機能としては変化しないので大きな課題 とは考えていません。これでHTABOXの骨格部分への変更が完了しました。
例によって非力なノートにIE8を入れてテストモジュールを動かしていますが ダイアログ表示のキレが予想以上に鋭いので驚いています。このダイアログは IE6以降が条件の比較的新しい手法によるものなのですが、デフォルトな生成 とは明らかにレスポンスが違います。HTMLダイアログの内部環境はHTAタグこ そ無効ですが、まんまHTAですので、これをアプリケーションベースとした体 系でも支障は無いと感じさせます。
961 :
945 :2012/10/03(水) 19:37:24.33
test.htm及びdialog.htmの機能は正常に動作しますが、 XP+IE6でまたタスクボタンが二重になるようです
今回のダイアログはIHostDialogHelperが生成するものなんですが、さて デバッグ環境をと、実行中のプロセスにアタッチすると、表示中ダイアログ のHTMLが見えないんです。なぜこのダイアログが高速にレスポンスするかの 答えはここにありそうです。ですから、HTABOXのスクリプトエンジンがそう であるように、このダイアログで実行されるスクリプトは通常より高速であ る可能性があります。
プログラミングというのは99%デバッグ環境を眺めている作業なわけで、ブレ イクポイントを置いて変数の変化を追跡できるということは必須な条件だと 考えます。現状では内部スクリプトエンジンで隠蔽さえしなければHTABOX自体 でもそういったデバッグは可能なようです。(前述ダイアログを除いて)
もう一つの要素として、外部スクリプトとの連携とデバッグについて構想を 練っています。WebBrowserのデモでやった、傍らのjsをHTMLをホストするEXE がインスタンス化し、相互にディスパッチで通信するという方式はCOM登録な しに傍らのjsへ拡張されたHTML機能を認識させることが可能なだけでなく、 傍らにあるのはjsで無くてもホストがインスタンス化できるなら.NETだろう が、Javaだろうが、ネイティブなDLLだろうが問題ないわけです。
HTMLと外部スクリプトの分割を強要するわけではありませんが、スクリプト を含めて100k、200kというHTMLをアプリケーション冒頭にパースするのは得 策ではありません。おそらくユーザーはそのどんよりとした起動レスポンス だけで萎えてしまうでしょう。理想はHTML中にはGUIに関連する引き金だけが 存在し、<HTABOX:Application id="WIN32"/>は傍らにあるjsやDLLのメソッド を知っていて、HTML中から直接呼び出せる事です。これならばHTML中のスク リプト実行速度の足枷もありませんし、本格的に隠蔽したければDLLにして しまう選択肢もできます。
誰しもがVisual Studioを持っているという前提なら、このデバッグ手法につ いては別の次元で論議すべきことなのだと思いますが、最低限office付属の MSEが起動する状態で、快適なデバッグを十分に考慮したシステムの構造とは 何かについて、結論を出したいと考えています。
とりあえずJScriptかVBScriptならWSH系はあえて使わず、並列スレッド又は 並列プロセスで生成した非表示HTMLダイアログ(旧形式)のスクリプトエン ジンでパースすべきというインスピレーションがあります。これならばエラ ーを待たずともアタッチしてブレイクポイント待機できそうな気がしますし、 WSHが持つWScriptオブジェクトとの関連を断ち切ることで、#define的手法を 用いずともHTABOXとMSHTA又はリリースとデバッグを渡り歩ける気がします。
あぁIHostDialogHelperが生成するHTMLが見えないというのは勘違いでした。 これも自作ビヘイビアを認識させるためにごにょごにょしている部分がある んですが、それが原因でHTMLをデバッガに見せないという性格に変化してい るというが正しいようです。今まで、MSHTMLが生成するドキュメントのHTML は隠せないと思っていたのですが、結果的にそれが実現されているのは驚き です。
<HTABOX:Extern type="jscript" src="test.js" id="JS"/> <HTABOX:Extern type="native" src="test.dll" id="COM"/> のような属性を解釈するビヘイビアを新設し、HTMLからは当該IDへの呼び出し を行うことができ、被参照側にディスパッチアドレスを保持可能な変数を置け ば、HTML側からJS.Disp = document;で設定ができ、被参照側では必要に応じ て、Disp.location等でHTML側情報を取得可能というのがシンプルで判りやす い気がします。<HTABOX:ExternはHTMLがパースされる前に文字列としてホスト が検出してsrc対象をインスタンス化、UIFLAGのようにHTML生成条件を設定可 能とすればよりエレガントですね。あぁ、私が漠然と思い描いていたHTMLアプ リケーションの形ってこういうものだったかも知れません。データバインドや CSSがらみのビヘイビアを除けば、完全なサイドバイサイドで動作させること ができます。
右クリックによるコンテキストメニューの場合も選択状態が変化した場合 アプリケーションメニューと同じようにwindow.onPopupSelect(i);をコール バックする仕様としましたが、改めて、WIN32APIメニュー系APIの作りの悪さ と、説明の意味不明さに疲れ果ててアップする気力も失せました。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。以前は通常生成のHTMLダイアログにもちょっかいを出していまし
たが、それを廃止し、拡張ダイアログの仕様を決定しました。
CreateDlgWindow(BSTR url, VARIANT arg, BSTR opt, bool mode);
引数は絶対パス、引数バリアント、ダイアログスタイル、モーダル真/モードレス偽
です。また、もうしこし柔軟な使い方ができるようにウインドウスタイルを
指定可能としたCreateDlgWindowExを新設しました。これによりダイアログ
をタスクに入れることが可能です。表示しつづけるヘルプウインドウ等に
利用できると思います。CreateDlgWindowにlong型の引数が追加され、この
引数が非ゼロであればダイアログ生成最終段階で適用されます。詳しくは
デモのtest.htmソースをご覧ください。
モーダルはwindow.returnValueを返さなければなりませんが、その辺の実装 がまだ甘かったようですので、見直します。COM的なリターンと、主スレッド の開放タイミングが別というきめ細かな動きをしてくれるものですから、扱 いにくい面も出るようです。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。拡張されたダイアログについてwindow.dialogArgumentsと
window.returnValueの部分を修正しました。なんか変な動きに見えたのは
リリースビルド状態でブレイクポイントを設定したからという落ちでした。
多くの場合、変数値は参照できなくても停止だけはしてくれるものなので
すが、今回は違ったようです。
HTABOXAPP.exe本体に起因するバグではないですけど onMenuSelectがシステムメニューにも反応してエラーになるのでtest.htm内でtry〜catchしておくと良いようです
>>977 了解しました。システムメニューからの情報が飛んでくることは考慮していま
せんでしたので、単に私の考えが浅いだけで対策が存在すると直感します。
貴重な情報をありがとうございました。
<HTA:Application 互換設定は必ず手がけますが、外部モジュール連携手法が 確立してからになります。私が認識している設定内容は下記のとおりです。 ・applicationName ・border ・borderStyle ・caption ・commandLine ・contextMenu ・icon ・innerBorder ・maximizeButton ・minimizeButton ・navigable ・scroll ・scrollFlat ・selection ・showInTaskBar ・singleInstance ・sysMenu ・version ・windowState
そろそろこのスレッドともお別れです。一気に埋まった場合、私が目を通せな い可能性が出ますので、新しいスレッド「HTABOXコア Part3」(予定)があった らそちらにも書き込んでください。このスレッドにも1年半つぶやき続けました のでなんか名残惜しい気がします。前スレも含めて長い間、遅々として進まな い私の仕事を暖かく見守っていただいて、感謝の言葉も見つかりません。
外部モジュール、手始めに隣接JS又はVBSをデバッグ時にパースするエンジン はHTAの中身である{3050F5C8-98B5-11CF-BB82-00AA00BDCE0B}を要求ファイル 毎に生成した方が非表示ダイアログで処理するより軽いだろと思われます。 この場合もMS純正スクリプトデバッガやMSEでアタッチしブレイク待機可能 だと思います。.NET系については、各環境でのコンパイラを探すのが面倒です からソースコード状態ならデバッグ時でもHTABOX内部のコンパイラ、もし各 言語でブレイクポイント待ちをしたい人はアセンブリをDLLコンパイルして Visual Studio環境で待つ、ネイティブDLLな場合はVisual Studio環境等で待 つという感じにできるんじゃないかと思います。
いつもスクリプトを隠すことだけ考えていたものですから、本体HTMLのパース を阻害しない状態でありながら、デバッガへ綺麗にスクリプトを見せるという のは意外と細かなテクニックが必要になるようです。やはりスクリプトの場合 は非表示ダイアログが最も扱いやすい補助エンジンですが、jsにナビゲートし てもパースはされないわけで、かといってdocument.write等で構築しても見え るのはその構築動作コードだけになります。結局、独自プロトコルという手段 で解決できそうです。内容は単にスクリプトコード前後に<html><script...> </script></html>を付加するだけですが、この場合はそういうHTMLファイルが あったかのように表示されます。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。外部JSをHTMLとは別にパースし、当該JSにdebugger;命令
を置いて、デバッガを起動するデモが加わりました。私の環境ではMSE7と
二つのバージョンのVisual Studioのいずれをデバッガとして起動するかの
ダイアログが表示され、JSのソースが表示されます。このデバッガ環境は
個々のインストール状況、開発環境状況によって千差万別ですが、インタ
ーネットオプションの「スクリプトのデバッグを使用しない」をオフにし
ないと自動的なデバッガの起動は抑制されてしまうと記憶しています。
最終的にスクリプトは自前の非表示HTA互換ウインドウで行っています。既製 品のHTMLダイアログは扱いが簡単でいいのですが、たとえ非表示でも必ずウイ ンドウのアクティブを奪うことろが致命的な欠点ですので採用しませんでした。 また、コンテキスト的に遠いと管理しにくいことから、完全な別スレッドでは なく、本体スレッドコンテキストではあるものの、ドキュメントはそのパース には無関心である状態としています。ただ、フレームとか、ダイアログとかの 関連無しに、別HTMLインスタンスを生成することはコンテキスト的にタイトロ ープです。例えば同じ結果を得る為にディスパッチ呼び出しをするのか生インタ ーフェース呼び出しをするのかといった違いだけで動作とクラッシュが決まる ような状態を体験しました。
C++とくにCOMプログラミングが難解とされる最大の要因はコンテキスト、 つまりその呼び出しはどのスレッドを起点にして行われているのか、その スレッドは何をトリガーに起動したのか、Postでプリミティブな値だけを 渡して代替できるのか、等々の問題が直接目に見えないことにあります。 これに立ち向かう武器は、あらゆるところにブレイクポイントを置き、そ こでインスタンスが生きているかを確認することに尽きますので、他人の ライブラリやATLのようなマクロ依存することは大きなマイナス要因だと 感じます。少なくともこの本質的な問題を理解する前にそういった出来合 いのコードを使うのは、愚かしい行為です。
しかし、COMプログラミングは魅力的です。私がもし、ゼロからHTMLを解釈し それをウインドウに描画し、イベントで連携するアプリケーションが書けるで しょうか?答えは当然「No」です。数メガに及ぶバイナリを生成するたのソー スは少なくとも数メガあります。これを僅か数百キロのソースでカスタマイズ できるのはCOMだからこそです。
いつのまにか、モーダルダイアログがモードレス動作していることに気づき ました。要因が判り次第、バイナリを更新する予定です。ご容赦ください。
ttp://kuroda.bglb.jp/htabox/htabox300.zip を更新しました。添付test.jsは毎回デバッガが起動して面倒なのでdebugger;
をコメントアウトしました。デバッガ起動をテストしたい場合は有効にして
ください。モーダルも正常動作に戻りました。
var WSS = new ActiveXObject("WScript.Shell");
function test()
{
//debugger;
WSS.Popup("Hello");
}
現在の流れから推察するに、このMSHTAフックモードはユーザーサイドでは 不要になると思われます。エディタから起動し、データバインドやGDI+系 COMDLLを絡めた検証は行ってませんが、その場合も通常のデバッガでアタッチ 可能なら、このモードは内輪だけのものになります。 内部生成HTAは本家よりやや柔軟なものですか、ついコンテキストを外した動 作となりがちなのですが、本家をフックした場合はその辺にシビアですから、 私の実験的なコードを正してくれる教師としては存在し続けると思います。
MSHTAをフックした状態のデモは単独EXEとして実行するとタスクにいやな残り 方をする場合があるので、公開を停止しました。Visual Studioでは正常なの ですが、まだ勉強不足なようです。もしこれを使う必要が生じた場合は、その 点を確実に克服したいと考えています。
可能であれば<OBJECT/>もマニフェストやレジストリに無関係な状態にできな いか半日もがきましたが、なかなか糸口がつかめません。COMサーバーでない 状態ならば、DLL無しでも自家発電マニフェストでHTABOXAPP.exe単体な状態 は作れたと記憶していますが、バイナリ開発時の事とは言え、MSHTAを利用す るな状態でも何らかの偽装工作で<OBJECT/>が挿入できると素敵なのですが。
前述の技術を確立することができました。HTML上に無害でおとなしいCLSIDの オブジェクト宣言を置き、生成過程をフックすることにより、任意なDLLへ摩 り替えるという手法です。現在の課題は各環境に必ず存在し、おとなしいとマ ークされているActiveXはどれか?に移行しています。現時点での有力候補は {1D2B4F40-1F10-11D1-9E88-00C04FDCAB92}、webvw.dllnなのですが、頻繁に使 用されるdllでは無いほうが好ましいので情報を収集しなければなりません。
ビヘイビアの有効利用、レジストリやマニフェストに依存しないオブジェク トインスタンスの生成という「パーフェクト」な技術的基盤ができました。 今回の解析で興味深かったのは、総てのモジュールロードには偽装の余地が あり、そこでロードされるjscritやvbscript用dllを軽くラップして渡すだけ で、拡張可能なことです。もし、VBの速度とJSの柔軟性をいいとこ取りした 状態を作れれば素晴らしいですが、それは今後の課題にしたいと思います。
今のところダミーのCLSIDは{62112AA1-EBE4-11CF-A5FB-0020AFE7292D} ShellFolderViewが最適ではないかと考えています。HTML冒頭にオブジェ クト宣言がある場合、その直前にマップされるDLLは常に一定のようです。 したがって直前DLLのマップ要求を検出して次を入れ替え、以降は無関心に なることで、実際にShellFolderViewが必要とされている場合との競合も 回避できるとの結果が出ました。この辺が環境やIEのバージョンに依存し なければHTABOXの機能として採用したいと思います。
1000ならHTABOXコアが商業的に成功する
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。