frog.raindrop.jp.knowledge > JavaScript / JScript / ECMAScript

December 24, 2012

ブログ記事にイメージを埋め込み、さらに拡大表示時に前後のイメージに移動することのできるスクリプト

写真をいっぱい埋め込んだブログ記事を書くのが面倒になってきて、省力化しようとスクリプトを書いてみました。
ライブラリフリー。innerHTML でなくて、普通に DOM 操作しているので処理速度は微妙かも。
まだちゃんと CSS ファイルを作成していなくて、スクリプト内部でいっぱい style アトリビュートを設定していますがご笑覧ください。
実際に diary の記事で使ってます。2個目以降のイメージをクリックすると拡大表示になり、拡大表示したイメージの上にマウスポインタを乗せると、前後のイメージを表示するための「<」と「>」が表示されます。

/** photo.js
 *
 * @author Kuwabara Miyuki (ba)
 * @version 1.0.0
 */
var jp;
if (!jp) jp = {};
if (!jp.raindrop) jp.raindrop = {};
if (!jp.raindrop.frog) jp.raindrop.frog = {};
if (!jp.raindrop.frog.photo) (function () {

    var _albums = [];

    var _getElementsByTagName = function (node, namespaceURI, tagName, prefix) {
//        var elements = node.getElementsByTagNameNS (namespaceURI, tagName);
//        if (!elements.length)
//            elements = node.getElementsByTagName ([prefix, tagName].join (':'));
        var elements = node.getElementsByTagName ([prefix, tagName].join (':'));
        if (!elements.length)
            elements = node.getElementsByTagName (tagName);
        return elements;
    };

    var _getContainedAlbum = function (id) {
        for (var i = 0; i < _albums.length; i ++)
            if (_albums [i].isExists (id))
                return _albums [i];
        return null;
    };

    var _load = function (targetDocument) {
        _loadAlbums (targetDocument);
        _loadThumbnails (targetDocument);
    };

    var _loadAlbums = function (targetDocument) {
        _albums = [];
        var albumElements = _getElementsByTagName (targetDocument, 'http://frog.raindrop.jp/ns', 'photo-album', 'frog');
        for (var i = 0; i < albumElements.length; i ++) {
            var itemElements = _getElementsByTagName (albumElements [i], 'http://frog.raindrop.jp/ns', 'photo-item', 'frog');
            if (itemElements.length) {
                var album = new jp.raindrop.frog.photo.__album ();
                for (var j = 0; j < itemElements.length; j ++) {
                    var id        = itemElements [j].getAttribute ('id');
                    var src        = itemElements [j].getAttribute ('src');
                    var title    = itemElements [j].getAttribute ('title');
                    album.add (id, src, title);
                }
                _albums.push (album);
            }
        }
    };

    var _loadThumbnails = function (targetDocument) {
        var elements = _getElementsByTagName (targetDocument, 'http://frog.raindrop.jp/ns', 'photo-thumbnail', 'frog');
        for (var i = 0; i < elements.length; i ++) {
            var caption    = (elements [i].getAttribute ('caption').match (/^yes$/i))? true: false;
            var link    = (elements [i].getAttribute ('link').match (/^yes$/i))? true: false;
            var content    = elements [i].getAttribute ('content');
            
            var album    = _getContainedAlbum (content);
            if (album) {
                var item = album.get (content);
                var thumbnail = item.getThumbnail (targetDocument, caption, link);
                elements [i].parentNode.insertBefore (thumbnail, elements [i]);
            }
        }
        for (var i = 0; i < elements.length; i ++) {
            elements [i].parentNode.removeChild (elements [i]);
        }
    };

    jp.raindrop.frog.photo = {
        "__album": function () {
            this._catalog = {};
        },
        "__item": function (id, src, title) {
            this.id        = id;
            this.src    = src;
            this.title    = title;
        },
        "__iterator": function (catalog, first, key) {
            var _keys = [];
            for (var k in catalog)
                _keys.push (k);
            
            var _index = first? 0: (_keys.length - 1);
            if (arguments.length > 2) {
                var index = 0;
                var length = _keys.length;
                
                _keys.push (key);
                while (_keys [index] != key)
                    index ++;
                _keys.length = length;
                if (index < length)
                    _index = index;
            }
            var _move = function (i) {
                if ((i < 0) || (i >= _keys.length))
                    return null;
                _index = i;
                return catalog[_keys[i]];
            };

            return {
                item: function () {
                    return _move (_index);
                },
                next: function () {
                    return _move (_index + 1);
                },
                previous: function () {
                    return _move (_index - 1);
                }
            };
        },
        '__albumWindow': function (iterator) {
            this._current    = iterator;
            var _this = this;
            var newWindow = window.open('', 'album', 'width=300,height=300,toolbar=no,directories=no,menubar=no,status=no,left=0,top=0');
            var newDocument = newWindow.document;
            newDocument.body.setAttribute ('style', [
                    'position: relative',
                    'background: black',
                    'color: #ccc',
                    'margin: 0',
                    'padding: 0',
                    'text-align: center',
                    ''
                ].join (';'));

            var baseLocation = newDocument.createElement ('base');
            baseLocation.setAttribute ('href', newWindow.opener.location.href);
            var head = newDocument.getElementsByTagName ('head');
            if (head.length) {
                head [0].insertBefore (baseLocation, head [0].firstChild);
            }
            else {
                head = newDocument.createElement ('head');
                head.appendChild (baseLocation);
                newDocument.body.parentNode.insertBefore (head, newDocument.body);
            }
            var container = newDocument.createElement ('div');
            container.setAttribute ('id', 'photo-container');
            container.setAttribute ('style', [
                'margin: 0',
                'padding: 0',
                ''
            ].join (';'));
            newDocument.body.appendChild (container);
            var caption = newDocument.createElement ('div');
            caption.setAttribute ('id', 'photo-caption');
            caption.setAttribute ('style', [
                'position: absolute',
                'visibility: hidden',
                'padding: 5px',
                'left: 0',
                'top: 0',
                'width: 100%',
                'text-align: center',
                'font: bold 25px/1.1 sans-serif',
                'color: white',
                ''
            ].join (';'));
            newDocument.body.appendChild (caption);
            var navigation = newDocument.createElement ('div');
            navigation.setAttribute ('id', 'album-navigation');
            navigation.setAttribute ('style', [
                'position: absolute',
                'visibility: hidden',
                'left: 0',
                'top: 0',
                'margin: 0',
                'padding: 0',
                'width: 100%',
                'vertical-align: middle',
                'font: bold 40px/1.1 sans-serif',
                'color: white',
                ''
            ].join (';'));
            var previous = newDocument.createElement ('div');
            previous.setAttribute ('id', 'album-navigation-previous');
            previous.setAttribute ('style', [
                'position: absolute',
                'left: 0',
                'top: 0',
                'margin: 0',
                'padding: 5px',
                'cursor: pointer',
                ''
            ].join (';'));
            previous.onclick = function (event) {
                _this.movePrevious ();
            };
            previous.innerHTML = '&lt;';
            navigation.appendChild (previous);
            var next = newDocument.createElement ('div');
            next.setAttribute ('id', 'album-navigation-next');
            next.setAttribute ('style', [
                'position: absolute',
                'right: 0',
                'top: 0',
                'margin: 0',
                'padding: 5px',
                'cursor: pointer',
                ''
            ].join (';'));
            next.onclick = function (event) {
                _this.moveNext ();
            };
            next.innerHTML = '&gt;'
            navigation.appendChild (next);
            newDocument.body.appendChild (navigation);

            newDocument.body.onmouseover = function (event) {
                caption.style.visibility = 'visible';
                navigation.style.visibility = 'visible';
            };
            newDocument.body.onmouseout = function (event) {
                caption.style.visibility = 'hidden';
                navigation.style.visibility = 'hidden';
            };

            this._update = function (item) {
                var image = item.getImageElement (newDocument);
                image.onload = function (event) {
                    newWindow.resizeTo (image.width, image.height + 20);
                    navigation.style.top = (image.height - 50) / 2;
                };
                if (container.firstChild)
                    container.replaceChild (image, container.firstChild);
                else
                    container.appendChild (image);
                caption.innerHTML = item.title;
                newDocument.title = item.title;
            };
            this._update (iterator.item ());
        },
        load: function (targetDocument) {
            return _load (targetDocument);
        }
    };
    
    jp.raindrop.frog.photo.__album.prototype = {
        add: function (id, src, title) {
            return this.append (new jp.raindrop.frog.photo.__item (id, src, title));
        },
        append: function (item) {
            item._setAlbum (this);
            this._catalog [item.id] = item;
            return item;
        },
        getCount: function () {
            return this._catalog.length;
        },
        get: function (id) {
            return this._catalog [id];
        },
        isExists: function (id) {
            return (id in this._catalog);
        },
        begin: function () {
            return new jp.raindrop.frog.photo.__iterator (this._catalog, true);
        },
        end: function () {
            return new jp.raindrop.frog.photo.__iterator (this._catalog, false);
        },
        iterator: function (id) {
            return new jp.raindrop.frog.photo.__iterator (this._catalog, false, id);
        }
    };

    jp.raindrop.frog.photo.__item.prototype = {
        getAlbum: function () {
            return this._album;
        },
        getImageElement: function (targetDocument) {
            var image = targetDocument.createElement ('img');
            image.setAttribute ('src', this.src);
            image.setAttribute ('alt', this.title);
            image.setAttribute ('title', this.title);
            return image;
        },
        getThumbnailURI: function () {
            var m = this.src.match (/^(.+)\.([^\.]+)$/);
            if (m)
                return [m [1], '-thumb.', m [2].toLowerCase ()].join ('');
            else
                return [this.src, '-thumb'].join ('');
        },
        getThumbnail: function (targetDocument, captionFlag, linkFlag) {
            var container = targetDocument.createElement ('div');
            container.setAttribute ('class', 'album-thumbnail');
            container.setAttribute ('style', 'display: inline-block; margin: 2px; vertical-align: top;');    // ★
            var thumbnail = targetDocument.createElement ('img');
            thumbnail.setAttribute ('title', this.title);
            thumbnail.setAttribute ('alt', this.title);
            thumbnail.setAttribute ('src', this.getThumbnailURI ());
            if (linkFlag) {
                var ancher = targetDocument.createElement ('a');
                var current = this._album.iterator (this.id);
                ancher.setAttribute ('href', this.src);
                ancher.setAttribute ('title', this.title);
                ancher.onclick = function (event) {
                    new jp.raindrop.frog.photo.__albumWindow (current);
                    return false;
                };
                ancher.appendChild (thumbnail);
                container.appendChild (ancher);
            }
            if (captionFlag) {
                var caption = targetDocument.createElement ('div');
                caption.setAttribute ('class', 'album-thumbnail-caption');
                caption.setAttribute ('style', 'margin: 0 0 0.5em 0;');    // ★
                thumbnail.onload = function (event) {
                    caption.setAttribute ('style', 'margin: 0 0 0.5em 0; width: ' + thumbnail.width + 'px;')
                };
                caption.appendChild (targetDocument.createTextNode (this.title));
                container.appendChild (caption);
            }
            return container;
        },
        '_setAlbum': function (album) {
            this._album = album;
        }
    };

    jp.raindrop.frog.photo.__albumWindow.prototype = {
        movePrevious: function () {
            var item = this._current.previous ();
            if (item)
                this._update (item);
        },
        moveNext: function () {
            var item = this._current.next ();
            if (item)
                this._update (item);
        }
    };

} ());
続きを読む...

