第27話:HTAを利用したウインドウ付きアプリケーション

第5部 応用編

目次

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ台詞

【1Page】
アイコン先生:前回はウィンドウなしの アプリケーションを作った
    今回はウインドウ付きの アプリケーションを作るぞ
アイコン麗:そんなことが できるんですか?
アイコン先生:ああ
    『HTA』を使えば バッチリできる
    それで 『HTA』なんだが HTMLファイルの拡張子を 『.hta』にすれば完成だ
        .html
        ↓
        .hta
アイコンアイコンアイコン3人:アイコンアイコンアイコン3人:はっ?
【2Page】
アイコン遊:いくらなんでも それは手抜き過ぎじゃ!
アイコン先生:ダブルクリック してみろ
    (ウィンドウ表示)
アイコン遊:あれ?
    ブラウザではなく ウインドウが 立ち上がった!
アイコン先生:どうだ 物すごく楽だろう?
アイコン遊:おみそれ しました
アイコン先生:前回の『cmnFunc.js』を 『HTA』用に改造すれば ファイル操作も行える
    追加する場所を 赤く塗るぞ
        1ヶ所目
        this.createObject = function(name) {
            try {
                return WScript.CreateObject(name);
            } catch (e) {
                // 『HTA』では『WScript』が使えない
                // 代わりに『ActiveXObject』を作成
                return new ActiveXObject(name);
            }
        };
        2ヶ所目
        try {
            this.rootPath = WScript.ScriptFullName;
        } catch (e) {
            // 『HTA』では『WScript』が使えない
            // 『window.location.pathname』を使ってパスを取得
            // (『unescape』は半角スペース対策)
            this.rootPath = unescape(window.location.pathname);
        }
【3Page】
アイコン先生:それじゃあ 『cmnFunc.js』を利用して サンプルを作ってみよう
    『HTA』はHTMLファイルなので 『jQuery』も利用できるぞ
        【sample.hta】
        <html>
            <head>
                <meta charset="Shift_JIS">
                <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
                <script language="JavaScript" src="cmnFunc.js"></script>
                <script>
                function read() {
                    // id『data』の内部の文字列を書き換え
                    $("#data").text(
                        // 『cmnFunc.rootPath』は自分自身のパス
                        // 『cmnFunc.readFile』で自分自身を読み込む
                        cmnFunc.readFile(cmnFunc.rootPath)
                    );
                }
                </script>
            </head>
            <body>
                <input type="button" onClick="read();" value="中身を表示">
                <pre id="data"></pre>
            </body>
        </html>
        『sample.hta』の中身を id『data』に表示
【4Page】
    (ウィンドウ)
        …sample.hta
        中身を表示
        カチッ
    (中身表示)
        …sample.hta
        中身を表示
        ザッ
    『中身を表示』ボタンを クリックすると
    『sample.hta』の中身が ウィンドウに表示される
アイコン先生:さて もう少し 『HTA』について 説明する
    『HTA』では 『HTA:APPLICATION』タグで 設定を追加できる
    アプリケーション らしい外観を 設定してみよう
【5Page】
        <html>
            <head>
                <meta charset="Shift_JIS">
                <title>HTAアプリケーション</title>
                <HTA:APPLICATION
                    icon="pic/star.ico"
                    id="thisHTA"
                />
                <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
                <script>
                var width = 640;
                var height = 480;
                $(document).ready(function(){
                    window.resizeTo(width, height);     // ウィンドウサイズ設定
                    window.moveTo(      //  ウィンドウを中央に
                        (window.screen.width - width) / 2,
                        (window.screen.height - height) / 2
                    );
                });
                </script>
            </head>
            <body>
                <script>
                // コマンドラインを表示(『thisHTA』は『<HTA>』タグで定義した『id』の値)
                document.write(thisHTA.commandLine);
                </script>
            </body>
        </html>
        『HTA』の設定
