diff --git a/honoka/src/honoka_def.h b/honoka/src/honoka_def.h
index 29171a7..66f7ffa 100644
--- a/honoka/src/honoka_def.h
+++ b/honoka/src/honoka_def.h
@@ -61,6 +61,8 @@
 #define HONOKA_DEFAULT_KEY_LOOKUPPAGEUP            "Page_Up"
 #define HONOKA_CONFIG_KEY_LOOKUPPAGEDOWN           "/IMEngine/Honoka/Key/LookupPageDown"
 #define HONOKA_DEFAULT_KEY_LOOKUPPAGEDOWN          "Page_Down"
+#define HONOKA_CONFIG_KEY_CONVERT_CTYPETOGGLE      "/IMEngine/Honoka/Key/ConvertCharsType"
+#define HONOKA_DEFAULT_KEY_CONVERT_CTYPETOGGLE     "Muhenkan"
 #define HONOKA_CONFIG_KEY_CONVERT_HIRAGANA         "/IMEngine/Honoka/Key/ConvertHiragana"
 #define HONOKA_DEFAULT_KEY_CONVERT_HIRAGANA        "Alt+h"
 #define HONOKA_CONFIG_KEY_CONVERT_KATAKANA         "/IMEngine/Honoka/Key/ConvertKatakana"
diff --git a/honoka/src/honoka_imengine.cpp b/honoka/src/honoka_imengine.cpp
index b6356d8..fd413d4 100644
--- a/honoka/src/honoka_imengine.cpp
+++ b/honoka/src/honoka_imengine.cpp
@@ -398,6 +398,9 @@
     scim_string_to_key_list(k_lookup_pagedown,
         _scim_config->read(String(HONOKA_CONFIG_KEY_LOOKUPPAGEDOWN),
             String(HONOKA_DEFAULT_KEY_LOOKUPPAGEDOWN)));
+    scim_string_to_key_list(k_convert_ctype,
+        _scim_config->read(String(HONOKA_CONFIG_KEY_CONVERT_CTYPETOGGLE),
+            String(HONOKA_DEFAULT_KEY_CONVERT_CTYPETOGGLE)));
     scim_string_to_key_list(k_convert_hiragana,
         _scim_config->read(String(HONOKA_CONFIG_KEY_CONVERT_HIRAGANA),
             String(HONOKA_DEFAULT_KEY_CONVERT_HIRAGANA)));
@@ -802,6 +805,7 @@
  */
 bool HonokaInstance::process_preedit_key_event(const KeyEvent &key)
 {
+    if (!m_preeditor->getTextLength()) pStringType = NORMAL;
     // PreEdit���Υ������٥�ȡ�
     // PreEditor�Υ������٥�ȥեå���
     if (m_preeditor->keyEventHook(key)) {
@@ -896,9 +900,49 @@
         } else
         if ((k_backspace.comp(key)) || (k_delete.comp(key))) {
             k_backspace.comp(key) ? m_preeditor->backspace(): m_preeditor->del();
+            if (preeditCache != m_preeditor->getText()) pStringType = NORMAL;
             updatePreEditor();
             return true;
         } else
+        if (k_convert_ctype.comp(key)) {
+            switch(pStringType) {
+                case NORMAL: {
+                    pString = m_preeditor->getText();
+                    pStringType = HIRA;
+                    m_preeditor->kataHira();
+                    break;
+                }
+                case HIRA: {
+                    m_preeditor->setText(pString);
+                    pStringType = KATA;
+                    m_preeditor->hiraKata();
+                    break;
+                }
+                case KATA: {
+                    m_preeditor->setText(pString);
+                    pStringType = HALF;
+                    m_preeditor->toHalf();
+                    break;
+                }
+                case HALF: {
+                    m_preeditor->setText(pString);
+                    pStringType = WIDE;
+                    m_preeditor->toWide();
+                    break;
+                }
+                case WIDE: {
+                    m_preeditor->setText(pString);
+                    pStringType = HIRA;
+                    m_preeditor->kataHira();
+                    break;
+                }
+                default: {
+                    break;
+                }
+            }
+            updatePreEditor();
+            return true;
+        }
         if (k_convert_hiragana.comp(key)) {
             m_preeditor->kataHira();
             updatePreEditor();
@@ -998,6 +1042,7 @@
     }
 
     if (m_preeditor->inputEvent(key)) {
+        if (preeditCache != m_preeditor->getText()) pStringType = NORMAL;
         updatePreEditor();
 
         return true;
@@ -1206,6 +1251,10 @@
     // �Ҥ餬��/���������Ѵ�������
     if (k_convert_hiragana.comp(key) || k_convert_katakana.comp(key)) {
         WideString res = m_convList.Yomi;
+        if (k_convert_hiragana.comp(key) && k_convert_katakana.comp(key)) {
+            PreEditor::convKataHira(res);
+            if (res == m_convList.kouho[m_convList.pos].kanji) PreEditor::convHiraKata(res);
+        } else
         k_convert_hiragana.comp(key) ? m_preeditor->convKataHira(res) : m_preeditor->convHiraKata(res);
         for(unsigned int i = 0;i < m_convList.count();i ++) {
             if (res == m_convList.kouho[i].kanji) {
diff --git a/honoka/src/honoka_imengine.h b/honoka/src/honoka_imengine.h
index aaac873..fad14e1 100644
--- a/honoka/src/honoka_imengine.h
+++ b/honoka/src/honoka_imengine.h
@@ -154,6 +154,9 @@
     int preeditKeyDelay;
     uint32 predictionDelay;
     WideString preeditCache;
+    enum convertedStringType { NORMAL , HIRA , KATA , HALF , WIDE };
+    WideString pString;
+    convertedStringType pStringType;
 protected:
     bool process_preedit_key_event(const KeyEvent &key);
     bool process_conversion_key_event(const KeyEvent &key);
@@ -197,6 +200,7 @@
         k_lookup_popup,         // �������ɽ��
         k_lookup_pageup,        // �����������
         k_lookup_pagedown,      // �����������
+        k_convert_ctype,        // ʸ�����Ѵ�
         k_convert_hiragana,     // �Ҥ餬���Ѵ�
         k_convert_katakana,     // ���������Ѵ�
         k_convert_half,         // Ⱦ���Ѵ