October 8, 2010

WSH よりクリップボード、次の手

このサイトで最も人気のある記事は WSH から IE を起動してクリップボードにアクセスする Tips を扱ったものなんだけど、IE のバージョンが上がってスクリプトからクリップボードにアクセスしようとすると警告が表示されるようになったため、現在では使えないテクニックになっちゃってた。で、年月を経て再び WSH からクリップボードを操作する方法を調べてたんだけど、id:ardarim さんがIE の execWB メソッドでコマンドを発行するテクニックを公開してくださってるのを発見した。

これは素晴らしい!というわけで、クリップボードからデータを取得する部分も考えてみた。

var jp;
if (!jp) jp = {};
if (!jp.raindrop) jp.raindrop = {};
if (!jp.raindrop.frog) jp.raindrop.frog = {};
jp.raindrop.frog.clipboard || (function ()
    {
        // コマンドのID
        var OLECMDID_COPY = 12;
        var OLECMDID_PASTE = 13;
        var OLECMDID_SELECTALL = 17;

        // IE の初期化
        var _internetExplorer = new ActiveXObject ('InternetExplorer.Application');
        _internetExplorer.navigate ("about:blank");
        while (_internetExplorer.Busy)
            WScript.Sleep (10);

        // textarea 要素を作成する
        var _textarea = _internetExplorer.document.createElement ("textarea");
        _internetExplorer.document.body.appendChild (_textarea);
        _textarea.focus ();

        jp.raindrop.frog.clipboard = {
            // クリップボードに文字列をコピー
            setText: function (text)
            {
                _textarea.innerText = text;
                _internetExplorer.execWB (OLECMDID_SELECTALL, 0);
                _internetExplorer.execWB (OLECMDID_COPY, 0);
            },

            // クリップボードより文字列を取得
            getText: function ()
            {
                _textarea.innerText = "";
                _internetExplorer.execWB (OLECMDID_PASTE, 0);
                return _textarea.innerText;
            },

            // IE を解放
            release: function ()
            {
                _internetExplorer.Quit ();
            }
        };
    }());