【6Page】
アイコン先生:『HTA:APPLICATION』の属性に 『icon』と『id』を設定している
        <HTA:APPLICATION
            icon="pic/star.ico"
            id="thisHTA"
        />
    拡張子『.ico』のアイコンを 『icon』に設定すれば タイトルバーにアイコンが付く
        icon="pic/star.ico"
    『id』を設定すれば 『thisHTA.commandLine』 のように
    アプリケーションの 値を取り出せる
    『commandLine』には アプリケーションの パスと引数が入っている
        id="thisHTA"

        // アプリケーションのパスと引数を表示
        document.write(thisHTA.commandLine);
【7Page】
アイコン先生:ウィンドウの 位置やサイズは 『resizeTo』や『moveTo』 で設定可能だ
                var width = 640;
                var height = 480;

                // ウィンドウサイズ設定
                window.resizeTo(width, height);
                //  ウィンドウを中央に
                window.moveTo(
                    (window.screen.width - width) / 2,
                    (window.screen.height - height) / 2
                );
アイコン麗:中身はHTMLと 同じだから 簡単に作れ そうですね
アイコン先生:JavaScriptを 学んだ人には 便利な手法なので 是非活用して欲しい
アイコン遊:ここまで手抜きだとは 想像していなかったわ

説明

この章では、『HTAを利用したウインドウ付きアプリケーション』について学びます。

Windowsでは、HTMLファイルと『WSH』の技術を組み合わせて、ウィンドウ付きのアプリケーションを手軽に作る方法が用意されています。それが『HTA』です。

『HTA』の作成は、特別な開発ツールなどを必要とせず、メモ帳もしくはテキストエディタだけで行えます。また、これまで学んできた、『WebページのJavaScript』、『jQuery』、『WSH』などの知識を応用して、アプリケーションを作成できます。

それでは以下、『HTA』について説明していきます。

『HTA』とは?

『HTA』(HTML Application)は、HTMLの技術を使って、Windows向けアプリケーションを作る方法です。

Windowsパソコンでは、HTMLファイルの拡張子を『.hta』に変えれば、アプリケーションとして扱われます。

こうすることで、ローカルファイルへのアクセスなどが行えるようになります。

参考

『HTA:APPLICATION』タグ

『HTA』ファイルには、『HTA:APPLICATION』タグを設定できます。

このタグを使えば、アプリケーションらしい外観を整えることができます。

以下、設定できる値の中で、よく使うものを掲載します。

属性 意味 設定する値
icon アイコンファイルのパス ~.ico
id HTAオブジェクトのID thisHTAなどの文字列
maximizeButton 最大化ボタンの表示 yes、no(標準はyes)
minimizeButton 最小化ボタンの表示 yes、no(標準はyes)
scroll スクロールバーの表示 yes、no、auto(標準はyes)
contextMenu 右クリックメニューの表示 yes、no(標準はyes)
showInTaskBar タスクバーへの表示 yes、no(標準はyes)
navigable リンクをウィンドウに読みこむか yes、no(標準はnoで別ウィンドウ)
singleInstance 複数起動を禁止する
yesの時は『applicationName』が必要
yes、no(標準はno)
applicationName アプリケーション名 uniqueNameなどの文字列

以下、その他の属性がまとめられているサイトです。

参考

『HTA』が使えない場合

以下、少し難しい操作です。『HTA』のファイルを、ダブルクリックしても起動できない人だけ、参考にしてください。

『HTA』ファイルは、『c:\Windows\system32\mshta.exe』に関連付けられていないと起動できません。上手く起動できない場合は、以下の操作を行ってください。

  1. 『HTA』ファイルを右クリックして、『プログラムから開く』メニューを選択する。
  2. 『ファイルを開くプログラムの選択』というダイアログが開く。
  3. 『推奨されたプログラム』の項目から『Microsoft (R) HTML アプリケーション ホスト』を選択する。
  4. もし、この項目がない場合は、『この種類のファイルを開くときは、選択したプログラムをいつも使う』にチェックを入れて、『参照』ボタンを押す。
  5. 『c:\Windows\system32\mshta.exe』を選択して、『OK』ボタンをクリックする。

