diff --git a/scim-wnn/data/scim-wnn-def.rkt b/scim-wnn/data/scim-wnn-def.rkt
index 5d87d47..052aa7b 100644
--- a/scim-wnn/data/scim-wnn-def.rkt
+++ b/scim-wnn/data/scim-wnn-def.rkt
@@ -8,6 +8,14 @@
 # Ascii/WideAsciiモードへの移行キー。
 $Key/Ascii      q
 $Key/WideAscii  Shift+Q
+# フックを使う
+$Hook           Z
+# 特殊キー
+#!Control+Up     ↑
+#!Control+Down   ↓
+#!Control+Left   ←
+#!Control+Right  →
+
 a       あ
 i       い
 u       う
@@ -338,3 +346,5 @@
 zv      ※
 zw      》
 zx      :-
+Z\        # 全角スペース
+
diff --git a/scim-wnn/src/romkan.cpp b/scim-wnn/src/romkan.cpp
index b263c45..34e6c1a 100644
--- a/scim-wnn/src/romkan.cpp
+++ b/scim-wnn/src/romkan.cpp
@@ -110,6 +110,13 @@
             tableConfig.insert(pair<String,String>(k.substr(1),r));
             continue;
         }
+        if ((k[0] == '!') && (!inc) && ex) {
+            RomkanKeyEventList kev;
+            scim_string_to_key_list(kev,k.substr(1));
+            kev.p = utf8_mbstowcs(r);
+            hookKey.push_back(kev);
+            continue;
+        }
         if (!r.size()) continue;
         RomkanTable.insert(pair<String,WideString>(k,utf8_mbstowcs(r)));
         
@@ -163,6 +170,9 @@
         scim_string_to_key_list(key_ascii_mode,tableConfig["Key/Ascii"]);
     if (tableConfig.find("Key/WideAscii") != tableConfig.end())
         scim_string_to_key_list(key_wascii_mode,tableConfig["Key/WideAscii"]);
+    if (tableConfig.find("Hook") != tableConfig.end())
+        hookp = tableConfig["Hook"];
+    else hookp = "";
 
 }
 
@@ -406,14 +416,19 @@
             return(true);
         }
     }
-
-    if (!buf.length()) return(false);
-    if (buf[buf.length() - 1] == 'Z') {
-        if (key.code == SCIM_KEY_space) {
-            insert(' ');
+    
+    for(vector<RomkanKeyEventList>::iterator it = hookKey.begin();it != hookKey.end();it ++) {
+        if (it->comp(key)) {
+            text = text.substr(0,pos) + it->p + text.substr(pos);
+            pos += it->p.length();
             return(true);
         }
     }
+
+    if ((buf.length() < hookp.length()) || (!hookp.length())) return(false);
+    else if (buf.substr(buf.length() - hookp.length()) == hookp) {
+        return(inputEvent(key));
+    }
     return(false);
 }
 
@@ -479,7 +494,7 @@
     }
 
     if (key.get_ascii_code() && (!key.is_alt_down()) && (!key.is_control_down())) {
-        if (key.get_ascii_code() == ' ') return(false);
+        if ((key.get_ascii_code() == ' ') && (!getTextLength())) return(false);
         // ��ľ���֤��٤����
         if ((key.code == SCIM_KEY_Return) ||
             (key.code == SCIM_KEY_Linefeed) ||
diff --git a/scim-wnn/src/romkan.h b/scim-wnn/src/romkan.h
index 4a4f07c..c54abdd 100644
--- a/scim-wnn/src/romkan.h
+++ b/scim-wnn/src/romkan.h
@@ -41,6 +41,13 @@
     WideString kana;
 };
 
+class RomkanKeyEventList : public PreEditorKeyEventList
+{
+public:
+    WideString p;
+};
+
+
 class Romkan : public PreEditor {
 public:
     Romkan(ConfigPointer cfg);
@@ -83,6 +90,8 @@
     map<String,WideString> RomkanTable;
     set<String> keepTable;
     map<String,String> tableConfig;
+    String hookp;
+    vector<RomkanKeyEventList> hookKey;
 };
 
 #endif