ちょっとテストしたところ動いてます。素晴らしい。

// クリップボードから取得したテキストを表示
WScript.echo (jp.raindrop.frog.clipboard.getText ());
// クリップボードに文字列を設定
jp.raindrop.frog.clipboard.setText ("JScript から設定したテキスト\nタブ「\t」も対応");

September 29, 2010

Google AJAX Feed API を使ってみる

Google AJAX Feed API ってライブラリがあるみたいです。これを使えば公開されているフィードに Javascript でアクセスすることができ、他ドメインのフィードも取得できちゃいます。

ためしにはてなアンテナのフィードを取得して表示してみました。

<script type="text/javascript" src="http://frog.raindrop.jp/scripts/xmlight.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_AJAX_API_KEY"></script>
<script type="text/javascript">
//<![CDATA[
// Google AJAX FEED API Version 1 を読み込む
google.load ("feeds", "1");
// AJAX Feed API のサンプルでは google.setOnLoadCallback でコールバックをバインドしてるけど
// jQuery と一緒に使用する場合は document.ready で実行したらよいと思う
$(function ()
{
    // RSS フィードの URI を指定して google.feeds.Feed を生成
    var feed = new google.feeds.Feed ("http://a.hatena.ne.jp/ba-raindrop/rss");
    // 読み込み件数を指定
    feed.setNumEntries (10);
    // フィード取得時に呼び出すコールバックを指定して load を呼び出す
    feed.load (function (result)
        {
            // 処理結果を判断する
            if (result.error)
                return;
            // 表示用の HTML の構築には自作の簡易 XML ビルダ/パーサを使用しています
            var list = jp.raindrop.frog.xmlight.create ("dl");
            // result.feed.entries を列挙
            for (var i = 0; i < result.feed.entries.length; i ++)
            {
                var entry = result.feed.entries[i];
                list.addChild ('dt').addText (entry.title);
                var memberList = list.addChild ('dd').addChild ('dl');
                // entries の各要素のメンバを列挙
                for (var member in entry)
                {
                    if (member === 'categories')
                        continue;    // categories は配列なので後で列挙
                    memberList.addChild ('dt').addText (member);
                    memberList.addChild ('dd').addText (entry[member]);
                }
                // categories を列挙
                memberList.addChild ('dt').addText ('categories');
                var categoryList = memberList.addChild ('dd').addChild ('ul');
                for (var j = 0; j < entry.categories.length; j ++)
                    categoryList.addChild ('li').addText (entry.categories [j]);
            }
            $(document.body).append (list.toString ());
        });
});
//]]>
</script>

サンプルを見る

September 22, 2010

最後の要素の後のカンマの件

識別子、文字列または数がありません。 で、ECMA でも新しい仕様では最後のカンマを許容することになってるらしいって結論になったけど、じゃあ JSON はどうよ ? と思って調べてみた。

object
{}
{ members }
members
pair
pair , members
pair
string : value
array
[]
[ elements ]
elements
value
value , elements
value
string
number
object
array
true
false
null

JSON では、最後の要素の後ろにカンマがあってはダメみたいです。配列でも同じ。
Standard ECMA-262 3rd Edition のサブセットってなってるから当然かな。

続きを読む...

September 21, 2010

識別子、文字列または数がありません。

Firefox や Chrome では正常に動作する Javascript が、IE では「識別子、文字列または数がありません。」というエラーになることが。さっぱり意味が分かんなくて調べてみたんですけど、結構あちこちのブログで取り上げられています。IE ではオブジェクトリテラルの最後のメンバの後ろにカンマがある場合に出るみたいです。

var person = {
    lastName: '鈴木',
    firstName: '一郎',
    age: 25,  // ←ここにカンマがあるとエラー
    };

C 言語などで、配列を中括弧で初期化する場合に最後の要素の後ろにもカンマを付けることが認められているので、ついついこのケースでもカンマを入れたくなってしまうんですが、意識して付けないようにした方がよさそうです。

ちなみに、WSH で実行するときも同じエラーになります。当然か。

ECMA の仕様ではどうなってるのかな…。

続きを読む...

September 16, 2010

関数内の this が参照するもの

あー、これはちょっと、今まで誤解してたかも。 this は実行時に評価されるんですね。
function Foo ()
{
    var _getx = function () { return this.x; };

    this.x = 'apple';
    this.getX = _getx;
    this.getBar = function () { return { x: 'banana', getX: _getx}; };
}

var foo = new Foo ();
alert (foo.getX ());    // 'apple'

var bar = foo.getBar ();
alert (bar.getX ());    // 'banana'
続きを読む...