これで、ファイルの関連付けが行われます。

マンガ中のプログラムの解説

マンガ中で出てきた、2種類の『HTA』アプリケーションのプログラムの解説を行います。また、その前に、『HTA』用に書き換えた『cmnFunc.js』も掲載しておきます。

『HTA』用に書き換えた『cmnFunc.js』

var cmnFunc = new function() {
    // オブジェクトの作成
    this.createObject = function(name) {
        try {
            //『HTA』では『WScript』が使えない
            return WScript.CreateObject(name);
        } catch (e) {
            //代わりに『ActiveXObject』を作成
            return new ActiveXObject(name);
        }
    };

    // WScriptのシェル
    // ファイル システム オブジェクト
    // 実行ファイルのパス
    // ルート ディレクトリ
    this.wshell = this.createObject("WScript.Shell");
    this.fs = this.createObject("Scripting.FileSystemObject");
    try {
        //『HTA』では『WScript』が使えない
        this.rootPath = WScript.ScriptFullName;
    } catch (e) {
        //『window.location.pathname』を使ってパスを取得
        //(『unescape』は半角スペース対策)
        this.rootPath = unescape(window.location.pathname);
    }
    this.rootDir = this.fs.GetFile(this.rootPath).ParentFolder;

    // ファイルに文字列を書き込み
    this.writeFile = function(path, data) {
        var stream = this.fs.CreateTextFile(path, true);
        stream.Write(data);
        stream.Close();
    };

    // ファイルから文字列を読み込み
    this.readFile = function(path) {
        if (this.fs.FileExists(path) == 0) return "";
        var stream = this.fs.OpenTextFile(path, 1);
        var rdStr = "";
        try {rdStr = stream.ReadAll();} catch(e){}
        stream.Close();
        return rdStr;
    };
}

赤色で強調した部分が、『HTA』用に書き換えた部分です。変更点は2ヶ所あり、それぞれ『try {~} catch (e) {~}』と、括弧でくくっています。

エラーを検出するための『try {~}』部分に『WScript』オブジェクトがあることに注目してください。『HTA』はHTMLファイルなので、『window』オブジェクトはありますが『WScript』オブジェクトはありません。そのため、『try {~}』で囲った部分は、実行時にエラーとなります。

エラーとなった処理は、そこでいったん終了して、『catch (e) {~}』部分に移ります。このエラー時の処理を書く領域に、『HTA』用のプログラムを書いています。

1ヶ所目の書き換え場所では、『WScript.CreateObject()』(オブジェクトの作成)メソッドの代わりに、『new ActiveXObject()』(『ActiveXObject』の新規作成)を使っています。

また、2ヶ所目の書き換え場所では、『WScript.ScriptFullName』(スクリプトのパス)の代わりに、『window.location.pathname』(HTMLファイルのパス名)を利用しています。

この2ヶ所目のパスの取得ですが、『window.location.pathname』を『unescape』メソッドでアンエスケープしています。

これは、パスに含まれる半角スペースが、『pathname』内では『%20』とエスケープされた状態になっているからです。この『%20』は、アンエスケープすることで、半角スペースに戻すことができます。

プログラム その1

<html>
    <head>
        <meta charset="Shift_JIS">
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script language="JavaScript" src="cmnFunc.js"></script>
        <script>
        function read() {
            // id『data』の内部の文字列を書き換え
            $("#data").text(
                // 『cmnFunc.rootPath』は自分自身のパス
                // 『cmnFunc.readFile』で自分自身を読み込む
                cmnFunc.readFile(cmnFunc.rootPath)
            );
        }
        </script>
    </head>
    <body>
        <input type="button" onClick="read();" value="中身を表示">
        <pre id="data"></pre>
    </body>
