Ruby on HTA

少し触っただけだけども、HTA + ActiveScriptRubyにぐっときた。

VisualuRubyよりも、もっともっとサクサク簡単なGUIを作りたいときに便利っぽい。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>サンプル</title>
		<script for="window" event="onload" language="RubyScript">
			@window.resizeTo(400, 100)
			
			def btnOk_onclick
				@window.document.getElementById("lblOutput").innerHTML = "Hello World!!!"
			end
		</script>
	</head>
	<body>
		<input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" />
		<span id="lblOutput">...</span>
	</body>
</html>



ちょっとめんどくさい

イベントハンドラを定義したり(onclick="...")するのが面倒なんで、うまいことできないか考え中。

んで、とりあえずidが付いている要素にイベントハンドラを定義するような仕組みを作ってみた。

ついでにHTAにスタイルを設定してもっとネイティブのアプリっぽく。


hta-support.rb

class HTASupport
  # イベントハンドラ一覧
  EVENTHANDLERS = [
    "onblur",
    "onfocus",
    "onchange",
    "onselect",
    "onselectstart",
    "onsubmit",
    "onreset",
    "onabort",
    "onerror",
    "onload",
    "onunload",
    "onclick",
    "ondblclick",
    "onkeyup",
    "onkeydown",
    "onkeypress",
    "onmouseout",
    "onmouseover",
    "onmouseup",
    "onmousedown",
    "onmousemove",
    "ondragdrop"
    ]

  def initialize(window)
    @window = window
    set_event_handler
  end

  # idを持つ要素すべてにイベントハンドラを設定します
  def set_event_handler
    body = _d.getElementsByTagName("body").item(0)
    set_event_handler_recursive(body)
  end

  # idを持つ要素すべてにイベントハンドラを設定します
  def set_event_handler_recursive(elem)
    # Element以外だったら終了
    return if elem.nodeType != 1

    id = elem.getAttribute("id")
    if id != ""
      EVENTHANDLERS.each do |name|
        handler_name = "#{id}_#{name}"
        elem.attachEvent(name, Proc.new {
          if methods.include?(handler_name)
            __send__(handler_name)
          end
        })
      end
    end

    # 子要素も処理する
    elem.childNodes.each do |i|
      set_event_handler_recursive(i)
    end
  end

  # windowへのショートカット
  def _w
    @window
  end

  # window.documentへのショートカット
  def _d
    _w.document
  end

  # window.document.getElementByIdへのショートカット
  def _e(id)
    _d.getElementById(id)
  end
end

sample.rb - このファイルに処理を実装する

require "hta-support"

class Sample < HTASupport
  def btnOk_onclick
    _e("lblOutput").innerHTML = "HelloWorld!!"
  end
end

sample.hta - HTA本体

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>サンプル</title>
		<style>
			body {
				background-color: ButtonFace;
			}
		</style>
		<script for="window" event="onload" language="RubyScript">
			require "sample"
			Sample.new(@window)
			@window.resizeTo(400, 100)
		</script>
		<hta:application
			applicationname="サンプル"
			version="1.0"
			singleinstance="no"
			showintaskbar="yes"
			navigable="no"
			windowstate="normal"
			border="dialog"
			innerborder="no"
			borderstyle="normal"
			contextmenu="yes"
			selection="yes"
			scroll="no"
			scrollflat="no"
			caption="yes"
			icon="explorer.exe"
			sysmenu="yes"
			maximizebutton="no"
			minimizebutton="yes"
			/>
	</head>
	<body>
		<input id="btnOk" type="submit" value="OK" />
		<span id="lblOutput">...</span>
	</body>
</html>



はまりどころ

openが何かの名前と衝突してるっぽくてうまく使えなかった。

そのときはKernel.openとすれば期待通りに動作する。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<title>サンプル</title>
		<script for="window" event="onload" language="RubyScript">
			@window.resizeTo(400, 100)
			
			def btnOk_onclick
				open("a.txt", "w") do |f|
					f.puts "aaa"
				end
			end
		</script>
	</head>
	<body>
		<input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" />
		<span id="lblOutput">...</span>
	</body>
</html>


ううーん

仕事ツール作りに使えるかな?

DBからselectした行はtableに出せば良さそう。


GUIエディタがほしいな。

hta:applicationタグを作ってくれたり、画面サイズを考慮しつつWYSIWYGでHTML編集したりとか。