September 15, 2010

簡易 XML ビルダ/パーサ

ブログのデザイン変更に伴い、jQuery で DOM を生成する部分が増えました。引数に渡す HTML ソースを作成するのに、文字列を + 演算子で連結していくと何が何やら…。ソースを見やすくしたくて、簡易的な XML ビルダ を作成してみました。"簡易" ってつけたら何を公開してもいいのか!という声が聞こえてきそうですが、でも実際このブログのあちこちでこのモジュールを活用しています。

一応、xml を渡すとパースもできますが、引用符のネストなんかにうまく対応できていません。誤りを検出するようには作ってないので、少々間違った xml を渡しても適当に解析してしまいます。なんちゃってです。

var jp;
if (!jp) jp = {};
if (!jp.raindrop) jp.raindrop = {};
if (!jp.raindrop.frog) jp.raindrop.frog = {};
jp.raindrop.frog.xmlight || (function () {

    function Element (name)
    {
        var _name = name;
        this.name = function () { return _name; };
        this.children = new Elements ();
        this.attributes = {};
        this.attr = function ()
            {
                if (!arguments.length)
                    return this.attributes;
                if (arguments.length == 1)
                    return this.attributes[arguments[0]];
                this.attributes[arguments[0]] = arguments[1];
                return this;
            }
        this.wrap = function (name) { var elem = new Element (name); elem.children.append (this); return elem; };
        this.toString = function ()
            {
                var s = '<' + _name;
                for (var key in this.attributes)
                    s += ' ' + key + '="' + this.attributes[key] + '"';
                var c = this.children.toString ();
                if (c.length)
                    s += '>' + c + '</' + _name + '>';
                else
                    s += ' />';
                return s;
            }
    };

    function TextNode (text) { this.toString = function () { return text; }; };

    function Elements ()
    {
        var _inner = [];
        this.add = function (name) { return this.append (new Element (name)); };
        this.append = function (elem) { _inner.push (elem); return elem; };
        this.addText = function (text) { return this.append (new TextNode (text)); };
        this.remove = function (elem)
            {
                var index = -1;
                for (var i = 0; i < _inner.length; i++)
                {
                    if (elem == _inner [i])
                    {
                        index = i;
                        break;
                    }
                }

                if (index < 0)
                    return;

                _inner.splice (index, 1);
            };
        this.insert = function (index, elem) { _inner.splice (index, 0, elem); return elem; };
        this.insertText = function (index, text) { return this.insert (index, new TextNode (text)); }
        this.item = function (index) { return _inner[index]; };
        this.wrap = function (name)
            {
                var elem = new Element (name);
                for (var i = 0; i < _inner.length; i ++)
                    elem.children.append (_inner[i]); 
                return elem;
            };
        this.length = function () { return _inner.length; };
        this.toString = function ()
            {
                var s = "";
                for (var i = 0; i < _inner.length; i ++)
                    s += _inner[i].toString ();
                return s;
            };
    }

    var _parse = function (str)
        {
            var elements = new Elements ();
            _parseElements (str, elements);
            return elements;
        };

    var _parseElements = function (str, elements)
        {
            var regex = /<((?:(\w+):)?(\w+))([^>]*)(?:\/|>(.*)<\/\1)>/g;
            var match = [];
            while (match = regex.exec (str))
            {
                var element = elements.add (match[1]);
                _parseAttributes (match[4], element);
                if (match.length > 5)
                    _parseElements (match[5], element.children);
            }
        };

    var _parseAttributes = function (str, element)
        {
            var regex = /((?:(\w+):)?(\w+))=(["'])(.*?)(\4)/g;
            var match = [];
            while (match = regex.exec (str))
            {
                element.attributes [match[1]] = match[5];
            }
        };

    jp.raindrop.frog.xmlight = {
        create: function (name) { return new Element (name); },
        parse: function (str) { var c = new Elements (); _parseElements (str, c); return c; }
        };
}());
続きを読む...

August 25, 2010

ZIP 作成処理を使ってみる。

昨日アップしたZIP 作成処理をコネコネして、毎日ソースをバックアップして、さらにしかるべき宛先にメールで送りつける処理をある程度自動化するようにしてみた。
mailto: でデフォルトのメーラが起動するようにしてるだけで、添付するのは手動。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
    <job>
        <?job error="True" debug="True" ?>
        <script language="JScript" src="sprintf-0.6.js"/>
        <script language="JScript" src="zipmaker.js"/>
        <script language="JScript"><![CDATA[
            // 外部のクラス
            var fso = new ActiveXObject ("Scripting.FileSystemObject");
            var shell = new ActiveXObject ("WScript.Shell");
            // パス
            var sourcePath = "C:\\project\\src";
            var destPath = "\\\\server\\share\\backup";
            // 本日の日付
            var now = new Date ();
            // ファイル名を作成
            var filename = "src_";
            filename += sprintf ("%04d%02d%02d", now.getFullYear (), now.getMonth () + 1, now.getDate ());
            filename += ".zip";
            var path = fso.BuildPath (destPath, filename);
            // ZIP ファイルを作成
            var zip = zipper.create (path);
            if (zip)
            {
                // ソースをすべて ZIP に含める
                var sourceFolder = fso.GetFolder (sourcePath);
                for (var itr = new Enumerator (sourceFolder.Files); !itr.atEnd (); itr.moveNext ())
                    zip.addItem (itr.item ().Path);
                // バックアップが格納されたフォルダを開く
                shell.run ("explorer /e,/n,\"" + destPath + "\"");
                // メール送信画面を開く
                var link = "mailto:<leader@example.com>";
                link += "?cc=<manager@example.com>&cc=<president@example.com>&bcc=<mine@example.com>";
                link += "&subject=ソース送付%20";
                link += sprintf ("%04d%02d%02d", now.getFullYear (), now.getMonth () + 1, now.getDate ());
                shell.run (link);
            }
        ]]></script>
    </job>
</package>

添付忘れに注意!

August 24, 2010

ZIP 作成処理を試作中。

手慰みに、圧縮フォルダを作成するスクリプトを汎用性を考慮して改修中。

var zipmaker = function  ()
    {
        var _fileSystemObject = new ActiveXObject ('Scripting.FileSystemObject');
        var _shell = new ActiveXObject ('Shell.Application');
        var _wshShell = new ActiveXObject ('WScript.Shell')

        // ZIP ファイル作成
        var _createZipFile = function (path)
            {
                try
                {
                    // 既に存在する場合
                    if (_fileSystemObject.FileExists (path))
                    {
                        if (7 == _wshShell.Popup ("既に存在する書庫 "+ path + " に追加してよろしいですか?", 0, "ZIP ファイル作成", 32 + 4))
                            return null;
                    }
                    else
                    {
                        // 空の ZIP ファイルを作成する
                        var file = _fileSystemObject.CreateTextFile (path, false);
                        file.Write ("PK\5\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
                        file.Close ();
                    }
                    // Shell.Folder オブジェクトを返す
                    return _shell.NameSpace (path);
                }
                catch (e)
                {
                }
                return null;
            };

        // ファイルやフォルダを追加する
        var _addItem = function (zipFolder, zipPath, path)
            {
                // Shell.FolderItem を取得する
                var file = _shell.NameSpace (_fileSystemObject.GetParentFolderName (path)).ParseName (_fileSystemObject.GetFileName (path));
                // コピー
                zipFolder.CopyHere (file);
                // コピーが開始されるようにディレイを設ける
                WScript.Sleep (100);
                while (true)
                {
                    try
                    {
                        // 追記モードで開く
                        _fileSystemObject.OpenTextFile (zipPath, 8, false).Close ();
                        // 開ければコピー完了とみなす
                        return true;
                    }
                    catch (e2)
                    {
                    }
                    WScript.Sleep (10);
                }
            }

        // ZIP オブジェクト作成用のオブジェクトを返す
        return {

            // ZIP オブジェクト作成処理
            create: function (zipPath)
            {
                var path = _fileSystemObject.GetAbsolutePathName (zipPath)
                var _zipFolder = _createZipFile (path);

                if (_zipFolder)
                {
                    return {
                        path: path,
                        addItem: function (filespec)
                        {
                            return _addItem (_zipFolder, zipPath, filespec);
                        }
                    };
                }
                return null;
            }
        };
    } ();
続きを読む...

August 23, 2010

インストールされている .NET Framework のバージョンをチェックするスクリプト - .NET Framework 4.0 対応版

インストールされている .NET Framework のバージョンをチェックするスクリプト を .NET Framework 4.0 に対応してみました。
4.0 は Full と Client Profile の 2 種類があるんですねー。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="Registry">
<?job error="True" debug="True" ?>
<script language="JScript">
<![CDATA[
var checker = function ()
    {
        var _reader = function ()
            {
                var _shell = new ActiveXObject ("WScript.Shell");
                return { read: function (name) { try { return _shell.RegRead (name); } catch (e) {}; return null; } };
            } ();

        var _checkKey = function (key)
            {
                var install = _reader.read (key + "\\Install");
                if (install == null || "" + install == "0")
                    return null;
                var servicePack = _reader.read (key + "\\SP");
                if (servicePack == null) servicePack = 0;
                return servicePack;
            };

        var _check10 = function ()
            {
                var install = _reader.read ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\Full\\v1.0.3705\\1041\\Microsoft .NET Framework Full v1.0.3705 (1041)\\Install");
                if (install == null || "" + install == "0")
                    return null;

                var version = _reader.read ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{78705f0d-e8db-4b2d-8193-982bdda15ecd}\\Version");
                if (version == null)
                    version = _reader.read ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{FDC11A6F-17D1-48f9-9EA3-9051954BAA24}\\Version");
                if (version == null)
                    return 0;

                var m = version.match (/^1,0,3705,(\d+)$/);
                var servicePack = 0;
                if (m != null && m.length > 1)
                    servicePack = m [1] - 0;

                return servicePack;
            };

        var _formatResult = function (check, label)
            {
                switch (check)
                {
                case null: return label + ": not installed.\n";
                case 0:    return label + ": installed.\n";
                default:   return label + ": SP" + check + " installed.\n";
                }
            };

        return {
            check10: _check10,
            check11: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322"); },
            check20: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727"); },
            check30: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0"); },
            check35: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5"); },
            check40Client: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client"); },
            check40Full:   function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full"); },
            check11JP: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322\\1041"); },
            check20JP: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727\\1041"); },
            check30JP: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0\\1041"); },
            check35JP: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5\\1041"); },
            check40ClientJP: function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client\\1041"); },
            check40FullJP:   function () { return _checkKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\1041"); },
            show: function ()
                {
                    WScript.echo (_formatResult (this.check10 (), ".NET Framework 1.0")
                        + _formatResult (this.check11 (), ".NET Framework 1.1")
                        + _formatResult (this.check11JP (), "    Japanese Langage Pack")
                        + _formatResult (this.check20 (), ".NET Framework 2.0")
                        + _formatResult (this.check20JP (), "    Japanese Langage Pack")
                        + _formatResult (this.check30 (), ".NET Framework 3.0")
                        + _formatResult (this.check30JP (), "    Japanese Langage Pack")
                        + _formatResult (this.check35 (), ".NET Framework 3.5")
                        + _formatResult (this.check35JP (), "    Japanese Langage Pack")
                        + _formatResult (this.check40Client (), ".NET Framework 4.0 Client Profile")
                        + _formatResult (this.check40ClientJP (), "    Japanese Langage Pack")
                        + _formatResult (this.check40Full (), ".NET Framework 4.0 Full")
                        + _formatResult (this.check40FullJP (), "    Japanese Langage Pack")
                        );
                }
        };
    } ();
checker.show ();
]]>
</script>
</job>
</package>

July 2, 2010

ネットワーク構成を保存・復元する

なんか前にも作った気もするんだけど…

続きを読む...

January 6, 2010

続、目次フレームを自動生成する

あと、目次フレームを自動生成するの toc.js の諸々を修正しました。主な修正点はオブジェクトメンバの実装をリテラル記法にして見やすくしたのと、自動生成される ID の番号の階層がおかしかった点を改善しました。

あと、汎用性を考慮して初期化ハンドラを自動で登録しないようにしたのでwindow.onload を待たずに処理を開始するを使ってもいいかも。

<script type="text/javascript" src="loadlistener.js"></script>
<script type="text/javascript" src="toc.js"></script>
<script type="text/javascript">//<![CDATA[
    LoadListener.onload = function () { toc.create(); };
//]]></script>
続きを読む...

window.onload を待たずに処理を開始する

Web ページの読み込み時に処理をさせる場合、何の疑問も持たずに window.onload を使っていたんですが、このハンドラは DOM ツリーだけじゃなくて画像まで全部読込んでから実行されるらしいです。知らんかった…。

で、そうじゃなくて DOM ツリーが生成されたタイミングで処理を開始したいなーってことで、あちこちのサイトでそんな Tips が取り上げられてるんですが、よんでもいまひとつ理解できない…。

なので調べつつ、結局自分でスクリプトを書き直してみました。こちらのブログ記事がよくまとまっていて大変参考になりました。あと、元ネタにあたるこちらとかこちらとか…。

続きを読む...

December 22, 2009

目次フレームを自動生成する

Javascript で HTML 文書中の h1 ~ h6 を抜き出して、目次を作成するスクリプトを作成しました。見出し要素に id が振られていなければ自動生成します。自動生成した場合にやたらと "-0" が付くのはご愛嬌…。


2010.01.06 10:40 追記
自動生成した id の階層がおかしかったのを修正したものはこちら

とりあえず、Google Chrome 3.0.195.38 と IE 8 で動作確認しました。あんまりきれいじゃないです。

さらに、CSS で目次部分を左側のフレームっぽく表示させるようにしています。なんちゃって擬似フレーム。これも動作確認環境は同じ。


2009.12.22 22:50 追記
Firefox 3.5 で確認したところ、目次が全部 "undefined" ってなっちゃってました。
Firefox は Element.innerText って使えないんでしたな… とりあえず、Element.textContent を優先的に使うように修正してみました。

サンプルの HTML / toc.js / toc.css

HTML 側では、toc.js と toc.css を読込むだけです。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
    <head>
        <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8"/>
        <meta http-equiv="content-script-type" content="text/javascript"/>
        <meta http-equiv="content-style-type" content="text/css"/>
        <link href="toc.css" rel="stylesheet" type="text/css"/> 
        <script type="text/javascript" src="toc.js"></script>
        <!-- 省略… -->
    </head>
    <body>
        <h1>1章</h1>
        <h2>1章-1節</h2>
        <h3>1章-1節-1項</h3>
        <!-- 省略… -->
    </body>
</html>

自動生成する内容は、若干カスタマイズできます。toc.js を読込んだより下の行で以下のように書けば。

<script type="text/javascript">//<![CDATA[
toc.listtag = "ol";    // 番号つきリストに
toc.tocId = "tableOfContents";    // 目次部分の id を別の値に
toc.defaultIdPrefix = "section";    // 見出し要素の自動生成 id のプリフィックス
//]]>
</script>
続きを読む...

November 27, 2009

address 要素を自動的にリンクする

body 要素の onload で下記関数をコールするようにして使用します。詳しい説明はまた。

function makeAddressLink ()
{
    var elements = document.getElementsByTagName ("address");
    for (var i = 0; i < elements.length; i ++)
    {
        var element = elements [i];
        var anchors = element.getElementsByTagName ("a");
        if (anchors == null || anchors.length == 0)
        {
            var first = element.firstChild;
            var anchor = document.createElement ("a");
            var text = document.createTextNode (first.nodeValue);
            anchor.setAttribute ("href", text.nodeValue);
            anchor.appendChild (text);
            element.replaceChild (anchor, first);
        }
    }
}

July 10, 2009

インストールされている .NET Framework のバージョンをチェックするスクリプト

.NET Frameworkのバージョンを確認する方法を参考に WSH スクリプトを書いた。

拡張子を .wsf で保存して実行してくださいねー。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="Registry">
<?job error="True" debug="True" ?>
<script language="JScript">
<![CDATA[
    var checker = new DotNetChecker ();
    var result = "";
    result += checker.FormatResult (checker.Check10 (), ".NET Framework 1.0");
    result += checker.FormatResult (checker.Check11 (), ".NET Framework 1.1");
    result += checker.FormatResult (checker.Check11JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check20 (), ".NET Framework 2.0");
    result += checker.FormatResult (checker.Check20JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check30 (), ".NET Framework 3.0");
    result += checker.FormatResult (checker.Check30JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check35 (), ".NET Framework 3.5");
    result += checker.FormatResult (checker.Check35JP (), "    Japanese Langage Pack");

    WScript.Echo (result);

    function DotNetChecker ()
    {
        this.reader = new RegReader ();

        this.Check10 = function ()
        {
            var install = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\Full\\v1.0.3705\\1041\\Microsoft .NET Framework Full v1.0.3705 (1041)\\Install");
            if (install == null || "" + install == "0")
                return null;

            var version = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{78705f0d-e8db-4b2d-8193-982bdda15ecd}\\Version");
            if (version == null)
                version = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{FDC11A6F-17D1-48f9-9EA3-9051954BAA24}\\Version");
            if (version == null)
                return 0;

            var regex = /^1,0,3705,(\d+)$/;
            var m = regex.exec (version);
            var sp = 0;
            if (m != null && m.length > 1)
                sp = m [1] - 0;

            return sp;
        }

        this.Check11 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322");
        }

        this.Check20 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727");
        }

        this.Check30 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0");
        }

        this.Check35 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5");
        }

        this.Check11JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322\\1041");
        }

        this.Check20JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727\\1041");
        }

        this.Check30JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0\\1041");
        }

        this.Check35JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5\\1041");
        }

        this.CheckKey = function (key)
        {
            var install = this.reader.RegRead (key + "\\Install");

            if (install == null || "" + install == "0")
                return null;

            var sp = this.reader.RegRead (key + "\\SP");
            if (sp == null)
                sp = 0;
            return sp;
        }

        this.FormatResult = function (value, label)
        {
            var result = label;

            switch (value)
            {
            case null:
                result += ": not installed.\n"; break;
            case 0:
                result += ": installed.\n"; break;
            default:
                result += ": SP" + value + " installed.\n"; break;
            }
            return result;
        }

    }

    function RegReader ()
    {
        this.shell = WScript.CreateObject ('WScript.Shell');

        this.RegRead = function (name)
        {
            var ret = null;
            try
            {
                ret = this.shell.RegRead (name);
            }
            catch (e)
            {
                //WScript.Echo (e.number + "\n" + e.description);
            }
            return ret;
        }

        return this;
}
]]>
</script>
</job>
</package>