</html>

『HTA』の実体は、HTMLファイルです。そのため、これまで学習してきたWebページのJavaScriptをそのまま使えます。ここでは『<script>』タグを利用して、『jQuery』を読み込んで利用しています。また、同じように『<script>』タグを利用して、『cmnFunc.js』を読み込んで利用しています。

この2つのファイルを読み込めば、Webページを簡単に読み書きしたり、ローカルへのファイルの入出力を手軽に行ったりできます。

『cmnFunc.js』を『Shift_JIS』で書いているので、『HTA』のファイルも『Shift_JIS』で書き、『<meta charset="Shift_JIS">』を付けています。

『jquery-1.12.4.min.js』を読み込んでいますが、『HTA』では、最新のWebブラウザ用のファイルであるjQueryのバージョン2系や3系を読み込むとエラーが起きます。なので1系を読み込むようにしています。

上記のプログラムでは、『cmnFunc.rootPath』でHTMLファイル自身のパスを取得しています。また、『cmnFunc.readFile』メソッドで、HTMLファイル自身をテキストファイルとして読み込んでいます。

そして、『$("#data")』として、『id』の値が『data』のタグを選択しています。また、『text』メソッドを使い、読み込んだファイルを、テキスト部分に挿入しています。

プログラム その2

こちらのプログラムでは、アプリケーションの外観を整える処理を行っています。

<html>
    <head>
        <meta charset="Shift_JIS">
        <title>HTAアプリケーション</title>
        <HTA:APPLICATION
            icon="pic/star.ico"
            id="thisHTA"
        />
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script>
        var width = 640;
        var height = 480;
        $(function(){
            window.resizeTo(width, height);   // ウィンドウサイズ設定
            window.moveTo(                    // ウィンドウを中央に
                (window.screen.width - width) / 2,
                (window.screen.height - height) / 2
            );
        });
        </script>
    </head>
    <body>
        <script>
        // コマンドラインを表示(『thisHTA』は『<HTA>』タグで定義した『id』の値)
        document.write(thisHTA.commandLine);
        </script>
    </body>
</html>

『<HTA:APPLICATION>』タグには、アプリケーションの基本的な設定を書くことができます。

『icon』には、アイコンとして利用するファイルのパスを書きます。このファイルには、拡張子『.ico』のアイコンファイルを指定できます。

『id』は、『HTA』自身を指し示すIDを記入します。この『id』の値は、あとでプログラム中で利用することができます。ここでは『thisHTA』という値を設定しています。

アプリケーションのサイズや表示位置は、『window.resizeTo』や『window.moveTo』メソッドを利用して設定します。

『window.screen.width』は、デスクトップ画面全体の横幅を、『window.screen.height』は、デスクトップ画面全体の高さを得るためのプロパティです。この値を元にして、『(デスクトップ画面のサイズ-ウィンドウのサイズ)÷2』と計算して、ウィンドウの位置を求めています。この値を、『moveTo』メソッドの引数に設定することで、ウィンドウを画面の中央に表示させています。

また、このウィンドウのサイズや位置の設定は、『$(document).ready』という、『jQuery』のメソッドの引数内で行っています。こうすることで、『document』の準備が完了した時点で、ウィンドウのサイズや位置を設定するようにしています。

さて、先ほど設定した『id』の値『thisHTA』ですが、『document.write(thisHTA.commandLine);』という行で利用しています。

先述したとおり、『thisHTA』はこの『HTA』自身を指し示すオブジェクトになっています。この『HTA』オブジェクトには『commandLine』という、引数を示すプロパティがあります。ここではその値を、『document.write』メソッドで画面に表示させています。

『HTA』を使ったアプリケーションの実例

前回作成した、Yahoo!ニュースのRSSを取得するアプリケーションを改造して、ウィンドウ付きで利用できるようにしたものです。