November 29, 2007

圧縮フォルダを作成してコピーする WSH スクリプト

shell32.dll の Shell オブジェクトを使用してZIPフォルダを作る JScript です。これも1回使っただけでお蔵入りの予感。VC++ 版もあるけど・・・API直叩きの方がいい気がするので、それはとりあえず保留。
//
// makeZipFolder.js
//

// スクリプト ランタイム関連
var fileSystemObject = new ActiveXObject ('Scripting.FileSystemObject');
var wsShell = new ActiveXObject ('WScript.Shell');

// 固めるパス
var sourcePath = wsShell.SpecialFolders ('AppData');
sourcePath = fileSystemObject.BuildPath (sourcePath, "Test");

// デスクトップ
var desktopPath = wsShell.SpecialFolders ('Desktop');

// 作成する ZIP ファイルのパス
var zipPath = fileSystemobject.BuildPath (desktopPath, 'Test.zip');

// ZIP ファイルを作成する
var zipFile = fileSystemObject.CreateTextFile (zipPath, false);
zipFile.Write ("PK\5\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
zipFile.Close ();

// ZIP ファイルを圧縮フォルダとして取得
var shell = new ActiveXObject ('Shell.Application');
var zipFolder = shell.NameSpace (zipPath);

// コピー元
var sourceFolder = fileSystemObject.GetFolder (sourcePath);

for (var n = 0, var e = new Enumerator (sourceFolder.Files); ! e.atEnd (); e.moveNext ())
{
    // ファイルをコピー
    var sourceFolderItem = shell.Namespace (e.item ().ParentFolder.Path).ParseName (e.item ().Name);
    zipFolder.CopyHere (sourceFolderItem);
    n ++;
    
    // コピーが完全に完了するまで待機
    while (n == zipFolder.Items ().Count)
    {
        WScript.Sleep (100);
    }
}
WScript.echo ("完了しました。");

入力システムを列挙する WSH スクリプト

タイトルの通りです。「テキスト サービスと入力言語」コントロールパネルでいうと、

規定の言語
HKCU\Keyboard Layout\Preload\1
インストールされているサービス
HKCU\Keyboard Layout\Preload 以下の値のリスト
[追加] ボタンより追加可能な全IME
HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layouts 以下のサブキーのリスト

と言う具合に、レジストリに情報が格納されているのでこれらを取得します。お蔵入りスクリプトになってしまい、もったいないのでアップします。

//
// enumIme.js
//

// 定義済み HKEY
var HKEY_CLASSES_ROOT    = 0x80000000;
var HKEY_CURRENT_USER    = 0x80000001;
var HKEY_LOCAL_MACHINE    = 0x80000002;
var HKEY_USERS            = 0x80000003;
var HKEY_CURRENT_CONFIG = 0x80000005;
var HKEY_DYN_DATA        = 0x80000006;

// WMI の StdRegProv を使用する
var locator = new ActiveXObject ("WbemScripting.SWbemLocator");
var service = locator.ConnectServer (null, "root\\default");
var stdRegProv = service.Get ("StdRegProv");

// スクリプト ランタイム関連
var fileSystemObject = new ActiveXObject ('Scripting.FileSystemObject');
var wsShell = new ActiveXObject ('WScript.Shell');
var desktopPath = wsShell.SpecialFolders ('Desktop');

// ログファイル、Layout Text 等が SJIS では表示できない可能性があるため、ユニコードテキストで
var logFile = fileSystemObject.CreateTextFile (fileSystemObject.BuildPath (desktopPath, "imecheck.txt"), true, true);

// すべてのキーボードレイアウト
// HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layouts
var lmImeList = new SubKey (stdRegProv, HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control", "Keyboard Layouts");
lmImeList.getSubKeys ();

// 言語バーより選択可能なキーボードレイアウト
// HKCU\Keyboard Layout\Preload
var preload = new SubKey (stdRegProv, HKEY_CURRENT_USER, "Keyboard Layout", "Preload");

for (var item in preload.getRegValues ())
{
    logFile.Write (item);    // 値名は番号
    logFile.Write (":");

    // 値はキーボードレイアウトの番号
    logFile.WriteLine (preload.regValues [item].value);

    // キーボードレイアウトの番号より、情報を取り出す
    var keyObj = lmImeList.subKeys [preload.regValues [item].value.toUpperCase ()];
    if (keyObj == null) keyObj = lmImeList.subKeys [preload.regValues [item].value.toLowerCase ()];

    // 情報あり
    if (keyObj != null)
    {
        for (var item2 in keyObj.getRegValues ())
        {
            // 値名 "layout text" を探す
            if (-1 != item2.search (/layout text/i))
            {// 見つかった
                logFile.Write ("        ");
                logFile.Write (item2);
                logFile.Write ("(" + keyObj.regValues [item2].typeName + ")");
                logFile.Write ("\t:");
                logFile.WriteLine (keyObj.regValues [item2].value);
            }
        }
    }
}

logFile.WriteBlankLine ();

// Keyboard Layouts のリスト
logFile.WriteLine (lmImeList.path);
writeImeList (logFile, lmImeList, "");

// ファイルを閉じる
logFile.Close ();

// 終了
WScript.echo ("完了しました");

//
// キーボードレイアウトのリストを出力する
//
function writeImeList (file, keyObj, padding)
{
    var item;
    var pad = padding + "  ";

    for (item in keyObj.getSubKeys ())
    {
        file.WriteLine (pad + keyObj.subKeys[item].name);
        writeImeList (file, keyObj.subKeys[item], pad);
    }

    for (item in keyObj.getRegValues ())
    {
        file.Write (pad);
        file.Write (item);
        file.Write ("(" + keyObj.regValues[item].typeName + ")");
        file.Write ("\t:");
        file.WriteLine (keyObj.regValues[item].value);
    }
    file.WriteLine ();
}



// レジストリキーオブジェクトのコンストラクタ
function SubKey (regProv, hDefKey, parentSubKey, name)
{
    //
    // メンバの初期化
    //
    this.regProv = regProv;
    this.hDefKey = hDefKey;
    this.parentSubKey = parentSubKey;
    this.name = name;
    this.path = parentSubKey + "\\" + name;
    this.subKeys = null;
    this.regValues = null;

    //
    // メソッドの定義
    //

    // サブキーのコレクションを取得
    this.getSubKeys = function ()
    {
        if (!this.subKeys)
        {
            var method = this.regProv.Methods_.Item ("EnumKey");
            var inParameter = method.InParameters.SpawnInstance_ ();
            inParameter.hDefKey = this.hDefKey;
            inParameter.sSubKeyName = this.path;
            var outParameter = this.regProv.ExecMethod_ (method.Name, inParameter);
            this.subKeys = new Array ();
            if (outParameter.sNames != null)
            {
                var subKeys = outParameter.sNames.toArray ();
                for (var i = 0; i < subKeys.length; i ++)
                {
                    this.subKeys [subKeys [i]] = new SubKey (this.regProv, this.hDefKey, this.path, subKeys [i]);
                }
            }
        }
        return this.subKeys;
    }

    // キー内の値の取得
    this.getRegValues = function ()
    {
        if (!this.regValues)
        {
            var method = this.regProv.Methods_.Item ("EnumValues");
            var inParameter = method.InParameters.SpawnInstance_ ();
            inParameter.hDefKey = this.hDefKey;
            inParameter.sSubKeyName = this.path;
            var outParameter = this.regProv.ExecMethod_ (method.Name, inParameter);
            this.regValues = new Array ();
            if (outParameter.sNames != null)
            {
                var names = outParameter.sNames.toArray ();
                var types = outParameter.Types.toArray ();
                var typeNames = new Array (
                    ""                                ,     // 0
                    "REG_SZ"                        ,     // 1
                    "REG_EXPAND_SZ"                 ,     // 2
                    "REG_BINARY"                    ,     // 3
                    "REG_DWORD"                     ,     // 4
                    "REG_DWORD_BIG_ENDIAN"            ,     // 5
                    "REG_LINK"                        ,     // 6
                    "REG_MULTI_SZ"                    ,     // 7
                    "REG_RESOURCE_LIST"             ,     // 8
                    "REG_FULL_RESOURCE_DESCRIPTOR"    ,     // 9
                    "REG_RESOURCE_REQUIREMENTS_LIST",     // 10
                    "REG_QWORD"                    );     // 11
                var getTypeValues = new Array (
                    null,
                    getStringValue,
                    getExpandedStringValue,
                    getBinaryValue,
                    getDWORDValue,
                    getDWORDValue,
                    null,
                    getMultiStringValue,
                    null,
                    null,
                    null,
                    getQWORDValue);

                for (var i = 0; i < names.length; i ++)
                {
                    this.regValues [names [i]] = new Object ();
                    this.regValues [names [i]].name = names [i];
                    this.regValues [names [i]].type = types [i];
                    this.regValues [names [i]].typeName = typeNames [types [i]];
                    this.regValues [names [i]].value = "";
                    var fn = getTypeValues [types [i]];
                    if (fn)
                    {
                        this.regValues [names [i]].value = fn (this.regProv, this.hDefKey, this.path, names [i]);
                    }
                }
            }
        }
        return this.regValues;
    }
    return this;
}


// 文字列値取得
function getStringValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetStringValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    return outParameter.sValue;
}

// 展開済み文字列値取得
function getExpandedStringValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetExpandedStringValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    return outParameter.sValue;
}