以下、『sample3.hta』です。これぐらいのアプリケーションが簡単にできるようになれば、JavaScriptをかなりのレベルで習得したと言えるでしょう。

<html>
    <head>
        <meta charset="Shift_JIS">
        <title>HTAアプリケーション</title>
        <HTA:APPLICATION
            icon="pic/star.ico"
            id="thisHTA"
        />
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script language="JavaScript" src="cmnFunc.js"></script>
        <script language="JavaScript" src="cmnFunc.run.js"></script>
        <script language="JavaScript" src="cmnFunc.download.js"></script>
        <script>
        var width = 640;
        var height = 480;
        $(function(){
            window.resizeTo(width, height);   // ウィンドウサイズ設定
            window.moveTo(                    // ウィンドウを中央に
                (window.screen.width - width) / 2,
                (window.screen.height - height) / 2
            );
        });
        function read() {
            var resText = cmnFunc.download(
                "https://news.yahoo.co.jp/pickup/rss.xml",
                ""
            );
            $("#data").val(resText);
        }
        function save() {
            var resText = cmnFunc.download(
                "https://news.yahoo.co.jp/pickup/rss.xml",
                "dailynews_yahoo_rss.xml"
            );
            cmnFunc.run("explorer.exe", cmnFunc.rootDir);
        }
        </script>
    </head>
    <body>
        <h1>Yahoo!ニュースのRSS</h1>
        <input type="button" onClick="read();" value="表示">
        <input type="button" onClick="save();" value="自フォルダに保存"><br>
        <textarea id="data" style="width: 500px; height: 300px;"></textarea>
    </body>
</html>

以下、『cmnFunc.js』です。

var cmnFunc = new function() {
    // オブジェクトの作成
    this.createObject = function(name) {
        try {
            return WScript.CreateObject(name);
        } catch (e) {
            return new ActiveXObject(name);
        }
    };

    // WScriptのシェル
    // ファイル システム オブジェクト
    // 実行ファイルのパス
    // ルート ディレクトリ
    this.wshell = this.createObject("WScript.Shell");
    this.fs = this.createObject("Scripting.FileSystemObject");
    try {
        this.rootPath = WScript.ScriptFullName;
    } catch (e) {
        this.rootPath = window.location.pathname;
    }
    this.rootDir = this.fs.GetFile(this.rootPath).ParentFolder;

    // ファイルに文字列を書き込み
    this.writeFile = function(path, data) {
        var stream = this.fs.CreateTextFile(path, true);
        stream.Write(data);
        stream.Close();
    };

    // ファイルから文字列を読み込み
    this.readFile = function(path) {
        if (this.fs.FileExists(path) == 0) return "";
        var stream = this.fs.OpenTextFile(path, 1);
        var rdStr = "";
        try {rdStr = stream.ReadAll();} catch(e){}
        stream.Close();
        return rdStr;
    };
}

『cmnFunc.run.js』と『cmnFunc.download.js』は、前回と共通です。

サンプルの入手

以下は、今回出てきたサンプルです。

ZIPでまとめてダウンロード (右クリックから保存してください)

sample1.hta』(自分自身を表示)(右クリックから保存してください)

cmnFunc.js』(共通関数)(右クリックから保存してください)

star.ico』(アイコン)(右クリックから保存してください)

sample2.hta』(『HTA:APPLICATION』タグ)(右クリックから保存してください)

sample3.hta』(ニュースのRSSをダウンロード)(右クリックから保存してください)

cmnFunc.run.js』(ファイルを実行関数)(右クリックから保存してください)

cmnFunc.download.js』(ダウンロード関数)(右クリックから保存してください)

プログラムの中身を見たい場合は、それぞれのHTMLファイルをブラウザで開いたあと、右クリックをして『ソースの表示』を選択してください。

メモ帳で、ファイルの中身を見ることができます。