// バイナリ値取得
function getBinaryValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetBinaryValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    var str = "";
    var ary = outParameter.uValue.toArray ();
    for (var i = 0; i < ary.length; i ++)
    {
        str += ary [i].toString (16) + ((i + 1) % 8)? " ": "\n";
    }
    return str;
}

// DWORD 値取得
function getDWORDValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetDWORDValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    return outParameter.uValue.toString (16);
}

// QWORD 値取得
function getQWORDValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetQWORDValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    return outParameter.uValue.toString (16);
}

// マルチ文字列値取得
function getMultiStringValue (regProv, hDefKey, sSubKeyName, sValueName)
{
    var method = regProv.Methods_.Item ("GetMultiStringValue");
    var inParameter = method.InParameters.SpawnInstance_ ();
    inParameter.hDefKey = hDefKey;
    inParameter.sSubKeyName = sSubKeyName;
    inParameter.sValueName = sValueName;
    var outParameter = regProv.ExecMethod_ (method.Name, inParameter);
    return outParameter.sValue.toArray ().toString ();
}

February 20, 2005

WSH よりクリップボードを使う

最近のバージョンの IE ではセキュリティが厳しくなったためこの手法は使いづらくなりました。
[WSH よりクリップボード、次の手] も参照してみてください。(2010.10.08)

WSH よりクリップボードにアクセスすることはできない。しかし、調べてみたところ、Internet Explorer がクリップボードにアクセスするためのインターフェースを公開していることがわかった(常套手段?)。

そんなわけで、文字列をコピー & 取得する部分をクラス化した。

使い方はこんな感じで。

var clipboard = new Clipboard ();
var s = clipboard.getText ();
WScript.Echo (s);
clipboard.setText (s.replace (/my/gi, "Your"));
続きを読む...

January 21, 2005

WSH でショートカットを作成する

WSH でショートカットを作成する方法です。どこにでも転がっているものと同じですが、自分のために。 コマンドラインコピーツール のインストーラとして作成したものです。

続きを読む...